blob: f0f31654d33e8f339d761ee988ed741d1724ef64 [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
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010042#define VERIFY(msg, data, len) \
43 if (msgb_l3len(msg) != len) { \
44 printf("%s:%d Length don't match: %d vs. %d. %s\n", \
Holger Hans Peter Freytherfdb46672015-11-09 16:32:43 +000045 __func__, __LINE__, msgb_l3len(msg), (int) len, \
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010046 osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
47 abort(); \
48 } else if (memcmp(msg->l3h, data, len) != 0) { \
49 printf("%s:%d didn't match: got: %s\n", \
50 __func__, __LINE__, \
51 osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
52 abort(); \
53 }
54
Philipp Maierfa896ab2017-03-27 16:55:32 +020055/* Setup a fake codec list for testing */
56static void setup_codec_list(struct gsm0808_speech_codec_list *scl)
57{
58 memset(scl, 0, sizeof(*scl));
59
60 scl->codec[0].pi = true;
61 scl->codec[0].tf = true;
Philipp Maierbb839662017-06-01 17:11:19 +020062 scl->codec[0].type = GSM0808_SCT_FR3;
Philipp Maierfa896ab2017-03-27 16:55:32 +020063 scl->codec[0].cfg = 0xcdef;
64
65 scl->codec[1].fi = true;
66 scl->codec[1].pt = true;
Philipp Maierbb839662017-06-01 17:11:19 +020067 scl->codec[1].type = GSM0808_SCT_FR2;
Philipp Maierfa896ab2017-03-27 16:55:32 +020068
69 scl->codec[2].fi = true;
70 scl->codec[2].tf = true;
Philipp Maierbb839662017-06-01 17:11:19 +020071 scl->codec[2].type = GSM0808_SCT_CSD;
72 scl->codec[2].cfg = 0xc0;
Philipp Maierfa896ab2017-03-27 16:55:32 +020073
74 scl->len = 3;
75}
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010076
Philipp Maier4f4905f2018-11-30 13:36:12 +010077void test_gsm0808_enc_cause(void)
78{
79 /* NOTE: This must be tested early because many of the following tests
80 * rely on the generation of a proper cause code. */
81
82 uint8_t rc_enc;
83 struct msgb *msg;
84
85 /* Test with a single byte cause code */
86 msg = msgb_alloc(1024, "output buffer");
87 rc_enc = gsm0808_enc_cause(msg, 0x41);
88 EXPECT_ENCODED("04 01 41");
89 msgb_free(msg);
90
91 /* Test with an extended (two byte) cause code */
92 msg = msgb_alloc(1024, "output buffer");
93 rc_enc = gsm0808_enc_cause(msg, 0x8041);
94 EXPECT_ENCODED("04 02 80 41");
95 msgb_free(msg);
96}
97
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010098static void test_create_layer3(void)
99{
100 static const uint8_t res[] = {
101 0x00, 0x0e, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
102 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23 };
103 struct msgb *msg, *in_msg;
Neels Hofmeyr178bf7a2018-04-20 12:23:45 +0200104 struct osmo_cell_global_id cgi = {
105 .lai = {
106 .plmn = {
107 .mcc = 0x2244,
108 .mnc = 0x1122,
109 },
110 .lac = 0x3366,
111 },
112 .cell_identity = 0x4488,
113 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100114 printf("Testing creating Layer3\n");
115
116 in_msg = msgb_alloc_headroom(512, 128, "foo");
117 in_msg->l3h = in_msg->data;
118 msgb_v_put(in_msg, 0x23);
119
Neels Hofmeyr178bf7a2018-04-20 12:23:45 +0200120 msg = gsm0808_create_layer3_2(in_msg, &cgi, NULL);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100121 VERIFY(msg, res, ARRAY_SIZE(res));
122 msgb_free(msg);
123 msgb_free(in_msg);
124}
125
Philipp Maierfa896ab2017-03-27 16:55:32 +0200126static void test_create_layer3_aoip()
127{
128 static const uint8_t res[] = {
129 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
130 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23,
Philipp Maierbb839662017-06-01 17:11:19 +0200131 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, GSM0808_SCT_FR3 | 0x50,
Philipp Maier7e27b142018-03-22 17:26:46 +0100132 0xef, 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f,
Philipp Maierbb839662017-06-01 17:11:19 +0200133 GSM0808_SCT_CSD | 0x90, 0xc0
Philipp Maierfa896ab2017-03-27 16:55:32 +0200134 };
Maxfa3b4822018-11-05 14:59:54 +0100135 struct osmo_cell_global_id cgi = {
136 .lai = {
137 .plmn = {
138 .mcc = 0x2244,
139 .mnc = 0x1122,
140 },
141 .lac = 0x3366,
142 },
143 .cell_identity = 0x4488,
144 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200145 struct msgb *msg, *in_msg;
146 struct gsm0808_speech_codec_list sc_list;
147 printf("Testing creating Layer3 (AoIP)\n");
148
149 setup_codec_list(&sc_list);
150
151 in_msg = msgb_alloc_headroom(512, 128, "foo");
152 in_msg->l3h = in_msg->data;
153 msgb_v_put(in_msg, 0x23);
154
Maxfa3b4822018-11-05 14:59:54 +0100155 msg = gsm0808_create_layer3_2(in_msg, &cgi, &sc_list);
156
Philipp Maierfa896ab2017-03-27 16:55:32 +0200157 VERIFY(msg, res, ARRAY_SIZE(res));
158
159 msgb_free(msg);
160 msgb_free(in_msg);
161}
162
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100163static void test_create_reset()
164{
165 static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 };
166 struct msgb *msg;
167
168 printf("Testing creating Reset\n");
169 msg = gsm0808_create_reset();
170 VERIFY(msg, res, ARRAY_SIZE(res));
171 msgb_free(msg);
172}
173
Philipp Maier15596e22017-04-05 17:55:27 +0200174static void test_create_reset_ack()
175{
176 static const uint8_t res[] = { 0x00, 0x01, 0x31 };
177 struct msgb *msg;
178
179 printf("Testing creating Reset Ack\n");
180 msg = gsm0808_create_reset_ack();
181 VERIFY(msg, res, ARRAY_SIZE(res));
182 msgb_free(msg);
183}
184
185
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100186static void test_create_clear_command()
187{
188 static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 };
189 struct msgb *msg;
190
191 printf("Testing creating Clear Command\n");
192 msg = gsm0808_create_clear_command(0x23);
193 VERIFY(msg, res, ARRAY_SIZE(res));
194 msgb_free(msg);
195}
196
197static void test_create_clear_complete()
198{
199 static const uint8_t res[] = { 0x00, 0x01, 0x21 };
200 struct msgb *msg;
201
202 printf("Testing creating Clear Complete\n");
203 msg = gsm0808_create_clear_complete();
204 VERIFY(msg, res, ARRAY_SIZE(res));
205 msgb_free(msg);
206}
207
Philipp Maierb478dd32017-03-29 15:50:05 +0200208static void test_create_cipher()
209{
210 static const uint8_t res[] =
211 { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa,
212 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 };
213 static const uint8_t res2[] =
214 { 0x00, 0x0e, 0x53, 0x0a, 0x09, 0x03, 0xaa,
215 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42,
216 GSM0808_IE_CIPHER_RESPONSE_MODE, 0x01 };
217 struct msgb *msg;
218 struct gsm0808_encrypt_info ei;
219 uint8_t include_imeisv;
220
221 memset(&ei, 0, sizeof(ei));
222 ei.perm_algo[0] = GSM0808_ALG_ID_A5_0;
223 ei.perm_algo[1] = GSM0808_ALG_ID_A5_1;
224 ei.perm_algo_len = 2;
225 ei.key[0] = 0xaa;
226 ei.key[1] = 0xbb;
227 ei.key[2] = 0xcc;
228 ei.key[3] = 0xdd;
229 ei.key[4] = 0xee;
230 ei.key[5] = 0xff;
231 ei.key[6] = 0x23;
232 ei.key[7] = 0x42;
233 ei.key_len = 8;
234 include_imeisv = 1;
235
236 printf("Testing creating Chipher Mode Command\n");
237 msg = gsm0808_create_cipher(&ei, NULL);
238 OSMO_ASSERT(msg);
239 VERIFY(msg, res, ARRAY_SIZE(res));
240 msgb_free(msg);
241
242 msg = gsm0808_create_cipher(&ei, &include_imeisv);
243 OSMO_ASSERT(msg);
244 VERIFY(msg, res2, ARRAY_SIZE(res2));
245 msgb_free(msg);
246}
247
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100248static void test_create_cipher_complete()
249{
250 static const uint8_t res1[] = {
251 0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 };
252 static const uint8_t res2[] = { 0x00, 0x03, 0x55, 0x2c, 0x04};
253 struct msgb *l3, *msg;
254
255 printf("Testing creating Cipher Complete\n");
256 l3 = msgb_alloc_headroom(512, 128, "l3h");
257 l3->l3h = l3->data;
258 msgb_v_put(l3, 0x23);
259 msgb_v_put(l3, 0x42);
260 msgb_v_put(l3, 0x21);
261
262 /* with l3 data */
263 msg = gsm0808_create_cipher_complete(l3, 4);
264 VERIFY(msg, res1, ARRAY_SIZE(res1));
265 msgb_free(msg);
266
267 /* with l3 data but short */
268 l3->len -= 1;
269 l3->tail -= 1;
270 msg = gsm0808_create_cipher_complete(l3, 4);
271 VERIFY(msg, res2, ARRAY_SIZE(res2));
272 msgb_free(msg);
273
274 /* without l3 data */
275 msg = gsm0808_create_cipher_complete(NULL, 4);
276 VERIFY(msg, res2, ARRAY_SIZE(res2));
277 msgb_free(msg);
278
279
280 msgb_free(l3);
281}
282
Maxed651d22018-11-07 15:25:05 +0100283static inline void parse_cipher_reject(struct msgb *msg, uint8_t exp)
284{
285 struct tlv_parsed tp;
286 int rc;
287
288 /* skip header and message type so we can parse Cause IE directly */
289 msg->l2h = msgb_data(msg) + sizeof(struct bssmap_header) + 1;
290
291 rc = osmo_bssap_tlv_parse(&tp, msg->l2h, msgb_l2len(msg));
292 if (rc < 0)
293 printf("FIXME: failed (%d) to parse created message %s\n", rc, msgb_hexdump(msg));
294
295 rc = gsm0808_get_cipher_reject_cause(&tp);
296 if (rc < 0)
297 printf("FIXME: failed (%s) to extract Cause from created message %s\n",
298 strerror(-rc), msgb_hexdump(msg));
299
300 if (exp != (enum gsm0808_cause)rc)
301 printf("FIXME: wrong Cause %d != %u (" OSMO_BIN_SPEC ") extracted from created message %s\n",
302 rc, exp, OSMO_BIT_PRINT(exp), msgb_hexdump(msg));
303}
304
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100305static void test_create_cipher_reject()
306{
Harald Welte62e40852017-12-17 20:50:34 +0100307 static const uint8_t res[] = { 0x00, 0x04, 0x59, 0x04, 0x01, 0x23 };
Maxed651d22018-11-07 15:25:05 +0100308 enum gsm0808_cause cause = GSM0808_CAUSE_CCCH_OVERLOAD;
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100309 struct msgb *msg;
310
311 printf("Testing creating Cipher Reject\n");
Maxed651d22018-11-07 15:25:05 +0100312 msg = gsm0808_create_cipher_reject(cause);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100313 VERIFY(msg, res, ARRAY_SIZE(res));
Maxed651d22018-11-07 15:25:05 +0100314
315 parse_cipher_reject(msg, cause);
316
317 msgb_free(msg);
318}
319
320static void test_create_cipher_reject_ext()
321{
322 static const uint8_t res[] = { 0x00, 0x05, 0x59, 0x04, 0x02, 0xd0, 0xFA };
323 uint8_t cause = 0xFA;
324 struct msgb *msg;
325
326 printf("Testing creating Cipher Reject (extended)\n");
327 msg = gsm0808_create_cipher_reject_ext(GSM0808_CAUSE_CLASS_INVAL, cause);
328 VERIFY(msg, res, ARRAY_SIZE(res));
329
330 parse_cipher_reject(msg, cause);
331
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100332 msgb_free(msg);
333}
334
335static void test_create_cm_u()
336{
Harald Welte07b625d2012-01-23 10:02:58 +0100337 static const uint8_t res[] = {
338 0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 };
339 static const uint8_t res2o[] = {
340 0x00, 0x04, 0x54, 0x12, 0x01, 0x23 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100341 struct msgb *msg;
Harald Welte07b625d2012-01-23 10:02:58 +0100342 const uint8_t cm2 = 0x23;
343 const uint8_t cm3 = 0x42;
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100344
345 printf("Testing creating CM U\n");
Harald Welte07b625d2012-01-23 10:02:58 +0100346 msg = gsm0808_create_classmark_update(&cm2, 1, &cm3, 1);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100347 VERIFY(msg, res, ARRAY_SIZE(res));
Harald Welte07b625d2012-01-23 10:02:58 +0100348
Neels Hofmeyr9a938ae2017-11-16 17:34:07 +0100349 msgb_free(msg);
350
Harald Welte07b625d2012-01-23 10:02:58 +0100351 msg = gsm0808_create_classmark_update(&cm2, 1, NULL, 0);
352 VERIFY(msg, res2o, ARRAY_SIZE(res2o));
353
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100354 msgb_free(msg);
355}
356
357static void test_create_sapi_reject()
358{
359 static const uint8_t res[] = { 0x00, 0x03, 0x25, 0x03, 0x25 };
360 struct msgb *msg;
361
362 printf("Testing creating SAPI Reject\n");
363 msg = gsm0808_create_sapi_reject(3);
364 VERIFY(msg, res, ARRAY_SIZE(res));
365 msgb_free(msg);
366}
367
Philipp Maierc6144a22017-03-29 17:53:43 +0200368static void test_create_ass()
369{
370 static const uint8_t res1[] =
371 { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
372 0x04 };
373 static const uint8_t res2[] =
374 { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
375 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17,
Philipp Maierbb839662017-06-01 17:11:19 +0200376 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07,
Philipp Maier7e27b142018-03-22 17:26:46 +0100377 GSM0808_SCT_FR3 | 0x50, 0xef, 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f,
Philipp Maierbb839662017-06-01 17:11:19 +0200378 GSM0808_SCT_CSD | 0x90, 0xc0, GSM0808_IE_CALL_ID, 0xaa, 0xbb,
379 0xcc, 0xdd };
Philipp Maierc6144a22017-03-29 17:53:43 +0200380
381 struct msgb *msg;
382 struct gsm0808_channel_type ct;
383 uint16_t cic = 0004;
384 struct sockaddr_storage ss;
385 struct sockaddr_in sin;
386 struct gsm0808_speech_codec_list sc_list;
387 uint32_t call_id = 0xAABBCCDD;
388
389 memset(&ct, 0, sizeof(ct));
390 ct.ch_indctr = GSM0808_CHAN_SPEECH;
391 ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF;
392 ct.perm_spch[0] = GSM0808_PERM_FR3;
393 ct.perm_spch[1] = GSM0808_PERM_HR3;
394 ct.perm_spch_len = 2;
395
396 memset(&sin, 0, sizeof(sin));
397 sin.sin_family = AF_INET;
398 sin.sin_port = htons(1234);
399 inet_aton("192.168.100.23", &sin.sin_addr);
400
401 memset(&ss, 0, sizeof(ss));
402 memcpy(&ss, &sin, sizeof(sin));
403
404 setup_codec_list(&sc_list);
405
406 printf("Testing creating Assignment Request\n");
407 msg = gsm0808_create_ass(&ct, &cic, NULL, NULL, NULL);
408 OSMO_ASSERT(msg);
409 VERIFY(msg, res1, ARRAY_SIZE(res1));
410 msgb_free(msg);
411
412 msg = gsm0808_create_ass(&ct, &cic, &ss, &sc_list, &call_id);
413 OSMO_ASSERT(msg);
414 VERIFY(msg, res2, ARRAY_SIZE(res2));
415 msgb_free(msg);
416}
417
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100418static void test_create_ass_compl()
419{
420 static const uint8_t res1[] = {
421 0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c,
422 0x11, 0x40, 0x22 };
423 static const uint8_t res2[] = {
424 0x00, 0x07, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11};
425 struct msgb *msg;
426
427 printf("Testing creating Assignment Complete\n");
428 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0x22);
429 VERIFY(msg, res1, ARRAY_SIZE(res1));
430 msgb_free(msg);
431
432 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0);
433 VERIFY(msg, res2, ARRAY_SIZE(res2));
434 msgb_free(msg);
435}
436
Philipp Maierfa896ab2017-03-27 16:55:32 +0200437static void test_create_ass_compl_aoip()
438{
439 struct sockaddr_storage ss;
440 struct sockaddr_in sin;
441 struct gsm0808_speech_codec sc;
442 struct gsm0808_speech_codec_list sc_list;
443 static const uint8_t res[] =
444 { 0x00, 0x1d, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22,
445 GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04,
Philipp Maierbb839662017-06-01 17:11:19 +0200446 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, GSM0808_SCT_HR1 | 0x90,
Philipp Maier7e27b142018-03-22 17:26:46 +0100447 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, GSM0808_SCT_FR3 | 0x50, 0xef,
448 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f, GSM0808_SCT_CSD | 0x90, 0xc0 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200449 struct msgb *msg;
450
451 memset(&sin, 0, sizeof(sin));
452 sin.sin_family = AF_INET;
453 sin.sin_port = htons(1234);
454 inet_aton("192.168.100.23", &sin.sin_addr);
455
456 memset(&ss, 0, sizeof(ss));
457 memcpy(&ss, &sin, sizeof(sin));
458
459 memset(&sc, 0, sizeof(sc));
460 sc.fi = true;
461 sc.tf = true;
Philipp Maierbb839662017-06-01 17:11:19 +0200462 sc.type = GSM0808_SCT_HR1;
Philipp Maierfa896ab2017-03-27 16:55:32 +0200463
464 setup_codec_list(&sc_list);
465
466 printf("Testing creating Assignment Complete (AoIP)\n");
467 msg = gsm0808_create_ass_compl(0x23, 0x42, 0x11, 0x22,
468 &ss, &sc, &sc_list);
469 VERIFY(msg, res, ARRAY_SIZE(res));
470 msgb_free(msg);
471}
472
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100473static void test_create_ass_fail()
474{
475 static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 };
476 static const uint8_t res2[] = {
477 0x00, 0x06, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02};
478 uint8_t rr_res = 2;
479 struct msgb *msg;
480
481 printf("Testing creating Assignment Failure\n");
482 msg = gsm0808_create_assignment_failure(0x23, NULL);
483 VERIFY(msg, res1, ARRAY_SIZE(res1));
484 msgb_free(msg);
485
486 msg = gsm0808_create_assignment_failure(0x23, &rr_res);
487 VERIFY(msg, res2, ARRAY_SIZE(res2));
488 msgb_free(msg);
489}
490
Philipp Maierfa896ab2017-03-27 16:55:32 +0200491static void test_create_ass_fail_aoip()
492{
493 static const uint8_t res1[] =
494 { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST,
Philipp Maier7e27b142018-03-22 17:26:46 +0100495 0x07, GSM0808_SCT_FR3 | 0x50, 0xef, 0xcd, GSM0808_SCT_FR2 | 0xa0,
Philipp Maierbb839662017-06-01 17:11:19 +0200496 0x9f, GSM0808_SCT_CSD | 0x90, 0xc0 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200497 static const uint8_t res2[] =
498 { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02,
Philipp Maier7e27b142018-03-22 17:26:46 +0100499 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, GSM0808_SCT_FR3 | 0x50, 0xef,
500 0xcd, GSM0808_SCT_FR2 | 0xa0, 0x9f, GSM0808_SCT_CSD | 0x90, 0xc0 };
Philipp Maierfa896ab2017-03-27 16:55:32 +0200501 uint8_t rr_res = 2;
502 struct msgb *msg;
503 struct gsm0808_speech_codec_list sc_list;
504
505 setup_codec_list(&sc_list);
506
507 printf("Testing creating Assignment Failure (AoIP)\n");
508 msg = gsm0808_create_ass_fail(0x23, NULL, &sc_list);
509 VERIFY(msg, res1, ARRAY_SIZE(res1));
510 msgb_free(msg);
511
512 msg = gsm0808_create_ass_fail(0x23, &rr_res, &sc_list);
513 VERIFY(msg, res2, ARRAY_SIZE(res2));
514 msgb_free(msg);
515}
516
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100517static void test_create_clear_rqst()
518{
519 static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 };
520 struct msgb *msg;
521
522 printf("Testing creating Clear Request\n");
523 msg = gsm0808_create_clear_rqst(0x23);
524 VERIFY(msg, res, ARRAY_SIZE(res));
525 msgb_free(msg);
526}
527
Philipp Maier3d48ec02017-03-29 17:37:55 +0200528static void test_create_paging()
529{
530 static const uint8_t res[] =
531 { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
532 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 };
533 static const uint8_t res2[] =
534 { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
535 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
536 0x03, 0x05, 0x23, 0x42 };
537 static const uint8_t res3[] =
538 { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
539 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
540 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED,
541 RSL_CHANNEED_TCH_ForH };
542
543 struct msgb *msg;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100544 struct gsm0808_cell_id_list2 cil;
Philipp Maier3d48ec02017-03-29 17:37:55 +0200545 uint32_t tmsi = 0x12345678;
546 uint8_t chan_needed = RSL_CHANNEED_TCH_ForH;
547
548 char imsi[] = "001010000001234";
549
550 cil.id_discr = CELL_IDENT_LAC;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100551 cil.id_list[0].lac = 0x2342;
Philipp Maier3d48ec02017-03-29 17:37:55 +0200552 cil.id_list_len = 1;
553
554 printf("Testing creating Paging Request\n");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100555 msg = gsm0808_create_paging2(imsi, NULL, &cil, NULL);
Philipp Maier3d48ec02017-03-29 17:37:55 +0200556 VERIFY(msg, res, ARRAY_SIZE(res));
557 msgb_free(msg);
558
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100559 msg = gsm0808_create_paging2(imsi, &tmsi, &cil, NULL);
Philipp Maier3d48ec02017-03-29 17:37:55 +0200560 VERIFY(msg, res2, ARRAY_SIZE(res2));
561 msgb_free(msg);
562
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100563 msg = gsm0808_create_paging2(imsi, &tmsi, &cil, &chan_needed);
Philipp Maier3d48ec02017-03-29 17:37:55 +0200564 VERIFY(msg, res3, ARRAY_SIZE(res3));
565 msgb_free(msg);
566}
567
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100568static void test_create_dtap()
569{
570 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
571 struct msgb *msg, *l3;
572
573 printf("Testing creating DTAP\n");
574 l3 = msgb_alloc_headroom(512, 128, "test");
575 l3->l3h = l3->data;
576 msgb_v_put(l3, 0x23);
577 msgb_v_put(l3, 0x42);
578
579 msg = gsm0808_create_dtap(l3, 0x3);
580 VERIFY(msg, res, ARRAY_SIZE(res));
581 msgb_free(msg);
582 msgb_free(l3);
583}
584
585static void test_prepend_dtap()
586{
587 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
588 struct msgb *in_msg;
589
590 printf("Testing prepend DTAP\n");
591
592 in_msg = msgb_alloc_headroom(512, 128, "test");
593 msgb_v_put(in_msg, 0x23);
594 msgb_v_put(in_msg, 0x42);
595
596 gsm0808_prepend_dtap_header(in_msg, 0x3);
597 in_msg->l3h = in_msg->data;
598 VERIFY(in_msg, res, ARRAY_SIZE(res));
599 msgb_free(in_msg);
600}
601
Max969fb2e2018-12-10 11:01:10 +0100602static void test_enc_dec_gcr()
603{
604 static const uint8_t res[] = {
605 GSM0808_IE_GLOBAL_CALL_REF,
606 0x0d, /* GCR length */
607 0x03, /* .net_len */
608 0xf1, 0xf2, 0xf3, /* .net */
609 0x02, /* .node length */
610 0xde, 0xad, /* .node */
611 0x05, /* length of Call. Ref. */
612 0x41, 0x42, 0x43, 0x44, 0x45 /* .cr - Call. Ref. */
613 };
614 uint8_t len;
615 struct msgb *msg;
616 struct osmo_gcr_parsed p = { 0 }, g = {
617 .net_len = 3,
618 .net = { 0xf1, 0xf2, 0xf3 },
619 .node = 0xDEAD,
620 .cr = { 0x41, 0x42, 0x43, 0x44, 0x45 },
621 };
622 int rc;
623 struct tlv_parsed tp;
624 msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "global call reference");
625 if (!msg)
626 return;
627
628 len = gsm0808_enc_gcr(msg, &g);
629 printf("Testing Global Call Reference IE encoder...\n\t%d bytes added: %s\n",
630 len, len == ARRAY_SIZE(res) ? "OK" : "FAIL");
631
632 if (!msgb_eq_data_print(msg, res, ARRAY_SIZE(res)))
633 abort();
634
635 rc = osmo_bssap_tlv_parse(&tp, msgb_data(msg), msgb_length(msg));
636 if (rc < 0) {
637 printf("parsing failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg));
638 abort();
639 }
640
641 rc = gsm0808_dec_gcr(&p, &tp);
642 if (rc < 0) {
643 printf("decoding failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg));
644 abort();
645 }
646
647 if (p.net_len != g.net_len) {
648 printf("Network ID length parsed wrong: %u != %u\n", p.net_len, g.net_len);
649 abort();
650 }
651
652 if (p.node != g.node) {
653 printf("Node ID parsed wrong: 0x%X != 0x%X\n", p.node, g.node);
654 abort();
655 }
656
657 if (memcmp(p.net, g.net, g.net_len) != 0) {
658 printf("Network ID parsed wrong: %s\n", osmo_hexdump(p.net, p.net_len));
659 abort();
660 }
661
662 if (memcmp(p.cr, g.cr, 5) != 0) {
663 printf("Call ref. ID parsed wrong: %s\n", osmo_hexdump(p.cr, 5));
664 abort();
665 }
666
667 printf("\tdecoded %d bytes: %s\n", rc, rc == len ? "OK" : "FAIL");
668 msgb_free(msg);
669}
670
Philipp Maier22401432017-03-24 17:59:26 +0100671static void test_enc_dec_aoip_trasp_addr_v4()
672{
673 struct sockaddr_storage enc_addr;
674 struct sockaddr_storage dec_addr;
675 struct sockaddr_in enc_addr_in;
676 struct msgb *msg;
677 uint8_t rc_enc;
678 int rc_dec;
679
680 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
681 enc_addr_in.sin_family = AF_INET;
682 enc_addr_in.sin_port = htons(1234);
683 inet_aton("255.0.255.255", &enc_addr_in.sin_addr);
684
685 memset(&enc_addr, 0, sizeof(enc_addr));
686 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
687
688 msg = msgb_alloc(1024, "output buffer");
689 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
690 OSMO_ASSERT(rc_enc == 8);
691 rc_dec =
692 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
693 OSMO_ASSERT(rc_dec == 6);
694 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
695
696 msgb_free(msg);
697}
698
699static void test_enc_dec_aoip_trasp_addr_v6()
700{
701 struct sockaddr_storage enc_addr;
702 struct sockaddr_storage dec_addr;
703 struct sockaddr_in6 enc_addr_in;
704 struct msgb *msg;
705 uint8_t rc_enc;
706 int rc_dec;
707
708 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
709 enc_addr_in.sin6_family = AF_INET6;
710 enc_addr_in.sin6_port = htons(4567);
711 inet_pton(AF_INET6, "2001:0db8:85a3:08d3:1319:8a2e:0370:7344",
712 &enc_addr_in.sin6_addr);
713
714 memset(&enc_addr, 0, sizeof(enc_addr));
715 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
716
717 msg = msgb_alloc(1024, "output buffer");
718 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
719 OSMO_ASSERT(rc_enc == 20);
720 rc_dec =
721 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
722 OSMO_ASSERT(rc_dec == 18);
723 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
724
725 msgb_free(msg);
726}
727
Philipp Maier6f725d62017-03-24 18:03:17 +0100728static void test_gsm0808_enc_dec_speech_codec()
729{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200730 struct gsm0808_speech_codec enc_sc = {
731 .pi = true,
732 .tf = true,
733 .type = GSM0808_SCT_FR2,
734 };
735 struct gsm0808_speech_codec dec_sc = {};
Philipp Maier6f725d62017-03-24 18:03:17 +0100736 struct msgb *msg;
737 uint8_t rc_enc;
738 int rc_dec;
739
Philipp Maier6f725d62017-03-24 18:03:17 +0100740 msg = msgb_alloc(1024, "output buffer");
741 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
742 OSMO_ASSERT(rc_enc == 3);
743
744 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
745 OSMO_ASSERT(rc_dec == 1);
746
747 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
748
749 msgb_free(msg);
750}
751
752
Philipp Maierbb839662017-06-01 17:11:19 +0200753static void test_gsm0808_enc_dec_speech_codec_with_cfg()
754{
Neels Hofmeyrc62c9342018-04-15 23:31:47 +0200755 struct gsm0808_speech_codec enc_sc = {
756 .pi = true,
757 .tf = true,
758 .type = GSM0808_SCT_FR3,
759 .cfg = 0xabcd,
760 };
761 struct gsm0808_speech_codec dec_sc = {};
Philipp Maierbb839662017-06-01 17:11:19 +0200762 struct msgb *msg;
763 uint8_t rc_enc;
764 int rc_dec;
765
Philipp Maierbb839662017-06-01 17:11:19 +0200766 msg = msgb_alloc(1024, "output buffer");
767 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
768 OSMO_ASSERT(rc_enc == 5);
769
770 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
771 OSMO_ASSERT(rc_dec == 3);
772
773 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
774
775 msgb_free(msg);
776}
777
Philipp Maier6f725d62017-03-24 18:03:17 +0100778static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg()
779{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200780 struct gsm0808_speech_codec enc_sc = {
781 .pi = true,
782 .tf = true,
783 .type = GSM0808_SCT_CSD,
784 .cfg = 0xc0,
785 };
786 struct gsm0808_speech_codec dec_sc = {};
Philipp Maier6f725d62017-03-24 18:03:17 +0100787 struct msgb *msg;
788 uint8_t rc_enc;
789 int rc_dec;
790
Philipp Maier6f725d62017-03-24 18:03:17 +0100791 msg = msgb_alloc(1024, "output buffer");
792 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
Philipp Maierbb839662017-06-01 17:11:19 +0200793 OSMO_ASSERT(rc_enc == 5);
Philipp Maier6f725d62017-03-24 18:03:17 +0100794
795 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
Philipp Maierbb839662017-06-01 17:11:19 +0200796 OSMO_ASSERT(rc_dec == 3);
Philipp Maier6f725d62017-03-24 18:03:17 +0100797
798 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
799
800 msgb_free(msg);
801}
802
803static void test_gsm0808_enc_dec_speech_codec_list()
804{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200805 struct gsm0808_speech_codec_list enc_scl = {
806 .codec = {
807 {
808 .pi = true,
809 .tf = true,
810 .type = GSM0808_SCT_FR3,
811 .cfg = 0xcdef,
812 },
813
814 {
815 .fi = true,
816 .pt = true,
817 .type = GSM0808_SCT_FR2,
818 },
819
820 {
821 .fi = true,
822 .tf = true,
823 .type = GSM0808_SCT_CSD,
824 .cfg = 0xc0,
825 },
826 },
827 .len = 3,
828 };
829 struct gsm0808_speech_codec_list dec_scl = {};
Philipp Maier6f725d62017-03-24 18:03:17 +0100830 struct msgb *msg;
831 uint8_t rc_enc;
832 int rc_dec;
833
Philipp Maier6f725d62017-03-24 18:03:17 +0100834 msg = msgb_alloc(1024, "output buffer");
835 rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
836 OSMO_ASSERT(rc_enc == 9);
837
838 rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
839 OSMO_ASSERT(rc_dec == 7);
840
841 OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0);
842
843 msgb_free(msg);
844}
845
Philipp Maierf6c369f2018-10-16 15:24:47 +0200846static void test_gsm0808_enc_dec_empty_speech_codec_list()
847{
848 struct gsm0808_speech_codec_list enc_scl = {
849 .len = 0,
850 };
851 struct gsm0808_speech_codec_list dec_scl = {};
852 struct msgb *msg;
853 uint8_t rc_enc;
854 int rc_dec;
855
856 msg = msgb_alloc(1024, "output buffer");
857 rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
858 OSMO_ASSERT(rc_enc == 2);
859
860 rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
861 OSMO_ASSERT(rc_dec == 0);
862
863 OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0);
864
865 msgb_free(msg);
866}
867
Philipp Maiere0c65302017-03-28 17:05:40 +0200868static void test_gsm0808_enc_dec_channel_type()
869{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200870 struct gsm0808_channel_type enc_ct = {
871 .ch_indctr = GSM0808_CHAN_SPEECH,
872 .ch_rate_type = GSM0808_SPEECH_HALF_PREF,
873 .perm_spch = { GSM0808_PERM_FR3, GSM0808_PERM_HR3 },
874 .perm_spch_len = 2,
875 };
876 struct gsm0808_channel_type dec_ct = {};
Philipp Maiere0c65302017-03-28 17:05:40 +0200877 struct msgb *msg;
878 uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE,
879 0x04, 0x01, 0x0b, 0xa1, 0x25
880 };
881 uint8_t rc_enc;
882 int rc_dec;
883
Philipp Maiere0c65302017-03-28 17:05:40 +0200884 msg = msgb_alloc(1024, "output buffer");
885 rc_enc = gsm0808_enc_channel_type(msg, &enc_ct);
886 OSMO_ASSERT(rc_enc == 6);
887 OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0);
888
889 rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2);
890 OSMO_ASSERT(rc_dec == 4);
891 OSMO_ASSERT(memcmp(&enc_ct, &dec_ct, sizeof(enc_ct)) == 0);
892
893 msgb_free(msg);
894}
895
Philipp Maier14e76b92017-03-28 18:36:52 +0200896static void test_gsm0808_enc_dec_encrypt_info()
897{
Neels Hofmeyr9a4286b2018-04-20 12:27:52 +0200898 struct gsm0808_encrypt_info enc_ei = {
899 .perm_algo = { GSM0808_ALG_ID_A5_0, GSM0808_ALG_ID_A5_1 },
900 .perm_algo_len = 2,
901 .key = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42, },
902 .key_len = 8,
903 };
904 struct gsm0808_encrypt_info dec_ei = {};
Philipp Maier14e76b92017-03-28 18:36:52 +0200905 struct msgb *msg;
906 uint8_t ei_enc_expected[] =
907 { GSM0808_IE_ENCRYPTION_INFORMATION, 0x09, 0x03, 0xaa, 0xbb,
908 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42
909 };
910 uint8_t rc_enc;
911 int rc_dec;
912
Philipp Maier14e76b92017-03-28 18:36:52 +0200913 msg = msgb_alloc(1024, "output buffer");
914 rc_enc = gsm0808_enc_encrypt_info(msg, &enc_ei);
915 OSMO_ASSERT(rc_enc == 11);
916 OSMO_ASSERT(memcmp(ei_enc_expected, msg->data, msg->len) == 0);
917
918 rc_dec = gsm0808_dec_encrypt_info(&dec_ei, msg->data + 2, msg->len - 2);
919 OSMO_ASSERT(rc_dec == 9);
920
921 OSMO_ASSERT(memcmp(&enc_ei, &dec_ei, sizeof(enc_ei)) == 0);
922
923 msgb_free(msg);
924}
925
Philipp Maier783047e2017-03-29 11:35:50 +0200926static void test_gsm0808_enc_dec_cell_id_list_lac()
927{
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100928 struct gsm0808_cell_id_list2 enc_cil;
929 struct gsm0808_cell_id_list2 dec_cil;
Philipp Maier783047e2017-03-29 11:35:50 +0200930 struct msgb *msg;
931 uint8_t rc_enc;
932 int rc_dec;
933
934 memset(&enc_cil, 0, sizeof(enc_cil));
935 enc_cil.id_discr = CELL_IDENT_LAC;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100936 enc_cil.id_list[0].lac = 0x0124;
Neels Hofmeyrdb2fa4e2018-04-13 04:11:20 +0200937 enc_cil.id_list[1].lac = 0xABCD;
938 enc_cil.id_list[2].lac = 0x5678;
Philipp Maier783047e2017-03-29 11:35:50 +0200939 enc_cil.id_list_len = 3;
940
941 msg = msgb_alloc(1024, "output buffer");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100942 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
Neels Hofmeyrdb2fa4e2018-04-13 04:11:20 +0200943 EXPECT_ENCODED("1a 07 05 01 24 ab cd 56 78");
Philipp Maier783047e2017-03-29 11:35:50 +0200944
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100945 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
Philipp Maier783047e2017-03-29 11:35:50 +0200946 OSMO_ASSERT(rc_dec == 7);
947
948 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
949
950 msgb_free(msg);
951}
952
953static void test_gsm0808_enc_dec_cell_id_list_single_lac()
954{
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100955 struct gsm0808_cell_id_list2 enc_cil;
956 struct gsm0808_cell_id_list2 dec_cil;
Philipp Maier783047e2017-03-29 11:35:50 +0200957 struct msgb *msg;
958 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x03,
959 0x05, 0x23, 0x42
960 };
961 uint8_t rc_enc;
962 int rc_dec;
963
964 memset(&enc_cil, 0, sizeof(enc_cil));
965 enc_cil.id_discr = CELL_IDENT_LAC;
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100966 enc_cil.id_list[0].lac = 0x2342;
Philipp Maier783047e2017-03-29 11:35:50 +0200967 enc_cil.id_list_len = 1;
968
969 msg = msgb_alloc(1024, "output buffer");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100970 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
Philipp Maier783047e2017-03-29 11:35:50 +0200971 OSMO_ASSERT(rc_enc == 5);
972 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
973
Stefan Sperling11a4d9d2018-02-15 18:28:04 +0100974 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
Philipp Maier783047e2017-03-29 11:35:50 +0200975 OSMO_ASSERT(rc_dec == 3);
976
977 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
978
979 msgb_free(msg);
980}
981
Stefan Sperlinge1a86742018-03-15 18:05:02 +0100982static void test_gsm0808_enc_dec_cell_id_list_multi_lac()
983{
984 struct gsm0808_cell_id_list2 enc_cil;
985 struct gsm0808_cell_id_list2 dec_cil;
986 struct msgb *msg;
987 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x0b, 0x05,
988 0x23, 0x42,
989 0x24, 0x43,
990 0x25, 0x44,
991 0x26, 0x45,
992 0x27, 0x46
993 };
994 uint8_t rc_enc;
995 int rc_dec;
996
997 memset(&enc_cil, 0, sizeof(enc_cil));
998 enc_cil.id_discr = CELL_IDENT_LAC;
999 enc_cil.id_list[0].lac = 0x2342;
1000 enc_cil.id_list[1].lac = 0x2443;
1001 enc_cil.id_list[2].lac = 0x2544;
1002 enc_cil.id_list[3].lac = 0x2645;
1003 enc_cil.id_list[4].lac = 0x2746;
1004 enc_cil.id_list_len = 5;
1005
1006 msg = msgb_alloc(1024, "output buffer");
1007 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1008 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
1009 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1010
1011 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1012 OSMO_ASSERT(rc_dec == msg->len - 2);
1013 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1014
1015 msgb_free(msg);
1016}
1017
Philipp Maier783047e2017-03-29 11:35:50 +02001018static void test_gsm0808_enc_dec_cell_id_list_bss()
1019{
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001020 struct gsm0808_cell_id_list2 enc_cil;
1021 struct gsm0808_cell_id_list2 dec_cil;
Philipp Maier783047e2017-03-29 11:35:50 +02001022 struct msgb *msg;
1023 uint8_t rc_enc;
1024 int rc_dec;
1025
1026 memset(&enc_cil, 0, sizeof(enc_cil));
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001027 enc_cil.id_discr = CELL_IDENT_BSS;
Philipp Maier783047e2017-03-29 11:35:50 +02001028
1029 msg = msgb_alloc(1024, "output buffer");
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001030 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
Philipp Maier783047e2017-03-29 11:35:50 +02001031 OSMO_ASSERT(rc_enc == 3);
1032
Stefan Sperling11a4d9d2018-02-15 18:28:04 +01001033 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
Philipp Maier783047e2017-03-29 11:35:50 +02001034 OSMO_ASSERT(rc_dec == 1);
1035
1036 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1037
1038 msgb_free(msg);
1039}
1040
Stefan Sperling23381452018-03-15 19:38:15 +01001041static void test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac()
1042{
1043 struct gsm0808_cell_id_list2 enc_cil;
1044 struct gsm0808_cell_id_list2 dec_cil;
1045 struct osmo_location_area_id id;
1046 struct msgb *msg;
1047 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x10, 0x04,
1048 0x92, 0x61, 0x54, 0x23, 0x42,
1049 0x92, 0x72, 0x54, 0x24, 0x43,
1050 0x92, 0x83, 0x54, 0x25, 0x44
1051 };
1052 uint8_t rc_enc;
1053 int rc_dec, i;
1054
1055 memset(&enc_cil, 0, sizeof(enc_cil));
1056 enc_cil.id_discr = CELL_IDENT_LAI_AND_LAC;
1057
1058 id.plmn.mcc = 0x123;
1059 osmo_mnc_from_str("456", &id.plmn.mnc, &id.plmn.mnc_3_digits);
1060 id.lac = 0x2342;
1061 memcpy(&enc_cil.id_list[0].lai_and_lac, &id, sizeof(id));
1062
1063 id.plmn.mcc = 0x124;
1064 osmo_mnc_from_str("457", &id.plmn.mnc, &id.plmn.mnc_3_digits);
1065 id.lac = 0x2443;
1066 memcpy(&enc_cil.id_list[1].lai_and_lac, &id, sizeof(id));
1067
1068 id.plmn.mcc = 0x125;
1069 osmo_mnc_from_str("458", &id.plmn.mnc, &id.plmn.mnc_3_digits);
1070 id.lac = 0x2544;
1071 memcpy(&enc_cil.id_list[2].lai_and_lac, &id, sizeof(id));
1072
1073 enc_cil.id_list_len = 3;
1074
1075 msg = msgb_alloc(1024, "output buffer");
1076 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1077 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
1078 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1079
1080 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1081 OSMO_ASSERT(rc_dec == msg->len - 2);
1082
1083 OSMO_ASSERT(dec_cil.id_list_len == 3);
1084 /* Check MAXLEN elements to ensure everything has been initialized. */
1085 for (i = 0; i < GSM0808_CELL_ID_LIST2_MAXLEN; i++) {
1086 struct osmo_location_area_id *enc_id;
1087 struct osmo_location_area_id *dec_id;
1088 enc_id = &enc_cil.id_list[i].lai_and_lac;
1089 dec_id = &dec_cil.id_list[i].lai_and_lac;
1090 OSMO_ASSERT(osmo_plmn_cmp(&enc_id->plmn, &dec_id->plmn) == 0);
1091 OSMO_ASSERT(enc_id->lac == dec_id->lac);
1092 }
1093
1094 msgb_free(msg);
1095}
1096
Stefan Sperling9c62fc62018-03-16 10:23:34 +01001097static void test_gsm0808_enc_dec_cell_id_list_multi_ci()
1098{
1099 struct gsm0808_cell_id_list2 enc_cil;
1100 struct gsm0808_cell_id_list2 dec_cil;
1101 struct msgb *msg;
1102 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x09, 0x02,
1103 0x00, 0x01,
1104 0x00, 0x02,
1105 0x00, 0x77,
1106 0x01, 0xff,
1107 };
1108 uint8_t rc_enc;
1109 int rc_dec;
1110
1111 memset(&enc_cil, 0, sizeof(enc_cil));
1112 enc_cil.id_discr = CELL_IDENT_CI;
1113 enc_cil.id_list[0].ci = 1;
1114 enc_cil.id_list[1].ci = 2;
1115 enc_cil.id_list[2].ci = 119;
1116 enc_cil.id_list[3].ci = 511;
1117 enc_cil.id_list_len = 4;
1118
1119 msg = msgb_alloc(1024, "output buffer");
1120 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1121 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
1122 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1123
1124 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1125 OSMO_ASSERT(rc_dec == msg->len - 2);
1126 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1127
1128 msgb_free(msg);
1129}
1130
Stefan Sperlinged4327c2018-03-16 11:02:59 +01001131static void test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci()
1132{
1133 struct gsm0808_cell_id_list2 enc_cil;
1134 struct gsm0808_cell_id_list2 dec_cil;
1135 struct msgb *msg;
1136 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x15, 0x01,
1137 0x23, 0x42, 0x00, 0x01,
1138 0x24, 0x43, 0x00, 0x02,
1139 0x25, 0x44, 0x00, 0x77,
1140 0x26, 0x45, 0x01, 0xff,
1141 0x27, 0x46, 0x02, 0xfe,
1142 };
1143 uint8_t rc_enc;
1144 int rc_dec;
1145
1146 memset(&enc_cil, 0, sizeof(enc_cil));
1147 enc_cil.id_discr = CELL_IDENT_LAC_AND_CI;
1148 enc_cil.id_list[0].lac_and_ci.lac = 0x2342;
1149 enc_cil.id_list[0].lac_and_ci.ci = 1;
1150 enc_cil.id_list[1].lac_and_ci.lac = 0x2443;
1151 enc_cil.id_list[1].lac_and_ci.ci = 2;
1152 enc_cil.id_list[2].lac_and_ci.lac = 0x2544;
1153 enc_cil.id_list[2].lac_and_ci.ci = 119;
1154 enc_cil.id_list[3].lac_and_ci.lac = 0x2645;
1155 enc_cil.id_list[3].lac_and_ci.ci = 511;
1156 enc_cil.id_list[4].lac_and_ci.lac = 0x2746;
1157 enc_cil.id_list[4].lac_and_ci.ci = 766;
1158 enc_cil.id_list_len = 5;
1159
1160 msg = msgb_alloc(1024, "output buffer");
1161 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1162 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
1163 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
1164
1165 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1166 OSMO_ASSERT(rc_dec == msg->len - 2);
1167 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
1168
1169 msgb_free(msg);
1170}
1171
Stefan Sperling483f3862018-03-16 12:21:26 +01001172static void test_gsm0808_enc_dec_cell_id_list_multi_global()
1173{
1174 struct gsm0808_cell_id_list2 enc_cil;
1175 struct gsm0808_cell_id_list2 dec_cil;
1176 struct msgb *msg;
1177 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x16, 0x00,
Neels Hofmeyr473485c2018-03-23 02:04:18 +01001178 0x21, 0x63, 0x54, 0x23, 0x42, 0x00, 0x1,
Neels Hofmeyrc44fc232018-03-23 02:15:12 +01001179 0x21, 0xf4, 0x75, 0x24, 0x43, 0x00, 0x2,
Neels Hofmeyr8b8cd932018-03-23 01:47:37 +01001180 0x21, 0x75, 0x00, 0x25, 0x44, 0x00, 0x77
Stefan Sperling483f3862018-03-16 12:21:26 +01001181 };
Stefan Sperling483f3862018-03-16 12:21:26 +01001182 uint8_t rc_enc;
1183 int rc_dec, i;
1184
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001185 enc_cil = (struct gsm0808_cell_id_list2){
1186 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1187 .id_list_len = 3,
1188 .id_list = {
1189 {
1190 .global = {
Neels Hofmeyr473485c2018-03-23 02:04:18 +01001191 .lai = { .plmn = { .mcc = 123, .mnc = 456 },
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001192 .lac = 0x2342 },
1193 .cell_identity = 1,
1194 }
1195 },
1196 {
1197 .global = {
Neels Hofmeyrc44fc232018-03-23 02:15:12 +01001198 .lai = { .plmn = { .mcc = 124, .mnc = 57 },
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001199 .lac = 0x2443 },
1200 .cell_identity = 2,
1201 }
1202 },
1203 {
1204 .global = {
Neels Hofmeyrc44fc232018-03-23 02:15:12 +01001205 .lai = { .plmn = { .mcc = 125, .mnc = 7,
1206 .mnc_3_digits = true },
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001207 .lac = 0x2544 },
1208 .cell_identity = 119,
1209 }
1210 },
1211 }
1212 };
Stefan Sperling483f3862018-03-16 12:21:26 +01001213
1214 msg = msgb_alloc(1024, "output buffer");
1215 rc_enc = gsm0808_enc_cell_id_list2(msg, &enc_cil);
1216 OSMO_ASSERT(rc_enc == sizeof(cil_enc_expected));
Neels Hofmeyrc1991df2018-03-23 02:00:00 +01001217 if (memcmp(cil_enc_expected, msg->data, msg->len)) {
1218 printf(" got: %s\n", osmo_hexdump(msg->data, msg->len));
1219 printf("expect: %s\n", osmo_hexdump(cil_enc_expected, sizeof(cil_enc_expected)));
1220 OSMO_ASSERT(false);
1221 }
Stefan Sperling483f3862018-03-16 12:21:26 +01001222
1223 rc_dec = gsm0808_dec_cell_id_list2(&dec_cil, msg->data + 2, msg->len - 2);
1224 OSMO_ASSERT(rc_dec == msg->len - 2);
1225
1226 /* Check MAXLEN elements to ensure everything has been initialized. */
1227 for (i = 0; i < GSM0808_CELL_ID_LIST2_MAXLEN; i++) {
1228 struct osmo_cell_global_id *enc_id;
1229 struct osmo_cell_global_id *dec_id;
1230 enc_id = &enc_cil.id_list[i].global;
1231 dec_id = &dec_cil.id_list[i].global;
1232 OSMO_ASSERT(osmo_plmn_cmp(&enc_id->lai.plmn, &dec_id->lai.plmn) == 0);
1233 OSMO_ASSERT(enc_id->lai.lac == dec_id->lai.lac);
1234 OSMO_ASSERT(enc_id->cell_identity == dec_id->cell_identity);
1235 }
1236
1237 msgb_free(msg);
1238}
1239
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001240static void print_cil(const struct gsm0808_cell_id_list2 *cil)
1241{
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001242 printf(" cell_id_list == %s\n", gsm0808_cell_id_list_name(cil));
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001243}
1244
1245void test_cell_id_list_add() {
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001246 size_t zu;
1247
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001248 const struct gsm0808_cell_id_list2 cgi1 = {
1249 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1250 .id_list_len = 1,
1251 .id_list = {
1252 {
1253 .global = {
1254 .lai = {
1255 .plmn = { .mcc = 1, .mnc = 2, .mnc_3_digits = false },
1256 .lac = 3,
1257 },
1258 .cell_identity = 4,
1259 }
1260 },
1261 },
1262 };
1263
1264 const struct gsm0808_cell_id_list2 cgi2 = {
1265 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1266 .id_list_len = 2,
1267 .id_list = {
1268 {
1269 .global = {
1270 .lai = {
1271 .plmn = { .mcc = 1, .mnc = 2, .mnc_3_digits = true },
1272 .lac = 3,
1273 },
1274 .cell_identity = 4,
1275 }
1276 },
1277 {
1278 .global = {
1279 .lai = {
1280 .plmn = { .mcc = 5, .mnc = 6, .mnc_3_digits = true },
1281 .lac = 7,
1282 },
1283 .cell_identity = 8,
1284 }
1285 },
1286 },
1287 };
1288
1289 const struct gsm0808_cell_id_list2 cgi2a = {
1290 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1291 .id_list_len = 2,
1292 .id_list = {
1293 {
1294 .global = cgi2.id_list[0].global
1295 },
1296 {
1297 .global = {
1298 .lai = {
1299 .plmn = { .mcc = 9, .mnc = 10, .mnc_3_digits = true },
1300 .lac = 11,
1301 },
1302 .cell_identity = 12,
1303 }
1304 },
1305 },
1306 };
1307
1308 const struct gsm0808_cell_id_list2 cgi3 = {
1309 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1310 .id_list_len = 2,
1311 .id_list = {
1312 {
1313 .global = {
1314 .lai = {
1315 .plmn = { .mcc = 13, .mnc = 14, .mnc_3_digits = true },
1316 .lac = 15,
1317 },
1318 .cell_identity = 16,
1319 }
1320 },
1321 {
1322 .global = {
1323 .lai = {
1324 .plmn = { .mcc = 16, .mnc = 17, .mnc_3_digits = true },
1325 .lac = 18,
1326 },
1327 .cell_identity = 19,
1328 }
1329 },
1330 },
1331 };
1332
1333
1334 const struct gsm0808_cell_id_list2 lac1 = {
1335 .id_discr = CELL_IDENT_LAC,
1336 .id_list_len = 1,
1337 .id_list = {
1338 {
1339 .lac = 123
1340 },
1341 },
1342 };
1343
1344 const struct gsm0808_cell_id_list2 lac2 = {
1345 .id_discr = CELL_IDENT_LAC,
1346 .id_list_len = 2,
1347 .id_list = {
1348 {
1349 .lac = 456
1350 },
1351 {
1352 .lac = 789
1353 },
1354 },
1355 };
1356
1357 struct gsm0808_cell_id_list2 cil = {};
1358
1359 printf("------- %s\n", __func__);
1360
1361 print_cil(&cil);
1362
1363#define ADD_QUIET(other_cil, expect_rc) do { \
1364 int rc = gsm0808_cell_id_list_add(&cil, &other_cil); \
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001365 printf("gsm0808_cell_id_list_add(&cil, &" #other_cil ") --> rc = %d\n", rc); \
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001366 OSMO_ASSERT(rc == expect_rc); \
1367 } while(0)
1368
1369#define ADD(other_cil, expect_rc) ADD_QUIET(other_cil, expect_rc); print_cil(&cil)
1370
1371 ADD(lac1, 1);
1372 ADD(lac1, 0);
1373 ADD(lac2, 2);
1374 ADD(lac2, 0);
1375 ADD(cil, 0);
1376 ADD(cgi1, -EINVAL);
1377
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001378 printf("* can't add to BSS list\n");
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001379 cil.id_list_len = 0;
1380 cil.id_discr = CELL_IDENT_BSS;
1381 print_cil(&cil);
1382 ADD(lac1, -EINVAL);
1383
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001384 printf("* other types (including NO_CELL) take on new type iff empty\n");
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001385 cil.id_list_len = 0;
1386 cil.id_discr = CELL_IDENT_NO_CELL;
1387 print_cil(&cil);
1388 ADD(cgi1, 1);
1389 ADD(cgi1, 0);
1390 ADD(cgi2, 2);
1391 ADD(cgi2, 0);
1392
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001393 printf("* test gsm0808_cell_id_list_name_buf()'s return val\n");
1394 zu = strlen(gsm0808_cell_id_list_name(&cil));
1395 printf(" strlen(gsm0808_cell_id_list_name(cil)) == %zu\n", zu);
1396 zu ++;
1397 while (1) {
1398 char buf[128] = "?";
1399 int rc;
1400 OSMO_ASSERT(zu < sizeof(buf));
1401 buf[zu] = '#';
1402 rc = gsm0808_cell_id_list_name_buf(buf, zu, &cil);
1403 printf(" gsm0808_cell_id_list_name_buf(buf, %zu, cil)) == %d \"%s\"\n",
1404 zu, rc, buf);
1405 OSMO_ASSERT(buf[zu] == '#');
1406 if (!zu)
1407 break;
1408 zu /= 2;
1409 }
1410
1411 printf("* list-full behavior\n");
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001412 cil.id_list_len = GSM0808_CELL_ID_LIST2_MAXLEN - 1;
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001413 printf("cil.id_list_len = %u\n", cil.id_list_len);
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001414 ADD_QUIET(cgi2a, 1);
1415 printf("cil.id_list_len = %u\n", cil.id_list_len);
1416
1417 cil.id_list_len = GSM0808_CELL_ID_LIST2_MAXLEN - 1;
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001418 printf("cil.id_list_len = %u\n", cil.id_list_len);
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001419 ADD_QUIET(cgi3, -ENOSPC);
Neels Hofmeyra4399c82018-04-17 02:26:10 +02001420 printf("cil.id_list_len = %u\n", cil.id_list_len);
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001421 ADD_QUIET(cgi2a, -ENOSPC);
1422 printf("cil.id_list_len = %u\n", cil.id_list_len);
1423
1424 printf("------- %s done\n", __func__);
1425}
1426
Neels Hofmeyr250e7f72018-04-13 03:30:14 +02001427static void test_gsm0808_enc_dec_cell_id_lac()
1428{
1429 struct gsm0808_cell_id enc_ci = {
1430 .id_discr = CELL_IDENT_LAC,
1431 .id.lac = 0x0124,
1432 };
1433 struct gsm0808_cell_id dec_ci;
1434 struct msgb *msg;
1435 uint8_t rc_enc;
1436 int rc_dec;
1437
1438 memset(&dec_ci, 0xa5, sizeof(dec_ci));
1439
1440 msg = msgb_alloc(1024, "output buffer");
1441 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1442 EXPECT_ENCODED("05 03 05 01 24");
1443
1444 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1445 OSMO_ASSERT(rc_dec == 3);
1446
1447 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1448 && enc_ci.id.lac == dec_ci.id.lac);
1449
1450 msgb_free(msg);
1451}
1452
1453static void test_gsm0808_enc_dec_cell_id_bss()
1454{
1455 struct gsm0808_cell_id enc_ci = {
1456 .id_discr = CELL_IDENT_BSS,
1457 };
1458 struct gsm0808_cell_id dec_ci;
1459 struct msgb *msg;
1460 uint8_t rc_enc;
1461 int rc_dec;
1462
1463 msg = msgb_alloc(1024, "output buffer");
1464 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1465 EXPECT_ENCODED("05 01 06");
1466
1467 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1468 OSMO_ASSERT(rc_dec == 1);
1469
1470 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr);
1471
1472 msgb_free(msg);
1473}
1474
1475static void test_gsm0808_enc_dec_cell_id_no_cell()
1476{
1477 struct gsm0808_cell_id enc_ci = {
1478 .id_discr = CELL_IDENT_NO_CELL,
1479 };
1480 struct gsm0808_cell_id dec_ci;
1481 struct msgb *msg;
1482 uint8_t rc_enc;
1483 int rc_dec;
1484
1485 msg = msgb_alloc(1024, "output buffer");
1486 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1487 EXPECT_ENCODED("05 01 03");
1488
1489 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1490 OSMO_ASSERT(rc_dec == 1);
1491
1492 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr);
1493
1494 msgb_free(msg);
1495}
1496
1497static void test_gsm0808_enc_dec_cell_id_lai_and_lac()
1498{
1499 struct gsm0808_cell_id enc_ci = {
1500 .id_discr = CELL_IDENT_LAI_AND_LAC,
1501 .id.lai_and_lac = {
1502 .plmn = {
1503 .mcc = 123,
1504 .mnc = 456,
1505 },
1506 .lac = 0x2342,
1507 },
1508 };
1509 struct gsm0808_cell_id dec_ci;
1510 struct msgb *msg;
1511 uint8_t rc_enc;
1512 int rc_dec;
1513
1514 msg = msgb_alloc(1024, "output buffer");
1515 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1516 EXPECT_ENCODED("05 06 04 21 63 54 23 42");
1517
1518 memset(&dec_ci, 0xa5, sizeof(dec_ci));
1519 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1520 OSMO_ASSERT(rc_dec == msg->len - 2);
1521
1522 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1523 && osmo_plmn_cmp(&enc_ci.id.lai_and_lac.plmn, &dec_ci.id.lai_and_lac.plmn) == 0
1524 && enc_ci.id.lai_and_lac.lac == dec_ci.id.lai_and_lac.lac);
1525 msgb_free(msg);
1526}
1527
1528static void test_gsm0808_enc_dec_cell_id_ci()
1529{
1530 struct gsm0808_cell_id enc_ci = {
1531 .id_discr = CELL_IDENT_CI,
1532 .id.ci = 0x423,
1533 };
1534 struct gsm0808_cell_id dec_ci;
1535 struct msgb *msg;
1536 uint8_t rc_enc;
1537 int rc_dec;
1538
1539 msg = msgb_alloc(1024, "output buffer");
1540 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1541 EXPECT_ENCODED("05 03 02 04 23");
1542
1543 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1544 OSMO_ASSERT(rc_dec == msg->len - 2);
1545 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1546 && enc_ci.id.ci == dec_ci.id.ci);
1547
1548 msgb_free(msg);
1549}
1550
1551static void test_gsm0808_enc_dec_cell_id_lac_and_ci()
1552{
1553 struct gsm0808_cell_id enc_ci = {
1554 .id_discr = CELL_IDENT_LAC_AND_CI,
1555 .id.lac_and_ci = {
1556 .lac = 0x423,
1557 .ci = 0x235,
1558 },
1559 };
1560 struct gsm0808_cell_id dec_ci;
1561 struct msgb *msg;
1562 uint8_t rc_enc;
1563 int rc_dec;
1564
1565 msg = msgb_alloc(1024, "output buffer");
1566 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1567 EXPECT_ENCODED("05 05 01 04 23 02 35");
1568
1569 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1570 OSMO_ASSERT(rc_dec == msg->len - 2);
1571 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1572 && enc_ci.id.lac_and_ci.lac == dec_ci.id.lac_and_ci.lac
1573 && enc_ci.id.lac_and_ci.ci == dec_ci.id.lac_and_ci.ci);
1574
1575 msgb_free(msg);
1576}
1577
1578static void test_gsm0808_enc_dec_cell_id_global()
1579{
1580 struct gsm0808_cell_id enc_ci = {
1581 .id_discr = CELL_IDENT_WHOLE_GLOBAL,
1582 .id.global = {
1583 .lai = {
1584 .plmn = { .mcc = 123, .mnc = 456 },
1585 .lac = 0x2342
1586 },
1587 .cell_identity = 0x423,
1588 }
1589 };
1590 struct gsm0808_cell_id dec_ci;
1591 struct msgb *msg;
1592 uint8_t rc_enc;
1593 int rc_dec;
1594
1595 msg = msgb_alloc(1024, "output buffer");
1596 rc_enc = gsm0808_enc_cell_id(msg, &enc_ci);
1597 EXPECT_ENCODED("05 08 00 21 63 54 23 42 04 23");
1598
1599 rc_dec = gsm0808_dec_cell_id(&dec_ci, msg->data + 2, msg->len - 2);
1600 OSMO_ASSERT(rc_dec == msg->len - 2);
1601
1602 OSMO_ASSERT(enc_ci.id_discr == dec_ci.id_discr
1603 && osmo_plmn_cmp(&enc_ci.id.global.lai.plmn,
1604 &dec_ci.id.global.lai.plmn) == 0
1605 && enc_ci.id.global.lai.lac == dec_ci.id.global.lai.lac
1606 && enc_ci.id.global.cell_identity == dec_ci.id.global.cell_identity);
1607 msgb_free(msg);
1608}
1609
Philipp Maier5f2eb152018-09-19 13:40:21 +02001610static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(struct gsm48_multi_rate_conf *cfg)
1611{
1612 uint16_t s15_s0;
1613
1614 printf("Input:\n");
1615 printf(" m4_75= %u smod= %u\n", cfg->m4_75, cfg->smod);
1616 printf(" m5_15= %u spare= %u\n", cfg->m5_15, cfg->spare);
1617 printf(" m5_90= %u icmi= %u\n", cfg->m5_90, cfg->icmi);
1618 printf(" m6_70= %u nscb= %u\n", cfg->m6_70, cfg->nscb);
1619 printf(" m7_40= %u ver= %u\n", cfg->m7_40, cfg->ver);
1620 printf(" m7_95= %u\n", cfg->m7_95);
1621 printf(" m10_2= %u\n", cfg->m10_2);
1622 printf(" m12_2= %u\n", cfg->m12_2);
1623
1624 s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, true);
1625 printf("Result (fr):\n");
1626 printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
1627 OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
1628
1629 s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, false);
1630 printf("Result (hr):\n");
1631 printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
1632 OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
1633
1634 printf("\n");
1635}
1636
1637static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg(void)
1638{
1639 struct gsm48_multi_rate_conf cfg;
1640
1641 printf("Testing gsm0808_sc_cfg_from_gsm48_mr_cfg():\n");
1642
1643 memset(&cfg, 0, sizeof(cfg));
1644
1645 cfg.m4_75 = 0;
1646 cfg.m5_15 = 0;
1647 cfg.m5_90 = 0;
1648 cfg.m6_70 = 0;
1649 cfg.m7_40 = 0;
1650 cfg.m7_95 = 0;
1651 cfg.m10_2 = 0;
1652 cfg.m12_2 = 0;
1653 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1654
1655 cfg.m4_75 = 1;
1656 cfg.m5_15 = 0;
1657 cfg.m5_90 = 0;
1658 cfg.m6_70 = 0;
1659 cfg.m7_40 = 0;
1660 cfg.m7_95 = 0;
1661 cfg.m10_2 = 0;
1662 cfg.m12_2 = 0;
1663 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1664
1665 cfg.m4_75 = 0;
1666 cfg.m5_15 = 1;
1667 cfg.m5_90 = 0;
1668 cfg.m6_70 = 0;
1669 cfg.m7_40 = 0;
1670 cfg.m7_95 = 0;
1671 cfg.m10_2 = 0;
1672 cfg.m12_2 = 0;
1673 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1674
1675 cfg.m4_75 = 0;
1676 cfg.m5_15 = 0;
1677 cfg.m5_90 = 1;
1678 cfg.m6_70 = 0;
1679 cfg.m7_40 = 0;
1680 cfg.m7_95 = 0;
1681 cfg.m10_2 = 0;
1682 cfg.m12_2 = 0;
1683 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1684
1685 cfg.m4_75 = 0;
1686 cfg.m5_15 = 0;
1687 cfg.m5_90 = 0;
1688 cfg.m6_70 = 1;
1689 cfg.m7_40 = 0;
1690 cfg.m7_95 = 0;
1691 cfg.m10_2 = 0;
1692 cfg.m12_2 = 0;
1693 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1694
1695 cfg.m4_75 = 0;
1696 cfg.m5_15 = 0;
1697 cfg.m5_90 = 0;
1698 cfg.m6_70 = 0;
1699 cfg.m7_40 = 1;
1700 cfg.m7_95 = 0;
1701 cfg.m10_2 = 0;
1702 cfg.m12_2 = 0;
1703 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1704
1705 cfg.m4_75 = 0;
1706 cfg.m5_15 = 0;
1707 cfg.m5_90 = 0;
1708 cfg.m6_70 = 0;
1709 cfg.m7_40 = 0;
1710 cfg.m7_95 = 1;
1711 cfg.m10_2 = 0;
1712 cfg.m12_2 = 0;
1713 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1714
1715 cfg.m4_75 = 0;
1716 cfg.m5_15 = 0;
1717 cfg.m5_90 = 0;
1718 cfg.m6_70 = 0;
1719 cfg.m7_40 = 0;
1720 cfg.m7_95 = 0;
1721 cfg.m10_2 = 1;
1722 cfg.m12_2 = 0;
1723 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1724
1725 cfg.m4_75 = 0;
1726 cfg.m5_15 = 0;
1727 cfg.m5_90 = 0;
1728 cfg.m6_70 = 0;
1729 cfg.m7_40 = 0;
1730 cfg.m7_95 = 0;
1731 cfg.m10_2 = 0;
1732 cfg.m12_2 = 1;
1733 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1734
1735 cfg.m4_75 = 1;
1736 cfg.m5_15 = 1;
1737 cfg.m5_90 = 1;
1738 cfg.m6_70 = 1;
1739 cfg.m7_40 = 0;
1740 cfg.m7_95 = 0;
1741 cfg.m10_2 = 0;
1742 cfg.m12_2 = 0;
1743 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1744
1745 cfg.m4_75 = 0;
1746 cfg.m5_15 = 0;
1747 cfg.m5_90 = 0;
1748 cfg.m6_70 = 0;
1749 cfg.m7_40 = 1;
1750 cfg.m7_95 = 1;
1751 cfg.m10_2 = 1;
1752 cfg.m12_2 = 1;
1753 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1754
1755 cfg.m4_75 = 0;
1756 cfg.m5_15 = 0;
1757 cfg.m5_90 = 1;
1758 cfg.m6_70 = 1;
1759 cfg.m7_40 = 0;
1760 cfg.m7_95 = 0;
1761 cfg.m10_2 = 1;
1762 cfg.m12_2 = 1;
1763 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1764
1765 cfg.m4_75 = 1;
1766 cfg.m5_15 = 1;
1767 cfg.m5_90 = 0;
1768 cfg.m6_70 = 0;
1769 cfg.m7_40 = 1;
1770 cfg.m7_95 = 1;
1771 cfg.m10_2 = 0;
1772 cfg.m12_2 = 0;
1773 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1774
1775 cfg.m4_75 = 0;
1776 cfg.m5_15 = 1;
1777 cfg.m5_90 = 0;
1778 cfg.m6_70 = 1;
1779 cfg.m7_40 = 0;
1780 cfg.m7_95 = 1;
1781 cfg.m10_2 = 0;
1782 cfg.m12_2 = 1;
1783 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1784
1785 cfg.m4_75 = 1;
1786 cfg.m5_15 = 0;
1787 cfg.m5_90 = 1;
1788 cfg.m6_70 = 0;
1789 cfg.m7_40 = 1;
1790 cfg.m7_95 = 0;
1791 cfg.m10_2 = 1;
1792 cfg.m12_2 = 0;
1793 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1794
1795 cfg.m4_75 = 1;
1796 cfg.m5_15 = 1;
1797 cfg.m5_90 = 1;
1798 cfg.m6_70 = 1;
1799 cfg.m7_40 = 1;
1800 cfg.m7_95 = 1;
1801 cfg.m10_2 = 1;
1802 cfg.m12_2 = 1;
1803 test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
1804}
1805
Philipp Maier8515d032018-09-25 15:57:49 +02001806static void test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(uint16_t s15_s0)
1807{
1808 struct gsm48_multi_rate_conf cfg;
1809
1810 printf("Input:\n");
1811 printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
1812 OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
1813
1814 gsm48_mr_cfg_from_gsm0808_sc_cfg(&cfg, s15_s0);
1815
1816 printf("Output:\n");
1817 printf(" m4_75= %u smod= %u\n", cfg.m4_75, cfg.smod);
1818 printf(" m5_15= %u spare= %u\n", cfg.m5_15, cfg.spare);
1819 printf(" m5_90= %u icmi= %u\n", cfg.m5_90, cfg.icmi);
1820 printf(" m6_70= %u nscb= %u\n", cfg.m6_70, cfg.nscb);
1821 printf(" m7_40= %u ver= %u\n", cfg.m7_40, cfg.ver);
1822 printf(" m7_95= %u\n", cfg.m7_95);
1823 printf(" m10_2= %u\n", cfg.m10_2);
1824 printf(" m12_2= %u\n", cfg.m12_2);
1825
1826 printf("\n");
1827}
1828
1829void test_gsm48_mr_cfg_from_gsm0808_sc_cfg()
1830{
1831 printf("Testing gsm48_mr_cfg_from_gsm0808_sc_cfg():\n");
1832
1833 /* Only one codec per setting */
1834 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1835 (GSM0808_SC_CFG_DEFAULT_AMR_4_75);
1836 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1837 (GSM0808_SC_CFG_DEFAULT_AMR_5_15);
1838 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1839 (GSM0808_SC_CFG_DEFAULT_AMR_5_90);
1840 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1841 (GSM0808_SC_CFG_DEFAULT_AMR_6_70);
1842 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1843 (GSM0808_SC_CFG_DEFAULT_AMR_7_40);
1844 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1845 (GSM0808_SC_CFG_DEFAULT_AMR_7_95);
1846 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1847 (GSM0808_SC_CFG_DEFAULT_AMR_10_2);
1848 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1849 (GSM0808_SC_CFG_DEFAULT_AMR_12_2);
1850
1851 /* Combinations */
1852 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1853 (GSM0808_SC_CFG_DEFAULT_AMR_4_75 | GSM0808_SC_CFG_DEFAULT_AMR_6_70 |
1854 GSM0808_SC_CFG_DEFAULT_AMR_10_2);
1855 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1856 (GSM0808_SC_CFG_DEFAULT_AMR_10_2 | GSM0808_SC_CFG_DEFAULT_AMR_12_2 |
1857 GSM0808_SC_CFG_DEFAULT_AMR_7_40);
1858 test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single
1859 (GSM0808_SC_CFG_DEFAULT_AMR_7_95 | GSM0808_SC_CFG_DEFAULT_AMR_12_2);
1860}
1861
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001862int main(int argc, char **argv)
1863{
Max969fb2e2018-12-10 11:01:10 +01001864 void *ctx = talloc_named_const(NULL, 0, "gsm0808 test");
1865 msgb_talloc_ctx_init(ctx, 0);
1866 osmo_init_logging2(ctx, NULL);
1867
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001868 printf("Testing generation of GSM0808 messages\n");
Philipp Maier4f4905f2018-11-30 13:36:12 +01001869 test_gsm0808_enc_cause();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001870 test_create_layer3();
Philipp Maierfa896ab2017-03-27 16:55:32 +02001871 test_create_layer3_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001872 test_create_reset();
Philipp Maier15596e22017-04-05 17:55:27 +02001873 test_create_reset_ack();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001874 test_create_clear_command();
1875 test_create_clear_complete();
Philipp Maierb478dd32017-03-29 15:50:05 +02001876 test_create_cipher();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001877 test_create_cipher_complete();
1878 test_create_cipher_reject();
Maxed651d22018-11-07 15:25:05 +01001879 test_create_cipher_reject_ext();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001880 test_create_cm_u();
1881 test_create_sapi_reject();
Philipp Maierc6144a22017-03-29 17:53:43 +02001882 test_create_ass();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001883 test_create_ass_compl();
Philipp Maierfa896ab2017-03-27 16:55:32 +02001884 test_create_ass_compl_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001885 test_create_ass_fail();
Philipp Maierfa896ab2017-03-27 16:55:32 +02001886 test_create_ass_fail_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001887 test_create_clear_rqst();
Philipp Maier3d48ec02017-03-29 17:37:55 +02001888 test_create_paging();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001889 test_create_dtap();
1890 test_prepend_dtap();
Max969fb2e2018-12-10 11:01:10 +01001891
1892 test_enc_dec_gcr();
1893
Philipp Maier22401432017-03-24 17:59:26 +01001894 test_enc_dec_aoip_trasp_addr_v4();
1895 test_enc_dec_aoip_trasp_addr_v6();
Philipp Maier6f725d62017-03-24 18:03:17 +01001896 test_gsm0808_enc_dec_speech_codec();
Philipp Maier6f725d62017-03-24 18:03:17 +01001897 test_gsm0808_enc_dec_speech_codec_ext_with_cfg();
Philipp Maierbb839662017-06-01 17:11:19 +02001898 test_gsm0808_enc_dec_speech_codec_with_cfg();
Philipp Maier6f725d62017-03-24 18:03:17 +01001899 test_gsm0808_enc_dec_speech_codec_list();
Philipp Maierf6c369f2018-10-16 15:24:47 +02001900 test_gsm0808_enc_dec_empty_speech_codec_list();
Philipp Maiere0c65302017-03-28 17:05:40 +02001901 test_gsm0808_enc_dec_channel_type();
Philipp Maier14e76b92017-03-28 18:36:52 +02001902 test_gsm0808_enc_dec_encrypt_info();
Neels Hofmeyr250e7f72018-04-13 03:30:14 +02001903
Philipp Maier783047e2017-03-29 11:35:50 +02001904 test_gsm0808_enc_dec_cell_id_list_lac();
1905 test_gsm0808_enc_dec_cell_id_list_single_lac();
Stefan Sperlinge1a86742018-03-15 18:05:02 +01001906 test_gsm0808_enc_dec_cell_id_list_multi_lac();
Philipp Maier783047e2017-03-29 11:35:50 +02001907 test_gsm0808_enc_dec_cell_id_list_bss();
Stefan Sperling23381452018-03-15 19:38:15 +01001908 test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac();
Stefan Sperling9c62fc62018-03-16 10:23:34 +01001909 test_gsm0808_enc_dec_cell_id_list_multi_ci();
Stefan Sperlinged4327c2018-03-16 11:02:59 +01001910 test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci();
Stefan Sperling483f3862018-03-16 12:21:26 +01001911 test_gsm0808_enc_dec_cell_id_list_multi_global();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001912
Neels Hofmeyr74663d92018-03-23 01:46:42 +01001913 test_cell_id_list_add();
1914
Neels Hofmeyr250e7f72018-04-13 03:30:14 +02001915 test_gsm0808_enc_dec_cell_id_lac();
1916 test_gsm0808_enc_dec_cell_id_bss();
1917 test_gsm0808_enc_dec_cell_id_no_cell();
1918 test_gsm0808_enc_dec_cell_id_lai_and_lac();
1919 test_gsm0808_enc_dec_cell_id_ci();
1920 test_gsm0808_enc_dec_cell_id_lac_and_ci();
1921 test_gsm0808_enc_dec_cell_id_global();
1922
Philipp Maier5f2eb152018-09-19 13:40:21 +02001923 test_gsm0808_sc_cfg_from_gsm48_mr_cfg();
Philipp Maier8515d032018-09-25 15:57:49 +02001924 test_gsm48_mr_cfg_from_gsm0808_sc_cfg();
Philipp Maier5f2eb152018-09-19 13:40:21 +02001925
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001926 printf("Done\n");
1927 return EXIT_SUCCESS;
1928}