aboutsummaryrefslogtreecommitdiffstats
path: root/src/hnbgw.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2015-08-29 21:47:39 +0200
committerHarald Welte <laforge@gnumonks.org>2015-08-29 21:47:39 +0200
commita2e6a7a05ef5ffa4fdbcebf28425d7e0b1eb5d6c (patch)
tree27f12669a2596bbdb1fef0f9fee9535fc304f188 /src/hnbgw.c
parent6392710f84a9f79818a93434ed567443021506d4 (diff)
further tiny steps of progress on the hnb-gw infrastructure
Diffstat (limited to 'src/hnbgw.c')
-rw-r--r--src/hnbgw.c97
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);
+}