blob: fc26d0de616860e8dee102779a03ac16c674e481 [file] [log] [blame]
Harald Weltea2e6a7a2015-08-29 21:47:39 +02001
2#include <osmocom/core/select.h>
3#include <osmocom/core/socket.h>
4#include <osmocom/core/linuxlist.h>
5
6#include "hnbgw.h"
7
8struct hnb_gw g_hnb_gw = {
9 .config = {
10 .iuh_listen_port = IUH_DEFAULT_SCTP_PORT,
11 },
12};
13
14static int hnb_socket_cb(struct osmo_fd *fd, unsigned int what)
15{
16 struct hnb_context *hnb = fd->data;
17 struct sctp_sndrcvinfo sinfo;
18 struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");
19 int flags;
20 int rc;
21
22 if (!msg)
23 return -ENOMEM;
24
25 rc = sctp_recvmsg(fd->fd, msgb_data(msg), msgb_tailroom(msg),
26 NULL, NULL, &sinfo, &flags);
27 if (rc < 0) {
28 LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
29 return rc;
30 } else
31 msgb_put(msg, rc);
32
33 switch (sinfo.sinfo_ppid) {
34 case IUH_PPI_HNBAP:
35 rc = hnbgw_hnbap_rx(hnb, msg);
36 break;
37 case IUH_PPI_RUA:
38 rc = hnbgw_rua_rx(hnb, msg);
39 break;
40 case IUH_PPI_SABP:
41 case IUH_PPI_RNA:
42 case IUH_PPI_PUA:
43 LOGP(DMAIN, LOGL_ERROR, "Unimplemented SCTP PPID=%u received\n",
44 sinfo.sinfo_ppid);
45 rc = 0;
46 break;
47 default:
48 LOGP(DMAIN, LOGL_ERROR, "Unknown SCTP PPID=%u received\n",
49 sinfo.sinfo_ppid);
50 rc = 0;
51 break;
52 }
53
54 return rc;
55}
56
57/*! call-back when the listen FD has something to read */
58static int listen_fd_cb(struct osmo_fd *fd, unsigned int what)
59{
60 struct hnb_gw *gw = fd->data;
61 struct hmb_context *ctx;
62 struct sokaddr_storage sockaddr;
63 socklen_t len = sizeof(sockaddr);
64
65 int new_fd = accept(fd->fd, (struct sockaddr *)&sockaddr, &len);
66 if (new_fd < 0) {
67 LOGP(DMAIN, LOGL_ERROR, "Iuh accept() failed\n");
68 return new_fd;
69 }
70
71 LOGP(DMAIN, LOGL_INFO, "SCTP Connection accept()ed\n");
72
73 ctx = talloc_zero(tall_hnb_ctx, struct hnb_context);
74 if (!ctx)
75 return -ENOMEM;
76
77 ctx->gw = gw;
78 ctx->socket.data = ctx;
79 ctx->socket.fd = new_fd;
80 ctx->socket.when = BSC_FD_READ;
81 ctx->socket.cb = hnb_socket_cb;
82 osmo_fd_register(&cttx->socket);
83
84 return 0;
85}
86
87
88
89{
90 g_hnb_gw.listen_fd.cb = listen_fd_cb;
91 g_hnb_gw.listen_fd.when = BSC_FD_READ;
92 g_hnb_gw.listen_fd.data = &g_hnb_gw;
93
94 osmo_sock_init_ofd(&g_hnb_gw.listen_fd, AF_INET, SOCK_STREAM,
95 IPPROTO_SCTP, "127.0.0.1",
96 g_hnb_gw.config.iuh_listen_port, OSMO_SOCK_F_BIND);
97}