mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-hnodeb.git
synced 2025-11-03 05:33:32 +00:00
Allocate g_hnb as a pointer, move code to hnb.c/h
Change-Id: I5ec61d2a72d55d182e1498939209b30b6e652467
This commit is contained in:
@@ -32,6 +32,7 @@ osmo_hnodeb_SOURCES = \
|
||||
main.c \
|
||||
debug.c \
|
||||
hnbap.c \
|
||||
hnb.c \
|
||||
ranap.c \
|
||||
rua.c \
|
||||
vty.c \
|
||||
|
||||
161
src/osmo-hnodeb/hnb.c
Normal file
161
src/osmo-hnodeb/hnb.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de>
|
||||
* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/lienses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/netif/stream.h>
|
||||
|
||||
#include <osmocom/hnodeb/hnbap.h>
|
||||
#include <osmocom/hnodeb/rua.h>
|
||||
#include <osmocom/hnodeb/hnodeb.h>
|
||||
|
||||
static int sctp_sock_init(int fd)
|
||||
{
|
||||
struct sctp_event_subscribe event;
|
||||
int rc;
|
||||
|
||||
/* subscribe for all events */
|
||||
memset((uint8_t *)&event, 1, sizeof(event));
|
||||
rc = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS,
|
||||
&event, sizeof(event));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int hnb_read_cb(struct osmo_fd *fd)
|
||||
{
|
||||
struct hnb *hnb = fd->data;
|
||||
struct sctp_sndrcvinfo sinfo;
|
||||
struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");
|
||||
int flags = 0;
|
||||
int rc;
|
||||
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = sctp_recvmsg(fd->fd, msgb_data(msg), msgb_tailroom(msg),
|
||||
NULL, NULL, &sinfo, &flags);
|
||||
if (rc < 0) {
|
||||
LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
|
||||
/* FIXME: clean up after disappeared HNB */
|
||||
close(fd->fd);
|
||||
osmo_fd_unregister(fd);
|
||||
return rc;
|
||||
} else if (rc == 0) {
|
||||
LOGP(DMAIN, LOGL_INFO, "Connection to HNB closed\n");
|
||||
close(fd->fd);
|
||||
osmo_fd_unregister(fd);
|
||||
fd->fd = -1;
|
||||
|
||||
return -1;
|
||||
} else {
|
||||
msgb_put(msg, rc);
|
||||
}
|
||||
|
||||
if (flags & MSG_NOTIFICATION) {
|
||||
LOGP(DMAIN, LOGL_DEBUG, "Ignoring SCTP notification\n");
|
||||
msgb_free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sinfo.sinfo_ppid = ntohl(sinfo.sinfo_ppid);
|
||||
|
||||
switch (sinfo.sinfo_ppid) {
|
||||
case IUH_PPI_HNBAP:
|
||||
printf("HNBAP message received\n");
|
||||
rc = hnb_hnbap_rx(hnb, msg);
|
||||
break;
|
||||
case IUH_PPI_RUA:
|
||||
printf("RUA message received\n");
|
||||
rc = hnb_rua_rx(hnb, msg);
|
||||
break;
|
||||
case IUH_PPI_SABP:
|
||||
case IUH_PPI_RNA:
|
||||
case IUH_PPI_PUA:
|
||||
LOGP(DMAIN, LOGL_ERROR, "Unimplemented SCTP PPID=%u received\n",
|
||||
sinfo.sinfo_ppid);
|
||||
rc = 0;
|
||||
break;
|
||||
default:
|
||||
LOGP(DMAIN, LOGL_ERROR, "Unknown SCTP PPID=%u received\n",
|
||||
sinfo.sinfo_ppid);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
msgb_free(msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int hnb_write_cb(struct osmo_fd *fd, struct msgb *msg)
|
||||
{
|
||||
/* struct hnb *ctx = fd->data; */
|
||||
struct sctp_sndrcvinfo sinfo = {
|
||||
.sinfo_ppid = htonl(msgb_sctp_ppid(msg)),
|
||||
.sinfo_stream = 0,
|
||||
};
|
||||
int rc;
|
||||
|
||||
printf("Sending: %s\n", osmo_hexdump(msgb_data(msg), msgb_length(msg)));
|
||||
rc = sctp_send(fd->fd, msgb_data(msg), msgb_length(msg),
|
||||
&sinfo, 0);
|
||||
/* we don't need to msgb_free(), write_queue does this for us */
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct hnb *hnb_alloc(void *tall_ctx)
|
||||
{
|
||||
struct hnb *hnb;
|
||||
hnb = talloc_zero(tall_ctx, struct hnb);
|
||||
if (!hnb)
|
||||
return NULL;
|
||||
|
||||
hnb->gw_addr = "127.0.0.1",
|
||||
hnb->gw_port = IUH_DEFAULT_SCTP_PORT,
|
||||
|
||||
osmo_wqueue_init(&hnb->wqueue, 16);
|
||||
hnb->wqueue.bfd.data = hnb;
|
||||
hnb->wqueue.read_cb = hnb_read_cb;
|
||||
hnb->wqueue.write_cb = hnb_write_cb;
|
||||
|
||||
return hnb;
|
||||
}
|
||||
|
||||
int hnb_connect(struct hnb *hnb)
|
||||
{
|
||||
int rc;
|
||||
rc = osmo_sock_init_ofd(&hnb->wqueue.bfd, AF_INET, SOCK_STREAM,
|
||||
IPPROTO_SCTP, hnb->gw_addr,
|
||||
hnb->gw_port, OSMO_SOCK_F_CONNECT);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
sctp_sock_init(hnb->wqueue.bfd.fd);
|
||||
return 0;
|
||||
}
|
||||
@@ -28,20 +28,11 @@
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocom/core/application.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
#include <osmocom/netif/stream.h>
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
|
||||
@@ -72,11 +63,7 @@
|
||||
#include <osmocom/hnodeb/hnodeb.h>
|
||||
|
||||
void *tall_hnb_ctx;
|
||||
|
||||
struct hnb g_hnb = {
|
||||
.gw_addr = "127.0.0.1",
|
||||
.gw_port = IUH_DEFAULT_SCTP_PORT,
|
||||
};
|
||||
struct hnb *g_hnb;
|
||||
|
||||
struct msgb *rua_new_udt(struct msgb *inmsg);
|
||||
|
||||
@@ -130,7 +117,7 @@ static int hnb_tx_dt(struct hnb *hnb, struct msgb *txm)
|
||||
}
|
||||
|
||||
rua = rua_new_dt(chan->is_ps, chan->conn_id, txm);
|
||||
osmo_wqueue_enqueue(&g_hnb.wqueue, rua);
|
||||
osmo_wqueue_enqueue(&hnb->wqueue, rua);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -360,105 +347,11 @@ void hnb_rx_paging(struct hnb *hnb, const char *imsi)
|
||||
|
||||
extern void direct_transfer_nas_pdu_print(ANY_t *in);
|
||||
|
||||
static int hnb_read_cb(struct osmo_fd *fd)
|
||||
{
|
||||
struct hnb *hnb = fd->data;
|
||||
struct sctp_sndrcvinfo sinfo;
|
||||
struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");
|
||||
int flags = 0;
|
||||
int rc;
|
||||
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = sctp_recvmsg(fd->fd, msgb_data(msg), msgb_tailroom(msg),
|
||||
NULL, NULL, &sinfo, &flags);
|
||||
if (rc < 0) {
|
||||
LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
|
||||
/* FIXME: clean up after disappeared HNB */
|
||||
close(fd->fd);
|
||||
osmo_fd_unregister(fd);
|
||||
return rc;
|
||||
} else if (rc == 0) {
|
||||
LOGP(DMAIN, LOGL_INFO, "Connection to HNB closed\n");
|
||||
close(fd->fd);
|
||||
osmo_fd_unregister(fd);
|
||||
fd->fd = -1;
|
||||
|
||||
return -1;
|
||||
} else {
|
||||
msgb_put(msg, rc);
|
||||
}
|
||||
|
||||
if (flags & MSG_NOTIFICATION) {
|
||||
LOGP(DMAIN, LOGL_DEBUG, "Ignoring SCTP notification\n");
|
||||
msgb_free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sinfo.sinfo_ppid = ntohl(sinfo.sinfo_ppid);
|
||||
|
||||
switch (sinfo.sinfo_ppid) {
|
||||
case IUH_PPI_HNBAP:
|
||||
printf("HNBAP message received\n");
|
||||
rc = hnb_hnbap_rx(hnb, msg);
|
||||
break;
|
||||
case IUH_PPI_RUA:
|
||||
printf("RUA message received\n");
|
||||
rc = hnb_rua_rx(hnb, msg);
|
||||
break;
|
||||
case IUH_PPI_SABP:
|
||||
case IUH_PPI_RNA:
|
||||
case IUH_PPI_PUA:
|
||||
LOGP(DMAIN, LOGL_ERROR, "Unimplemented SCTP PPID=%u received\n",
|
||||
sinfo.sinfo_ppid);
|
||||
rc = 0;
|
||||
break;
|
||||
default:
|
||||
LOGP(DMAIN, LOGL_ERROR, "Unknown SCTP PPID=%u received\n",
|
||||
sinfo.sinfo_ppid);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
msgb_free(msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int hnb_write_cb(struct osmo_fd *fd, struct msgb *msg)
|
||||
{
|
||||
/* struct hnb *ctx = fd->data; */
|
||||
struct sctp_sndrcvinfo sinfo = {
|
||||
.sinfo_ppid = htonl(msgb_sctp_ppid(msg)),
|
||||
.sinfo_stream = 0,
|
||||
};
|
||||
int rc;
|
||||
|
||||
printf("Sending: %s\n", osmo_hexdump(msgb_data(msg), msgb_length(msg)));
|
||||
rc = sctp_send(fd->fd, msgb_data(msg), msgb_length(msg),
|
||||
&sinfo, 0);
|
||||
/* we don't need to msgb_free(), write_queue does this for us */
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct vty_app_info vty_info = {
|
||||
.name = "OsmohNodeB",
|
||||
.version = "0",
|
||||
};
|
||||
|
||||
static int sctp_sock_init(int fd)
|
||||
{
|
||||
struct sctp_event_subscribe event;
|
||||
int rc;
|
||||
|
||||
/* subscribe for all events */
|
||||
memset((uint8_t *)&event, 1, sizeof(event));
|
||||
rc = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS,
|
||||
&event, sizeof(event));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi)
|
||||
{
|
||||
@@ -509,10 +402,10 @@ static void handle_options(int argc, char **argv)
|
||||
|
||||
switch (c) {
|
||||
case 'u':
|
||||
g_hnb.ues = atoi(optarg);
|
||||
g_hnb->ues = atoi(optarg);
|
||||
break;
|
||||
case 'g':
|
||||
g_hnb.gw_addr = optarg;
|
||||
g_hnb->gw_addr = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -538,6 +431,8 @@ int main(int argc, char **argv)
|
||||
log_set_print_category(osmo_stderr_target, 0);
|
||||
log_set_print_category_hex(osmo_stderr_target, 0);
|
||||
|
||||
g_hnb = hnb_alloc(tall_hnb_ctx);
|
||||
|
||||
vty_init(&vty_info);
|
||||
hnb_vty_init();
|
||||
|
||||
@@ -549,19 +444,11 @@ int main(int argc, char **argv)
|
||||
|
||||
handle_options(argc, argv);
|
||||
|
||||
osmo_wqueue_init(&g_hnb.wqueue, 16);
|
||||
g_hnb.wqueue.bfd.data = &g_hnb;
|
||||
g_hnb.wqueue.read_cb = hnb_read_cb;
|
||||
g_hnb.wqueue.write_cb = hnb_write_cb;
|
||||
|
||||
rc = osmo_sock_init_ofd(&g_hnb.wqueue.bfd, AF_INET, SOCK_STREAM,
|
||||
IPPROTO_SCTP, g_hnb.gw_addr,
|
||||
g_hnb.gw_port, OSMO_SOCK_F_CONNECT);
|
||||
rc = hnb_connect(g_hnb);
|
||||
if (rc < 0) {
|
||||
perror("Error connecting to Iuh port");
|
||||
exit(1);
|
||||
}
|
||||
sctp_sock_init(g_hnb.wqueue.bfd.fd);
|
||||
|
||||
while (1) {
|
||||
rc = osmo_select_main(0);
|
||||
|
||||
@@ -51,7 +51,7 @@ static struct cmd_node chan_node = {
|
||||
DEFUN(hnb_register, hnb_register_cmd,
|
||||
"hnbap hnb register", HNBAP_STR HNB_STR "Send HNB-REGISTER REQUEST")
|
||||
{
|
||||
hnb_send_register_req(&g_hnb);
|
||||
hnb_send_register_req(g_hnb);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ DEFUN(hnb_register, hnb_register_cmd,
|
||||
DEFUN(hnb_deregister, hnb_deregister_cmd,
|
||||
"hnbap hnb deregister", HNBAP_STR HNB_STR "Send HNB-DEREGISTER REQUEST")
|
||||
{
|
||||
hnb_send_deregister_req(&g_hnb);
|
||||
hnb_send_deregister_req(g_hnb);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ DEFUN(hnb_deregister, hnb_deregister_cmd,
|
||||
DEFUN(ue_register, ue_register_cmd,
|
||||
"hnbap ue register IMSI", HNBAP_STR UE_STR "Send UE-REGISTER REQUEST")
|
||||
{
|
||||
hnb_ue_register_tx(&g_hnb, argv[0]);
|
||||
hnb_ue_register_tx(g_hnb, argv[0]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -97,7 +97,7 @@ DEFUN(ranap_reset, ranap_reset_cmd,
|
||||
msg = ranap_new_msg_reset(is_ps, &cause);
|
||||
rua = rua_new_udt(msg);
|
||||
//msgb_free(msg);
|
||||
osmo_wqueue_enqueue(&g_hnb.wqueue, rua);
|
||||
osmo_wqueue_enqueue(&g_hnb->wqueue, rua);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -124,13 +124,13 @@ DEFUN(chan, chan_cmd,
|
||||
msg = gen_initue_lu(chan->is_ps, chan->conn_id, chan->imsi);
|
||||
rua = rua_new_conn(chan->is_ps, chan->conn_id, msg);
|
||||
|
||||
osmo_wqueue_enqueue(&g_hnb.wqueue, rua);
|
||||
osmo_wqueue_enqueue(&g_hnb->wqueue, rua);
|
||||
|
||||
vty->index = chan;
|
||||
vty->node = CHAN_NODE;
|
||||
|
||||
if (!chan->is_ps)
|
||||
g_hnb.cs.chan = chan;
|
||||
g_hnb->cs.chan = chan;
|
||||
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user