diff options
Diffstat (limited to 'src/hnbgw.c')
-rw-r--r-- | src/hnbgw.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/hnbgw.c b/src/hnbgw.c new file mode 100644 index 0000000..fc26d0d --- /dev/null +++ b/src/hnbgw.c @@ -0,0 +1,97 @@ + +#include <osmocom/core/select.h> +#include <osmocom/core/socket.h> +#include <osmocom/core/linuxlist.h> + +#include "hnbgw.h" + +struct hnb_gw g_hnb_gw = { + .config = { + .iuh_listen_port = IUH_DEFAULT_SCTP_PORT, + }, +}; + +static int hnb_socket_cb(struct osmo_fd *fd, unsigned int what) +{ + struct hnb_context *hnb = fd->data; + struct sctp_sndrcvinfo sinfo; + struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx"); + int flags; + 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"); + return rc; + } else + msgb_put(msg, rc); + + switch (sinfo.sinfo_ppid) { + case IUH_PPI_HNBAP: + rc = hnbgw_hnbap_rx(hnb, msg); + break; + case IUH_PPI_RUA: + rc = hnbgw_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; + } + + return rc; +} + +/*! call-back when the listen FD has something to read */ +static int listen_fd_cb(struct osmo_fd *fd, unsigned int what) +{ + struct hnb_gw *gw = fd->data; + struct hmb_context *ctx; + struct sokaddr_storage sockaddr; + socklen_t len = sizeof(sockaddr); + + int new_fd = accept(fd->fd, (struct sockaddr *)&sockaddr, &len); + if (new_fd < 0) { + LOGP(DMAIN, LOGL_ERROR, "Iuh accept() failed\n"); + return new_fd; + } + + LOGP(DMAIN, LOGL_INFO, "SCTP Connection accept()ed\n"); + + ctx = talloc_zero(tall_hnb_ctx, struct hnb_context); + if (!ctx) + return -ENOMEM; + + ctx->gw = gw; + ctx->socket.data = ctx; + ctx->socket.fd = new_fd; + ctx->socket.when = BSC_FD_READ; + ctx->socket.cb = hnb_socket_cb; + osmo_fd_register(&cttx->socket); + + return 0; +} + + + +{ + g_hnb_gw.listen_fd.cb = listen_fd_cb; + g_hnb_gw.listen_fd.when = BSC_FD_READ; + g_hnb_gw.listen_fd.data = &g_hnb_gw; + + osmo_sock_init_ofd(&g_hnb_gw.listen_fd, AF_INET, SOCK_STREAM, + IPPROTO_SCTP, "127.0.0.1", + g_hnb_gw.config.iuh_listen_port, OSMO_SOCK_F_BIND); +} |