blob: 0b2794f1350fec91e344b3f01a2a53eb283d150f [file] [log] [blame]
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001/*
2 * (C) 2012 by Holger Hans Peter Freyther
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 */
20
21#include <osmocom/gsm/gsm0808.h>
Philipp Maier22401432017-03-24 17:59:26 +010022#include <osmocom/gsm/gsm0808_utils.h>
23#include <osmocom/gsm/protocol/gsm_08_08.h>
Philipp Maier3d48ec02017-03-29 17:37:55 +020024#include <osmocom/gsm/protocol/gsm_08_58.h>
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010025
26#include <stdio.h>
27#include <stdlib.h>
Philipp Maier22401432017-03-24 17:59:26 +010028#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
Neels Hofmeyr74663d92018-03-23 01:46:42 +010031#include <errno.h>
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010032
33#define VERIFY(msg, data, len) \
34 if (msgb_l3len(msg) != len) { \
35 printf("%s:%d Length don't match: %d vs. %d. %s\n", \
Holger Hans Peter Freytherfdb46672015-11-09 16:32:43 +000036 __func__, __LINE__, msgb_l3len(msg), (int) len, \
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010037 osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
38 abort(); \
39 } else if (memcmp(msg->l3h, data, len) != 0) { \
40 printf("%s:%d didn't match: got: %s\n", \
41 __func__, __LINE__, \
42 osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
43 abort(); \
44 }
45
Philipp Maierfa896ab2017-03-27 16:55:32 +020046/* Setup a fake codec list for testing */
47static void setup_codec_list(struct gsm0808_speech_codec_list *scl)
48{
49 memset(scl, 0, sizeof(*scl));
50
51 scl->codec[0].pi = true;
52 scl->codec[0].tf = true;
Philipp Maierbb839662017-06-01 17:11:19 +020053 scl->codec[0].type = GSM0808_SCT_FR3;
Philipp Maierfa896ab2017-03-27 16:55:32 +020054 scl->codec[0].cfg = 0xcdef;
55
56 scl->codec[1].fi = true;
57 scl->codec[1].pt = true;
Philipp Maierbb839662017-06-01 17:11:19 +020058 scl->codec[1].type = GSM0808_SCT_FR2;
Philipp Maierfa896ab2017-03-27 16:55:32 +020059
60 scl->codec[2].fi = true;
61 scl->codec[2].tf = true;
Philipp Maierbb839662017-06-01 17:11:19 +020062 scl->codec[2].type = GSM0808_SCT_CSD;
63 scl->codec[2].cfg = 0xc0;
Philipp Maierfa896ab2017-03-27 16:55:32 +020064
65 scl->len = 3;
66}
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010067
68static void test_create_layer3(void)
69{
70 static const uint8_t res[] = {
71 0x00, 0x0e, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
72 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23 };
73 struct msgb *msg, *in_msg;
Neels Hofmeyr178bf7a2018-04-20 12:23:45 +020074 struct osmo_cell_global_id cgi = {
75 .lai = {
76 .plmn = {
77 .mcc = 0x2244,
78 .mnc = 0x1122,
79 },
80 .lac = 0x3366,
81 },
82 .cell_identity = 0x4488,
83 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010084 printf("Testing creating Layer3\n");
85
86 in_msg = msgb_alloc_headroom(512, 128, "foo");
87 in_msg->l3h = in_msg->data;
88 msgb_v_put(in_msg, 0x23);
89
Neels Hofmeyr178bf7a2018-04-20 12:23:45 +020090 msg = gsm0808_create_layer3_2(in_msg, &cgi, NULL);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010091 VERIFY(msg, res, ARRAY_SIZE(res));
92 msgb_free(msg);
93 msgb_free(in_msg);
94}
95
Philipp Maierfa896ab2017-03-27 16:55:32 +020096static void test_create_layer3_aoip()
97{
98 static const uint8_t res[] = {
99 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
100 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23,
Philipp Maierbb839662017-06-01 17:11:19 +0200101 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, GSM0808_SCT_FR3 | 0x50,
Philipp Maier7e27b142018-03-22 17:26:46 +0100102 0xef, 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f,
Philipp Maierbb839662017-06-01 17:11:19 +0200103 GSM0808_SCT_CSD | 0x90, 0xc0
Philipp Maierfa896ab2017-03-27 16:55:32 +0200104 };
105
106 struct msgb *msg, *in_msg;
107 struct gsm0808_speech_codec_list sc_list;
108 printf("Testing creating Layer3 (AoIP)\n");
109
110 setup_codec_list(&sc_list);
111
112 in_msg = msgb_alloc_headroom(512, 128, "foo");
113 in_msg->l3h = in_msg->data;
114 msgb_v_put(in_msg, 0x23);
115
116 msg =
117 gsm0808_create_layer3_aoip(in_msg, 0x1122, 0x2244, 0x3366, 0x4488,
118 &sc_list);
119 VERIFY(msg, res, ARRAY_SIZE(res));
120
121 msgb_free(msg);
122 msgb_free(in_msg);
123}
124
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100125static void test_create_reset()
126{
127 static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 };
128 struct msgb *msg;
129
130 printf("Testing creating Reset\n");
131 msg = gsm0808_create_reset();
132 VERIFY(msg, res, ARRAY_SIZE(res));
133 msgb_free(msg);
134}
135
Philipp Maier15596e22017-04-05 17:55:27 +0200136static void test_create_reset_ack()
137{
138 static const uint8_t res[] = { 0x00, 0x01, 0x31 };
139 struct msgb *msg;
140
141 printf("Testing creating Reset Ack\n");
142 msg = gsm0808_create_reset_ack();
143 VERIFY(msg, res, ARRAY_SIZE(res));
144 msgb_free(msg);
145}
146
147
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100148static void test_create_clear_command()
149{
150 static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 };
151 struct msgb *msg;
152
153 printf("Testing creating Clear Command\n");
154 msg = gsm0808_create_clear_command(0x23);
155 VERIFY(msg, res, ARRAY_SIZE(res));
156 msgb_free(msg);
157}
158
159static void test_create_clear_complete()
160{
161 static const uint8_t res[] = { 0x00, 0x01, 0x21 };
162 struct msgb *msg;
163
164 printf("Testing creating Clear Complete\n");
165 msg = gsm0808_create_clear_complete();
166 VERIFY(msg, res, ARRAY_SIZE(res));
167 msgb_free(msg);
168}
169
Philipp Maierb478dd32017-03-29 15:50:05 +0200170static void test_create_cipher()
171{
172 static const uint8_t res[] =
173 { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa,
174 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 };
175 static const uint8_t res2[] =
176 { 0x00, 0x0e, 0x53, 0x0a, 0x09, 0x03, 0xaa,
177 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42,
178 GSM0808_IE_CIPHER_RESPONSE_MODE, 0x01 };
179 struct msgb *msg;
180 struct gsm0808_encrypt_info ei;
181 uint8_t include_imeisv;
182
183 memset(&ei, 0, sizeof(ei));
184 ei.perm_algo[0] = GSM0808_ALG_ID_A5_0;
185 ei.perm_algo[1] = GSM0808_ALG_ID_A5_1;
186 ei.perm_algo_len = 2;
187 ei.key[0] = 0xaa;
188 ei.key[1] = 0xbb;
189 ei.key[2] = 0xcc;
190 ei.key[3] = 0xdd;
191 ei.key[4] = 0xee;
192 ei.key[5] = 0xff;
193 ei.key[6] = 0x23;
194 ei.key[7] = 0x42;
195 ei.key_len = 8;
196 include_imeisv = 1;
197
198 printf("Testing creating Chipher Mode Command\n");
199 msg = gsm0808_create_cipher(&ei, NULL);
200 OSMO_ASSERT(msg);
201 VERIFY(msg, res, ARRAY_SIZE(res));
202 msgb_free(msg);
203
204 msg = gsm0808_create_cipher(&ei, &include_imeisv);
205 OSMO_ASSERT(msg);
206 VERIFY(msg, res2, ARRAY_SIZE(res2));
207 msgb_free(msg);
208}
209
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100210static void test_create_cipher_complete()
211{
212 static const uint8_t res1[] = {
213 0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 };
214 static const uint8_t res2[] = { 0x00, 0x03, 0x55, 0x2c, 0x04};
215 struct msgb *l3, *msg;
216
217 printf("Testing creating Cipher Complete\n");
218 l3 = msgb_alloc_headroom(512, 128, "l3h");
219 l3->l3h = l3->data;
220 msgb_v_put(l3, 0x23);
221 msgb_v_put(l3, 0x42);
222 msgb_v_put(l3, 0x21);
223
224 /* with l3 data */
225 msg = gsm0808_create_cipher_complete(l3, 4);
226 VERIFY(msg, res1, ARRAY_SIZE(res1));
227 msgb_free(msg);
228
229 /* with l3 data but short */
230 l3->len -= 1;
231 l3->tail -= 1;
232 msg = gsm0808_create_cipher_complete(l3, 4);
233 VERIFY(msg, res2, ARRAY_SIZE(res2));
234 msgb_free(msg);
235
236 /* without l3 data */
237 msg = gsm0808_create_cipher_complete(NULL, 4);
238 VERIFY(msg, res2, ARRAY_SIZE(res2));
239 msgb_free(msg);
240
241
242 msgb_free(l3);
243}
244
245static void test_create_cipher_reject()
246{
Harald Welte62e40852017-12-17 20:50:34 +0100247 static const uint8_t res[] = { 0x00, 0x04, 0x59, 0x04, 0x01, 0x23 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100248 struct msgb *msg;
249
250 printf("Testing creating Cipher Reject\n");
251 msg = gsm0808_create_cipher_reject(0x23);
252 VERIFY(msg, res, ARRAY_SIZE(res));
253 msgb_free(msg);
254}
255
256static void test_create_cm_u()
257{
Harald Welte07b625d2012-01-23 10:02:58 +0100258 static const uint8_t res[] = {
259 0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 };
260 static const uint8_t res2o[] = {
261 0x00, 0x04, 0x54, 0x12, 0x01, 0x23 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100262 struct msgb *msg;
Harald Welte07b625d2012-01-23 10:02:58 +0100263 const uint8_t cm2 = 0x23;
264 const uint8_t cm3 = 0x42;
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100265
266 printf("Testing creating CM U\n");
Harald Welte07b625d2012-01-23 10:02:58 +0100267 msg = gsm0808_create_classmark_update(&cm2, 1, &cm3, 1);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100268 VERIFY(msg, res, ARRAY_SIZE(res));
Harald Welte07b625d2012-01-23 10:02:58 +0100269
Neels Hofmeyr9a938ae2017-11-16 17:34:07 +0100270 msgb_free(msg);
271
Harald Welte07b625d2012-01-23 10:02:58 +0100272 msg = gsm0808_create_classmark_update(&cm2, 1, NULL, 0);
273 VERIFY(msg, res2o, ARRAY_SIZE(res2o));
274
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100275 msgb_free(msg);
276}
277
278static void test_create_sapi_reject()
279{
280 static const uint8_t res[] = { 0x00, 0x03, 0x25, 0x03, 0x25 };
281 struct msgb *msg;
282
283 printf("Testing creating SAPI Reject\n");
284 msg = gsm0808_create_sapi_reject(3);
285 VERIFY(msg, res, ARRAY_SIZE(res));
286 msgb_free(msg);
287}
288
Philipp Maierc6144a22017-03-29 17:53:43 +0200289static void test_create_ass()
290{
291 static const uint8_t res1[] =
292 { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
293 0x04 };
294 static const uint8_t res2[] =
295 { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
296 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17,
Philipp Maierbb839662017-06-01 17:11:19 +0200297 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07,
Philipp Maier7e27b142018-03-22 17:26:46 +0100298 GSM0808_SCT_FR3 | 0x50, 0xef, 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f,
Philipp Maierbb839662017-06-01 17:11:19 +0200299 GSM0808_SCT_CSD | 0x90, 0xc0, GSM0808_IE_CALL_ID, 0xaa, 0xbb,
300 0xcc, 0xdd };
Philipp Maierc6144a22017-03-29 17:53:43 +0200301
302 struct msgb *msg;
303 struct gsm0808_channel_type ct;
304 uint16_t cic = 0004;
305 struct sockaddr_storage ss;
306 struct sockaddr_in sin;
307 struct gsm0808_speech_codec_list sc_list;
308 uint32_t call_id = 0xAABBCCDD;
309
310 memset(&ct, 0, sizeof(ct));
311 ct.ch_indctr = GSM0808_CHAN_SPEECH;
312 ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF;
313 ct.perm_spch[0] = GSM0808_PERM_FR3;
314 ct.perm_spch[1] = GSM0808_PERM_HR3;
315 ct.perm_spch_len = 2;
316
317 memset(&sin, 0, sizeof(sin));
318 sin.sin_family = AF_INET;
319 sin.sin_port = htons(1234);
320 inet_aton("192.168.100.23", &sin.sin_addr);
321
322 memset(&ss, 0, sizeof(ss));
323 memcpy(&ss, &sin, sizeof(sin));
324
325 setup_codec_list(&sc_list);
326
327 printf("Testing creating Assignment Request\n");
328 msg = gsm0808_create_ass(&ct, &cic, NULL, NULL, NULL);
329 OSMO_ASSERT(msg);
330 VERIFY(msg, res1, ARRAY_SIZE(res1));
331 msgb_free(msg);
332
333 msg = gsm0808_create_ass(&ct, &cic, &ss, &sc_list, &call_id);
334 OSMO_ASSERT(msg);
335 VERIFY(msg, res2, ARRAY_SIZE(res2));
336 msgb_free(msg);
337}
338
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100339static void test_create_ass_compl()
340{
341 static const uint8_t res1[] = {
342 0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c,
343 0x11, 0x40, 0x22 };
344 static const uint8_t res2[] = {
345 0x00, 0x07, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11};
346 struct msgb *msg;
347
348 printf("Testing creating Assignment Complete\n");
349 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0x22);
350 VERIFY(msg, res1, ARRAY_SIZE(res1));
351 msgb_free(msg);
352
353 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0);
354 VERIFY(msg, res2, ARRAY_SIZE(res2));
355 msgb_free(msg);
356}
357
Philipp Maierfa896ab2017-03-27 16:55:32 +0200358static void test_create_ass_compl_aoip()
359{
360 struct sockaddr_storage ss;
361 struct sockaddr_in sin;
362 struct gsm0808_speech_codec sc;
363 struct gsm0808_speech_codec_list sc_list;
364 static const uint8_t res[] =
365 { 0x00, 0x1d, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22,
366 GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04,
Philipp Maierbb839662017-06-01 17:11:19 +0200367 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, GSM0808_SCT_HR1 | 0x90,
Philipp Maier7e27b142018-03-22 17:26:46 +0100368 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, GSM0808_SCT_FR3 | 0x50, 0xef,
369 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f, GSM0808_SCT_CSD | 0x90, 0xc0 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200370 struct msgb *msg;
371
372 memset(&sin, 0, sizeof(sin));
373 sin.sin_family = AF_INET;
374 sin.sin_port = htons(1234);
375 inet_aton("192.168.100.23", &sin.sin_addr);
376
377 memset(&ss, 0, sizeof(ss));
378 memcpy(&ss, &sin, sizeof(sin));
379
380 memset(&sc, 0, sizeof(sc));
381 sc.fi = true;
382 sc.tf = true;
Philipp Maierbb839662017-06-01 17:11:19 +0200383 sc.type = GSM0808_SCT_HR1;
Philipp Maierfa896ab2017-03-27 16:55:32 +0200384
385 setup_codec_list(&sc_list);
386
387 printf("Testing creating Assignment Complete (AoIP)\n");
388 msg = gsm0808_create_ass_compl(0x23, 0x42, 0x11, 0x22,
389 &ss, &sc, &sc_list);
390 VERIFY(msg, res, ARRAY_SIZE(res));
391 msgb_free(msg);
392}
393
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100394static void test_create_ass_fail()
395{
396 static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 };
397 static const uint8_t res2[] = {
398 0x00, 0x06, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02};
399 uint8_t rr_res = 2;
400 struct msgb *msg;
401
402 printf("Testing creating Assignment Failure\n");
403 msg = gsm0808_create_assignment_failure(0x23, NULL);
404 VERIFY(msg, res1, ARRAY_SIZE(res1));
405 msgb_free(msg);
406
407 msg = gsm0808_create_assignment_failure(0x23, &rr_res);
408 VERIFY(msg, res2, ARRAY_SIZE(res2));
409 msgb_free(msg);
410}
411
Philipp Maierfa896ab2017-03-27 16:55:32 +0200412static void test_create_ass_fail_aoip()
413{
414 static const uint8_t res1[] =
415 { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST,
Philipp Maier7e27b142018-03-22 17:26:46 +0100416 0x07, GSM0808_SCT_FR3 | 0x50, 0xef, 0xcd, GSM0808_SCT_FR2 | 0xa0,
Philipp Maierbb839662017-06-01 17:11:19 +0200417 0x9f, GSM0808_SCT_CSD | 0x90, 0xc0 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200418 static const uint8_t res2[] =
419 { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02,
Philipp Maier7e27b142018-03-22 17:26:46 +0100420 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, GSM0808_SCT_FR3 | 0x50, 0xef,
421 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f, GSM0808_SCT_CSD | 0x90, 0xc0 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200422 uint8_t rr_res = 2;
423 struct msgb *msg;
424 struct gsm0808_speech_codec_list sc_list;
425
426 setup_codec_list(&sc_list);
427
428 printf("Testing creating Assignment Failure (AoIP)\n");
429 msg = gsm0808_create_ass_fail(0x23, NULL, &sc_list);
430 VERIFY(msg, res1, ARRAY_SIZE(res1));
431 msgb_free(msg);
432
433 msg = gsm0808_create_ass_fail(0x23, &rr_res, &sc_list);
434 VERIFY(msg, res2, ARRAY_SIZE(res2));
435 msgb_free(msg);
436}
437
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100438static void test_create_clear_rqst()
439{
440 static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 };
441 struct msgb *msg;
442
443 printf("Testing creating Clear Request\n");
444 msg = gsm0808_create_clear_rqst(0x23);
445 VERIFY(msg, res, ARRAY_SIZE(res));
446 msgb_free(msg);
447}
448
Philipp Maier3d48ec02017-03-29 17:37:55 +0200449static void test_create_paging()
450{
451 static const uint8_t res[] =
452 { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
453 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 };
454 static const uint8_t res2[] =
455 { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
456 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
457 0x03, 0x05, 0x23, 0x42 };
458 static const uint8_t res3[] =
459 { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
460 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
461 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED,
462 RSL_CHANNEED_TCH_ForH };
463
464 struct msgb *msg;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100465 struct gsm0808_cell_id_list2 cil;
Philipp Maier3d48ec02017-03-29 17:37:55 +0200466 uint32_t tmsi = 0x12345678;
467 uint8_t chan_needed = RSL_CHANNEED_TCH_ForH;
468
469 char imsi[] = "001010000001234";
470
471 cil.id_discr = CELL_IDENT_LAC;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100472 cil.id_list[0].lac = 0x2342;
Philipp Maier3d48ec02017-03-29 17:37:55 +0200473 cil.id_list_len = 1;
474
475 printf("Testing creating Paging Request\n");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100476 msg = gsm0808_create_paging2(imsi, NULL, &cil, NULL);
Philipp Maier3d48ec02017-03-29 17:37:55 +0200477 VERIFY(msg, res, ARRAY_SIZE(res));
478 msgb_free(msg);
479
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100480 msg = gsm0808_create_paging2(imsi, &tmsi, &cil, NULL);
Philipp Maier3d48ec02017-03-29 17:37:55 +0200481 VERIFY(msg, res2, ARRAY_SIZE(res2));
482 msgb_free(msg);
483
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100484 msg = gsm0808_create_paging2(imsi, &tmsi, &cil, &chan_needed);
Philipp Maier3d48ec02017-03-29 17:37:55 +0200485 VERIFY(msg, res3, ARRAY_SIZE(res3));
486 msgb_free(msg);
487}
488
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100489static void test_create_dtap()
490{
491 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
492 struct msgb *msg, *l3;
493
494 printf("Testing creating DTAP\n");
495 l3 = msgb_alloc_headroom(512, 128, "test");
496 l3->l3h = l3->data;
497 msgb_v_put(l3, 0x23);
498 msgb_v_put(l3, 0x42);
499
500 msg = gsm0808_create_dtap(l3, 0x3);
501 VERIFY(msg, res, ARRAY_SIZE(res));
502 msgb_free(msg);
503 msgb_free(l3);
504}
505
506static void test_prepend_dtap()
507{
508 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
509 struct msgb *in_msg;
510
511 printf("Testing prepend DTAP\n");
512
513 in_msg = msgb_alloc_headroom(512, 128, "test");
514 msgb_v_put(in_msg, 0x23);
515 msgb_v_put(in_msg, 0x42);
516
517 gsm0808_prepend_dtap_header(in_msg, 0x3);
518 in_msg->l3h = in_msg->data;
519 VERIFY(in_msg, res, ARRAY_SIZE(res));
520 msgb_free(in_msg);
521}
522
Philipp Maier22401432017-03-24 17:59:26 +0100523static void test_enc_dec_aoip_trasp_addr_v4()
524{
525 struct sockaddr_storage enc_addr;
526 struct sockaddr_storage dec_addr;
527 struct sockaddr_in enc_addr_in;
528 struct msgb *msg;
529 uint8_t rc_enc;
530 int rc_dec;
531
532 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
533 enc_addr_in.sin_family = AF_INET;
534 enc_addr_in.sin_port = htons(1234);
535 inet_aton("255.0.255.255", &enc_addr_in.sin_addr);
536
537 memset(&enc_addr, 0, sizeof(enc_addr));
538 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
539
540 msg = msgb_alloc(1024, "output buffer");
541 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
542 OSMO_ASSERT(rc_enc == 8);
543 rc_dec =
544 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
545 OSMO_ASSERT(rc_dec == 6);
546 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
547
548 msgb_free(msg);
549}
550
551static void test_enc_dec_aoip_trasp_addr_v6()
552{
553 struct sockaddr_storage enc_addr;
554 struct sockaddr_storage dec_addr;
555 struct sockaddr_in6 enc_addr_in;
556 struct msgb *msg;
557 uint8_t rc_enc;
558 int rc_dec;
559
560 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
561 enc_addr_in.sin6_family = AF_INET6;
562 enc_addr_in.sin6_port = htons(4567);
563 inet_pton(AF_INET6, "2001:0db8:85a3:08d3:1319:8a2e:0370:7344",
564 &enc_addr_in.sin6_addr);
565
566 memset(&enc_addr, 0, sizeof(enc_addr));
567 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
568
569 msg = msgb_alloc(1024, "output buffer");
570 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
571 OSMO_ASSERT(rc_enc == 20);
572 rc_dec =
573 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
574 OSMO_ASSERT(rc_dec == 18);
575 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
576
577 msgb_free(msg);
578}
579
Philipp Maier6f725d62017-03-24 18:03:17 +0100580static void test_gsm0808_enc_dec_speech_codec()
581{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200582 struct gsm0808_speech_codec enc_sc = {
583 .pi = true,
584 .tf = true,
585 .type = GSM0808_SCT_FR2,
586 };
587 struct gsm0808_speech_codec dec_sc = {};
Philipp Maier6f725d62017-03-24 18:03:17 +0100588 struct msgb *msg;
589 uint8_t rc_enc;
590 int rc_dec;
591
Philipp Maier6f725d62017-03-24 18:03:17 +0100592 msg = msgb_alloc(1024, "output buffer");
593 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
594 OSMO_ASSERT(rc_enc == 3);
595
596 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
597 OSMO_ASSERT(rc_dec == 1);
598
599 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
600
601 msgb_free(msg);
602}
603
604
Philipp Maierbb839662017-06-01 17:11:19 +0200605static void test_gsm0808_enc_dec_speech_codec_with_cfg()
606{
Neels Hofmeyrc62c9342018-04-15 23:31:47 +0200607 struct gsm0808_speech_codec enc_sc = {
608 .pi = true,
609 .tf = true,
610 .type = GSM0808_SCT_FR3,
611 .cfg = 0xabcd,
612 };
613 struct gsm0808_speech_codec dec_sc = {};
Philipp Maierbb839662017-06-01 17:11:19 +0200614 struct msgb *msg;
615 uint8_t rc_enc;
616 int rc_dec;
617
Philipp Maierbb839662017-06-01 17:11:19 +0200618 msg = msgb_alloc(1024, "output buffer");
619 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
620 OSMO_ASSERT(rc_enc == 5);
621
622 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
623 OSMO_ASSERT(rc_dec == 3);
624
625 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
626
627 msgb_free(msg);
628}
629
Philipp Maier6f725d62017-03-24 18:03:17 +0100630static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg()
631{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200632 struct gsm0808_speech_codec enc_sc = {
633 .pi = true,
634 .tf = true,
635 .type = GSM0808_SCT_CSD,
636 .cfg = 0xc0,
637 };
638 struct gsm0808_speech_codec dec_sc = {};
Philipp Maier6f725d62017-03-24 18:03:17 +0100639 struct msgb *msg;
640 uint8_t rc_enc;
641 int rc_dec;
642
Philipp Maier6f725d62017-03-24 18:03:17 +0100643 msg = msgb_alloc(1024, "output buffer");
644 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
Philipp Maierbb839662017-06-01 17:11:19 +0200645 OSMO_ASSERT(rc_enc == 5);
Philipp Maier6f725d62017-03-24 18:03:17 +0100646
647 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
Philipp Maierbb839662017-06-01 17:11:19 +0200648 OSMO_ASSERT(rc_dec == 3);
Philipp Maier6f725d62017-03-24 18:03:17 +0100649
650 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
651
652 msgb_free(msg);
653}
654
655static void test_gsm0808_enc_dec_speech_codec_list()
656{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200657 struct gsm0808_speech_codec_list enc_scl = {
658 .codec = {
659 {
660 .pi = true,
661 .tf = true,
662 .type = GSM0808_SCT_FR3,
663 .cfg = 0xcdef,
664 },
665
666 {
667 .fi = true,
668 .pt = true,
669 .type = GSM0808_SCT_FR2,
670 },
671
672 {
673 .fi = true,
674 .tf = true,
675 .type = GSM0808_SCT_CSD,
676 .cfg = 0xc0,
677 },
678 },
679 .len = 3,
680 };
681 struct gsm0808_speech_codec_list dec_scl = {};
Philipp Maier6f725d62017-03-24 18:03:17 +0100682 struct msgb *msg;
683 uint8_t rc_enc;
684 int rc_dec;
685
Philipp Maier6f725d62017-03-24 18:03:17 +0100686 msg = msgb_alloc(1024, "output buffer");
687 rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
688 OSMO_ASSERT(rc_enc == 9);
689
690 rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
691 OSMO_ASSERT(rc_dec == 7);
692
693 OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0);
694
695 msgb_free(msg);
696}
697
Philipp Maierf6c369f2018-10-16 15:24:47 +0200698static void test_gsm0808_enc_dec_empty_speech_codec_list()
699{
700 struct gsm0808_speech_codec_list enc_scl = {
701 .len = 0,
702 };
703 struct gsm0808_speech_codec_list dec_scl = {};
704 struct msgb *msg;
705 uint8_t rc_enc;
706 int rc_dec;
707
708 msg = msgb_alloc(1024, "output buffer");
709 rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
710 OSMO_ASSERT(rc_enc == 2);
711
712 rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
713 OSMO_ASSERT(rc_dec == 0);
714
715 OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0);
716
717 msgb_free(msg);
718}
719
Philipp Maiere0c65302017-03-28 17:05:40 +0200720static void test_gsm0808_enc_dec_channel_type()
721{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200722 struct gsm0808_channel_type enc_ct = {
723 .ch_indctr = GSM0808_CHAN_SPEECH,
724 .ch_rate_type = GSM0808_SPEECH_HALF_PREF,
725 .perm_spch = { GSM0808_PERM_FR3, GSM0808_PERM_HR3 },
726 .perm_spch_len = 2,
727 };
728 struct gsm0808_channel_type dec_ct = {};
Philipp Maiere0c65302017-03-28 17:05:40 +0200729 struct msgb *msg;
730 uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE,
731 0x04, 0x01, 0x0b, 0xa1, 0x25
732 };
733 uint8_t rc_enc;
734 int rc_dec;
735
Philipp Maiere0c65302017-03-28 17:05:40 +0200736 msg = msgb_alloc(1024, "output buffer");
737 rc_enc = gsm0808_enc_channel_type(msg, &enc_ct);
738 OSMO_ASSERT(rc_enc == 6);
739 OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0);
740
741 rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2);
742 OSMO_ASSERT(rc_dec == 4);
743 OSMO_ASSERT(memcmp(&enc_ct, &dec_ct, sizeof(enc_ct)) == 0);
744
745 msgb_free(msg);
746}
747
Philipp Maier14e76b92017-03-28 18:36:52 +0200748static void test_gsm0808_enc_dec_encrypt_info()
749{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200750 struct gsm0808_encrypt_info enc_ei = {
751 .perm_algo = { GSM0808_ALG_ID_A5_0, GSM0808_ALG_ID_A5_1 },
752 .perm_algo_len = 2,
753 .key = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42, },
754 .key_len = 8,
755 };
756 struct gsm0808_encrypt_info dec_ei = {};
Philipp Maier14e76b92017-03-28 18:36:52 +0200757 struct msgb *msg;
758 uint8_t ei_enc_expected[] =
759 { GSM0808_IE_ENCRYPTION_INFORMATION, 0x09, 0x03, 0xaa, 0xbb,
760 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42
761 };
762 uint8_t rc_enc;
763 int rc_dec;
764
Philipp Maier14e76b92017-03-28 18:36:52 +0200765 msg = msgb_alloc(1024, "output buffer");
766 rc_enc = gsm0808_enc_encrypt_info(msg, &enc_ei);
767 OSMO_ASSERT(rc_enc == 11);
768 OSMO_ASSERT(memcmp(ei_enc_expected, msg->data, msg->len) == 0);
769
770 rc_dec = gsm0808_dec_encrypt_info(&dec_ei, msg->data + 2, msg->len - 2);
771 OSMO_ASSERT(rc_dec == 9);
772
773 OSMO_ASSERT(memcmp(&enc_ei, &dec_ei, sizeof(enc_ei)) == 0);
774
775 msgb_free(msg);
776}
777
Neels Hofmeyr066473f2018-04-13 04:10:58 +0200778#define EXPECT_ENCODED(hexstr) do { \
779 const char *enc_str = msgb_hexdump(msg); \
780 printf("%s: encoded: %s(rc = %u)\n", __func__, enc_str, rc_enc); \
781 OSMO_ASSERT(strcmp(enc_str, hexstr " ") == 0); \
782 OSMO_ASSERT(rc_enc == msg->len); \
783 } while(0)
784
Philipp Maier783047e2017-03-29 11:35:50 +0200785static void test_gsm0808_enc_dec_cell_id_list_lac()
786{
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100787 struct gsm0808_cell_id_list2 enc_cil;
788 struct gsm0808_cell_id_list2 dec_cil;
Philipp Maier783047e2017-03-29 11:35:50 +0200789 struct msgb *msg;
790 uint8_t rc_enc;
791 int rc_dec;
792
793 memset(&enc_cil, 0, sizeof(enc_cil));
794 enc_cil.id_discr = CELL_IDENT_LAC;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100795 enc_cil.id_list[0].lac = 0x0124;
Neels Hofmeyrdb2fa4e2018-04-13 04:11:20 +0200796 enc_cil.id_list[1].lac = 0xABCD;
797 enc_cil.id_list[2].lac = 0x5678;
Philipp Maier783047e2017-03-29 11:35:50 +0200798 enc_cil.id_list_len = 3;
799
800 msg = msgb_alloc(1024, "output buffer");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100801 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
Neels Hofmeyrdb2fa4e2018-04-13 04:11:20 +0200802 EXPECT_ENCODED("1a 07 05 01 24 ab cd 56 78");
Philipp Maier783047e2017-03-29 11:35:50 +0200803
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100804 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
Philipp Maier783047e2017-03-29 11:35:50 +0200805 OSMO_ASSERT(rc_dec == 7);
806
807 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
808
809 msgb_free(msg);
810}
811
812static void test_gsm0808_enc_dec_cell_id_list_single_lac()
813{
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100814 struct gsm0808_cell_id_list2 enc_cil;
815 struct gsm0808_cell_id_list2 dec_cil;
Philipp Maier783047e2017-03-29 11:35:50 +0200816 struct msgb *msg;
817 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x03,
818 0x05, 0x23, 0x42
819 };
820 uint8_t rc_enc;
821 int rc_dec;
822
823 memset(&enc_cil, 0, sizeof(enc_cil));
824 enc_cil.id_discr = CELL_IDENT_LAC;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100825 enc_cil.id_list[0].lac = 0x2342;
Philipp Maier783047e2017-03-29 11:35:50 +0200826 enc_cil.id_list_len = 1;
827
828 msg = msgb_alloc(1024, "output buffer");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100829 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
Philipp Maier783047e2017-03-29 11:35:50 +0200830 OSMO_ASSERT(rc_enc == 5);
831 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
832
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100833 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
Philipp Maier783047e2017-03-29 11:35:50 +0200834 OSMO_ASSERT(rc_dec == 3);
835
836 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
837
838 msgb_free(msg);
839}
840
Stefan Sperlinge1a86742018-03-15 18:05:02 +0100841static void test_gsm0808_enc_dec_cell_id_list_multi_lac()
842{
843 struct gsm0808_cell_id_list2 enc_cil;
844 struct gsm0808_cell_id_list2 dec_cil;
845 struct msgb *msg;
846 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x0b, 0x05,
847 0x23, 0x42,
848 0x24, 0x43,
849 0x25, 0x44,
850 0x26, 0x45,
851 0x27, 0x46
852 };
853 uint8_t rc_enc;
854 int rc_dec;
855
856 memset(&enc_cil, 0, sizeof(enc_cil));
857 enc_cil.id_discr = CELL_IDENT_LAC;
858 enc_cil.id_list[0].lac = 0x2342;
859 enc_cil.id_list[1].lac = 0x2443;
860 enc_cil.id_list[2].lac = 0x2544;
861 enc_cil.id_list[3].lac = 0x2645;
862 enc_cil.id_list[4].lac = 0x2746;
863 enc_cil.id_list_len = 5;
864
865 msg = msgb_alloc(1024, "output buffer");
866 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
867 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
868 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
869
870 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
871 OSMO_ASSERT(rc_dec == msg->len - 2);
872 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
873
874 msgb_free(msg);
875}
876
Philipp Maier783047e2017-03-29 11:35:50 +0200877static void test_gsm0808_enc_dec_cell_id_list_bss()
878{
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100879 struct gsm0808_cell_id_list2 enc_cil;
880 struct gsm0808_cell_id_list2 dec_cil;
Philipp Maier783047e2017-03-29 11:35:50 +0200881 struct msgb *msg;
882 uint8_t rc_enc;
883 int rc_dec;
884
885 memset(&enc_cil, 0, sizeof(enc_cil));
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100886 enc_cil.id_discr = CELL_IDENT_BSS;
Philipp Maier783047e2017-03-29 11:35:50 +0200887
888 msg = msgb_alloc(1024, "output buffer");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100889 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
Philipp Maier783047e2017-03-29 11:35:50 +0200890 OSMO_ASSERT(rc_enc == 3);
891
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100892 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
Philipp Maier783047e2017-03-29 11:35:50 +0200893 OSMO_ASSERT(rc_dec == 1);
894
895 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
896
897 msgb_free(msg);
898}
899
Stefan Sperling23381452018-03-15 19:38:15 +0100900static void test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac()
901{
902 struct gsm0808_cell_id_list2 enc_cil;
903 struct gsm0808_cell_id_list2 dec_cil;
904 struct osmo_location_area_id id;
905 struct msgb *msg;
906 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x10, 0x04,
907 0x92, 0x61, 0x54, 0x23, 0x42,
908 0x92, 0x72, 0x54, 0x24, 0x43,
909 0x92, 0x83, 0x54, 0x25, 0x44
910 };
911 uint8_t rc_enc;
912 int rc_dec, i;
913
914 memset(&enc_cil, 0, sizeof(enc_cil));
915 enc_cil.id_discr = CELL_IDENT_LAI_AND_LAC;
916
917 id.plmn.mcc = 0x123;
918 osmo_mnc_from_str("456", &id.plmn.mnc, &id.plmn.mnc_3_digits);
919 id.lac = 0x2342;
920 memcpy(&enc_cil.id_list[0].lai_and_lac, &id, sizeof(id));
921
922 id.plmn.mcc = 0x124;
923 osmo_mnc_from_str("457", &id.plmn.mnc, &id.plmn.mnc_3_digits);
924 id.lac = 0x2443;
925 memcpy(&enc_cil.id_list[1].lai_and_lac, &id, sizeof(id));
926
927 id.plmn.mcc = 0x125;
928 osmo_mnc_from_str("458", &id.plmn.mnc, &id.plmn.mnc_3_digits);
929 id.lac = 0x2544;
930 memcpy(&enc_cil.id_list[2].lai_and_lac, &id, sizeof(id));
931
932 enc_cil.id_list_len = 3;
933
934 msg = msgb_alloc(1024, "output buffer");
935 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
936 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
937 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
938
939 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
940 OSMO_ASSERT(rc_dec == msg->len - 2);
941
942 OSMO_ASSERT(dec_cil.id_list_len == 3);
943 /* Check MAXLEN elements to ensure everything has been initialized. */
944 for (i = 0; i < GSM0808_CELL_ID_LIST2_MAXLEN; i++) {
945 struct osmo_location_area_id *enc_id;
946 struct osmo_location_area_id *dec_id;
947 enc_id = &enc_cil.id_list[i].lai_and_lac;
948 dec_id = &dec_cil.id_list[i].lai_and_lac;
949 OSMO_ASSERT(osmo_plmn_cmp(&enc_id->plmn, &dec_id->plmn) == 0);
950 OSMO_ASSERT(enc_id->lac == dec_id->lac);
951 }
952
953 msgb_free(msg);
954}
955
Stefan Sperling9c62fc62018-03-16 10:23:34 +0100956static void test_gsm0808_enc_dec_cell_id_list_multi_ci()
957{
958 struct gsm0808_cell_id_list2 enc_cil;
959 struct gsm0808_cell_id_list2 dec_cil;
960 struct msgb *msg;
961 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x09, 0x02,
962 0x00, 0x01,
963 0x00, 0x02,
964 0x00, 0x77,
965 0x01, 0xff,
966 };
967 uint8_t rc_enc;
968 int rc_dec;
969
970 memset(&enc_cil, 0, sizeof(enc_cil));
971 enc_cil.id_discr = CELL_IDENT_CI;
972 enc_cil.id_list[0].ci = 1;
973 enc_cil.id_list[1].ci = 2;
974 enc_cil.id_list[2].ci = 119;
975 enc_cil.id_list[3].ci = 511;
976 enc_cil.id_list_len = 4;
977
978 msg = msgb_alloc(1024, "output buffer");
979 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
980 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
981 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
982
983 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
984 OSMO_ASSERT(rc_dec == msg->len - 2);
985 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
986
987 msgb_free(msg);
988}
989
Stefan Sperlinged4327c2018-03-16 11:02:59 +0100990static void test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci()
991{
992 struct gsm0808_cell_id_list2 enc_cil;
993 struct gsm0808_cell_id_list2 dec_cil;
994 struct msgb *msg;
995 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x15, 0x01,
996 0x23, 0x42, 0x00, 0x01,
997 0x24, 0x43, 0x00, 0x02,
998 0x25, 0x44, 0x00, 0x77,
999 0x26, 0x45, 0x01, 0xff,
1000 0x27, 0x46, 0x02, 0xfe,
1001 };
1002 uint8_t rc_enc;
1003 int rc_dec;
1004
1005 memset(&enc_cil, 0, sizeof(enc_cil));
1006 enc_cil.id_discr = CELL_IDENT_LAC_AND_CI;
1007 enc_cil.id_list[0].lac_and_ci.lac = 0x2342;
1008 enc_cil.id_list[0].lac_and_ci.ci = 1;
1009 enc_cil.id_list[1].lac_and_ci.lac = 0x2443;
1010 enc_cil.id_list[1].lac_and_ci.ci = 2;
1011 enc_cil.id_list[2].lac_and_ci.lac = 0x2544;
1012 enc_cil.id_list[2].lac_and_ci.ci = 119;
1013 enc_cil.id_list[3].lac_and_ci.lac = 0x2645;
1014 enc_cil.id_list[3].lac_and_ci.ci = 511;
1015 enc_cil.id_list[4].lac_and_ci.lac = 0x2746;
1016 enc_cil.id_list[4].lac_and_ci.ci = 766;
1017 enc_cil.id_list_len = 5;
1018
1019 msg = msgb_alloc(1024, "output buffer");
1020 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1021 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
1022 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1023
1024 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1025 OSMO_ASSERT(rc_dec == msg->len - 2);
1026 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1027
1028 msgb_free(msg);
1029}
1030
Stefan Sperling483f3862018-03-16 12:21:26 +01001031static void test_gsm0808_enc_dec_cell_id_list_multi_global()
1032{
1033 struct gsm0808_cell_id_list2 enc_cil;
1034 struct gsm0808_cell_id_list2 dec_cil;
1035 struct msgb *msg;
1036 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x16, 0x00,
Neels Hofmeyr473485c2018-03-23 02:04:18 +01001037 0x21, 0x63, 0x54, 0x23, 0x42, 0x00, 0x1,
Neels Hofmeyrc44fc232018-03-23 02:15:12 +01001038 0x21, 0xf4, 0x75, 0x24, 0x43, 0x00, 0x2,
Neels Hofmeyr8b8cd932018-03-23 01:47:37 +01001039 0x21, 0x75, 0x00, 0x25, 0x44, 0x00, 0x77
Stefan Sperling483f3862018-03-16 12:21:26 +01001040 };
Stefan Sperling483f3862018-03-16 12:21:26 +01001041 uint8_t rc_enc;
1042 int rc_dec, i;
1043
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001044 enc_cil = (struct gsm0808_cell_id_list2){
1045 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1046 .id_list_len = 3,
1047 .id_list = {
1048 {
1049 .global = {
Neels Hofmeyr473485c2018-03-23 02:04:18 +01001050 .lai = { .plmn = { .mcc = 123, .mnc = 456 },
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001051 .lac = 0x2342 },
1052 .cell_identity = 1,
1053 }
1054 },
1055 {
1056 .global = {
Neels Hofmeyrc44fc232018-03-23 02:15:12 +01001057 .lai = { .plmn = { .mcc = 124, .mnc = 57 },
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001058 .lac = 0x2443 },
1059 .cell_identity = 2,
1060 }
1061 },
1062 {
1063 .global = {
Neels Hofmeyrc44fc232018-03-23 02:15:12 +01001064 .lai = { .plmn = { .mcc = 125, .mnc = 7,
1065 .mnc_3_digits = true },
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001066 .lac = 0x2544 },
1067 .cell_identity = 119,
1068 }
1069 },
1070 }
1071 };
Stefan Sperling483f3862018-03-16 12:21:26 +01001072
1073 msg = msgb_alloc(1024, "output buffer");
1074 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1075 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001076 if (memcmp(cil_enc_expected, msg->data, msg->len)) {
1077 printf(" got: %s\n", osmo_hexdump(msg->data, msg->len));
1078 printf("expect: %s\n", osmo_hexdump(cil_enc_expected, sizeof(cil_enc_expected)));
1079 OSMO_ASSERT(false);
1080 }
Stefan Sperling483f3862018-03-16 12:21:26 +01001081
1082 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1083 OSMO_ASSERT(rc_dec == msg->len - 2);
1084
1085 /* Check MAXLEN elements to ensure everything has been initialized. */
1086 for (i = 0; i < GSM0808_CELL_ID_LIST2_MAXLEN; i++) {
1087 struct osmo_cell_global_id *enc_id;
1088 struct osmo_cell_global_id *dec_id;
1089 enc_id = &enc_cil.id_list[i].global;
1090 dec_id = &dec_cil.id_list[i].global;
1091 OSMO_ASSERT(osmo_plmn_cmp(&enc_id->lai.plmn, &dec_id->lai.plmn) == 0);
1092 OSMO_ASSERT(enc_id->lai.lac == dec_id->lai.lac);
1093 OSMO_ASSERT(enc_id->cell_identity == dec_id->cell_identity);
1094 }
1095
1096 msgb_free(msg);
1097}
1098
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001099static void print_cil(const struct gsm0808_cell_id_list2 *cil)
1100{
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001101 printf(" cell_id_list == %s\n", gsm0808_cell_id_list_name(cil));
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001102}
1103
1104void test_cell_id_list_add() {
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001105 size_t zu;
1106
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001107 const struct gsm0808_cell_id_list2 cgi1 = {
1108 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1109 .id_list_len = 1,
1110 .id_list = {
1111 {
1112 .global = {
1113 .lai = {
1114 .plmn = { .mcc = 1, .mnc = 2, .mnc_3_digits = false },
1115 .lac = 3,
1116 },
1117 .cell_identity = 4,
1118 }
1119 },
1120 },
1121 };
1122
1123 const struct gsm0808_cell_id_list2 cgi2 = {
1124 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1125 .id_list_len = 2,
1126 .id_list = {
1127 {
1128 .global = {
1129 .lai = {
1130 .plmn = { .mcc = 1, .mnc = 2, .mnc_3_digits = true },
1131 .lac = 3,
1132 },
1133 .cell_identity = 4,
1134 }
1135 },
1136 {
1137 .global = {
1138 .lai = {
1139 .plmn = { .mcc = 5, .mnc = 6, .mnc_3_digits = true },
1140 .lac = 7,
1141 },
1142 .cell_identity = 8,
1143 }
1144 },
1145 },
1146 };
1147
1148 const struct gsm0808_cell_id_list2 cgi2a = {
1149 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1150 .id_list_len = 2,
1151 .id_list = {
1152 {
1153 .global = cgi2.id_list[0].global
1154 },
1155 {
1156 .global = {
1157 .lai = {
1158 .plmn = { .mcc = 9, .mnc = 10, .mnc_3_digits = true },
1159 .lac = 11,
1160 },
1161 .cell_identity = 12,
1162 }
1163 },
1164 },
1165 };
1166
1167 const struct gsm0808_cell_id_list2 cgi3 = {
1168 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1169 .id_list_len = 2,
1170 .id_list = {
1171 {
1172 .global = {
1173 .lai = {
1174 .plmn = { .mcc = 13, .mnc = 14, .mnc_3_digits = true },
1175 .lac = 15,
1176 },
1177 .cell_identity = 16,
1178 }
1179 },
1180 {
1181 .global = {
1182 .lai = {
1183 .plmn = { .mcc = 16, .mnc = 17, .mnc_3_digits = true },
1184 .lac = 18,
1185 },
1186 .cell_identity = 19,
1187 }
1188 },
1189 },
1190 };
1191
1192
1193 const struct gsm0808_cell_id_list2 lac1 = {
1194 .id_discr = CELL_IDENT_LAC,
1195 .id_list_len = 1,
1196 .id_list = {
1197 {
1198 .lac = 123
1199 },
1200 },
1201 };
1202
1203 const struct gsm0808_cell_id_list2 lac2 = {
1204 .id_discr = CELL_IDENT_LAC,
1205 .id_list_len = 2,
1206 .id_list = {
1207 {
1208 .lac = 456
1209 },
1210 {
1211 .lac = 789
1212 },
1213 },
1214 };
1215
1216 struct gsm0808_cell_id_list2 cil = {};
1217
1218 printf("------- %s\n", __func__);
1219
1220 print_cil(&cil);
1221
1222#define ADD_QUIET(other_cil, expect_rc) do { \
1223 int rc = gsm0808_cell_id_list_add(&cil, &other_cil); \
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001224 printf("gsm0808_cell_id_list_add(&cil, &" #other_cil ") --> rc = %d\n", rc); \
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001225 OSMO_ASSERT(rc == expect_rc); \
1226 } while(0)
1227
1228#define ADD(other_cil, expect_rc) ADD_QUIET(other_cil, expect_rc); print_cil(&cil)
1229
1230 ADD(lac1, 1);
1231 ADD(lac1, 0);
1232 ADD(lac2, 2);
1233 ADD(lac2, 0);
1234 ADD(cil, 0);
1235 ADD(cgi1, -EINVAL);
1236
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001237 printf("* can't add to BSS list\n");
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001238 cil.id_list_len = 0;
1239 cil.id_discr = CELL_IDENT_BSS;
1240 print_cil(&cil);
1241 ADD(lac1, -EINVAL);
1242
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001243 printf("* other types (including NO_CELL) take on new type iff empty\n");
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001244 cil.id_list_len = 0;
1245 cil.id_discr = CELL_IDENT_NO_CELL;
1246 print_cil(&cil);
1247 ADD(cgi1, 1);
1248 ADD(cgi1, 0);
1249 ADD(cgi2, 2);
1250 ADD(cgi2, 0);
1251
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001252 printf("* test gsm0808_cell_id_list_name_buf()'s return val\n");
1253 zu = strlen(gsm0808_cell_id_list_name(&cil));
1254 printf(" strlen(gsm0808_cell_id_list_name(cil)) == %zu\n", zu);
1255 zu ++;
1256 while (1) {
1257 char buf[128] = "?";
1258 int rc;
1259 OSMO_ASSERT(zu < sizeof(buf));
1260 buf[zu] = '#';
1261 rc = gsm0808_cell_id_list_name_buf(buf, zu, &cil);
1262 printf(" gsm0808_cell_id_list_name_buf(buf, %zu, cil)) == %d \"%s\"\n",
1263 zu, rc, buf);
1264 OSMO_ASSERT(buf[zu] == '#');
1265 if (!zu)
1266 break;
1267 zu /= 2;
1268 }
1269
1270 printf("* list-full behavior\n");
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001271 cil.id_list_len = GSM0808_CELL_ID_LIST2_MAXLEN - 1;
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001272 printf("cil.id_list_len = %u\n", cil.id_list_len);
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001273 ADD_QUIET(cgi2a, 1);
1274 printf("cil.id_list_len = %u\n", cil.id_list_len);
1275
1276 cil.id_list_len = GSM0808_CELL_ID_LIST2_MAXLEN - 1;
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001277 printf("cil.id_list_len = %u\n", cil.id_list_len);
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001278 ADD_QUIET(cgi3, -ENOSPC);
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001279 printf("cil.id_list_len = %u\n", cil.id_list_len);
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001280 ADD_QUIET(cgi2a, -ENOSPC);
1281 printf("cil.id_list_len = %u\n", cil.id_list_len);
1282
1283 printf("------- %s done\n", __func__);
1284}
1285
Neels Hofmeyr250e7f72018-04-13 03:30:14 +02001286static void test_gsm0808_enc_dec_cell_id_lac()
1287{
1288 struct gsm0808_cell_id enc_ci = {
1289 .id_discr = CELL_IDENT_LAC,
1290 .id.lac = 0x0124,
1291 };
1292 struct gsm0808_cell_id dec_ci;
1293 struct msgb *msg;
1294 uint8_t rc_enc;
1295 int rc_dec;
1296
1297 memset(&dec_ci, 0xa5, sizeof(dec_ci));
1298
1299 msg = msgb_alloc(1024, "output buffer");
1300 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1301 EXPECT_ENCODED("05 03 05 01 24");
1302
1303 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1304 OSMO_ASSERT(rc_dec == 3);
1305
1306 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1307 && enc_ci.id.lac == dec_ci.id.lac);
1308
1309 msgb_free(msg);
1310}
1311
1312static void test_gsm0808_enc_dec_cell_id_bss()
1313{
1314 struct gsm0808_cell_id enc_ci = {
1315 .id_discr = CELL_IDENT_BSS,
1316 };
1317 struct gsm0808_cell_id dec_ci;
1318 struct msgb *msg;
1319 uint8_t rc_enc;
1320 int rc_dec;
1321
1322 msg = msgb_alloc(1024, "output buffer");
1323 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1324 EXPECT_ENCODED("05 01 06");
1325
1326 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1327 OSMO_ASSERT(rc_dec == 1);
1328
1329 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr);
1330
1331 msgb_free(msg);
1332}
1333
1334static void test_gsm0808_enc_dec_cell_id_no_cell()
1335{
1336 struct gsm0808_cell_id enc_ci = {
1337 .id_discr = CELL_IDENT_NO_CELL,
1338 };
1339 struct gsm0808_cell_id dec_ci;
1340 struct msgb *msg;
1341 uint8_t rc_enc;
1342 int rc_dec;
1343
1344 msg = msgb_alloc(1024, "output buffer");
1345 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1346 EXPECT_ENCODED("05 01 03");
1347
1348 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1349 OSMO_ASSERT(rc_dec == 1);
1350
1351 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr);
1352
1353 msgb_free(msg);
1354}
1355
1356static void test_gsm0808_enc_dec_cell_id_lai_and_lac()
1357{
1358 struct gsm0808_cell_id enc_ci = {
1359 .id_discr = CELL_IDENT_LAI_AND_LAC,
1360 .id.lai_and_lac = {
1361 .plmn = {
1362 .mcc = 123,
1363 .mnc = 456,
1364 },
1365 .lac = 0x2342,
1366 },
1367 };
1368 struct gsm0808_cell_id dec_ci;
1369 struct msgb *msg;
1370 uint8_t rc_enc;
1371 int rc_dec;
1372
1373 msg = msgb_alloc(1024, "output buffer");
1374 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1375 EXPECT_ENCODED("05 06 04 21 63 54 23 42");
1376
1377 memset(&dec_ci, 0xa5, sizeof(dec_ci));
1378 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1379 OSMO_ASSERT(rc_dec == msg->len - 2);
1380
1381 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1382 && osmo_plmn_cmp(&enc_ci.id.lai_and_lac.plmn, &dec_ci.id.lai_and_lac.plmn) == 0
1383 && enc_ci.id.lai_and_lac.lac == dec_ci.id.lai_and_lac.lac);
1384 msgb_free(msg);
1385}
1386
1387static void test_gsm0808_enc_dec_cell_id_ci()
1388{
1389 struct gsm0808_cell_id enc_ci = {
1390 .id_discr = CELL_IDENT_CI,
1391 .id.ci = 0x423,
1392 };
1393 struct gsm0808_cell_id dec_ci;
1394 struct msgb *msg;
1395 uint8_t rc_enc;
1396 int rc_dec;
1397
1398 msg = msgb_alloc(1024, "output buffer");
1399 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1400 EXPECT_ENCODED("05 03 02 04 23");
1401
1402 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1403 OSMO_ASSERT(rc_dec == msg->len - 2);
1404 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1405 && enc_ci.id.ci == dec_ci.id.ci);
1406
1407 msgb_free(msg);
1408}
1409
1410static void test_gsm0808_enc_dec_cell_id_lac_and_ci()
1411{
1412 struct gsm0808_cell_id enc_ci = {
1413 .id_discr = CELL_IDENT_LAC_AND_CI,
1414 .id.lac_and_ci = {
1415 .lac = 0x423,
1416 .ci = 0x235,
1417 },
1418 };
1419 struct gsm0808_cell_id dec_ci;
1420 struct msgb *msg;
1421 uint8_t rc_enc;
1422 int rc_dec;
1423
1424 msg = msgb_alloc(1024, "output buffer");
1425 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1426 EXPECT_ENCODED("05 05 01 04 23 02 35");
1427
1428 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1429 OSMO_ASSERT(rc_dec == msg->len - 2);
1430 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1431 && enc_ci.id.lac_and_ci.lac == dec_ci.id.lac_and_ci.lac
1432 && enc_ci.id.lac_and_ci.ci == dec_ci.id.lac_and_ci.ci);
1433
1434 msgb_free(msg);
1435}
1436
1437static void test_gsm0808_enc_dec_cell_id_global()
1438{
1439 struct gsm0808_cell_id enc_ci = {
1440 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1441 .id.global = {
1442 .lai = {
1443 .plmn = { .mcc = 123, .mnc = 456 },
1444 .lac = 0x2342
1445 },
1446 .cell_identity = 0x423,
1447 }
1448 };
1449 struct gsm0808_cell_id dec_ci;
1450 struct msgb *msg;
1451 uint8_t rc_enc;
1452 int rc_dec;
1453
1454 msg = msgb_alloc(1024, "output buffer");
1455 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1456 EXPECT_ENCODED("05 08 00 21 63 54 23 42 04 23");
1457
1458 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1459 OSMO_ASSERT(rc_dec == msg->len - 2);
1460
1461 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1462 && osmo_plmn_cmp(&enc_ci.id.global.lai.plmn,
1463 &dec_ci.id.global.lai.plmn) == 0
1464 && enc_ci.id.global.lai.lac == dec_ci.id.global.lai.lac
1465 && enc_ci.id.global.cell_identity == dec_ci.id.global.cell_identity);
1466 msgb_free(msg);
1467}
1468
Philipp Maier5f2eb152018-09-19 13:40:21 +02001469static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(struct gsm48_multi_rate_conf *cfg)
1470{
1471 uint16_t s15_s0;
1472
1473 printf("Input:\n");
1474 printf(" m4_75= %u smod= %u\n", cfg->m4_75, cfg->smod);
1475 printf(" m5_15= %u spare= %u\n", cfg->m5_15, cfg->spare);
1476 printf(" m5_90= %u icmi= %u\n", cfg->m5_90, cfg->icmi);
1477 printf(" m6_70= %u nscb= %u\n", cfg->m6_70, cfg->nscb);
1478 printf(" m7_40= %u ver= %u\n", cfg->m7_40, cfg->ver);
1479 printf(" m7_95= %u\n", cfg->m7_95);
1480 printf(" m10_2= %u\n", cfg->m10_2);
1481 printf(" m12_2= %u\n", cfg->m12_2);
1482
1483 s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, true);
1484 printf("Result (fr):\n");
1485 printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
1486 OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
1487
1488 s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, false);
1489 printf("Result (hr):\n");
1490 printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
1491 OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
1492
1493 printf("\n");
1494}
1495
1496static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg(void)
1497{
1498 struct gsm48_multi_rate_conf cfg;
1499
1500 printf("Testing gsm0808_sc_cfg_from_gsm48_mr_cfg():\n");
1501
1502 memset(&cfg, 0, sizeof(cfg));
1503
1504 cfg.m4_75 = 0;
1505 cfg.m5_15 = 0;
1506 cfg.m5_90 = 0;
1507 cfg.m6_70 = 0;
1508 cfg.m7_40 = 0;
1509 cfg.m7_95 = 0;
1510 cfg.m10_2 = 0;
1511 cfg.m12_2 = 0;
1512 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1513
1514 cfg.m4_75 = 1;
1515 cfg.m5_15 = 0;
1516 cfg.m5_90 = 0;
1517 cfg.m6_70 = 0;
1518 cfg.m7_40 = 0;
1519 cfg.m7_95 = 0;
1520 cfg.m10_2 = 0;
1521 cfg.m12_2 = 0;
1522 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1523
1524 cfg.m4_75 = 0;
1525 cfg.m5_15 = 1;
1526 cfg.m5_90 = 0;
1527 cfg.m6_70 = 0;
1528 cfg.m7_40 = 0;
1529 cfg.m7_95 = 0;
1530 cfg.m10_2 = 0;
1531 cfg.m12_2 = 0;
1532 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1533
1534 cfg.m4_75 = 0;
1535 cfg.m5_15 = 0;
1536 cfg.m5_90 = 1;
1537 cfg.m6_70 = 0;
1538 cfg.m7_40 = 0;
1539 cfg.m7_95 = 0;
1540 cfg.m10_2 = 0;
1541 cfg.m12_2 = 0;
1542 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1543
1544 cfg.m4_75 = 0;
1545 cfg.m5_15 = 0;
1546 cfg.m5_90 = 0;
1547 cfg.m6_70 = 1;
1548 cfg.m7_40 = 0;
1549 cfg.m7_95 = 0;
1550 cfg.m10_2 = 0;
1551 cfg.m12_2 = 0;
1552 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1553
1554 cfg.m4_75 = 0;
1555 cfg.m5_15 = 0;
1556 cfg.m5_90 = 0;
1557 cfg.m6_70 = 0;
1558 cfg.m7_40 = 1;
1559 cfg.m7_95 = 0;
1560 cfg.m10_2 = 0;
1561 cfg.m12_2 = 0;
1562 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1563
1564 cfg.m4_75 = 0;
1565 cfg.m5_15 = 0;
1566 cfg.m5_90 = 0;
1567 cfg.m6_70 = 0;
1568 cfg.m7_40 = 0;
1569 cfg.m7_95 = 1;
1570 cfg.m10_2 = 0;
1571 cfg.m12_2 = 0;
1572 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1573
1574 cfg.m4_75 = 0;
1575 cfg.m5_15 = 0;
1576 cfg.m5_90 = 0;
1577 cfg.m6_70 = 0;
1578 cfg.m7_40 = 0;
1579 cfg.m7_95 = 0;
1580 cfg.m10_2 = 1;
1581 cfg.m12_2 = 0;
1582 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1583
1584 cfg.m4_75 = 0;
1585 cfg.m5_15 = 0;
1586 cfg.m5_90 = 0;
1587 cfg.m6_70 = 0;
1588 cfg.m7_40 = 0;
1589 cfg.m7_95 = 0;
1590 cfg.m10_2 = 0;
1591 cfg.m12_2 = 1;
1592 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1593
1594 cfg.m4_75 = 1;
1595 cfg.m5_15 = 1;
1596 cfg.m5_90 = 1;
1597 cfg.m6_70 = 1;
1598 cfg.m7_40 = 0;
1599 cfg.m7_95 = 0;
1600 cfg.m10_2 = 0;
1601 cfg.m12_2 = 0;
1602 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1603
1604 cfg.m4_75 = 0;
1605 cfg.m5_15 = 0;
1606 cfg.m5_90 = 0;
1607 cfg.m6_70 = 0;
1608 cfg.m7_40 = 1;
1609 cfg.m7_95 = 1;
1610 cfg.m10_2 = 1;
1611 cfg.m12_2 = 1;
1612 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1613
1614 cfg.m4_75 = 0;
1615 cfg.m5_15 = 0;
1616 cfg.m5_90 = 1;
1617 cfg.m6_70 = 1;
1618 cfg.m7_40 = 0;
1619 cfg.m7_95 = 0;
1620 cfg.m10_2 = 1;
1621 cfg.m12_2 = 1;
1622 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1623
1624 cfg.m4_75 = 1;
1625 cfg.m5_15 = 1;
1626 cfg.m5_90 = 0;
1627 cfg.m6_70 = 0;
1628 cfg.m7_40 = 1;
1629 cfg.m7_95 = 1;
1630 cfg.m10_2 = 0;
1631 cfg.m12_2 = 0;
1632 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1633
1634 cfg.m4_75 = 0;
1635 cfg.m5_15 = 1;
1636 cfg.m5_90 = 0;
1637 cfg.m6_70 = 1;
1638 cfg.m7_40 = 0;
1639 cfg.m7_95 = 1;
1640 cfg.m10_2 = 0;
1641 cfg.m12_2 = 1;
1642 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1643
1644 cfg.m4_75 = 1;
1645 cfg.m5_15 = 0;
1646 cfg.m5_90 = 1;
1647 cfg.m6_70 = 0;
1648 cfg.m7_40 = 1;
1649 cfg.m7_95 = 0;
1650 cfg.m10_2 = 1;
1651 cfg.m12_2 = 0;
1652 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1653
1654 cfg.m4_75 = 1;
1655 cfg.m5_15 = 1;
1656 cfg.m5_90 = 1;
1657 cfg.m6_70 = 1;
1658 cfg.m7_40 = 1;
1659 cfg.m7_95 = 1;
1660 cfg.m10_2 = 1;
1661 cfg.m12_2 = 1;
1662 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1663}
1664
Philipp Maier8515d032018-09-25 15:57:49 +02001665static void test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(uint16_t s15_s0)
1666{
1667 struct gsm48_multi_rate_conf cfg;
1668
1669 printf("Input:\n");
1670 printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
1671 OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
1672
1673 gsm48_mr_cfg_from_gsm0808_sc_cfg(&cfg, s15_s0);
1674
1675 printf("Output:\n");
1676 printf(" m4_75= %u smod= %u\n", cfg.m4_75, cfg.smod);
1677 printf(" m5_15= %u spare= %u\n", cfg.m5_15, cfg.spare);
1678 printf(" m5_90= %u icmi= %u\n", cfg.m5_90, cfg.icmi);
1679 printf(" m6_70= %u nscb= %u\n", cfg.m6_70, cfg.nscb);
1680 printf(" m7_40= %u ver= %u\n", cfg.m7_40, cfg.ver);
1681 printf(" m7_95= %u\n", cfg.m7_95);
1682 printf(" m10_2= %u\n", cfg.m10_2);
1683 printf(" m12_2= %u\n", cfg.m12_2);
1684
1685 printf("\n");
1686}
1687
1688void test_gsm48_mr_cfg_from_gsm0808_sc_cfg()
1689{
1690 printf("Testing gsm48_mr_cfg_from_gsm0808_sc_cfg():\n");
1691
1692 /* Only one codec per setting */
1693 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1694 (GSM0808_SC_CFG_DEFAULT_AMR_4_75);
1695 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1696 (GSM0808_SC_CFG_DEFAULT_AMR_5_15);
1697 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1698 (GSM0808_SC_CFG_DEFAULT_AMR_5_90);
1699 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1700 (GSM0808_SC_CFG_DEFAULT_AMR_6_70);
1701 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1702 (GSM0808_SC_CFG_DEFAULT_AMR_7_40);
1703 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1704 (GSM0808_SC_CFG_DEFAULT_AMR_7_95);
1705 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1706 (GSM0808_SC_CFG_DEFAULT_AMR_10_2);
1707 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1708 (GSM0808_SC_CFG_DEFAULT_AMR_12_2);
1709
1710 /* Combinations */
1711 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1712 (GSM0808_SC_CFG_DEFAULT_AMR_4_75 | GSM0808_SC_CFG_DEFAULT_AMR_6_70 |
1713 GSM0808_SC_CFG_DEFAULT_AMR_10_2);
1714 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1715 (GSM0808_SC_CFG_DEFAULT_AMR_10_2 | GSM0808_SC_CFG_DEFAULT_AMR_12_2 |
1716 GSM0808_SC_CFG_DEFAULT_AMR_7_40);
1717 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1718 (GSM0808_SC_CFG_DEFAULT_AMR_7_95 | GSM0808_SC_CFG_DEFAULT_AMR_12_2);
1719}
1720
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001721int main(int argc, char **argv)
1722{
1723 printf("Testing generation of GSM0808 messages\n");
1724 test_create_layer3();
Philipp Maierfa896ab2017-03-27 16:55:32 +02001725 test_create_layer3_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001726 test_create_reset();
Philipp Maier15596e22017-04-05 17:55:27 +02001727 test_create_reset_ack();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001728 test_create_clear_command();
1729 test_create_clear_complete();
Philipp Maierb478dd32017-03-29 15:50:05 +02001730 test_create_cipher();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001731 test_create_cipher_complete();
1732 test_create_cipher_reject();
1733 test_create_cm_u();
1734 test_create_sapi_reject();
Philipp Maierc6144a22017-03-29 17:53:43 +02001735 test_create_ass();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001736 test_create_ass_compl();
Philipp Maierfa896ab2017-03-27 16:55:32 +02001737 test_create_ass_compl_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001738 test_create_ass_fail();
Philipp Maierfa896ab2017-03-27 16:55:32 +02001739 test_create_ass_fail_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001740 test_create_clear_rqst();
Philipp Maier3d48ec02017-03-29 17:37:55 +02001741 test_create_paging();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001742 test_create_dtap();
1743 test_prepend_dtap();
Philipp Maier22401432017-03-24 17:59:26 +01001744 test_enc_dec_aoip_trasp_addr_v4();
1745 test_enc_dec_aoip_trasp_addr_v6();
Philipp Maier6f725d62017-03-24 18:03:17 +01001746 test_gsm0808_enc_dec_speech_codec();
Philipp Maier6f725d62017-03-24 18:03:17 +01001747 test_gsm0808_enc_dec_speech_codec_ext_with_cfg();
Philipp Maierbb839662017-06-01 17:11:19 +02001748 test_gsm0808_enc_dec_speech_codec_with_cfg();
Philipp Maier6f725d62017-03-24 18:03:17 +01001749 test_gsm0808_enc_dec_speech_codec_list();
Philipp Maierf6c369f2018-10-16 15:24:47 +02001750 test_gsm0808_enc_dec_empty_speech_codec_list();
Philipp Maiere0c65302017-03-28 17:05:40 +02001751 test_gsm0808_enc_dec_channel_type();
Philipp Maier14e76b92017-03-28 18:36:52 +02001752 test_gsm0808_enc_dec_encrypt_info();
Neels Hofmeyr250e7f72018-04-13 03:30:14 +02001753
Philipp Maier783047e2017-03-29 11:35:50 +02001754 test_gsm0808_enc_dec_cell_id_list_lac();
1755 test_gsm0808_enc_dec_cell_id_list_single_lac();
Stefan Sperlinge1a86742018-03-15 18:05:02 +01001756 test_gsm0808_enc_dec_cell_id_list_multi_lac();
Philipp Maier783047e2017-03-29 11:35:50 +02001757 test_gsm0808_enc_dec_cell_id_list_bss();
Stefan Sperling23381452018-03-15 19:38:15 +01001758 test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac();
Stefan Sperling9c62fc62018-03-16 10:23:34 +01001759 test_gsm0808_enc_dec_cell_id_list_multi_ci();
Stefan Sperlinged4327c2018-03-16 11:02:59 +01001760 test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci();
Stefan Sperling483f3862018-03-16 12:21:26 +01001761 test_gsm0808_enc_dec_cell_id_list_multi_global();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001762
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001763 test_cell_id_list_add();
1764
Neels Hofmeyr250e7f72018-04-13 03:30:14 +02001765 test_gsm0808_enc_dec_cell_id_lac();
1766 test_gsm0808_enc_dec_cell_id_bss();
1767 test_gsm0808_enc_dec_cell_id_no_cell();
1768 test_gsm0808_enc_dec_cell_id_lai_and_lac();
1769 test_gsm0808_enc_dec_cell_id_ci();
1770 test_gsm0808_enc_dec_cell_id_lac_and_ci();
1771 test_gsm0808_enc_dec_cell_id_global();
1772
Philipp Maier5f2eb152018-09-19 13:40:21 +02001773 test_gsm0808_sc_cfg_from_gsm48_mr_cfg();
Philipp Maier8515d032018-09-25 15:57:49 +02001774 test_gsm48_mr_cfg_from_gsm0808_sc_cfg();
Philipp Maier5f2eb152018-09-19 13:40:21 +02001775
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001776 printf("Done\n");
1777 return EXIT_SUCCESS;
1778}