blob: ce73390157f275ef80bffaffd40d570f4c8e1af7 [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>
Max969fb2e2018-12-10 11:01:10 +010025#include <osmocom/core/logging.h>
26#include <osmocom/core/application.h>
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010027
28#include <stdio.h>
29#include <stdlib.h>
Philipp Maier22401432017-03-24 17:59:26 +010030#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
Neels Hofmeyr74663d92018-03-23 01:46:42 +010033#include <errno.h>
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010034
Philipp Maier4f4905f2018-11-30 13:36:12 +010035#define EXPECT_ENCODED(hexstr) do { \
36 const char *enc_str = msgb_hexdump(msg); \
37 printf("%s: encoded: %s(rc = %u)\n", __func__, enc_str, rc_enc); \
38 OSMO_ASSERT(strcmp(enc_str, hexstr " ") == 0); \
39 OSMO_ASSERT(rc_enc == msg->len); \
40 } while(0)
41
Vadim Yanitskiycf6ee642018-12-20 05:23:00 +070042#define VERIFY(msg, data, data_len) do { \
43 if (!msgb_eq_l3_data_print(msg, data, data_len)) \
44 abort(); \
45 } while(0)
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010046
Philipp Maierfa896ab2017-03-27 16:55:32 +020047/* Setup a fake codec list for testing */
48static void setup_codec_list(struct gsm0808_speech_codec_list *scl)
49{
50 memset(scl, 0, sizeof(*scl));
51
52 scl->codec[0].pi = true;
53 scl->codec[0].tf = true;
Philipp Maierbb839662017-06-01 17:11:19 +020054 scl->codec[0].type = GSM0808_SCT_FR3;
Philipp Maierfa896ab2017-03-27 16:55:32 +020055 scl->codec[0].cfg = 0xcdef;
56
57 scl->codec[1].fi = true;
58 scl->codec[1].pt = true;
Philipp Maierbb839662017-06-01 17:11:19 +020059 scl->codec[1].type = GSM0808_SCT_FR2;
Philipp Maierfa896ab2017-03-27 16:55:32 +020060
61 scl->codec[2].fi = true;
62 scl->codec[2].tf = true;
Philipp Maierbb839662017-06-01 17:11:19 +020063 scl->codec[2].type = GSM0808_SCT_CSD;
64 scl->codec[2].cfg = 0xc0;
Philipp Maierfa896ab2017-03-27 16:55:32 +020065
66 scl->len = 3;
67}
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010068
Philipp Maier4f4905f2018-11-30 13:36:12 +010069void test_gsm0808_enc_cause(void)
70{
71 /* NOTE: This must be tested early because many of the following tests
72 * rely on the generation of a proper cause code. */
73
74 uint8_t rc_enc;
75 struct msgb *msg;
76
77 /* Test with a single byte cause code */
78 msg = msgb_alloc(1024, "output buffer");
79 rc_enc = gsm0808_enc_cause(msg, 0x41);
80 EXPECT_ENCODED("04 01 41");
81 msgb_free(msg);
82
83 /* Test with an extended (two byte) cause code */
84 msg = msgb_alloc(1024, "output buffer");
85 rc_enc = gsm0808_enc_cause(msg, 0x8041);
86 EXPECT_ENCODED("04 02 80 41");
87 msgb_free(msg);
88}
89
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010090static void test_create_layer3(void)
91{
92 static const uint8_t res[] = {
93 0x00, 0x0e, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
94 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23 };
95 struct msgb *msg, *in_msg;
Neels Hofmeyr178bf7a2018-04-20 12:23:45 +020096 struct osmo_cell_global_id cgi = {
97 .lai = {
98 .plmn = {
99 .mcc = 0x2244,
100 .mnc = 0x1122,
101 },
102 .lac = 0x3366,
103 },
104 .cell_identity = 0x4488,
105 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100106 printf("Testing creating Layer3\n");
107
108 in_msg = msgb_alloc_headroom(512, 128, "foo");
109 in_msg->l3h = in_msg->data;
110 msgb_v_put(in_msg, 0x23);
111
Neels Hofmeyr178bf7a2018-04-20 12:23:45 +0200112 msg = gsm0808_create_layer3_2(in_msg, &cgi, NULL);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100113 VERIFY(msg, res, ARRAY_SIZE(res));
114 msgb_free(msg);
115 msgb_free(in_msg);
116}
117
Philipp Maierfa896ab2017-03-27 16:55:32 +0200118static void test_create_layer3_aoip()
119{
120 static const uint8_t res[] = {
121 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
122 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23,
Philipp Maierbb839662017-06-01 17:11:19 +0200123 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, GSM0808_SCT_FR3 | 0x50,
Philipp Maier7e27b142018-03-22 17:26:46 +0100124 0xef, 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f,
Philipp Maierbb839662017-06-01 17:11:19 +0200125 GSM0808_SCT_CSD | 0x90, 0xc0
Philipp Maierfa896ab2017-03-27 16:55:32 +0200126 };
Maxfa3b4822018-11-05 14:59:54 +0100127 struct osmo_cell_global_id cgi = {
128 .lai = {
129 .plmn = {
130 .mcc = 0x2244,
131 .mnc = 0x1122,
132 },
133 .lac = 0x3366,
134 },
135 .cell_identity = 0x4488,
136 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200137 struct msgb *msg, *in_msg;
138 struct gsm0808_speech_codec_list sc_list;
139 printf("Testing creating Layer3 (AoIP)\n");
140
141 setup_codec_list(&sc_list);
142
143 in_msg = msgb_alloc_headroom(512, 128, "foo");
144 in_msg->l3h = in_msg->data;
145 msgb_v_put(in_msg, 0x23);
146
Maxfa3b4822018-11-05 14:59:54 +0100147 msg = gsm0808_create_layer3_2(in_msg, &cgi, &sc_list);
148
Philipp Maierfa896ab2017-03-27 16:55:32 +0200149 VERIFY(msg, res, ARRAY_SIZE(res));
150
151 msgb_free(msg);
152 msgb_free(in_msg);
153}
154
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100155static void test_create_reset()
156{
157 static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 };
158 struct msgb *msg;
159
160 printf("Testing creating Reset\n");
161 msg = gsm0808_create_reset();
162 VERIFY(msg, res, ARRAY_SIZE(res));
163 msgb_free(msg);
164}
165
Philipp Maier15596e22017-04-05 17:55:27 +0200166static void test_create_reset_ack()
167{
168 static const uint8_t res[] = { 0x00, 0x01, 0x31 };
169 struct msgb *msg;
170
171 printf("Testing creating Reset Ack\n");
172 msg = gsm0808_create_reset_ack();
173 VERIFY(msg, res, ARRAY_SIZE(res));
174 msgb_free(msg);
175}
176
177
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100178static void test_create_clear_command()
179{
180 static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 };
181 struct msgb *msg;
182
183 printf("Testing creating Clear Command\n");
184 msg = gsm0808_create_clear_command(0x23);
185 VERIFY(msg, res, ARRAY_SIZE(res));
186 msgb_free(msg);
187}
188
Harald Weltecf665fc2019-02-18 13:45:36 +0100189static void test_create_clear_command2()
190{
191 static const uint8_t res[] = { 0x00, 0x04, 0x20, 0x04, 0x01, 0x23 };
192 struct msgb *msg;
193
194 printf("Testing creating Clear Command 2\n");
195 msg = gsm0808_create_clear_command2(0x23, false);
196 VERIFY(msg, res, ARRAY_SIZE(res));
197 msgb_free(msg);
198}
199
200static void test_create_clear_command2_csfb()
201{
202 static const uint8_t res[] = { 0x00, 0x05, 0x20, 0x04, 0x01, 0x23, 0x8F };
203 struct msgb *msg;
204
205 printf("Testing creating Clear Command 2 (CSFB)\n");
206 msg = gsm0808_create_clear_command2(0x23, true);
207 VERIFY(msg, res, ARRAY_SIZE(res));
208 msgb_free(msg);
209}
210
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100211static void test_create_clear_complete()
212{
213 static const uint8_t res[] = { 0x00, 0x01, 0x21 };
214 struct msgb *msg;
215
216 printf("Testing creating Clear Complete\n");
217 msg = gsm0808_create_clear_complete();
218 VERIFY(msg, res, ARRAY_SIZE(res));
219 msgb_free(msg);
220}
221
Philipp Maierb478dd32017-03-29 15:50:05 +0200222static void test_create_cipher()
223{
224 static const uint8_t res[] =
225 { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa,
226 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 };
227 static const uint8_t res2[] =
228 { 0x00, 0x0e, 0x53, 0x0a, 0x09, 0x03, 0xaa,
229 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42,
230 GSM0808_IE_CIPHER_RESPONSE_MODE, 0x01 };
231 struct msgb *msg;
232 struct gsm0808_encrypt_info ei;
233 uint8_t include_imeisv;
234
235 memset(&ei, 0, sizeof(ei));
236 ei.perm_algo[0] = GSM0808_ALG_ID_A5_0;
237 ei.perm_algo[1] = GSM0808_ALG_ID_A5_1;
238 ei.perm_algo_len = 2;
239 ei.key[0] = 0xaa;
240 ei.key[1] = 0xbb;
241 ei.key[2] = 0xcc;
242 ei.key[3] = 0xdd;
243 ei.key[4] = 0xee;
244 ei.key[5] = 0xff;
245 ei.key[6] = 0x23;
246 ei.key[7] = 0x42;
247 ei.key_len = 8;
248 include_imeisv = 1;
249
250 printf("Testing creating Chipher Mode Command\n");
251 msg = gsm0808_create_cipher(&ei, NULL);
252 OSMO_ASSERT(msg);
253 VERIFY(msg, res, ARRAY_SIZE(res));
254 msgb_free(msg);
255
256 msg = gsm0808_create_cipher(&ei, &include_imeisv);
257 OSMO_ASSERT(msg);
258 VERIFY(msg, res2, ARRAY_SIZE(res2));
259 msgb_free(msg);
260}
261
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100262static void test_create_cipher_complete()
263{
264 static const uint8_t res1[] = {
265 0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 };
266 static const uint8_t res2[] = { 0x00, 0x03, 0x55, 0x2c, 0x04};
267 struct msgb *l3, *msg;
268
269 printf("Testing creating Cipher Complete\n");
270 l3 = msgb_alloc_headroom(512, 128, "l3h");
271 l3->l3h = l3->data;
272 msgb_v_put(l3, 0x23);
273 msgb_v_put(l3, 0x42);
274 msgb_v_put(l3, 0x21);
275
276 /* with l3 data */
277 msg = gsm0808_create_cipher_complete(l3, 4);
278 VERIFY(msg, res1, ARRAY_SIZE(res1));
279 msgb_free(msg);
280
281 /* with l3 data but short */
282 l3->len -= 1;
283 l3->tail -= 1;
284 msg = gsm0808_create_cipher_complete(l3, 4);
285 VERIFY(msg, res2, ARRAY_SIZE(res2));
286 msgb_free(msg);
287
288 /* without l3 data */
289 msg = gsm0808_create_cipher_complete(NULL, 4);
290 VERIFY(msg, res2, ARRAY_SIZE(res2));
291 msgb_free(msg);
292
293
294 msgb_free(l3);
295}
296
Maxed651d22018-11-07 15:25:05 +0100297static inline void parse_cipher_reject(struct msgb *msg, uint8_t exp)
298{
299 struct tlv_parsed tp;
300 int rc;
301
302 /* skip header and message type so we can parse Cause IE directly */
303 msg->l2h = msgb_data(msg) + sizeof(struct bssmap_header) + 1;
304
305 rc = osmo_bssap_tlv_parse(&tp, msg->l2h, msgb_l2len(msg));
306 if (rc < 0)
307 printf("FIXME: failed (%d) to parse created message %s\n", rc, msgb_hexdump(msg));
308
Alexander Chemerisfdfe25b2020-05-12 23:21:56 +0300309 rc = gsm0808_get_cause(&tp);
Maxed651d22018-11-07 15:25:05 +0100310 if (rc < 0)
311 printf("FIXME: failed (%s) to extract Cause from created message %s\n",
312 strerror(-rc), msgb_hexdump(msg));
313
314 if (exp != (enum gsm0808_cause)rc)
315 printf("FIXME: wrong Cause %d != %u (" OSMO_BIN_SPEC ") extracted from created message %s\n",
316 rc, exp, OSMO_BIT_PRINT(exp), msgb_hexdump(msg));
317}
318
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100319static void test_create_cipher_reject()
320{
Harald Welte62e40852017-12-17 20:50:34 +0100321 static const uint8_t res[] = { 0x00, 0x04, 0x59, 0x04, 0x01, 0x23 };
Maxed651d22018-11-07 15:25:05 +0100322 enum gsm0808_cause cause = GSM0808_CAUSE_CCCH_OVERLOAD;
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100323 struct msgb *msg;
324
325 printf("Testing creating Cipher Reject\n");
Maxed651d22018-11-07 15:25:05 +0100326 msg = gsm0808_create_cipher_reject(cause);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100327 VERIFY(msg, res, ARRAY_SIZE(res));
Maxed651d22018-11-07 15:25:05 +0100328
329 parse_cipher_reject(msg, cause);
330
331 msgb_free(msg);
332}
333
334static void test_create_cipher_reject_ext()
335{
336 static const uint8_t res[] = { 0x00, 0x05, 0x59, 0x04, 0x02, 0xd0, 0xFA };
337 uint8_t cause = 0xFA;
338 struct msgb *msg;
339
340 printf("Testing creating Cipher Reject (extended)\n");
341 msg = gsm0808_create_cipher_reject_ext(GSM0808_CAUSE_CLASS_INVAL, cause);
342 VERIFY(msg, res, ARRAY_SIZE(res));
343
344 parse_cipher_reject(msg, cause);
345
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100346 msgb_free(msg);
347}
348
349static void test_create_cm_u()
350{
Harald Welte07b625d2012-01-23 10:02:58 +0100351 static const uint8_t res[] = {
352 0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 };
353 static const uint8_t res2o[] = {
354 0x00, 0x04, 0x54, 0x12, 0x01, 0x23 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100355 struct msgb *msg;
Harald Welte07b625d2012-01-23 10:02:58 +0100356 const uint8_t cm2 = 0x23;
357 const uint8_t cm3 = 0x42;
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100358
359 printf("Testing creating CM U\n");
Harald Welte07b625d2012-01-23 10:02:58 +0100360 msg = gsm0808_create_classmark_update(&cm2, 1, &cm3, 1);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100361 VERIFY(msg, res, ARRAY_SIZE(res));
Harald Welte07b625d2012-01-23 10:02:58 +0100362
Neels Hofmeyr9a938ae2017-11-16 17:34:07 +0100363 msgb_free(msg);
364
Harald Welte07b625d2012-01-23 10:02:58 +0100365 msg = gsm0808_create_classmark_update(&cm2, 1, NULL, 0);
366 VERIFY(msg, res2o, ARRAY_SIZE(res2o));
367
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100368 msgb_free(msg);
369}
370
371static void test_create_sapi_reject()
372{
Alexander Chemerisa5b1b862020-05-12 01:03:08 +0300373 static const uint8_t res[] = { 0x00, 0x06, 0x25, 0x18, 0x03, 0x04, 0x01, 0x25 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100374 struct msgb *msg;
375
376 printf("Testing creating SAPI Reject\n");
377 msg = gsm0808_create_sapi_reject(3);
378 VERIFY(msg, res, ARRAY_SIZE(res));
379 msgb_free(msg);
380}
381
Philipp Maierc6144a22017-03-29 17:53:43 +0200382static void test_create_ass()
383{
384 static const uint8_t res1[] =
385 { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
386 0x04 };
387 static const uint8_t res2[] =
388 { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
389 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17,
Philipp Maierbb839662017-06-01 17:11:19 +0200390 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07,
Philipp Maier7e27b142018-03-22 17:26:46 +0100391 GSM0808_SCT_FR3 | 0x50, 0xef, 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f,
Philipp Maierbb839662017-06-01 17:11:19 +0200392 GSM0808_SCT_CSD | 0x90, 0xc0, GSM0808_IE_CALL_ID, 0xaa, 0xbb,
393 0xcc, 0xdd };
Philipp Maierc6144a22017-03-29 17:53:43 +0200394
395 struct msgb *msg;
396 struct gsm0808_channel_type ct;
397 uint16_t cic = 0004;
398 struct sockaddr_storage ss;
399 struct sockaddr_in sin;
400 struct gsm0808_speech_codec_list sc_list;
401 uint32_t call_id = 0xAABBCCDD;
402
403 memset(&ct, 0, sizeof(ct));
404 ct.ch_indctr = GSM0808_CHAN_SPEECH;
405 ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF;
406 ct.perm_spch[0] = GSM0808_PERM_FR3;
407 ct.perm_spch[1] = GSM0808_PERM_HR3;
408 ct.perm_spch_len = 2;
409
410 memset(&sin, 0, sizeof(sin));
411 sin.sin_family = AF_INET;
412 sin.sin_port = htons(1234);
413 inet_aton("192.168.100.23", &sin.sin_addr);
414
415 memset(&ss, 0, sizeof(ss));
416 memcpy(&ss, &sin, sizeof(sin));
417
418 setup_codec_list(&sc_list);
419
420 printf("Testing creating Assignment Request\n");
421 msg = gsm0808_create_ass(&ct, &cic, NULL, NULL, NULL);
422 OSMO_ASSERT(msg);
423 VERIFY(msg, res1, ARRAY_SIZE(res1));
424 msgb_free(msg);
425
426 msg = gsm0808_create_ass(&ct, &cic, &ss, &sc_list, &call_id);
427 OSMO_ASSERT(msg);
428 VERIFY(msg, res2, ARRAY_SIZE(res2));
429 msgb_free(msg);
430}
431
Max52074322018-11-30 10:44:07 +0100432static void test_create_ass2()
433{
434 static const uint8_t res[] = {
435 BSSAP_MSG_BSS_MANAGEMENT,
436 0x45,
437 BSS_MAP_MSG_ASSIGMENT_RQST,
438 GSM0808_IE_CHANNEL_TYPE,
439 0x04, 0x01, 0x0b, 0x91, 0x15, 0x01, 0x00, 0x04,
440 GSM0808_IE_AOIP_TRASP_ADDR,
441 0x06,
442 0xac, 0x0c, 0x65, 0x0d, /* IPv4 */
443 0x02, 0x9a,
444 GSM0808_IE_SPEECH_CODEC_LIST,
445 0x07,
446 GSM0808_SCT_FR3 | 0x50,
447 0xef, 0xcd,
448 GSM0808_SCT_FR2 | 0xa0,
449 0x9f,
450 GSM0808_SCT_CSD | 0x90,
451 0xc0,
452 GSM0808_IE_CALL_ID,
453 0xde, 0xad, 0xfa, 0xce, /* CallID */
454 0x83, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, /* Kc */
455 GSM0808_IE_GLOBAL_CALL_REF, 0x0d, /* GCR, length */
456 0x03, 0x44, 0x44, 0x44, /* GCR, Net ID */
457 0x02, 0xfe, 0xed, /* GCR, Node ID */
458 0x05, 0x41, 0x41, 0x41, 0x41, 0x41, /* GCR, Call ref. ID */
459 GSM0808_IE_LCLS_CONFIG, GSM0808_LCLS_CFG_BOTH_WAY,
460 GSM0808_IE_LCLS_CONN_STATUS_CTRL, GSM0808_LCLS_CSC_CONNECT,
461 GSM0808_IE_LCLS_CORR_NOT_NEEDED,
462 };
463 struct msgb *msg;
464 struct gsm0808_channel_type ct;
465 uint16_t cic = 4;
466 struct sockaddr_storage ss;
467 struct sockaddr_in sin;
468 struct gsm0808_speech_codec_list sc_list;
469 uint32_t call_id = 0xDEADFACE;
Max52074322018-11-30 10:44:07 +0100470 uint8_t Kc[16];
471 struct osmo_lcls lcls = {
472 .config = GSM0808_LCLS_CFG_BOTH_WAY,
473 .control = GSM0808_LCLS_CSC_CONNECT,
Max3b901252019-01-15 14:15:11 +0100474 .gcr = { .net_len = 3, .node = 0xFEED },
475 .gcr_available = true,
Max52074322018-11-30 10:44:07 +0100476 .corr_needed = false
477 };
478
Max3b901252019-01-15 14:15:11 +0100479 memset(lcls.gcr.cr, 'A', 5);
480 memset(lcls.gcr.net, 'D', lcls.gcr.net_len);
Max52074322018-11-30 10:44:07 +0100481 memset(Kc, 'E', 16);
482
483 memset(&ct, 0, sizeof(ct));
484 ct.ch_indctr = GSM0808_CHAN_SPEECH;
485 ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF;
486 ct.perm_spch[0] = GSM0808_PERM_FR2;
487 ct.perm_spch[1] = GSM0808_PERM_HR2;
488 ct.perm_spch_len = 2;
489
490 memset(&sin, 0, sizeof(sin));
491 sin.sin_family = AF_INET;
492 sin.sin_port = htons(666);
493 inet_aton("172.12.101.13", &sin.sin_addr); /* IPv4 */
494
495 memset(&ss, 0, sizeof(ss));
496 memcpy(&ss, &sin, sizeof(sin));
497
498 setup_codec_list(&sc_list);
499
500 printf("Testing creating Assignment Request with Kc and LCLS\n");
501
502 msg = gsm0808_create_ass2(&ct, &cic, &ss, &sc_list, &call_id, Kc, &lcls);
503 if (!msgb_eq_l3_data_print(msg, res, ARRAY_SIZE(res)))
504 abort();
505
506 msgb_free(msg);
507}
508
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100509static void test_create_ass_compl()
510{
511 static const uint8_t res1[] = {
512 0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c,
513 0x11, 0x40, 0x22 };
514 static const uint8_t res2[] = {
515 0x00, 0x07, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11};
516 struct msgb *msg;
517
518 printf("Testing creating Assignment Complete\n");
519 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0x22);
520 VERIFY(msg, res1, ARRAY_SIZE(res1));
521 msgb_free(msg);
522
523 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0);
524 VERIFY(msg, res2, ARRAY_SIZE(res2));
525 msgb_free(msg);
526}
527
Philipp Maierfa896ab2017-03-27 16:55:32 +0200528static void test_create_ass_compl_aoip()
529{
530 struct sockaddr_storage ss;
531 struct sockaddr_in sin;
532 struct gsm0808_speech_codec sc;
533 struct gsm0808_speech_codec_list sc_list;
534 static const uint8_t res[] =
Max414c8f52019-01-08 14:44:24 +0100535 { 0x00, 0x1f, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22,
Philipp Maierfa896ab2017-03-27 16:55:32 +0200536 GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04,
Philipp Maierbb839662017-06-01 17:11:19 +0200537 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, GSM0808_SCT_HR1 | 0x90,
Philipp Maier7e27b142018-03-22 17:26:46 +0100538 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, GSM0808_SCT_FR3 | 0x50, 0xef,
Max414c8f52019-01-08 14:44:24 +0100539 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f, GSM0808_SCT_CSD | 0x90, 0xc0,
540 GSM0808_IE_LCLS_BSS_STATUS, GSM0808_LCLS_STS_LOCALLY_SWITCHED };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200541 struct msgb *msg;
542
543 memset(&sin, 0, sizeof(sin));
544 sin.sin_family = AF_INET;
545 sin.sin_port = htons(1234);
546 inet_aton("192.168.100.23", &sin.sin_addr);
547
548 memset(&ss, 0, sizeof(ss));
549 memcpy(&ss, &sin, sizeof(sin));
550
551 memset(&sc, 0, sizeof(sc));
552 sc.fi = true;
553 sc.tf = true;
Philipp Maierbb839662017-06-01 17:11:19 +0200554 sc.type = GSM0808_SCT_HR1;
Philipp Maierfa896ab2017-03-27 16:55:32 +0200555
556 setup_codec_list(&sc_list);
557
558 printf("Testing creating Assignment Complete (AoIP)\n");
Max414c8f52019-01-08 14:44:24 +0100559 msg = gsm0808_create_ass_compl2(0x23, 0x42, 0x11, 0x22,
560 &ss, &sc, &sc_list, GSM0808_LCLS_STS_LOCALLY_SWITCHED);
Philipp Maierfa896ab2017-03-27 16:55:32 +0200561 VERIFY(msg, res, ARRAY_SIZE(res));
562 msgb_free(msg);
563}
564
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100565static void test_create_ass_fail()
566{
567 static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 };
568 static const uint8_t res2[] = {
569 0x00, 0x06, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02};
570 uint8_t rr_res = 2;
571 struct msgb *msg;
572
573 printf("Testing creating Assignment Failure\n");
574 msg = gsm0808_create_assignment_failure(0x23, NULL);
575 VERIFY(msg, res1, ARRAY_SIZE(res1));
576 msgb_free(msg);
577
578 msg = gsm0808_create_assignment_failure(0x23, &rr_res);
579 VERIFY(msg, res2, ARRAY_SIZE(res2));
580 msgb_free(msg);
581}
582
Philipp Maierfa896ab2017-03-27 16:55:32 +0200583static void test_create_ass_fail_aoip()
584{
585 static const uint8_t res1[] =
586 { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST,
Philipp Maier7e27b142018-03-22 17:26:46 +0100587 0x07, GSM0808_SCT_FR3 | 0x50, 0xef, 0xcd, GSM0808_SCT_FR2 | 0xa0,
Philipp Maierbb839662017-06-01 17:11:19 +0200588 0x9f, GSM0808_SCT_CSD | 0x90, 0xc0 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200589 static const uint8_t res2[] =
590 { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02,
Philipp Maier7e27b142018-03-22 17:26:46 +0100591 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, GSM0808_SCT_FR3 | 0x50, 0xef,
592 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f, GSM0808_SCT_CSD | 0x90, 0xc0 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200593 uint8_t rr_res = 2;
594 struct msgb *msg;
595 struct gsm0808_speech_codec_list sc_list;
596
597 setup_codec_list(&sc_list);
598
599 printf("Testing creating Assignment Failure (AoIP)\n");
600 msg = gsm0808_create_ass_fail(0x23, NULL, &sc_list);
601 VERIFY(msg, res1, ARRAY_SIZE(res1));
602 msgb_free(msg);
603
604 msg = gsm0808_create_ass_fail(0x23, &rr_res, &sc_list);
605 VERIFY(msg, res2, ARRAY_SIZE(res2));
606 msgb_free(msg);
607}
608
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100609static void test_create_clear_rqst()
610{
611 static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 };
612 struct msgb *msg;
613
614 printf("Testing creating Clear Request\n");
615 msg = gsm0808_create_clear_rqst(0x23);
616 VERIFY(msg, res, ARRAY_SIZE(res));
617 msgb_free(msg);
618}
619
Philipp Maier3d48ec02017-03-29 17:37:55 +0200620static void test_create_paging()
621{
622 static const uint8_t res[] =
623 { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
624 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 };
625 static const uint8_t res2[] =
626 { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
627 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
628 0x03, 0x05, 0x23, 0x42 };
629 static const uint8_t res3[] =
630 { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
631 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
632 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED,
633 RSL_CHANNEED_TCH_ForH };
634
635 struct msgb *msg;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100636 struct gsm0808_cell_id_list2 cil;
Philipp Maier3d48ec02017-03-29 17:37:55 +0200637 uint32_t tmsi = 0x12345678;
638 uint8_t chan_needed = RSL_CHANNEED_TCH_ForH;
639
640 char imsi[] = "001010000001234";
641
642 cil.id_discr = CELL_IDENT_LAC;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100643 cil.id_list[0].lac = 0x2342;
Philipp Maier3d48ec02017-03-29 17:37:55 +0200644 cil.id_list_len = 1;
645
646 printf("Testing creating Paging Request\n");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100647 msg = gsm0808_create_paging2(imsi, NULL, &cil, NULL);
Philipp Maier3d48ec02017-03-29 17:37:55 +0200648 VERIFY(msg, res, ARRAY_SIZE(res));
649 msgb_free(msg);
650
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100651 msg = gsm0808_create_paging2(imsi, &tmsi, &cil, NULL);
Philipp Maier3d48ec02017-03-29 17:37:55 +0200652 VERIFY(msg, res2, ARRAY_SIZE(res2));
653 msgb_free(msg);
654
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100655 msg = gsm0808_create_paging2(imsi, &tmsi, &cil, &chan_needed);
Philipp Maier3d48ec02017-03-29 17:37:55 +0200656 VERIFY(msg, res3, ARRAY_SIZE(res3));
657 msgb_free(msg);
658}
659
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100660static void test_create_dtap()
661{
662 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
663 struct msgb *msg, *l3;
664
665 printf("Testing creating DTAP\n");
666 l3 = msgb_alloc_headroom(512, 128, "test");
667 l3->l3h = l3->data;
668 msgb_v_put(l3, 0x23);
669 msgb_v_put(l3, 0x42);
670
671 msg = gsm0808_create_dtap(l3, 0x3);
672 VERIFY(msg, res, ARRAY_SIZE(res));
673 msgb_free(msg);
674 msgb_free(l3);
675}
676
677static void test_prepend_dtap()
678{
679 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
680 struct msgb *in_msg;
681
682 printf("Testing prepend DTAP\n");
683
684 in_msg = msgb_alloc_headroom(512, 128, "test");
685 msgb_v_put(in_msg, 0x23);
686 msgb_v_put(in_msg, 0x42);
687
688 gsm0808_prepend_dtap_header(in_msg, 0x3);
689 in_msg->l3h = in_msg->data;
690 VERIFY(in_msg, res, ARRAY_SIZE(res));
691 msgb_free(in_msg);
692}
693
Max47022152018-12-19 18:51:00 +0100694static void test_enc_dec_lcls()
Max969fb2e2018-12-10 11:01:10 +0100695{
696 static const uint8_t res[] = {
697 GSM0808_IE_GLOBAL_CALL_REF,
698 0x0d, /* GCR length */
699 0x03, /* .net_len */
700 0xf1, 0xf2, 0xf3, /* .net */
701 0x02, /* .node length */
702 0xde, 0xad, /* .node */
703 0x05, /* length of Call. Ref. */
704 0x41, 0x42, 0x43, 0x44, 0x45 /* .cr - Call. Ref. */
705 };
706 uint8_t len;
707 struct msgb *msg;
Max969fb2e2018-12-10 11:01:10 +0100708 int rc;
709 struct tlv_parsed tp;
Max3b901252019-01-15 14:15:11 +0100710 struct osmo_lcls *lcls_out, lcls_in = {
711 .gcr = {
712 .net_len = 3,
713 .net = { 0xf1, 0xf2, 0xf3 },
714 .node = 0xDEAD,
715 .cr = { 0x41, 0x42, 0x43, 0x44, 0x45 },
716 },
717 .gcr_available = true,
Max47022152018-12-19 18:51:00 +0100718 .config = GSM0808_LCLS_CFG_NA,
719 .control = GSM0808_LCLS_CSC_NA,
720 .corr_needed = true,
721 };
722
723 msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "LCLS IE");
Max969fb2e2018-12-10 11:01:10 +0100724 if (!msg)
725 return;
726
Max3b901252019-01-15 14:15:11 +0100727 lcls_out = talloc_zero(msg, struct osmo_lcls);
728 if (!lcls_out)
729 return;
730
Max47022152018-12-19 18:51:00 +0100731 len = gsm0808_enc_lcls(msg, &lcls_in);
Max969fb2e2018-12-10 11:01:10 +0100732 printf("Testing Global Call Reference IE encoder...\n\t%d bytes added: %s\n",
733 len, len == ARRAY_SIZE(res) ? "OK" : "FAIL");
734
735 if (!msgb_eq_data_print(msg, res, ARRAY_SIZE(res)))
736 abort();
737
738 rc = osmo_bssap_tlv_parse(&tp, msgb_data(msg), msgb_length(msg));
739 if (rc < 0) {
740 printf("parsing failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg));
741 abort();
742 }
743
Max3b901252019-01-15 14:15:11 +0100744 rc = gsm0808_dec_lcls(lcls_out, &tp);
Max969fb2e2018-12-10 11:01:10 +0100745 if (rc < 0) {
746 printf("decoding failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg));
747 abort();
748 }
749
Max3b901252019-01-15 14:15:11 +0100750 if (lcls_out->config != lcls_in.config) {
Max4fd64e52019-01-14 19:27:44 +0100751 printf("LCLS Config parsed wrong: %s != %s\n",
Max3b901252019-01-15 14:15:11 +0100752 gsm0808_lcls_config_name(lcls_out->config), gsm0808_lcls_config_name(lcls_in.config));
Max4fd64e52019-01-14 19:27:44 +0100753 abort();
754 }
755
Max3b901252019-01-15 14:15:11 +0100756 if (lcls_out->control != lcls_in.control) {
Max4fd64e52019-01-14 19:27:44 +0100757 printf("LCLS Control parsed wrong: %s != %s\n",
Max3b901252019-01-15 14:15:11 +0100758 gsm0808_lcls_control_name(lcls_out->control), gsm0808_lcls_control_name(lcls_in.control));
Max4fd64e52019-01-14 19:27:44 +0100759 abort();
760 }
761
Max3b901252019-01-15 14:15:11 +0100762 if (!osmo_gcr_eq(&lcls_out->gcr, &lcls_in.gcr)) {
Max5ec0cf52019-01-15 16:37:09 +0100763 printf("GCR parsed wrong:\n\t%s\n\t%s\n", osmo_gcr_dump(lcls_out), osmo_gcr_dump(&lcls_in));
Max1bec3902019-01-14 19:31:42 +0100764 abort();
765 }
Max969fb2e2018-12-10 11:01:10 +0100766
Max5ec0cf52019-01-15 16:37:09 +0100767 printf("\tdecoded %d bytes: %s:\n%s\n", rc, rc == len ? "OK" : "FAIL", osmo_lcls_dump(lcls_out));
768 printf("\t%s\n", osmo_gcr_dump(lcls_out));
Max969fb2e2018-12-10 11:01:10 +0100769 msgb_free(msg);
770}
771
Philipp Maier22401432017-03-24 17:59:26 +0100772static void test_enc_dec_aoip_trasp_addr_v4()
773{
774 struct sockaddr_storage enc_addr;
775 struct sockaddr_storage dec_addr;
776 struct sockaddr_in enc_addr_in;
777 struct msgb *msg;
778 uint8_t rc_enc;
779 int rc_dec;
780
781 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
782 enc_addr_in.sin_family = AF_INET;
783 enc_addr_in.sin_port = htons(1234);
784 inet_aton("255.0.255.255", &enc_addr_in.sin_addr);
785
786 memset(&enc_addr, 0, sizeof(enc_addr));
787 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
788
789 msg = msgb_alloc(1024, "output buffer");
790 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
791 OSMO_ASSERT(rc_enc == 8);
792 rc_dec =
793 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
794 OSMO_ASSERT(rc_dec == 6);
795 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
796
797 msgb_free(msg);
798}
799
800static void test_enc_dec_aoip_trasp_addr_v6()
801{
802 struct sockaddr_storage enc_addr;
803 struct sockaddr_storage dec_addr;
804 struct sockaddr_in6 enc_addr_in;
805 struct msgb *msg;
806 uint8_t rc_enc;
807 int rc_dec;
808
809 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
810 enc_addr_in.sin6_family = AF_INET6;
811 enc_addr_in.sin6_port = htons(4567);
812 inet_pton(AF_INET6, "2001:0db8:85a3:08d3:1319:8a2e:0370:7344",
813 &enc_addr_in.sin6_addr);
814
815 memset(&enc_addr, 0, sizeof(enc_addr));
816 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
817
818 msg = msgb_alloc(1024, "output buffer");
819 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
820 OSMO_ASSERT(rc_enc == 20);
821 rc_dec =
822 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
823 OSMO_ASSERT(rc_dec == 18);
824 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
825
826 msgb_free(msg);
827}
828
Philipp Maier6f725d62017-03-24 18:03:17 +0100829static void test_gsm0808_enc_dec_speech_codec()
830{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200831 struct gsm0808_speech_codec enc_sc = {
832 .pi = true,
833 .tf = true,
834 .type = GSM0808_SCT_FR2,
835 };
836 struct gsm0808_speech_codec dec_sc = {};
Philipp Maier6f725d62017-03-24 18:03:17 +0100837 struct msgb *msg;
838 uint8_t rc_enc;
839 int rc_dec;
840
Philipp Maier6f725d62017-03-24 18:03:17 +0100841 msg = msgb_alloc(1024, "output buffer");
842 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
843 OSMO_ASSERT(rc_enc == 3);
844
845 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
846 OSMO_ASSERT(rc_dec == 1);
847
848 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
849
850 msgb_free(msg);
851}
852
853
Philipp Maierbb839662017-06-01 17:11:19 +0200854static void test_gsm0808_enc_dec_speech_codec_with_cfg()
855{
Neels Hofmeyrc62c9342018-04-15 23:31:47 +0200856 struct gsm0808_speech_codec enc_sc = {
857 .pi = true,
858 .tf = true,
859 .type = GSM0808_SCT_FR3,
860 .cfg = 0xabcd,
861 };
862 struct gsm0808_speech_codec dec_sc = {};
Philipp Maierbb839662017-06-01 17:11:19 +0200863 struct msgb *msg;
864 uint8_t rc_enc;
865 int rc_dec;
866
Philipp Maierbb839662017-06-01 17:11:19 +0200867 msg = msgb_alloc(1024, "output buffer");
868 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
869 OSMO_ASSERT(rc_enc == 5);
870
871 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
872 OSMO_ASSERT(rc_dec == 3);
873
874 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
875
876 msgb_free(msg);
877}
878
Philipp Maier6f725d62017-03-24 18:03:17 +0100879static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg()
880{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200881 struct gsm0808_speech_codec enc_sc = {
882 .pi = true,
883 .tf = true,
884 .type = GSM0808_SCT_CSD,
885 .cfg = 0xc0,
886 };
887 struct gsm0808_speech_codec dec_sc = {};
Philipp Maier6f725d62017-03-24 18:03:17 +0100888 struct msgb *msg;
889 uint8_t rc_enc;
890 int rc_dec;
891
Philipp Maier6f725d62017-03-24 18:03:17 +0100892 msg = msgb_alloc(1024, "output buffer");
893 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
Philipp Maierbb839662017-06-01 17:11:19 +0200894 OSMO_ASSERT(rc_enc == 5);
Philipp Maier6f725d62017-03-24 18:03:17 +0100895
896 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
Philipp Maierbb839662017-06-01 17:11:19 +0200897 OSMO_ASSERT(rc_dec == 3);
Philipp Maier6f725d62017-03-24 18:03:17 +0100898
899 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
900
901 msgb_free(msg);
902}
903
904static void test_gsm0808_enc_dec_speech_codec_list()
905{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200906 struct gsm0808_speech_codec_list enc_scl = {
907 .codec = {
908 {
909 .pi = true,
910 .tf = true,
911 .type = GSM0808_SCT_FR3,
912 .cfg = 0xcdef,
913 },
914
915 {
916 .fi = true,
917 .pt = true,
918 .type = GSM0808_SCT_FR2,
919 },
920
921 {
922 .fi = true,
923 .tf = true,
924 .type = GSM0808_SCT_CSD,
925 .cfg = 0xc0,
926 },
927 },
928 .len = 3,
929 };
930 struct gsm0808_speech_codec_list dec_scl = {};
Philipp Maier6f725d62017-03-24 18:03:17 +0100931 struct msgb *msg;
932 uint8_t rc_enc;
933 int rc_dec;
934
Philipp Maier6f725d62017-03-24 18:03:17 +0100935 msg = msgb_alloc(1024, "output buffer");
936 rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
937 OSMO_ASSERT(rc_enc == 9);
938
939 rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
940 OSMO_ASSERT(rc_dec == 7);
941
942 OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0);
943
944 msgb_free(msg);
945}
946
Philipp Maierf6c369f2018-10-16 15:24:47 +0200947static void test_gsm0808_enc_dec_empty_speech_codec_list()
948{
949 struct gsm0808_speech_codec_list enc_scl = {
950 .len = 0,
951 };
952 struct gsm0808_speech_codec_list dec_scl = {};
953 struct msgb *msg;
954 uint8_t rc_enc;
955 int rc_dec;
956
957 msg = msgb_alloc(1024, "output buffer");
958 rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
959 OSMO_ASSERT(rc_enc == 2);
960
961 rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
962 OSMO_ASSERT(rc_dec == 0);
963
964 OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0);
965
966 msgb_free(msg);
967}
968
Philipp Maiere0c65302017-03-28 17:05:40 +0200969static void test_gsm0808_enc_dec_channel_type()
970{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200971 struct gsm0808_channel_type enc_ct = {
972 .ch_indctr = GSM0808_CHAN_SPEECH,
973 .ch_rate_type = GSM0808_SPEECH_HALF_PREF,
974 .perm_spch = { GSM0808_PERM_FR3, GSM0808_PERM_HR3 },
975 .perm_spch_len = 2,
976 };
977 struct gsm0808_channel_type dec_ct = {};
Philipp Maiere0c65302017-03-28 17:05:40 +0200978 struct msgb *msg;
979 uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE,
980 0x04, 0x01, 0x0b, 0xa1, 0x25
981 };
982 uint8_t rc_enc;
983 int rc_dec;
984
Philipp Maiere0c65302017-03-28 17:05:40 +0200985 msg = msgb_alloc(1024, "output buffer");
986 rc_enc = gsm0808_enc_channel_type(msg, &enc_ct);
987 OSMO_ASSERT(rc_enc == 6);
988 OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0);
989
990 rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2);
991 OSMO_ASSERT(rc_dec == 4);
Pau Espin Pedrol2605ffc2019-07-29 16:44:22 +0200992 OSMO_ASSERT(enc_ct.ch_indctr == dec_ct.ch_indctr);
993 OSMO_ASSERT(enc_ct.ch_rate_type == dec_ct.ch_rate_type);
994 OSMO_ASSERT(enc_ct.perm_spch_len == dec_ct.perm_spch_len);
995 OSMO_ASSERT(memcmp(&enc_ct.perm_spch[0], &dec_ct.perm_spch[0], enc_ct.perm_spch_len) == 0);
Philipp Maiere0c65302017-03-28 17:05:40 +0200996
997 msgb_free(msg);
998}
999
Philipp Maier14e76b92017-03-28 18:36:52 +02001000static void test_gsm0808_enc_dec_encrypt_info()
1001{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +02001002 struct gsm0808_encrypt_info enc_ei = {
1003 .perm_algo = { GSM0808_ALG_ID_A5_0, GSM0808_ALG_ID_A5_1 },
1004 .perm_algo_len = 2,
1005 .key = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42, },
1006 .key_len = 8,
1007 };
1008 struct gsm0808_encrypt_info dec_ei = {};
Philipp Maier14e76b92017-03-28 18:36:52 +02001009 struct msgb *msg;
1010 uint8_t ei_enc_expected[] =
1011 { GSM0808_IE_ENCRYPTION_INFORMATION, 0x09, 0x03, 0xaa, 0xbb,
1012 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42
1013 };
1014 uint8_t rc_enc;
1015 int rc_dec;
1016
Philipp Maier14e76b92017-03-28 18:36:52 +02001017 msg = msgb_alloc(1024, "output buffer");
1018 rc_enc = gsm0808_enc_encrypt_info(msg, &enc_ei);
1019 OSMO_ASSERT(rc_enc == 11);
1020 OSMO_ASSERT(memcmp(ei_enc_expected, msg->data, msg->len) == 0);
1021
1022 rc_dec = gsm0808_dec_encrypt_info(&dec_ei, msg->data + 2, msg->len - 2);
1023 OSMO_ASSERT(rc_dec == 9);
1024
1025 OSMO_ASSERT(memcmp(&enc_ei, &dec_ei, sizeof(enc_ei)) == 0);
1026
1027 msgb_free(msg);
1028}
1029
Philipp Maier783047e2017-03-29 11:35:50 +02001030static void test_gsm0808_enc_dec_cell_id_list_lac()
1031{
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001032 struct gsm0808_cell_id_list2 enc_cil;
1033 struct gsm0808_cell_id_list2 dec_cil;
Philipp Maier783047e2017-03-29 11:35:50 +02001034 struct msgb *msg;
1035 uint8_t rc_enc;
1036 int rc_dec;
1037
1038 memset(&enc_cil, 0, sizeof(enc_cil));
1039 enc_cil.id_discr = CELL_IDENT_LAC;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001040 enc_cil.id_list[0].lac = 0x0124;
Neels Hofmeyrdb2fa4e2018-04-13 04:11:20 +02001041 enc_cil.id_list[1].lac = 0xABCD;
1042 enc_cil.id_list[2].lac = 0x5678;
Philipp Maier783047e2017-03-29 11:35:50 +02001043 enc_cil.id_list_len = 3;
1044
1045 msg = msgb_alloc(1024, "output buffer");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001046 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
Neels Hofmeyrdb2fa4e2018-04-13 04:11:20 +02001047 EXPECT_ENCODED("1a 07 05 01 24 ab cd 56 78");
Philipp Maier783047e2017-03-29 11:35:50 +02001048
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001049 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
Philipp Maier783047e2017-03-29 11:35:50 +02001050 OSMO_ASSERT(rc_dec == 7);
1051
1052 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1053
1054 msgb_free(msg);
1055}
1056
1057static void test_gsm0808_enc_dec_cell_id_list_single_lac()
1058{
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001059 struct gsm0808_cell_id_list2 enc_cil;
1060 struct gsm0808_cell_id_list2 dec_cil;
Philipp Maier783047e2017-03-29 11:35:50 +02001061 struct msgb *msg;
1062 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x03,
1063 0x05, 0x23, 0x42
1064 };
1065 uint8_t rc_enc;
1066 int rc_dec;
1067
1068 memset(&enc_cil, 0, sizeof(enc_cil));
1069 enc_cil.id_discr = CELL_IDENT_LAC;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001070 enc_cil.id_list[0].lac = 0x2342;
Philipp Maier783047e2017-03-29 11:35:50 +02001071 enc_cil.id_list_len = 1;
1072
1073 msg = msgb_alloc(1024, "output buffer");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001074 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
Philipp Maier783047e2017-03-29 11:35:50 +02001075 OSMO_ASSERT(rc_enc == 5);
1076 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1077
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001078 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
Philipp Maier783047e2017-03-29 11:35:50 +02001079 OSMO_ASSERT(rc_dec == 3);
1080
1081 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1082
1083 msgb_free(msg);
1084}
1085
Stefan Sperlinge1a86742018-03-15 18:05:02 +01001086static void test_gsm0808_enc_dec_cell_id_list_multi_lac()
1087{
1088 struct gsm0808_cell_id_list2 enc_cil;
1089 struct gsm0808_cell_id_list2 dec_cil;
1090 struct msgb *msg;
1091 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x0b, 0x05,
1092 0x23, 0x42,
1093 0x24, 0x43,
1094 0x25, 0x44,
1095 0x26, 0x45,
1096 0x27, 0x46
1097 };
1098 uint8_t rc_enc;
1099 int rc_dec;
1100
1101 memset(&enc_cil, 0, sizeof(enc_cil));
1102 enc_cil.id_discr = CELL_IDENT_LAC;
1103 enc_cil.id_list[0].lac = 0x2342;
1104 enc_cil.id_list[1].lac = 0x2443;
1105 enc_cil.id_list[2].lac = 0x2544;
1106 enc_cil.id_list[3].lac = 0x2645;
1107 enc_cil.id_list[4].lac = 0x2746;
1108 enc_cil.id_list_len = 5;
1109
1110 msg = msgb_alloc(1024, "output buffer");
1111 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1112 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
1113 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1114
1115 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1116 OSMO_ASSERT(rc_dec == msg->len - 2);
1117 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1118
1119 msgb_free(msg);
1120}
1121
Philipp Maier783047e2017-03-29 11:35:50 +02001122static void test_gsm0808_enc_dec_cell_id_list_bss()
1123{
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001124 struct gsm0808_cell_id_list2 enc_cil;
1125 struct gsm0808_cell_id_list2 dec_cil;
Philipp Maier783047e2017-03-29 11:35:50 +02001126 struct msgb *msg;
1127 uint8_t rc_enc;
1128 int rc_dec;
1129
1130 memset(&enc_cil, 0, sizeof(enc_cil));
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001131 enc_cil.id_discr = CELL_IDENT_BSS;
Philipp Maier783047e2017-03-29 11:35:50 +02001132
1133 msg = msgb_alloc(1024, "output buffer");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001134 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
Philipp Maier783047e2017-03-29 11:35:50 +02001135 OSMO_ASSERT(rc_enc == 3);
1136
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001137 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
Philipp Maier783047e2017-03-29 11:35:50 +02001138 OSMO_ASSERT(rc_dec == 1);
1139
1140 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1141
1142 msgb_free(msg);
1143}
1144
Stefan Sperling23381452018-03-15 19:38:15 +01001145static void test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac()
1146{
1147 struct gsm0808_cell_id_list2 enc_cil;
1148 struct gsm0808_cell_id_list2 dec_cil;
1149 struct osmo_location_area_id id;
1150 struct msgb *msg;
1151 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x10, 0x04,
1152 0x92, 0x61, 0x54, 0x23, 0x42,
1153 0x92, 0x72, 0x54, 0x24, 0x43,
1154 0x92, 0x83, 0x54, 0x25, 0x44
1155 };
1156 uint8_t rc_enc;
1157 int rc_dec, i;
1158
1159 memset(&enc_cil, 0, sizeof(enc_cil));
1160 enc_cil.id_discr = CELL_IDENT_LAI_AND_LAC;
1161
1162 id.plmn.mcc = 0x123;
1163 osmo_mnc_from_str("456", &id.plmn.mnc, &id.plmn.mnc_3_digits);
1164 id.lac = 0x2342;
1165 memcpy(&enc_cil.id_list[0].lai_and_lac, &id, sizeof(id));
1166
1167 id.plmn.mcc = 0x124;
1168 osmo_mnc_from_str("457", &id.plmn.mnc, &id.plmn.mnc_3_digits);
1169 id.lac = 0x2443;
1170 memcpy(&enc_cil.id_list[1].lai_and_lac, &id, sizeof(id));
1171
1172 id.plmn.mcc = 0x125;
1173 osmo_mnc_from_str("458", &id.plmn.mnc, &id.plmn.mnc_3_digits);
1174 id.lac = 0x2544;
1175 memcpy(&enc_cil.id_list[2].lai_and_lac, &id, sizeof(id));
1176
1177 enc_cil.id_list_len = 3;
1178
1179 msg = msgb_alloc(1024, "output buffer");
1180 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1181 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
1182 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1183
1184 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1185 OSMO_ASSERT(rc_dec == msg->len - 2);
1186
1187 OSMO_ASSERT(dec_cil.id_list_len == 3);
1188 /* Check MAXLEN elements to ensure everything has been initialized. */
1189 for (i = 0; i < GSM0808_CELL_ID_LIST2_MAXLEN; i++) {
1190 struct osmo_location_area_id *enc_id;
1191 struct osmo_location_area_id *dec_id;
1192 enc_id = &enc_cil.id_list[i].lai_and_lac;
1193 dec_id = &dec_cil.id_list[i].lai_and_lac;
1194 OSMO_ASSERT(osmo_plmn_cmp(&enc_id->plmn, &dec_id->plmn) == 0);
1195 OSMO_ASSERT(enc_id->lac == dec_id->lac);
1196 }
1197
1198 msgb_free(msg);
1199}
1200
Stefan Sperling9c62fc62018-03-16 10:23:34 +01001201static void test_gsm0808_enc_dec_cell_id_list_multi_ci()
1202{
1203 struct gsm0808_cell_id_list2 enc_cil;
1204 struct gsm0808_cell_id_list2 dec_cil;
1205 struct msgb *msg;
1206 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x09, 0x02,
1207 0x00, 0x01,
1208 0x00, 0x02,
1209 0x00, 0x77,
1210 0x01, 0xff,
1211 };
1212 uint8_t rc_enc;
1213 int rc_dec;
1214
1215 memset(&enc_cil, 0, sizeof(enc_cil));
1216 enc_cil.id_discr = CELL_IDENT_CI;
1217 enc_cil.id_list[0].ci = 1;
1218 enc_cil.id_list[1].ci = 2;
1219 enc_cil.id_list[2].ci = 119;
1220 enc_cil.id_list[3].ci = 511;
1221 enc_cil.id_list_len = 4;
1222
1223 msg = msgb_alloc(1024, "output buffer");
1224 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1225 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
1226 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1227
1228 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1229 OSMO_ASSERT(rc_dec == msg->len - 2);
1230 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1231
1232 msgb_free(msg);
1233}
1234
Stefan Sperlinged4327c2018-03-16 11:02:59 +01001235static void test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci()
1236{
1237 struct gsm0808_cell_id_list2 enc_cil;
1238 struct gsm0808_cell_id_list2 dec_cil;
1239 struct msgb *msg;
1240 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x15, 0x01,
1241 0x23, 0x42, 0x00, 0x01,
1242 0x24, 0x43, 0x00, 0x02,
1243 0x25, 0x44, 0x00, 0x77,
1244 0x26, 0x45, 0x01, 0xff,
1245 0x27, 0x46, 0x02, 0xfe,
1246 };
1247 uint8_t rc_enc;
1248 int rc_dec;
1249
1250 memset(&enc_cil, 0, sizeof(enc_cil));
1251 enc_cil.id_discr = CELL_IDENT_LAC_AND_CI;
1252 enc_cil.id_list[0].lac_and_ci.lac = 0x2342;
1253 enc_cil.id_list[0].lac_and_ci.ci = 1;
1254 enc_cil.id_list[1].lac_and_ci.lac = 0x2443;
1255 enc_cil.id_list[1].lac_and_ci.ci = 2;
1256 enc_cil.id_list[2].lac_and_ci.lac = 0x2544;
1257 enc_cil.id_list[2].lac_and_ci.ci = 119;
1258 enc_cil.id_list[3].lac_and_ci.lac = 0x2645;
1259 enc_cil.id_list[3].lac_and_ci.ci = 511;
1260 enc_cil.id_list[4].lac_and_ci.lac = 0x2746;
1261 enc_cil.id_list[4].lac_and_ci.ci = 766;
1262 enc_cil.id_list_len = 5;
1263
1264 msg = msgb_alloc(1024, "output buffer");
1265 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1266 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
1267 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1268
1269 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1270 OSMO_ASSERT(rc_dec == msg->len - 2);
1271 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1272
1273 msgb_free(msg);
1274}
1275
Stefan Sperling483f3862018-03-16 12:21:26 +01001276static void test_gsm0808_enc_dec_cell_id_list_multi_global()
1277{
1278 struct gsm0808_cell_id_list2 enc_cil;
1279 struct gsm0808_cell_id_list2 dec_cil;
1280 struct msgb *msg;
1281 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x16, 0x00,
Neels Hofmeyr473485c2018-03-23 02:04:18 +01001282 0x21, 0x63, 0x54, 0x23, 0x42, 0x00, 0x1,
Neels Hofmeyrc44fc232018-03-23 02:15:12 +01001283 0x21, 0xf4, 0x75, 0x24, 0x43, 0x00, 0x2,
Neels Hofmeyr8b8cd932018-03-23 01:47:37 +01001284 0x21, 0x75, 0x00, 0x25, 0x44, 0x00, 0x77
Stefan Sperling483f3862018-03-16 12:21:26 +01001285 };
Stefan Sperling483f3862018-03-16 12:21:26 +01001286 uint8_t rc_enc;
1287 int rc_dec, i;
1288
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001289 enc_cil = (struct gsm0808_cell_id_list2){
1290 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1291 .id_list_len = 3,
1292 .id_list = {
1293 {
1294 .global = {
Neels Hofmeyr473485c2018-03-23 02:04:18 +01001295 .lai = { .plmn = { .mcc = 123, .mnc = 456 },
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001296 .lac = 0x2342 },
1297 .cell_identity = 1,
1298 }
1299 },
1300 {
1301 .global = {
Neels Hofmeyrc44fc232018-03-23 02:15:12 +01001302 .lai = { .plmn = { .mcc = 124, .mnc = 57 },
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001303 .lac = 0x2443 },
1304 .cell_identity = 2,
1305 }
1306 },
1307 {
1308 .global = {
Neels Hofmeyrc44fc232018-03-23 02:15:12 +01001309 .lai = { .plmn = { .mcc = 125, .mnc = 7,
1310 .mnc_3_digits = true },
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001311 .lac = 0x2544 },
1312 .cell_identity = 119,
1313 }
1314 },
1315 }
1316 };
Stefan Sperling483f3862018-03-16 12:21:26 +01001317
1318 msg = msgb_alloc(1024, "output buffer");
1319 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1320 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001321 if (memcmp(cil_enc_expected, msg->data, msg->len)) {
1322 printf(" got: %s\n", osmo_hexdump(msg->data, msg->len));
1323 printf("expect: %s\n", osmo_hexdump(cil_enc_expected, sizeof(cil_enc_expected)));
1324 OSMO_ASSERT(false);
1325 }
Stefan Sperling483f3862018-03-16 12:21:26 +01001326
1327 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1328 OSMO_ASSERT(rc_dec == msg->len - 2);
1329
1330 /* Check MAXLEN elements to ensure everything has been initialized. */
1331 for (i = 0; i < GSM0808_CELL_ID_LIST2_MAXLEN; i++) {
1332 struct osmo_cell_global_id *enc_id;
1333 struct osmo_cell_global_id *dec_id;
1334 enc_id = &enc_cil.id_list[i].global;
1335 dec_id = &dec_cil.id_list[i].global;
1336 OSMO_ASSERT(osmo_plmn_cmp(&enc_id->lai.plmn, &dec_id->lai.plmn) == 0);
1337 OSMO_ASSERT(enc_id->lai.lac == dec_id->lai.lac);
1338 OSMO_ASSERT(enc_id->cell_identity == dec_id->cell_identity);
1339 }
1340
1341 msgb_free(msg);
1342}
1343
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001344static void print_cil(const struct gsm0808_cell_id_list2 *cil)
1345{
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001346 printf(" cell_id_list == %s\n", gsm0808_cell_id_list_name(cil));
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001347}
1348
1349void test_cell_id_list_add() {
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001350 size_t zu;
1351
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001352 const struct gsm0808_cell_id_list2 cgi1 = {
1353 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1354 .id_list_len = 1,
1355 .id_list = {
1356 {
1357 .global = {
1358 .lai = {
1359 .plmn = { .mcc = 1, .mnc = 2, .mnc_3_digits = false },
1360 .lac = 3,
1361 },
1362 .cell_identity = 4,
1363 }
1364 },
1365 },
1366 };
1367
1368 const struct gsm0808_cell_id_list2 cgi2 = {
1369 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1370 .id_list_len = 2,
1371 .id_list = {
1372 {
1373 .global = {
1374 .lai = {
1375 .plmn = { .mcc = 1, .mnc = 2, .mnc_3_digits = true },
1376 .lac = 3,
1377 },
1378 .cell_identity = 4,
1379 }
1380 },
1381 {
1382 .global = {
1383 .lai = {
1384 .plmn = { .mcc = 5, .mnc = 6, .mnc_3_digits = true },
1385 .lac = 7,
1386 },
1387 .cell_identity = 8,
1388 }
1389 },
1390 },
1391 };
1392
1393 const struct gsm0808_cell_id_list2 cgi2a = {
1394 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1395 .id_list_len = 2,
1396 .id_list = {
1397 {
1398 .global = cgi2.id_list[0].global
1399 },
1400 {
1401 .global = {
1402 .lai = {
1403 .plmn = { .mcc = 9, .mnc = 10, .mnc_3_digits = true },
1404 .lac = 11,
1405 },
1406 .cell_identity = 12,
1407 }
1408 },
1409 },
1410 };
1411
1412 const struct gsm0808_cell_id_list2 cgi3 = {
1413 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1414 .id_list_len = 2,
1415 .id_list = {
1416 {
1417 .global = {
1418 .lai = {
1419 .plmn = { .mcc = 13, .mnc = 14, .mnc_3_digits = true },
1420 .lac = 15,
1421 },
1422 .cell_identity = 16,
1423 }
1424 },
1425 {
1426 .global = {
1427 .lai = {
1428 .plmn = { .mcc = 16, .mnc = 17, .mnc_3_digits = true },
1429 .lac = 18,
1430 },
1431 .cell_identity = 19,
1432 }
1433 },
1434 },
1435 };
1436
1437
1438 const struct gsm0808_cell_id_list2 lac1 = {
1439 .id_discr = CELL_IDENT_LAC,
1440 .id_list_len = 1,
1441 .id_list = {
1442 {
1443 .lac = 123
1444 },
1445 },
1446 };
1447
1448 const struct gsm0808_cell_id_list2 lac2 = {
1449 .id_discr = CELL_IDENT_LAC,
1450 .id_list_len = 2,
1451 .id_list = {
1452 {
1453 .lac = 456
1454 },
1455 {
1456 .lac = 789
1457 },
1458 },
1459 };
1460
1461 struct gsm0808_cell_id_list2 cil = {};
1462
1463 printf("------- %s\n", __func__);
1464
1465 print_cil(&cil);
1466
1467#define ADD_QUIET(other_cil, expect_rc) do { \
1468 int rc = gsm0808_cell_id_list_add(&cil, &other_cil); \
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001469 printf("gsm0808_cell_id_list_add(&cil, &" #other_cil ") --> rc = %d\n", rc); \
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001470 OSMO_ASSERT(rc == expect_rc); \
1471 } while(0)
1472
1473#define ADD(other_cil, expect_rc) ADD_QUIET(other_cil, expect_rc); print_cil(&cil)
1474
1475 ADD(lac1, 1);
1476 ADD(lac1, 0);
1477 ADD(lac2, 2);
1478 ADD(lac2, 0);
1479 ADD(cil, 0);
1480 ADD(cgi1, -EINVAL);
1481
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001482 printf("* can't add to BSS list\n");
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001483 cil.id_list_len = 0;
1484 cil.id_discr = CELL_IDENT_BSS;
1485 print_cil(&cil);
1486 ADD(lac1, -EINVAL);
1487
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001488 printf("* other types (including NO_CELL) take on new type iff empty\n");
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001489 cil.id_list_len = 0;
1490 cil.id_discr = CELL_IDENT_NO_CELL;
1491 print_cil(&cil);
1492 ADD(cgi1, 1);
1493 ADD(cgi1, 0);
1494 ADD(cgi2, 2);
1495 ADD(cgi2, 0);
1496
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001497 printf("* test gsm0808_cell_id_list_name_buf()'s return val\n");
1498 zu = strlen(gsm0808_cell_id_list_name(&cil));
1499 printf(" strlen(gsm0808_cell_id_list_name(cil)) == %zu\n", zu);
1500 zu ++;
1501 while (1) {
1502 char buf[128] = "?";
1503 int rc;
1504 OSMO_ASSERT(zu < sizeof(buf));
1505 buf[zu] = '#';
1506 rc = gsm0808_cell_id_list_name_buf(buf, zu, &cil);
1507 printf(" gsm0808_cell_id_list_name_buf(buf, %zu, cil)) == %d \"%s\"\n",
1508 zu, rc, buf);
1509 OSMO_ASSERT(buf[zu] == '#');
1510 if (!zu)
1511 break;
1512 zu /= 2;
1513 }
1514
1515 printf("* list-full behavior\n");
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001516 cil.id_list_len = GSM0808_CELL_ID_LIST2_MAXLEN - 1;
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001517 printf("cil.id_list_len = %u\n", cil.id_list_len);
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001518 ADD_QUIET(cgi2a, 1);
1519 printf("cil.id_list_len = %u\n", cil.id_list_len);
1520
1521 cil.id_list_len = GSM0808_CELL_ID_LIST2_MAXLEN - 1;
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001522 printf("cil.id_list_len = %u\n", cil.id_list_len);
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001523 ADD_QUIET(cgi3, -ENOSPC);
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001524 printf("cil.id_list_len = %u\n", cil.id_list_len);
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001525 ADD_QUIET(cgi2a, -ENOSPC);
1526 printf("cil.id_list_len = %u\n", cil.id_list_len);
1527
1528 printf("------- %s done\n", __func__);
1529}
1530
Neels Hofmeyr250e7f72018-04-13 03:30:14 +02001531static void test_gsm0808_enc_dec_cell_id_lac()
1532{
1533 struct gsm0808_cell_id enc_ci = {
1534 .id_discr = CELL_IDENT_LAC,
1535 .id.lac = 0x0124,
1536 };
1537 struct gsm0808_cell_id dec_ci;
1538 struct msgb *msg;
1539 uint8_t rc_enc;
1540 int rc_dec;
1541
1542 memset(&dec_ci, 0xa5, sizeof(dec_ci));
1543
1544 msg = msgb_alloc(1024, "output buffer");
1545 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1546 EXPECT_ENCODED("05 03 05 01 24");
1547
1548 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1549 OSMO_ASSERT(rc_dec == 3);
1550
1551 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1552 && enc_ci.id.lac == dec_ci.id.lac);
1553
1554 msgb_free(msg);
1555}
1556
1557static void test_gsm0808_enc_dec_cell_id_bss()
1558{
1559 struct gsm0808_cell_id enc_ci = {
1560 .id_discr = CELL_IDENT_BSS,
1561 };
1562 struct gsm0808_cell_id dec_ci;
1563 struct msgb *msg;
1564 uint8_t rc_enc;
1565 int rc_dec;
1566
1567 msg = msgb_alloc(1024, "output buffer");
1568 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1569 EXPECT_ENCODED("05 01 06");
1570
1571 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1572 OSMO_ASSERT(rc_dec == 1);
1573
1574 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr);
1575
1576 msgb_free(msg);
1577}
1578
1579static void test_gsm0808_enc_dec_cell_id_no_cell()
1580{
1581 struct gsm0808_cell_id enc_ci = {
1582 .id_discr = CELL_IDENT_NO_CELL,
1583 };
1584 struct gsm0808_cell_id dec_ci;
1585 struct msgb *msg;
1586 uint8_t rc_enc;
1587 int rc_dec;
1588
1589 msg = msgb_alloc(1024, "output buffer");
1590 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1591 EXPECT_ENCODED("05 01 03");
1592
1593 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1594 OSMO_ASSERT(rc_dec == 1);
1595
1596 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr);
1597
1598 msgb_free(msg);
1599}
1600
1601static void test_gsm0808_enc_dec_cell_id_lai_and_lac()
1602{
1603 struct gsm0808_cell_id enc_ci = {
1604 .id_discr = CELL_IDENT_LAI_AND_LAC,
1605 .id.lai_and_lac = {
1606 .plmn = {
1607 .mcc = 123,
1608 .mnc = 456,
1609 },
1610 .lac = 0x2342,
1611 },
1612 };
1613 struct gsm0808_cell_id dec_ci;
1614 struct msgb *msg;
1615 uint8_t rc_enc;
1616 int rc_dec;
1617
1618 msg = msgb_alloc(1024, "output buffer");
1619 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1620 EXPECT_ENCODED("05 06 04 21 63 54 23 42");
1621
1622 memset(&dec_ci, 0xa5, sizeof(dec_ci));
1623 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1624 OSMO_ASSERT(rc_dec == msg->len - 2);
1625
1626 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1627 && osmo_plmn_cmp(&enc_ci.id.lai_and_lac.plmn, &dec_ci.id.lai_and_lac.plmn) == 0
1628 && enc_ci.id.lai_and_lac.lac == dec_ci.id.lai_and_lac.lac);
1629 msgb_free(msg);
1630}
1631
1632static void test_gsm0808_enc_dec_cell_id_ci()
1633{
1634 struct gsm0808_cell_id enc_ci = {
1635 .id_discr = CELL_IDENT_CI,
1636 .id.ci = 0x423,
1637 };
1638 struct gsm0808_cell_id dec_ci;
1639 struct msgb *msg;
1640 uint8_t rc_enc;
1641 int rc_dec;
1642
1643 msg = msgb_alloc(1024, "output buffer");
1644 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1645 EXPECT_ENCODED("05 03 02 04 23");
1646
1647 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1648 OSMO_ASSERT(rc_dec == msg->len - 2);
1649 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1650 && enc_ci.id.ci == dec_ci.id.ci);
1651
1652 msgb_free(msg);
1653}
1654
1655static void test_gsm0808_enc_dec_cell_id_lac_and_ci()
1656{
1657 struct gsm0808_cell_id enc_ci = {
1658 .id_discr = CELL_IDENT_LAC_AND_CI,
1659 .id.lac_and_ci = {
1660 .lac = 0x423,
1661 .ci = 0x235,
1662 },
1663 };
1664 struct gsm0808_cell_id dec_ci;
1665 struct msgb *msg;
1666 uint8_t rc_enc;
1667 int rc_dec;
1668
1669 msg = msgb_alloc(1024, "output buffer");
1670 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1671 EXPECT_ENCODED("05 05 01 04 23 02 35");
1672
1673 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1674 OSMO_ASSERT(rc_dec == msg->len - 2);
1675 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1676 && enc_ci.id.lac_and_ci.lac == dec_ci.id.lac_and_ci.lac
1677 && enc_ci.id.lac_and_ci.ci == dec_ci.id.lac_and_ci.ci);
1678
1679 msgb_free(msg);
1680}
1681
1682static void test_gsm0808_enc_dec_cell_id_global()
1683{
1684 struct gsm0808_cell_id enc_ci = {
1685 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1686 .id.global = {
1687 .lai = {
1688 .plmn = { .mcc = 123, .mnc = 456 },
1689 .lac = 0x2342
1690 },
1691 .cell_identity = 0x423,
1692 }
1693 };
1694 struct gsm0808_cell_id dec_ci;
1695 struct msgb *msg;
1696 uint8_t rc_enc;
1697 int rc_dec;
1698
1699 msg = msgb_alloc(1024, "output buffer");
1700 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1701 EXPECT_ENCODED("05 08 00 21 63 54 23 42 04 23");
1702
1703 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1704 OSMO_ASSERT(rc_dec == msg->len - 2);
1705
1706 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1707 && osmo_plmn_cmp(&enc_ci.id.global.lai.plmn,
1708 &dec_ci.id.global.lai.plmn) == 0
1709 && enc_ci.id.global.lai.lac == dec_ci.id.global.lai.lac
1710 && enc_ci.id.global.cell_identity == dec_ci.id.global.cell_identity);
1711 msgb_free(msg);
1712}
1713
Philipp Maier5f2eb152018-09-19 13:40:21 +02001714static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(struct gsm48_multi_rate_conf *cfg)
1715{
1716 uint16_t s15_s0;
1717
1718 printf("Input:\n");
1719 printf(" m4_75= %u smod= %u\n", cfg->m4_75, cfg->smod);
1720 printf(" m5_15= %u spare= %u\n", cfg->m5_15, cfg->spare);
1721 printf(" m5_90= %u icmi= %u\n", cfg->m5_90, cfg->icmi);
1722 printf(" m6_70= %u nscb= %u\n", cfg->m6_70, cfg->nscb);
1723 printf(" m7_40= %u ver= %u\n", cfg->m7_40, cfg->ver);
1724 printf(" m7_95= %u\n", cfg->m7_95);
1725 printf(" m10_2= %u\n", cfg->m10_2);
1726 printf(" m12_2= %u\n", cfg->m12_2);
1727
1728 s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, true);
1729 printf("Result (fr):\n");
1730 printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
1731 OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
1732
1733 s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, false);
1734 printf("Result (hr):\n");
1735 printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
1736 OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
1737
1738 printf("\n");
1739}
1740
1741static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg(void)
1742{
1743 struct gsm48_multi_rate_conf cfg;
1744
1745 printf("Testing gsm0808_sc_cfg_from_gsm48_mr_cfg():\n");
1746
1747 memset(&cfg, 0, sizeof(cfg));
1748
1749 cfg.m4_75 = 0;
1750 cfg.m5_15 = 0;
1751 cfg.m5_90 = 0;
1752 cfg.m6_70 = 0;
1753 cfg.m7_40 = 0;
1754 cfg.m7_95 = 0;
1755 cfg.m10_2 = 0;
1756 cfg.m12_2 = 0;
1757 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1758
1759 cfg.m4_75 = 1;
1760 cfg.m5_15 = 0;
1761 cfg.m5_90 = 0;
1762 cfg.m6_70 = 0;
1763 cfg.m7_40 = 0;
1764 cfg.m7_95 = 0;
1765 cfg.m10_2 = 0;
1766 cfg.m12_2 = 0;
1767 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1768
1769 cfg.m4_75 = 0;
1770 cfg.m5_15 = 1;
1771 cfg.m5_90 = 0;
1772 cfg.m6_70 = 0;
1773 cfg.m7_40 = 0;
1774 cfg.m7_95 = 0;
1775 cfg.m10_2 = 0;
1776 cfg.m12_2 = 0;
1777 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1778
1779 cfg.m4_75 = 0;
1780 cfg.m5_15 = 0;
1781 cfg.m5_90 = 1;
1782 cfg.m6_70 = 0;
1783 cfg.m7_40 = 0;
1784 cfg.m7_95 = 0;
1785 cfg.m10_2 = 0;
1786 cfg.m12_2 = 0;
1787 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1788
1789 cfg.m4_75 = 0;
1790 cfg.m5_15 = 0;
1791 cfg.m5_90 = 0;
1792 cfg.m6_70 = 1;
1793 cfg.m7_40 = 0;
1794 cfg.m7_95 = 0;
1795 cfg.m10_2 = 0;
1796 cfg.m12_2 = 0;
1797 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1798
1799 cfg.m4_75 = 0;
1800 cfg.m5_15 = 0;
1801 cfg.m5_90 = 0;
1802 cfg.m6_70 = 0;
1803 cfg.m7_40 = 1;
1804 cfg.m7_95 = 0;
1805 cfg.m10_2 = 0;
1806 cfg.m12_2 = 0;
1807 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1808
1809 cfg.m4_75 = 0;
1810 cfg.m5_15 = 0;
1811 cfg.m5_90 = 0;
1812 cfg.m6_70 = 0;
1813 cfg.m7_40 = 0;
1814 cfg.m7_95 = 1;
1815 cfg.m10_2 = 0;
1816 cfg.m12_2 = 0;
1817 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1818
1819 cfg.m4_75 = 0;
1820 cfg.m5_15 = 0;
1821 cfg.m5_90 = 0;
1822 cfg.m6_70 = 0;
1823 cfg.m7_40 = 0;
1824 cfg.m7_95 = 0;
1825 cfg.m10_2 = 1;
1826 cfg.m12_2 = 0;
1827 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1828
1829 cfg.m4_75 = 0;
1830 cfg.m5_15 = 0;
1831 cfg.m5_90 = 0;
1832 cfg.m6_70 = 0;
1833 cfg.m7_40 = 0;
1834 cfg.m7_95 = 0;
1835 cfg.m10_2 = 0;
1836 cfg.m12_2 = 1;
1837 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1838
1839 cfg.m4_75 = 1;
1840 cfg.m5_15 = 1;
1841 cfg.m5_90 = 1;
1842 cfg.m6_70 = 1;
1843 cfg.m7_40 = 0;
1844 cfg.m7_95 = 0;
1845 cfg.m10_2 = 0;
1846 cfg.m12_2 = 0;
1847 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1848
1849 cfg.m4_75 = 0;
1850 cfg.m5_15 = 0;
1851 cfg.m5_90 = 0;
1852 cfg.m6_70 = 0;
1853 cfg.m7_40 = 1;
1854 cfg.m7_95 = 1;
1855 cfg.m10_2 = 1;
1856 cfg.m12_2 = 1;
1857 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1858
1859 cfg.m4_75 = 0;
1860 cfg.m5_15 = 0;
1861 cfg.m5_90 = 1;
1862 cfg.m6_70 = 1;
1863 cfg.m7_40 = 0;
1864 cfg.m7_95 = 0;
1865 cfg.m10_2 = 1;
1866 cfg.m12_2 = 1;
1867 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1868
1869 cfg.m4_75 = 1;
1870 cfg.m5_15 = 1;
1871 cfg.m5_90 = 0;
1872 cfg.m6_70 = 0;
1873 cfg.m7_40 = 1;
1874 cfg.m7_95 = 1;
1875 cfg.m10_2 = 0;
1876 cfg.m12_2 = 0;
1877 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1878
1879 cfg.m4_75 = 0;
1880 cfg.m5_15 = 1;
1881 cfg.m5_90 = 0;
1882 cfg.m6_70 = 1;
1883 cfg.m7_40 = 0;
1884 cfg.m7_95 = 1;
1885 cfg.m10_2 = 0;
1886 cfg.m12_2 = 1;
1887 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1888
1889 cfg.m4_75 = 1;
1890 cfg.m5_15 = 0;
1891 cfg.m5_90 = 1;
1892 cfg.m6_70 = 0;
1893 cfg.m7_40 = 1;
1894 cfg.m7_95 = 0;
1895 cfg.m10_2 = 1;
1896 cfg.m12_2 = 0;
1897 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1898
1899 cfg.m4_75 = 1;
1900 cfg.m5_15 = 1;
1901 cfg.m5_90 = 1;
1902 cfg.m6_70 = 1;
1903 cfg.m7_40 = 1;
1904 cfg.m7_95 = 1;
1905 cfg.m10_2 = 1;
1906 cfg.m12_2 = 1;
1907 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
Philipp Maier94d79fd2019-03-01 10:40:48 +01001908
1909 cfg.m4_75 = 1;
1910 cfg.m5_15 = 0;
1911 cfg.m5_90 = 1;
1912 cfg.m6_70 = 0;
1913 cfg.m7_40 = 1;
1914 cfg.m7_95 = 0;
1915 cfg.m10_2 = 0;
1916 cfg.m12_2 = 1;
1917 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1918
1919 cfg.m4_75 = 1;
1920 cfg.m5_15 = 0;
1921 cfg.m5_90 = 1;
1922 cfg.m6_70 = 0;
1923 cfg.m7_40 = 1;
1924 cfg.m7_95 = 0;
1925 cfg.m10_2 = 0;
1926 cfg.m12_2 = 0;
1927 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1928
Philipp Maier5f2eb152018-09-19 13:40:21 +02001929}
1930
Philipp Maier8515d032018-09-25 15:57:49 +02001931static void test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(uint16_t s15_s0)
1932{
1933 struct gsm48_multi_rate_conf cfg;
Philipp Maier3713af82019-02-27 16:48:25 +01001934 int rc;
Philipp Maier8515d032018-09-25 15:57:49 +02001935
1936 printf("Input:\n");
1937 printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
1938 OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
1939
Philipp Maier3713af82019-02-27 16:48:25 +01001940 rc = gsm48_mr_cfg_from_gsm0808_sc_cfg(&cfg, s15_s0);
Philipp Maier8515d032018-09-25 15:57:49 +02001941
1942 printf("Output:\n");
1943 printf(" m4_75= %u smod= %u\n", cfg.m4_75, cfg.smod);
1944 printf(" m5_15= %u spare= %u\n", cfg.m5_15, cfg.spare);
1945 printf(" m5_90= %u icmi= %u\n", cfg.m5_90, cfg.icmi);
1946 printf(" m6_70= %u nscb= %u\n", cfg.m6_70, cfg.nscb);
1947 printf(" m7_40= %u ver= %u\n", cfg.m7_40, cfg.ver);
1948 printf(" m7_95= %u\n", cfg.m7_95);
1949 printf(" m10_2= %u\n", cfg.m10_2);
1950 printf(" m12_2= %u\n", cfg.m12_2);
1951
Philipp Maier3713af82019-02-27 16:48:25 +01001952 if (rc != 0)
1953 printf(" Result invalid!\n");
1954
Philipp Maier8515d032018-09-25 15:57:49 +02001955 printf("\n");
1956}
1957
1958void test_gsm48_mr_cfg_from_gsm0808_sc_cfg()
1959{
1960 printf("Testing gsm48_mr_cfg_from_gsm0808_sc_cfg():\n");
1961
Philipp Maier3713af82019-02-27 16:48:25 +01001962 /* Test with settings as defined in 3GPP TS 28.062, Table 7.11.3.1.3-2,
1963 * (up to four codecs may become selected) */
Philipp Maier8515d032018-09-25 15:57:49 +02001964 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1965 (GSM0808_SC_CFG_DEFAULT_AMR_4_75);
1966 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1967 (GSM0808_SC_CFG_DEFAULT_AMR_5_15);
1968 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1969 (GSM0808_SC_CFG_DEFAULT_AMR_5_90);
1970 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1971 (GSM0808_SC_CFG_DEFAULT_AMR_6_70);
1972 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1973 (GSM0808_SC_CFG_DEFAULT_AMR_7_40);
1974 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1975 (GSM0808_SC_CFG_DEFAULT_AMR_7_95);
1976 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1977 (GSM0808_SC_CFG_DEFAULT_AMR_10_2);
1978 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1979 (GSM0808_SC_CFG_DEFAULT_AMR_12_2);
1980
Philipp Maier3713af82019-02-27 16:48:25 +01001981 /* Test with settings as defined in 3GPP TS 28.062, Table 7.11.3.1.3-2,
1982 * but pick only one distinctive setting at a time */
1983 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_4_75);
Philipp Maier8515d032018-09-25 15:57:49 +02001984 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
Philipp Maier3713af82019-02-27 16:48:25 +01001985 (GSM0808_SC_CFG_AMR_4_75_5_90_7_40_12_20);
1986 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_5_90);
1987 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_6_70);
1988 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_7_40);
1989 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_7_95);
1990 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_10_2);
1991 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_12_2);
1992
1993 /* Arbitrary, but valid combinations */
1994 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_7_40 |
1995 GSM0808_SC_CFG_AMR_6_70 |
1996 GSM0808_SC_CFG_AMR_10_2);
1997 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_7_95 |
1998 GSM0808_SC_CFG_AMR_4_75);
1999 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_5_90 |
2000 GSM0808_SC_CFG_AMR_12_2);
Philipp Maier8515d032018-09-25 15:57:49 +02002001 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
Philipp Maier3713af82019-02-27 16:48:25 +01002002 (GSM0808_SC_CFG_AMR_4_75_5_90_7_40_12_20 | GSM0808_SC_CFG_AMR_5_90 |
2003 GSM0808_SC_CFG_AMR_12_2);
2004
2005 /* Invalid combinations */
Philipp Maier8515d032018-09-25 15:57:49 +02002006 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
Philipp Maier3713af82019-02-27 16:48:25 +01002007 (GSM0808_SC_CFG_AMR_4_75_5_90_7_40_12_20 | GSM0808_SC_CFG_AMR_6_70);
2008 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(GSM0808_SC_CFG_AMR_7_40 |
2009 GSM0808_SC_CFG_AMR_6_70 |
2010 GSM0808_SC_CFG_AMR_10_2 |
2011 GSM0808_SC_CFG_AMR_7_95 |
2012 GSM0808_SC_CFG_AMR_4_75);
2013 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(0x0000);
2014 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(0xffff);
Philipp Maier8515d032018-09-25 15:57:49 +02002015}
2016
Neels Hofmeyrd01ef752018-09-21 15:57:26 +02002017struct test_cell_id_matching_data {
2018 struct gsm0808_cell_id id;
2019 struct gsm0808_cell_id match_id;
2020 bool expect_match;
2021 bool expect_exact_match;
2022};
2023
2024#define lac_23 { .id_discr = CELL_IDENT_LAC, .id.lac = 23, }
2025#define lac_42 { .id_discr = CELL_IDENT_LAC, .id.lac = 42, }
2026#define ci_5 { .id_discr = CELL_IDENT_CI, .id.ci = 5, }
2027#define ci_6 { .id_discr = CELL_IDENT_CI, .id.ci = 6, }
2028#define lac_ci_23_5 { \
2029 .id_discr = CELL_IDENT_LAC_AND_CI, \
2030 .id.lac_and_ci = { .lac = 23, .ci = 5, }, \
2031 }
2032#define lac_ci_42_6 { \
2033 .id_discr = CELL_IDENT_LAC_AND_CI, \
2034 .id.lac_and_ci = { .lac = 42, .ci = 6, }, \
2035 }
2036#define lai_23_042_23 { \
2037 .id_discr = CELL_IDENT_LAI_AND_LAC, \
2038 .id.lai_and_lac = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = true }, .lac = 23, }, \
2039 }
2040#define lai_23_042_42 { \
2041 .id_discr = CELL_IDENT_LAI_AND_LAC, \
2042 .id.lai_and_lac = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = true }, .lac = 42, }, \
2043 }
2044#define lai_23_99_23 { \
2045 .id_discr = CELL_IDENT_LAI_AND_LAC, \
2046 .id.lai_and_lac = { .plmn = { .mcc = 23, .mnc = 99, .mnc_3_digits = false }, .lac = 23, }, \
2047 }
2048#define lai_23_42_23 { \
2049 .id_discr = CELL_IDENT_LAI_AND_LAC, \
2050 .id.lai_and_lac = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = false }, .lac = 23, }, \
2051 }
2052#define cgi_23_042_23_5 { \
2053 .id_discr = CELL_IDENT_WHOLE_GLOBAL, \
2054 .id.global = { \
2055 .lai = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = true }, .lac = 23, }, \
2056 .cell_identity = 5, \
2057 }, \
2058 }
2059#define cgi_23_042_42_6 { \
2060 .id_discr = CELL_IDENT_WHOLE_GLOBAL, \
2061 .id.global = { \
2062 .lai = { .plmn = { .mcc = 23, .mnc = 42, .mnc_3_digits = true }, .lac = 42, }, \
2063 .cell_identity = 6, \
2064 }, \
2065 }
2066#define cgi_23_99_23_5 { \
2067 .id_discr = CELL_IDENT_WHOLE_GLOBAL, \
2068 .id.global = { \
2069 .lai = { .plmn = { .mcc = 23, .mnc = 99, .mnc_3_digits = false }, .lac = 23, }, \
2070 .cell_identity = 5, \
2071 }, \
2072 }
2073
2074
2075static const struct test_cell_id_matching_data test_cell_id_matching_tests[] = {
2076 { .id = lac_23, .match_id = lac_23, .expect_match = true, .expect_exact_match = true },
2077 { .id = lac_23, .match_id = lac_42, .expect_match = false, .expect_exact_match = false },
2078 { .id = lac_23, .match_id = ci_5, .expect_match = true, .expect_exact_match = false },
2079 { .id = lac_23, .match_id = ci_6, .expect_match = true, .expect_exact_match = false },
2080 { .id = lac_23, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = false },
2081 { .id = lac_23, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },
2082 { .id = lac_23, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = false },
2083 { .id = lac_23, .match_id = lai_23_042_42, .expect_match = false, .expect_exact_match = false },
2084 { .id = lac_23, .match_id = lai_23_99_23, .expect_match = true, .expect_exact_match = false },
2085 { .id = lac_23, .match_id = lai_23_42_23, .expect_match = true, .expect_exact_match = false },
2086 { .id = lac_23, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = false },
2087 { .id = lac_23, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },
2088 { .id = lac_23, .match_id = cgi_23_99_23_5, .expect_match = true, .expect_exact_match = false },
2089 { .id = ci_5, .match_id = lac_23, .expect_match = true, .expect_exact_match = false },
2090 { .id = ci_5, .match_id = lac_42, .expect_match = true, .expect_exact_match = false },
2091 { .id = ci_5, .match_id = ci_5, .expect_match = true, .expect_exact_match = true },
2092 { .id = ci_5, .match_id = ci_6, .expect_match = false, .expect_exact_match = false },
2093 { .id = ci_5, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = false },
2094 { .id = ci_5, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },
2095 { .id = ci_5, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = false },
2096 { .id = ci_5, .match_id = lai_23_042_42, .expect_match = true, .expect_exact_match = false },
2097 { .id = ci_5, .match_id = lai_23_99_23, .expect_match = true, .expect_exact_match = false },
2098 { .id = ci_5, .match_id = lai_23_42_23, .expect_match = true, .expect_exact_match = false },
2099 { .id = ci_5, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = false },
2100 { .id = ci_5, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },
2101 { .id = ci_5, .match_id = cgi_23_99_23_5, .expect_match = true, .expect_exact_match = false },
2102 { .id = lac_ci_23_5, .match_id = lac_23, .expect_match = true, .expect_exact_match = false },
2103 { .id = lac_ci_23_5, .match_id = lac_42, .expect_match = false, .expect_exact_match = false },
2104 { .id = lac_ci_23_5, .match_id = ci_5, .expect_match = true, .expect_exact_match = false },
2105 { .id = lac_ci_23_5, .match_id = ci_6, .expect_match = false, .expect_exact_match = false },
2106 { .id = lac_ci_23_5, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = true },
2107 { .id = lac_ci_23_5, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },
2108 { .id = lac_ci_23_5, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = false },
2109 { .id = lac_ci_23_5, .match_id = lai_23_042_42, .expect_match = false, .expect_exact_match = false },
2110 { .id = lac_ci_23_5, .match_id = lai_23_99_23, .expect_match = true, .expect_exact_match = false },
2111 { .id = lac_ci_23_5, .match_id = lai_23_42_23, .expect_match = true, .expect_exact_match = false },
2112 { .id = lac_ci_23_5, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = false },
2113 { .id = lac_ci_23_5, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },
2114 { .id = lac_ci_23_5, .match_id = cgi_23_99_23_5, .expect_match = true, .expect_exact_match = false },
2115 { .id = lai_23_042_23, .match_id = lac_23, .expect_match = true, .expect_exact_match = false },
2116 { .id = lai_23_042_23, .match_id = lac_42, .expect_match = false, .expect_exact_match = false },
2117 { .id = lai_23_042_23, .match_id = ci_5, .expect_match = true, .expect_exact_match = false },
2118 { .id = lai_23_042_23, .match_id = ci_6, .expect_match = true, .expect_exact_match = false },
2119 { .id = lai_23_042_23, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = false },
2120 { .id = lai_23_042_23, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },
2121 { .id = lai_23_042_23, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = true },
2122 { .id = lai_23_042_23, .match_id = lai_23_042_42, .expect_match = false, .expect_exact_match = false },
2123 { .id = lai_23_042_23, .match_id = lai_23_99_23, .expect_match = false, .expect_exact_match = false },
2124 { .id = lai_23_042_23, .match_id = lai_23_42_23, .expect_match = false, .expect_exact_match = false },
2125 { .id = lai_23_042_23, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = false },
2126 { .id = lai_23_042_23, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },
2127 { .id = lai_23_042_23, .match_id = cgi_23_99_23_5, .expect_match = false, .expect_exact_match = false },
2128 { .id = cgi_23_042_23_5, .match_id = lac_23, .expect_match = true, .expect_exact_match = false },
2129 { .id = cgi_23_042_23_5, .match_id = lac_42, .expect_match = false, .expect_exact_match = false },
2130 { .id = cgi_23_042_23_5, .match_id = ci_5, .expect_match = true, .expect_exact_match = false },
2131 { .id = cgi_23_042_23_5, .match_id = ci_6, .expect_match = false, .expect_exact_match = false },
2132 { .id = cgi_23_042_23_5, .match_id = lac_ci_23_5, .expect_match = true, .expect_exact_match = false },
2133 { .id = cgi_23_042_23_5, .match_id = lac_ci_42_6, .expect_match = false, .expect_exact_match = false },
2134 { .id = cgi_23_042_23_5, .match_id = lai_23_042_23, .expect_match = true, .expect_exact_match = false },
2135 { .id = cgi_23_042_23_5, .match_id = lai_23_042_42, .expect_match = false, .expect_exact_match = false },
2136 { .id = cgi_23_042_23_5, .match_id = lai_23_99_23, .expect_match = false, .expect_exact_match = false },
2137 { .id = cgi_23_042_23_5, .match_id = lai_23_42_23, .expect_match = false, .expect_exact_match = false },
2138 { .id = cgi_23_042_23_5, .match_id = cgi_23_042_23_5, .expect_match = true, .expect_exact_match = true },
2139 { .id = cgi_23_042_23_5, .match_id = cgi_23_042_42_6, .expect_match = false, .expect_exact_match = false },
2140 { .id = cgi_23_042_23_5, .match_id = cgi_23_99_23_5, .expect_match = false, .expect_exact_match = false },
2141};
2142
2143static void test_cell_id_matching()
2144{
2145 int i;
2146 bool ok = true;
2147 printf("\n%s\n", __func__);
2148
2149 for (i = 0; i < ARRAY_SIZE(test_cell_id_matching_tests); i++) {
2150 const struct test_cell_id_matching_data *d = &test_cell_id_matching_tests[i];
2151 int exact_match;
2152
2153 for (exact_match = 0; exact_match < 2; exact_match++) {
2154 bool result;
2155 bool expect_result = exact_match ? d->expect_exact_match : d->expect_match;
2156
2157 result = gsm0808_cell_ids_match(&d->id, &d->match_id, (bool)exact_match);
2158
2159 printf("[%d] %s %s %s%s\n",
2160 i,
2161 gsm0808_cell_id_name(&d->id),
2162 gsm0808_cell_id_name2(&d->match_id),
2163 result ? "MATCH" : "don't match",
2164 exact_match ? " exactly" : "");
2165 if (result != expect_result) {
2166 printf(" ERROR: expected %s\n", d->expect_match ? "MATCH" : "no match");
2167 ok = false;
2168 }
2169 }
2170 }
2171
2172 OSMO_ASSERT(ok);
2173}
2174
2175static bool test_cell_id_list_matching_discrs(bool test_match,
2176 enum CELL_IDENT id_discr,
2177 enum CELL_IDENT list_discr)
2178{
2179 int i, j;
2180 const struct gsm0808_cell_id *id = NULL;
2181 struct gsm0808_cell_id_list2 list = {};
2182 int match_idx = -1;
2183 int result;
2184
2185 for (i = 0; i < ARRAY_SIZE(test_cell_id_matching_tests); i++) {
2186 const struct test_cell_id_matching_data *d = &test_cell_id_matching_tests[i];
2187 if (id_discr != d->id.id_discr)
2188 continue;
2189 id = &d->id;
2190 break;
2191 }
2192
2193 if (!id) {
2194 printf("Did not find any entry for %s\n", gsm0808_cell_id_discr_name(id_discr));
2195 return true;
2196 }
2197
2198 /* Collect those entries with exactly this id on the left, of type list_discr on the right.
2199 * Collect the mismatches first, for more interesting match indexes in the results. */
2200 for (j = 0; j < 2; j++) {
2201 bool collect_matches = (bool)j;
2202
2203 /* If we want to have a mismatching list, don't add any entries that match. */
2204 if (!test_match && collect_matches)
2205 continue;
2206
2207 for (i = 0; i < ARRAY_SIZE(test_cell_id_matching_tests); i++) {
2208 const struct test_cell_id_matching_data *d = &test_cell_id_matching_tests[i];
2209 struct gsm0808_cell_id_list2 add;
2210
2211 /* Ignore those with a different d->id */
2212 if (!gsm0808_cell_ids_match(&d->id, id, true))
2213 continue;
2214
2215 /* Ignore those with a different d->match_id discr */
2216 if (d->match_id.id_discr != list_discr)
2217 continue;
2218
2219 if (collect_matches != d->expect_match)
2220 continue;
2221
2222 if (match_idx < 0 && d->expect_match) {
2223 match_idx = list.id_list_len;
2224 }
2225
2226 gsm0808_cell_id_to_list(&add, &d->match_id);
2227 gsm0808_cell_id_list_add(&list, &add);
2228 }
2229 }
2230
2231 if (!list.id_list_len) {
2232 printf("%s vs. %s: No match_id entries to test %s\n",
2233 gsm0808_cell_id_name(id),
2234 gsm0808_cell_id_discr_name(list_discr),
2235 test_match ? "MATCH" : "mismatch");
2236 return true;
2237 }
2238
2239 result = gsm0808_cell_id_matches_list(id, &list, 0, false);
2240
2241 printf("%s and %s: ",
2242 gsm0808_cell_id_name(id),
2243 gsm0808_cell_id_list_name(&list));
2244 if (result >= 0)
2245 printf("MATCH at [%d]\n", result);
2246 else
2247 printf("mismatch\n");
2248
2249 if (test_match
2250 && (result < 0 || result != match_idx)) {
2251 printf(" ERROR: expected MATCH at %d\n", match_idx);
2252 return false;
2253 }
2254
2255 if (!test_match && result >= 0) {
2256 printf(" ERROR: expected mismatch\n");
2257 return false;
2258 }
2259
2260 return true;
2261}
2262
Neels Hofmeyr3a504532019-02-10 22:28:27 +01002263const enum CELL_IDENT cell_ident_discrs[] = {
2264 CELL_IDENT_LAC, CELL_IDENT_CI, CELL_IDENT_LAC_AND_CI, CELL_IDENT_LAI_AND_LAC,
2265 CELL_IDENT_WHOLE_GLOBAL,
2266};
2267
2268
Neels Hofmeyrd01ef752018-09-21 15:57:26 +02002269static void test_cell_id_list_matching(bool test_match)
2270{
2271 int i, j;
2272 bool ok = true;
2273
Neels Hofmeyrd01ef752018-09-21 15:57:26 +02002274 printf("\n%s(%s)\n", __func__, test_match ? "test match" : "test mismatch");
2275
2276 /* Autogenerate Cell ID lists from above dataset, which should match / not match. */
Neels Hofmeyr3a504532019-02-10 22:28:27 +01002277 for (i = 0; i < ARRAY_SIZE(cell_ident_discrs); i++) {
2278 for (j = 0; j < ARRAY_SIZE(cell_ident_discrs); j++)
Neels Hofmeyrd01ef752018-09-21 15:57:26 +02002279 if (!test_cell_id_list_matching_discrs(test_match,
Neels Hofmeyr3a504532019-02-10 22:28:27 +01002280 cell_ident_discrs[i], cell_ident_discrs[j]))
Neels Hofmeyrd01ef752018-09-21 15:57:26 +02002281 ok = false;
2282 }
2283
2284 OSMO_ASSERT(ok);
2285}
2286
Neels Hofmeyr3a504532019-02-10 22:28:27 +01002287
2288static const struct gsm0808_cell_id test_gsm0808_cell_id_to_from_cgi_data[] = {
2289 lac_23,
2290 lac_42,
2291 ci_5,
2292 ci_6,
2293 lac_ci_23_5,
2294 lac_ci_42_6,
2295 lai_23_042_23,
2296 lai_23_042_42,
2297 lai_23_99_23,
2298 lai_23_42_23,
2299 cgi_23_042_23_5,
2300 cgi_23_042_42_6,
2301 cgi_23_99_23_5,
2302 { .id_discr = CELL_IDENT_NO_CELL },
2303 { .id_discr = 423 },
2304};
2305
2306static void test_gsm0808_cell_id_to_from_cgi()
2307{
2308 int i;
2309 int j;
2310
2311 printf("\n%s()\n", __func__);
2312
2313 for (i = 0; i < ARRAY_SIZE(test_gsm0808_cell_id_to_from_cgi_data); i++) {
2314 const struct gsm0808_cell_id *from_cid = &test_gsm0808_cell_id_to_from_cgi_data[i];
2315 struct osmo_cell_global_id cgi = {
2316 .lai = {
2317 .plmn = {
2318 .mcc = 777,
2319 .mnc = 7,
2320 .mnc_3_digits = true,
2321 },
2322 .lac = 7777,
2323 },
2324 .cell_identity = 7777,
2325 };
2326 struct gsm0808_cell_id cid = {};
2327 int rc;
2328
2329 rc = gsm0808_cell_id_to_cgi(&cgi, from_cid);
2330 printf("cid %s -> cgi %s", gsm0808_cell_id_name(from_cid), osmo_cgi_name(&cgi));
2331
2332 if (rc & OSMO_CGI_PART_PLMN)
2333 printf(" PLMN");
2334 if (rc & OSMO_CGI_PART_LAC)
2335 printf(" LAC");
2336 if (rc & OSMO_CGI_PART_CI)
2337 printf(" CI");
2338
2339 gsm0808_cell_id_from_cgi(&cid, from_cid->id_discr, &cgi);
2340 printf(" -> cid %s\n", gsm0808_cell_id_name(&cid));
2341 if (!gsm0808_cell_ids_match(from_cid, &cid, true))
2342 printf(" MISMATCH!\n");
2343
2344 for (j = 0; j < ARRAY_SIZE(cell_ident_discrs); j++) {
2345 enum CELL_IDENT discr = cell_ident_discrs[j];
2346
2347 gsm0808_cell_id_from_cgi(&cid, discr, &cgi);
2348 printf(" --> gsm0808_cell_id{%s} = %s\n", gsm0808_cell_id_discr_name(discr), gsm0808_cell_id_name(&cid));
2349 }
2350 }
2351}
2352
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002353int main(int argc, char **argv)
2354{
Max969fb2e2018-12-10 11:01:10 +01002355 void *ctx = talloc_named_const(NULL, 0, "gsm0808 test");
2356 msgb_talloc_ctx_init(ctx, 0);
2357 osmo_init_logging2(ctx, NULL);
2358
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002359 printf("Testing generation of GSM0808 messages\n");
Philipp Maier4f4905f2018-11-30 13:36:12 +01002360 test_gsm0808_enc_cause();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002361 test_create_layer3();
Philipp Maierfa896ab2017-03-27 16:55:32 +02002362 test_create_layer3_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002363 test_create_reset();
Philipp Maier15596e22017-04-05 17:55:27 +02002364 test_create_reset_ack();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002365 test_create_clear_command();
Harald Weltecf665fc2019-02-18 13:45:36 +01002366 test_create_clear_command2();
2367 test_create_clear_command2_csfb();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002368 test_create_clear_complete();
Philipp Maierb478dd32017-03-29 15:50:05 +02002369 test_create_cipher();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002370 test_create_cipher_complete();
2371 test_create_cipher_reject();
Maxed651d22018-11-07 15:25:05 +01002372 test_create_cipher_reject_ext();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002373 test_create_cm_u();
2374 test_create_sapi_reject();
Philipp Maierc6144a22017-03-29 17:53:43 +02002375 test_create_ass();
Max52074322018-11-30 10:44:07 +01002376 test_create_ass2();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002377 test_create_ass_compl();
Philipp Maierfa896ab2017-03-27 16:55:32 +02002378 test_create_ass_compl_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002379 test_create_ass_fail();
Philipp Maierfa896ab2017-03-27 16:55:32 +02002380 test_create_ass_fail_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002381 test_create_clear_rqst();
Philipp Maier3d48ec02017-03-29 17:37:55 +02002382 test_create_paging();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002383 test_create_dtap();
2384 test_prepend_dtap();
Max969fb2e2018-12-10 11:01:10 +01002385
Max47022152018-12-19 18:51:00 +01002386 test_enc_dec_lcls();
Max969fb2e2018-12-10 11:01:10 +01002387
Philipp Maier22401432017-03-24 17:59:26 +01002388 test_enc_dec_aoip_trasp_addr_v4();
2389 test_enc_dec_aoip_trasp_addr_v6();
Philipp Maier6f725d62017-03-24 18:03:17 +01002390 test_gsm0808_enc_dec_speech_codec();
Philipp Maier6f725d62017-03-24 18:03:17 +01002391 test_gsm0808_enc_dec_speech_codec_ext_with_cfg();
Philipp Maierbb839662017-06-01 17:11:19 +02002392 test_gsm0808_enc_dec_speech_codec_with_cfg();
Philipp Maier6f725d62017-03-24 18:03:17 +01002393 test_gsm0808_enc_dec_speech_codec_list();
Philipp Maierf6c369f2018-10-16 15:24:47 +02002394 test_gsm0808_enc_dec_empty_speech_codec_list();
Philipp Maiere0c65302017-03-28 17:05:40 +02002395 test_gsm0808_enc_dec_channel_type();
Philipp Maier14e76b92017-03-28 18:36:52 +02002396 test_gsm0808_enc_dec_encrypt_info();
Neels Hofmeyr250e7f72018-04-13 03:30:14 +02002397
Philipp Maier783047e2017-03-29 11:35:50 +02002398 test_gsm0808_enc_dec_cell_id_list_lac();
2399 test_gsm0808_enc_dec_cell_id_list_single_lac();
Stefan Sperlinge1a86742018-03-15 18:05:02 +01002400 test_gsm0808_enc_dec_cell_id_list_multi_lac();
Philipp Maier783047e2017-03-29 11:35:50 +02002401 test_gsm0808_enc_dec_cell_id_list_bss();
Stefan Sperling23381452018-03-15 19:38:15 +01002402 test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac();
Stefan Sperling9c62fc62018-03-16 10:23:34 +01002403 test_gsm0808_enc_dec_cell_id_list_multi_ci();
Stefan Sperlinged4327c2018-03-16 11:02:59 +01002404 test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci();
Stefan Sperling483f3862018-03-16 12:21:26 +01002405 test_gsm0808_enc_dec_cell_id_list_multi_global();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002406
Neels Hofmeyr74663d92018-03-23 01:46:42 +01002407 test_cell_id_list_add();
2408
Neels Hofmeyr250e7f72018-04-13 03:30:14 +02002409 test_gsm0808_enc_dec_cell_id_lac();
2410 test_gsm0808_enc_dec_cell_id_bss();
2411 test_gsm0808_enc_dec_cell_id_no_cell();
2412 test_gsm0808_enc_dec_cell_id_lai_and_lac();
2413 test_gsm0808_enc_dec_cell_id_ci();
2414 test_gsm0808_enc_dec_cell_id_lac_and_ci();
2415 test_gsm0808_enc_dec_cell_id_global();
Philipp Maier5f2eb152018-09-19 13:40:21 +02002416 test_gsm0808_sc_cfg_from_gsm48_mr_cfg();
Philipp Maier8515d032018-09-25 15:57:49 +02002417 test_gsm48_mr_cfg_from_gsm0808_sc_cfg();
Philipp Maier5f2eb152018-09-19 13:40:21 +02002418
Neels Hofmeyrd01ef752018-09-21 15:57:26 +02002419 test_cell_id_matching();
2420 test_cell_id_list_matching(true);
2421 test_cell_id_list_matching(false);
2422
Neels Hofmeyr3a504532019-02-10 22:28:27 +01002423 test_gsm0808_cell_id_to_from_cgi();
2424
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01002425 printf("Done\n");
2426 return EXIT_SUCCESS;
2427}