blob: 6c717d0b6eca5f31c06ad2b352f1948a214fb07f [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"
Daniel Willmanna1e202e2015-12-07 17:21:07 +010048#include "hnbap_common.h"
49#include "hnbap_ies_defs.h"
Daniel Willmann97374c02015-12-03 09:37:58 +010050
51static void *tall_hnb_ctx;
52void *talloc_asn1_ctx;
53
54struct hnb_test g_hnb_test = {
55 .gw_port = IUH_DEFAULT_SCTP_PORT,
56};
57
58static int hnb_read_cb(struct osmo_fd *fd)
59{
60 struct hnb_test *hnb_test = fd->data;
61 struct sctp_sndrcvinfo sinfo;
62 struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");
63 int flags = 0;
64 int rc;
65
66 if (!msg)
67 return -ENOMEM;
68
69 rc = sctp_recvmsg(fd->fd, msgb_data(msg), msgb_tailroom(msg),
70 NULL, NULL, &sinfo, &flags);
71 if (rc < 0) {
72 LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");
73 /* FIXME: clean up after disappeared HNB */
74 return rc;
75 } else
76 msgb_put(msg, rc);
77
78 if (flags & MSG_NOTIFICATION) {
79 LOGP(DMAIN, LOGL_INFO, "Ignoring SCTP notification\n");
80 msgb_free(msg);
81 return 0;
82 }
83
84 sinfo.sinfo_ppid = ntohl(sinfo.sinfo_ppid);
85
86 switch (sinfo.sinfo_ppid) {
87 case IUH_PPI_HNBAP:
88 printf("HNBAP mesage received\n");
89// rc = hnbgw_hnbap_rx(hnb, msg);
90 break;
91 case IUH_PPI_RUA:
92 printf("RUA mesage received\n");
93// rc = hnbgw_rua_rx(hnb, msg);
94 break;
95 case IUH_PPI_SABP:
96 case IUH_PPI_RNA:
97 case IUH_PPI_PUA:
98 LOGP(DMAIN, LOGL_ERROR, "Unimplemented SCTP PPID=%u received\n",
99 sinfo.sinfo_ppid);
100 rc = 0;
101 break;
102 default:
103 LOGP(DMAIN, LOGL_ERROR, "Unknown SCTP PPID=%u received\n",
104 sinfo.sinfo_ppid);
105 rc = 0;
106 break;
107 }
108
109 msgb_free(msg);
110 return rc;
111}
112
113static int hnb_write_cb(struct osmo_fd *fd, struct msgb *msg)
114{
115 struct hnb_test *ctx = fd->data;
116 struct sctp_sndrcvinfo sinfo = {
117 .sinfo_ppid = htonl(msgb_ppid(msg)),
118 .sinfo_stream = 0,
119 };
120 int rc;
121
122 rc = sctp_send(fd->fd, msgb_data(msg), msgb_length(msg),
123 &sinfo, 0);
124 /* we don't need to msgb_free(), write_queue does this for us */
125 return rc;
126}
127
Daniel Willmann4aeef6c2015-12-03 17:02:13 +0100128#include "pdus.h"
129
130static void hnb_send_register_req(struct hnb_test *hnb_test)
131{
Daniel Willmanna1e202e2015-12-07 17:21:07 +0100132 HNBRegisterRequest_t request_out;
Daniel Willmann4aeef6c2015-12-03 17:02:13 +0100133 struct msgb *msg;
134 int rc;
Daniel Willmanna1e202e2015-12-07 17:21:07 +0100135 uint16_t lac, sac;
136 uint8_t rac;
137 uint32_t cid;
138 uint8_t plmn[] = {0x09, 0xf1, 0x99};
139 char identity[50] = "ATestHNB@";
Daniel Willmann4aeef6c2015-12-03 17:02:13 +0100140
Daniel Willmanna1e202e2015-12-07 17:21:07 +0100141 HNBRegisterRequestIEs_t request;
142 memset(&request, 0, sizeof(request));
Daniel Willmann4aeef6c2015-12-03 17:02:13 +0100143
Daniel Willmanna1e202e2015-12-07 17:21:07 +0100144 lac = 0xc0fe;
145 sac = 0xabab;
146 rac = 0x42;
Daniel Willmannd6a45b42015-12-08 13:55:17 +0100147 cid = 0xadceaab;
Daniel Willmann4aeef6c2015-12-03 17:02:13 +0100148
Daniel Willmanna1e202e2015-12-07 17:21:07 +0100149 asn1_u16_to_str(&request.lac, &lac, lac);
150 asn1_u16_to_str(&request.sac, &sac, sac);
151 asn1_u8_to_str(&request.rac, &rac, rac);
Daniel Willmannd6a45b42015-12-08 13:55:17 +0100152 asn1_u28_to_bitstring(&request.cellIdentity, &cid, cid);
Daniel Willmanna1e202e2015-12-07 17:21:07 +0100153
154 request.hnB_Identity.hNB_Identity_Info.buf = identity;
155 request.hnB_Identity.hNB_Identity_Info.size = strlen(identity);
156
157 request.plmNidentity.buf = plmn;
158 request.plmNidentity.size = 3;
159
160
161
162 memset(&request_out, 0, sizeof(request_out));
163 rc = hnbap_encode_hnbregisterrequesties(&request_out, &request);
164 if (rc < 0) {
165 printf("Could not encode HNB register request IEs\n");
166 }
167
168 msg = hnbap_generate_initiating_message(ProcedureCode_id_HNBRegister,
169 Criticality_reject,
170 &asn_DEF_HNBRegisterRequest,
171 &request_out);
172
Daniel Willmann4aeef6c2015-12-03 17:02:13 +0100173
174 msgb_ppid(msg) = IUH_PPI_HNBAP;
175
176 osmo_wqueue_enqueue(&hnb_test->wqueue, msg);
177}
178
179
Daniel Willmann97374c02015-12-03 09:37:58 +0100180static const struct log_info_cat log_cat[] = {
181 [DMAIN] = {
182 .name = "DMAIN", .loglevel = LOGL_DEBUG, .enabled = 1,
183 .color = "",
184 .description = "Main program",
185 },
186};
187
188static const struct log_info hnb_test_log_info = {
189 .cat = log_cat,
190 .num_cat = ARRAY_SIZE(log_cat),
191};
192
193static struct vty_app_info vty_info = {
194 .name = "OsmoHNB-Test",
195 .version = "0",
196};
197
198int main(int argc, const char *argv)
199{
200 int rc;
201
202 tall_hnb_ctx = talloc_named_const(NULL, 0, "hnb_context");
203 talloc_asn1_ctx = talloc_named_const(NULL, 0, "asn1_context");
204
205 rc = osmo_init_logging(&hnb_test_log_info);
206 if (rc < 0)
207 exit(1);
208
209 vty_init(&vty_info);
210
211 osmo_wqueue_init(&g_hnb_test.wqueue, 16);
212 g_hnb_test.wqueue.bfd.data = &g_hnb_test;
213 g_hnb_test.wqueue.read_cb = hnb_read_cb;
214 g_hnb_test.wqueue.write_cb = hnb_write_cb;
215
216 rc = osmo_sock_init_ofd(&g_hnb_test.wqueue.bfd, AF_INET, SOCK_STREAM,
217 IPPROTO_SCTP, "127.0.0.1",
218 g_hnb_test.gw_port, OSMO_SOCK_F_CONNECT);
219 if (rc < 0) {
220 perror("Error connecting to Iuh port");
221 exit(1);
222 }
223// sctp_sock_init(g_hnb_test.conn_fd);
224
Daniel Willmann4aeef6c2015-12-03 17:02:13 +0100225 hnb_send_register_req(&g_hnb_test);
226
Daniel Willmann97374c02015-12-03 09:37:58 +0100227 while (1) {
228 rc = osmo_select_main(0);
229 if (rc < 0)
230 exit(3);
231 }
232
233 /* not reached */
234 exit(0);
235}