blob: 2823076822f3fc22f24359d5ee2fb8448eba1771 [file] [log] [blame]
Daniel Willmann97374c02015-12-03 09:37:58 +01001/* Test HNB */
2
3/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de>
4 * (C) 2015 by Sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#include <unistd.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <getopt.h>
27#include <errno.h>
28#include <signal.h>
29
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <netinet/in.h>
33#include <netinet/sctp.h>
34#include <arpa/inet.h>
35
36#include <osmocom/core/application.h>
37#include <osmocom/core/talloc.h>
38#include <osmocom/core/select.h>
39#include <osmocom/core/logging.h>
40#include <osmocom/core/socket.h>
41#include <osmocom/core/msgb.h>
42#include <osmocom/core/write_queue.h>
43
44#include <osmocom/vty/telnet_interface.h>
45#include <osmocom/vty/logging.h>
46
47#include "hnb-test.h"
48
49static void *tall_hnb_ctx;
50void *talloc_asn1_ctx;
51
52struct hnb_test g_hnb_test = {
53 .gw_port = IUH_DEFAULT_SCTP_PORT,
54};
55
56static int hnb_read_cb(struct osmo_fd *fd)
57{
58 struct hnb_test *hnb_test = fd->data;
59 struct sctp_sndrcvinfo sinfo;
60 struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");
61 int flags = 0;
62 int rc;
63
64 if (!msg)
65 return -ENOMEM;
66
67 rc = sctp_recvmsg(fd->fd, msgb_data(msg), msgb_tailroom(msg),
68 NULL, NULL, &sinfo, &flags);
69 if (rc < 0) {
70 LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
71 /* FIXME: clean up after disappeared HNB */
72 return rc;
73 } else
74 msgb_put(msg, rc);
75
76 if (flags & MSG_NOTIFICATION) {
77 LOGP(DMAIN, LOGL_INFO, "Ignoring SCTP notification\n");
78 msgb_free(msg);
79 return 0;
80 }
81
82 sinfo.sinfo_ppid = ntohl(sinfo.sinfo_ppid);
83
84 switch (sinfo.sinfo_ppid) {
85 case IUH_PPI_HNBAP:
86 printf("HNBAP mesage received\n");
87// rc = hnbgw_hnbap_rx(hnb, msg);
88 break;
89 case IUH_PPI_RUA:
90 printf("RUA mesage received\n");
91// rc = hnbgw_rua_rx(hnb, msg);
92 break;
93 case IUH_PPI_SABP:
94 case IUH_PPI_RNA:
95 case IUH_PPI_PUA:
96 LOGP(DMAIN, LOGL_ERROR, "Unimplemented SCTP PPID=%u received\n",
97 sinfo.sinfo_ppid);
98 rc = 0;
99 break;
100 default:
101 LOGP(DMAIN, LOGL_ERROR, "Unknown SCTP PPID=%u received\n",
102 sinfo.sinfo_ppid);
103 rc = 0;
104 break;
105 }
106
107 msgb_free(msg);
108 return rc;
109}
110
111static int hnb_write_cb(struct osmo_fd *fd, struct msgb *msg)
112{
113 struct hnb_test *ctx = fd->data;
114 struct sctp_sndrcvinfo sinfo = {
115 .sinfo_ppid = htonl(msgb_ppid(msg)),
116 .sinfo_stream = 0,
117 };
118 int rc;
119
120 rc = sctp_send(fd->fd, msgb_data(msg), msgb_length(msg),
121 &sinfo, 0);
122 /* we don't need to msgb_free(), write_queue does this for us */
123 return rc;
124}
125
Daniel Willmann4aeef6c2015-12-03 17:02:13 +0100126#include "pdus.h"
127
128static void hnb_send_register_req(struct hnb_test *hnb_test)
129{
130 struct msgb *msg;
131 int rc;
132
133 msg = msgb_alloc(1024, "HNBAP Tx");
134
135 memcpy(msgb_data(msg), hnbap_reg_req, sizeof(hnbap_reg_req));
136
137 msgb_put(msg, sizeof(hnbap_reg_req));
138
139 msgb_ppid(msg) = IUH_PPI_HNBAP;
140
141 osmo_wqueue_enqueue(&hnb_test->wqueue, msg);
142}
143
144
Daniel Willmann97374c02015-12-03 09:37:58 +0100145static const struct log_info_cat log_cat[] = {
146 [DMAIN] = {
147 .name = "DMAIN", .loglevel = LOGL_DEBUG, .enabled = 1,
148 .color = "",
149 .description = "Main program",
150 },
151};
152
153static const struct log_info hnb_test_log_info = {
154 .cat = log_cat,
155 .num_cat = ARRAY_SIZE(log_cat),
156};
157
158static struct vty_app_info vty_info = {
159 .name = "OsmoHNB-Test",
160 .version = "0",
161};
162
163int main(int argc, const char *argv)
164{
165 int rc;
166
167 tall_hnb_ctx = talloc_named_const(NULL, 0, "hnb_context");
168 talloc_asn1_ctx = talloc_named_const(NULL, 0, "asn1_context");
169
170 rc = osmo_init_logging(&hnb_test_log_info);
171 if (rc < 0)
172 exit(1);
173
174 vty_init(&vty_info);
175
176 osmo_wqueue_init(&g_hnb_test.wqueue, 16);
177 g_hnb_test.wqueue.bfd.data = &g_hnb_test;
178 g_hnb_test.wqueue.read_cb = hnb_read_cb;
179 g_hnb_test.wqueue.write_cb = hnb_write_cb;
180
181 rc = osmo_sock_init_ofd(&g_hnb_test.wqueue.bfd, AF_INET, SOCK_STREAM,
182 IPPROTO_SCTP, "127.0.0.1",
183 g_hnb_test.gw_port, OSMO_SOCK_F_CONNECT);
184 if (rc < 0) {
185 perror("Error connecting to Iuh port");
186 exit(1);
187 }
188// sctp_sock_init(g_hnb_test.conn_fd);
189
Daniel Willmann4aeef6c2015-12-03 17:02:13 +0100190 hnb_send_register_req(&g_hnb_test);
191
Daniel Willmann97374c02015-12-03 09:37:58 +0100192 while (1) {
193 rc = osmo_select_main(0);
194 if (rc < 0)
195 exit(3);
196 }
197
198 /* not reached */
199 exit(0);
200}