Allocate g_hnb as a pointer, move code to hnb.c/h

Change-Id: I5ec61d2a72d55d182e1498939209b30b6e652467
This commit is contained in:
Pau Espin Pedrol
2021-10-27 18:38:52 +02:00
parent 8403def059
commit c1307f75b2
5 changed files with 178 additions and 127 deletions

View File

@@ -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
View 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;
}

View File

@@ -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);

View File

@@ -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;