blob: 8304052db636a28e79e524a60ed2a289b0cdecca [file] [log] [blame]
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001/*
2 * (C) 2012 by Holger Hans Peter Freyther
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 */
20
21#include <osmocom/gsm/gsm0808.h>
Philipp Maier22401432017-03-24 17:59:26 +010022#include <osmocom/gsm/gsm0808_utils.h>
23#include <osmocom/gsm/protocol/gsm_08_08.h>
Philipp Maier3d48ec02017-03-29 17:37:55 +020024#include <osmocom/gsm/protocol/gsm_08_58.h>
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010025
26#include <stdio.h>
27#include <stdlib.h>
Philipp Maier22401432017-03-24 17:59:26 +010028#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010031
32#define VERIFY(msg, data, len) \
33 if (msgb_l3len(msg) != len) { \
34 printf("%s:%d Length don't match: %d vs. %d. %s\n", \
Holger Hans Peter Freytherfdb46672015-11-09 16:32:43 +000035 __func__, __LINE__, msgb_l3len(msg), (int) len, \
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010036 osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
37 abort(); \
38 } else if (memcmp(msg->l3h, data, len) != 0) { \
39 printf("%s:%d didn't match: got: %s\n", \
40 __func__, __LINE__, \
41 osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
42 abort(); \
43 }
44
Philipp Maierfa896ab2017-03-27 16:55:32 +020045/* Setup a fake codec list for testing */
46static void setup_codec_list(struct gsm0808_speech_codec_list *scl)
47{
48 memset(scl, 0, sizeof(*scl));
49
50 scl->codec[0].pi = true;
51 scl->codec[0].tf = true;
52 scl->codec[0].type = 0xab;
53 scl->codec[0].type_extended = true;
54 scl->codec[0].cfg_present = true;
55 scl->codec[0].cfg = 0xcdef;
56
57 scl->codec[1].fi = true;
58 scl->codec[1].pt = true;
59 scl->codec[1].type = 0x05;
60
61 scl->codec[2].fi = true;
62 scl->codec[2].tf = true;
63 scl->codec[2].type = 0xf2;
64 scl->codec[2].type_extended = true;
65
66 scl->len = 3;
67}
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +010068
69static void test_create_layer3(void)
70{
71 static const uint8_t res[] = {
72 0x00, 0x0e, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
73 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23 };
74 struct msgb *msg, *in_msg;
75 printf("Testing creating Layer3\n");
76
77 in_msg = msgb_alloc_headroom(512, 128, "foo");
78 in_msg->l3h = in_msg->data;
79 msgb_v_put(in_msg, 0x23);
80
81 msg = gsm0808_create_layer3(in_msg, 0x1122, 0x2244, 0x3366, 0x4488);
82 VERIFY(msg, res, ARRAY_SIZE(res));
83 msgb_free(msg);
84 msgb_free(in_msg);
85}
86
Philipp Maierfa896ab2017-03-27 16:55:32 +020087static void test_create_layer3_aoip()
88{
89 static const uint8_t res[] = {
90 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
91 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23,
92 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef,
93 0xa5, 0x9f, 0xf2
94 };
95
96 struct msgb *msg, *in_msg;
97 struct gsm0808_speech_codec_list sc_list;
98 printf("Testing creating Layer3 (AoIP)\n");
99
100 setup_codec_list(&sc_list);
101
102 in_msg = msgb_alloc_headroom(512, 128, "foo");
103 in_msg->l3h = in_msg->data;
104 msgb_v_put(in_msg, 0x23);
105
106 msg =
107 gsm0808_create_layer3_aoip(in_msg, 0x1122, 0x2244, 0x3366, 0x4488,
108 &sc_list);
109 VERIFY(msg, res, ARRAY_SIZE(res));
110
111 msgb_free(msg);
112 msgb_free(in_msg);
113}
114
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100115static void test_create_reset()
116{
117 static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 };
118 struct msgb *msg;
119
120 printf("Testing creating Reset\n");
121 msg = gsm0808_create_reset();
122 VERIFY(msg, res, ARRAY_SIZE(res));
123 msgb_free(msg);
124}
125
Philipp Maier15596e22017-04-05 17:55:27 +0200126static void test_create_reset_ack()
127{
128 static const uint8_t res[] = { 0x00, 0x01, 0x31 };
129 struct msgb *msg;
130
131 printf("Testing creating Reset Ack\n");
132 msg = gsm0808_create_reset_ack();
133 VERIFY(msg, res, ARRAY_SIZE(res));
134 msgb_free(msg);
135}
136
137
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100138static void test_create_clear_command()
139{
140 static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 };
141 struct msgb *msg;
142
143 printf("Testing creating Clear Command\n");
144 msg = gsm0808_create_clear_command(0x23);
145 VERIFY(msg, res, ARRAY_SIZE(res));
146 msgb_free(msg);
147}
148
149static void test_create_clear_complete()
150{
151 static const uint8_t res[] = { 0x00, 0x01, 0x21 };
152 struct msgb *msg;
153
154 printf("Testing creating Clear Complete\n");
155 msg = gsm0808_create_clear_complete();
156 VERIFY(msg, res, ARRAY_SIZE(res));
157 msgb_free(msg);
158}
159
Philipp Maierb478dd32017-03-29 15:50:05 +0200160static void test_create_cipher()
161{
162 static const uint8_t res[] =
163 { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa,
164 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 };
165 static const uint8_t res2[] =
166 { 0x00, 0x0e, 0x53, 0x0a, 0x09, 0x03, 0xaa,
167 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42,
168 GSM0808_IE_CIPHER_RESPONSE_MODE, 0x01 };
169 struct msgb *msg;
170 struct gsm0808_encrypt_info ei;
171 uint8_t include_imeisv;
172
173 memset(&ei, 0, sizeof(ei));
174 ei.perm_algo[0] = GSM0808_ALG_ID_A5_0;
175 ei.perm_algo[1] = GSM0808_ALG_ID_A5_1;
176 ei.perm_algo_len = 2;
177 ei.key[0] = 0xaa;
178 ei.key[1] = 0xbb;
179 ei.key[2] = 0xcc;
180 ei.key[3] = 0xdd;
181 ei.key[4] = 0xee;
182 ei.key[5] = 0xff;
183 ei.key[6] = 0x23;
184 ei.key[7] = 0x42;
185 ei.key_len = 8;
186 include_imeisv = 1;
187
188 printf("Testing creating Chipher Mode Command\n");
189 msg = gsm0808_create_cipher(&ei, NULL);
190 OSMO_ASSERT(msg);
191 VERIFY(msg, res, ARRAY_SIZE(res));
192 msgb_free(msg);
193
194 msg = gsm0808_create_cipher(&ei, &include_imeisv);
195 OSMO_ASSERT(msg);
196 VERIFY(msg, res2, ARRAY_SIZE(res2));
197 msgb_free(msg);
198}
199
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100200static void test_create_cipher_complete()
201{
202 static const uint8_t res1[] = {
203 0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 };
204 static const uint8_t res2[] = { 0x00, 0x03, 0x55, 0x2c, 0x04};
205 struct msgb *l3, *msg;
206
207 printf("Testing creating Cipher Complete\n");
208 l3 = msgb_alloc_headroom(512, 128, "l3h");
209 l3->l3h = l3->data;
210 msgb_v_put(l3, 0x23);
211 msgb_v_put(l3, 0x42);
212 msgb_v_put(l3, 0x21);
213
214 /* with l3 data */
215 msg = gsm0808_create_cipher_complete(l3, 4);
216 VERIFY(msg, res1, ARRAY_SIZE(res1));
217 msgb_free(msg);
218
219 /* with l3 data but short */
220 l3->len -= 1;
221 l3->tail -= 1;
222 msg = gsm0808_create_cipher_complete(l3, 4);
223 VERIFY(msg, res2, ARRAY_SIZE(res2));
224 msgb_free(msg);
225
226 /* without l3 data */
227 msg = gsm0808_create_cipher_complete(NULL, 4);
228 VERIFY(msg, res2, ARRAY_SIZE(res2));
229 msgb_free(msg);
230
231
232 msgb_free(l3);
233}
234
235static void test_create_cipher_reject()
236{
237 static const uint8_t res[] = { 0x00, 0x02, 0x59, 0x23 };
238 struct msgb *msg;
239
240 printf("Testing creating Cipher Reject\n");
241 msg = gsm0808_create_cipher_reject(0x23);
242 VERIFY(msg, res, ARRAY_SIZE(res));
243 msgb_free(msg);
244}
245
246static void test_create_cm_u()
247{
Harald Welte07b625d2012-01-23 10:02:58 +0100248 static const uint8_t res[] = {
249 0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 };
250 static const uint8_t res2o[] = {
251 0x00, 0x04, 0x54, 0x12, 0x01, 0x23 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100252 struct msgb *msg;
Harald Welte07b625d2012-01-23 10:02:58 +0100253 const uint8_t cm2 = 0x23;
254 const uint8_t cm3 = 0x42;
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100255
256 printf("Testing creating CM U\n");
Harald Welte07b625d2012-01-23 10:02:58 +0100257 msg = gsm0808_create_classmark_update(&cm2, 1, &cm3, 1);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100258 VERIFY(msg, res, ARRAY_SIZE(res));
Harald Welte07b625d2012-01-23 10:02:58 +0100259
260 msg = gsm0808_create_classmark_update(&cm2, 1, NULL, 0);
261 VERIFY(msg, res2o, ARRAY_SIZE(res2o));
262
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100263 msgb_free(msg);
264}
265
266static void test_create_sapi_reject()
267{
268 static const uint8_t res[] = { 0x00, 0x03, 0x25, 0x03, 0x25 };
269 struct msgb *msg;
270
271 printf("Testing creating SAPI Reject\n");
272 msg = gsm0808_create_sapi_reject(3);
273 VERIFY(msg, res, ARRAY_SIZE(res));
274 msgb_free(msg);
275}
276
Philipp Maierc6144a22017-03-29 17:53:43 +0200277static void test_create_ass()
278{
279 static const uint8_t res1[] =
280 { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
281 0x04 };
282 static const uint8_t res2[] =
283 { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
284 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17,
285 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd,
286 0xef, 0xa5, 0x9f, 0xf2, GSM0808_IE_CALL_ID, 0xaa, 0xbb, 0xcc,
287 0xdd };
288
289 struct msgb *msg;
290 struct gsm0808_channel_type ct;
291 uint16_t cic = 0004;
292 struct sockaddr_storage ss;
293 struct sockaddr_in sin;
294 struct gsm0808_speech_codec_list sc_list;
295 uint32_t call_id = 0xAABBCCDD;
296
297 memset(&ct, 0, sizeof(ct));
298 ct.ch_indctr = GSM0808_CHAN_SPEECH;
299 ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF;
300 ct.perm_spch[0] = GSM0808_PERM_FR3;
301 ct.perm_spch[1] = GSM0808_PERM_HR3;
302 ct.perm_spch_len = 2;
303
304 memset(&sin, 0, sizeof(sin));
305 sin.sin_family = AF_INET;
306 sin.sin_port = htons(1234);
307 inet_aton("192.168.100.23", &sin.sin_addr);
308
309 memset(&ss, 0, sizeof(ss));
310 memcpy(&ss, &sin, sizeof(sin));
311
312 setup_codec_list(&sc_list);
313
314 printf("Testing creating Assignment Request\n");
315 msg = gsm0808_create_ass(&ct, &cic, NULL, NULL, NULL);
316 OSMO_ASSERT(msg);
317 VERIFY(msg, res1, ARRAY_SIZE(res1));
318 msgb_free(msg);
319
320 msg = gsm0808_create_ass(&ct, &cic, &ss, &sc_list, &call_id);
321 OSMO_ASSERT(msg);
322 VERIFY(msg, res2, ARRAY_SIZE(res2));
323 msgb_free(msg);
324}
325
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100326static void test_create_ass_compl()
327{
328 static const uint8_t res1[] = {
329 0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c,
330 0x11, 0x40, 0x22 };
331 static const uint8_t res2[] = {
332 0x00, 0x07, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11};
333 struct msgb *msg;
334
335 printf("Testing creating Assignment Complete\n");
336 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0x22);
337 VERIFY(msg, res1, ARRAY_SIZE(res1));
338 msgb_free(msg);
339
340 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0);
341 VERIFY(msg, res2, ARRAY_SIZE(res2));
342 msgb_free(msg);
343}
344
Philipp Maierfa896ab2017-03-27 16:55:32 +0200345static void test_create_ass_compl_aoip()
346{
347 struct sockaddr_storage ss;
348 struct sockaddr_in sin;
349 struct gsm0808_speech_codec sc;
350 struct gsm0808_speech_codec_list sc_list;
351 static const uint8_t res[] =
352 { 0x00, 0x1d, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22,
353 GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04,
354 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, 0x9a,
355 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5,
356 0x9f, 0xf2 };
357 struct msgb *msg;
358
359 memset(&sin, 0, sizeof(sin));
360 sin.sin_family = AF_INET;
361 sin.sin_port = htons(1234);
362 inet_aton("192.168.100.23", &sin.sin_addr);
363
364 memset(&ss, 0, sizeof(ss));
365 memcpy(&ss, &sin, sizeof(sin));
366
367 memset(&sc, 0, sizeof(sc));
368 sc.fi = true;
369 sc.tf = true;
370 sc.type = 0x0a;
371
372 setup_codec_list(&sc_list);
373
374 printf("Testing creating Assignment Complete (AoIP)\n");
375 msg = gsm0808_create_ass_compl(0x23, 0x42, 0x11, 0x22,
376 &ss, &sc, &sc_list);
377 VERIFY(msg, res, ARRAY_SIZE(res));
378 msgb_free(msg);
379}
380
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100381static void test_create_ass_fail()
382{
383 static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 };
384 static const uint8_t res2[] = {
385 0x00, 0x06, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02};
386 uint8_t rr_res = 2;
387 struct msgb *msg;
388
389 printf("Testing creating Assignment Failure\n");
390 msg = gsm0808_create_assignment_failure(0x23, NULL);
391 VERIFY(msg, res1, ARRAY_SIZE(res1));
392 msgb_free(msg);
393
394 msg = gsm0808_create_assignment_failure(0x23, &rr_res);
395 VERIFY(msg, res2, ARRAY_SIZE(res2));
396 msgb_free(msg);
397}
398
Philipp Maierfa896ab2017-03-27 16:55:32 +0200399static void test_create_ass_fail_aoip()
400{
401 static const uint8_t res1[] =
402 { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST,
403 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, 0x9f, 0xf2 };
404 static const uint8_t res2[] =
405 { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02,
406 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab,
407 0xcd, 0xef, 0xa5, 0x9f, 0xf2 };
408 uint8_t rr_res = 2;
409 struct msgb *msg;
410 struct gsm0808_speech_codec_list sc_list;
411
412 setup_codec_list(&sc_list);
413
414 printf("Testing creating Assignment Failure (AoIP)\n");
415 msg = gsm0808_create_ass_fail(0x23, NULL, &sc_list);
416 VERIFY(msg, res1, ARRAY_SIZE(res1));
417 msgb_free(msg);
418
419 msg = gsm0808_create_ass_fail(0x23, &rr_res, &sc_list);
420 VERIFY(msg, res2, ARRAY_SIZE(res2));
421 msgb_free(msg);
422}
423
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100424static void test_create_clear_rqst()
425{
426 static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 };
427 struct msgb *msg;
428
429 printf("Testing creating Clear Request\n");
430 msg = gsm0808_create_clear_rqst(0x23);
431 VERIFY(msg, res, ARRAY_SIZE(res));
432 msgb_free(msg);
433}
434
Philipp Maier3d48ec02017-03-29 17:37:55 +0200435static void test_create_paging()
436{
437 static const uint8_t res[] =
438 { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
439 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 };
440 static const uint8_t res2[] =
441 { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
442 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
443 0x03, 0x05, 0x23, 0x42 };
444 static const uint8_t res3[] =
445 { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
446 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
447 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED,
448 RSL_CHANNEED_TCH_ForH };
449
450 struct msgb *msg;
451 struct gsm0808_cell_id_list cil;
452 uint32_t tmsi = 0x12345678;
453 uint8_t chan_needed = RSL_CHANNEED_TCH_ForH;
454
455 char imsi[] = "001010000001234";
456
457 cil.id_discr = CELL_IDENT_LAC;
458 cil.id_list_lac[0] = 0x2342;
459 cil.id_list_len = 1;
460
461 printf("Testing creating Paging Request\n");
462 msg = gsm0808_create_paging(imsi, NULL, &cil, NULL);
463 VERIFY(msg, res, ARRAY_SIZE(res));
464 msgb_free(msg);
465
466 msg = gsm0808_create_paging(imsi, &tmsi, &cil, NULL);
467 VERIFY(msg, res2, ARRAY_SIZE(res2));
468 msgb_free(msg);
469
470 msg = gsm0808_create_paging(imsi, &tmsi, &cil, &chan_needed);
471 VERIFY(msg, res3, ARRAY_SIZE(res3));
472 msgb_free(msg);
473}
474
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100475static void test_create_dtap()
476{
477 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
478 struct msgb *msg, *l3;
479
480 printf("Testing creating DTAP\n");
481 l3 = msgb_alloc_headroom(512, 128, "test");
482 l3->l3h = l3->data;
483 msgb_v_put(l3, 0x23);
484 msgb_v_put(l3, 0x42);
485
486 msg = gsm0808_create_dtap(l3, 0x3);
487 VERIFY(msg, res, ARRAY_SIZE(res));
488 msgb_free(msg);
489 msgb_free(l3);
490}
491
492static void test_prepend_dtap()
493{
494 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
495 struct msgb *in_msg;
496
497 printf("Testing prepend DTAP\n");
498
499 in_msg = msgb_alloc_headroom(512, 128, "test");
500 msgb_v_put(in_msg, 0x23);
501 msgb_v_put(in_msg, 0x42);
502
503 gsm0808_prepend_dtap_header(in_msg, 0x3);
504 in_msg->l3h = in_msg->data;
505 VERIFY(in_msg, res, ARRAY_SIZE(res));
506 msgb_free(in_msg);
507}
508
Philipp Maier22401432017-03-24 17:59:26 +0100509static void test_enc_dec_aoip_trasp_addr_v4()
510{
511 struct sockaddr_storage enc_addr;
512 struct sockaddr_storage dec_addr;
513 struct sockaddr_in enc_addr_in;
514 struct msgb *msg;
515 uint8_t rc_enc;
516 int rc_dec;
517
518 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
519 enc_addr_in.sin_family = AF_INET;
520 enc_addr_in.sin_port = htons(1234);
521 inet_aton("255.0.255.255", &enc_addr_in.sin_addr);
522
523 memset(&enc_addr, 0, sizeof(enc_addr));
524 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
525
526 msg = msgb_alloc(1024, "output buffer");
527 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
528 OSMO_ASSERT(rc_enc == 8);
529 rc_dec =
530 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
531 OSMO_ASSERT(rc_dec == 6);
532 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
533
534 msgb_free(msg);
535}
536
537static void test_enc_dec_aoip_trasp_addr_v6()
538{
539 struct sockaddr_storage enc_addr;
540 struct sockaddr_storage dec_addr;
541 struct sockaddr_in6 enc_addr_in;
542 struct msgb *msg;
543 uint8_t rc_enc;
544 int rc_dec;
545
546 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
547 enc_addr_in.sin6_family = AF_INET6;
548 enc_addr_in.sin6_port = htons(4567);
549 inet_pton(AF_INET6, "2001:0db8:85a3:08d3:1319:8a2e:0370:7344",
550 &enc_addr_in.sin6_addr);
551
552 memset(&enc_addr, 0, sizeof(enc_addr));
553 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
554
555 msg = msgb_alloc(1024, "output buffer");
556 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
557 OSMO_ASSERT(rc_enc == 20);
558 rc_dec =
559 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
560 OSMO_ASSERT(rc_dec == 18);
561 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
562
563 msgb_free(msg);
564}
565
Philipp Maier6f725d62017-03-24 18:03:17 +0100566static void test_gsm0808_enc_dec_speech_codec()
567{
568 struct gsm0808_speech_codec enc_sc;
569 struct gsm0808_speech_codec dec_sc;
570 struct msgb *msg;
571 uint8_t rc_enc;
572 int rc_dec;
573
574 memset(&enc_sc, 0, sizeof(enc_sc));
575 enc_sc.fi = true;
576 enc_sc.pt = true;
577 enc_sc.type = 0x05;
578
579 msg = msgb_alloc(1024, "output buffer");
580 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
581 OSMO_ASSERT(rc_enc == 3);
582
583 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
584 OSMO_ASSERT(rc_dec == 1);
585
586 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
587
588 msgb_free(msg);
589}
590
591
592static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg()
593{
594 struct gsm0808_speech_codec enc_sc;
595 struct gsm0808_speech_codec dec_sc;
596 struct msgb *msg;
597 uint8_t rc_enc;
598 int rc_dec;
599
600 enc_sc.pi = true;
601 enc_sc.tf = true;
602 enc_sc.type = 0xab;
603 enc_sc.type_extended = true;
604 enc_sc.cfg_present = true;
605 enc_sc.cfg = 0xcdef;
606
607 msg = msgb_alloc(1024, "output buffer");
608 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
609 OSMO_ASSERT(rc_enc == 6);
610
611 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
612 OSMO_ASSERT(rc_dec == 4);
613
614 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
615
616 msgb_free(msg);
617}
618
619static void test_gsm0808_enc_dec_speech_codec_ext()
620{
621 struct gsm0808_speech_codec enc_sc;
622 struct gsm0808_speech_codec dec_sc;
623 struct msgb *msg;
624 uint8_t rc_enc;
625 int rc_dec;
626
627 enc_sc.fi = true;
628 enc_sc.tf = true;
629 enc_sc.type = 0xf2;
630 enc_sc.type_extended = true;
631 enc_sc.cfg_present = false;
632 enc_sc.cfg = 0x0000;
633
634 msg = msgb_alloc(1024, "output buffer");
635 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
636 OSMO_ASSERT(rc_enc == 4);
637
638 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
639 OSMO_ASSERT(rc_dec == 2);
640
641 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
642
643 msgb_free(msg);
644}
645
646static void test_gsm0808_enc_dec_speech_codec_list()
647{
648 struct gsm0808_speech_codec_list enc_scl;
649 struct gsm0808_speech_codec_list dec_scl;
650 struct msgb *msg;
651 uint8_t rc_enc;
652 int rc_dec;
653
654 memset(&enc_scl, 0, sizeof(enc_scl));
655
656 enc_scl.codec[0].pi = true;
657 enc_scl.codec[0].tf = true;
658 enc_scl.codec[0].type = 0xab;
659 enc_scl.codec[0].type_extended = true;
660 enc_scl.codec[0].cfg_present = true;
661 enc_scl.codec[0].cfg = 0xcdef;
662
663 enc_scl.codec[1].fi = true;
664 enc_scl.codec[1].pt = true;
665 enc_scl.codec[1].type = 0x05;
666
667 enc_scl.codec[2].fi = true;
668 enc_scl.codec[2].tf = true;
669 enc_scl.codec[2].type = 0xf2;
670 enc_scl.codec[2].type_extended = true;
671
672 enc_scl.len = 3;
673
674 msg = msgb_alloc(1024, "output buffer");
675 rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
676 OSMO_ASSERT(rc_enc == 9);
677
678 rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
679 OSMO_ASSERT(rc_dec == 7);
680
681 OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0);
682
683 msgb_free(msg);
684}
685
Philipp Maiere0c65302017-03-28 17:05:40 +0200686static void test_gsm0808_enc_dec_channel_type()
687{
688 struct gsm0808_channel_type enc_ct;
689 struct gsm0808_channel_type dec_ct;
690 struct msgb *msg;
691 uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE,
692 0x04, 0x01, 0x0b, 0xa1, 0x25
693 };
694 uint8_t rc_enc;
695 int rc_dec;
696
697 memset(&enc_ct, 0, sizeof(enc_ct));
698 enc_ct.ch_indctr = GSM0808_CHAN_SPEECH;
699 enc_ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF;
700 enc_ct.perm_spch[0] = GSM0808_PERM_FR3;
701 enc_ct.perm_spch[1] = GSM0808_PERM_HR3;
702 enc_ct.perm_spch_len = 2;
703
704 msg = msgb_alloc(1024, "output buffer");
705 rc_enc = gsm0808_enc_channel_type(msg, &enc_ct);
706 OSMO_ASSERT(rc_enc == 6);
707 OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0);
708
709 rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2);
710 OSMO_ASSERT(rc_dec == 4);
711 OSMO_ASSERT(memcmp(&enc_ct, &dec_ct, sizeof(enc_ct)) == 0);
712
713 msgb_free(msg);
714}
715
Philipp Maier14e76b92017-03-28 18:36:52 +0200716static void test_gsm0808_enc_dec_encrypt_info()
717{
718 struct gsm0808_encrypt_info enc_ei;
719 struct gsm0808_encrypt_info dec_ei;
720 struct msgb *msg;
721 uint8_t ei_enc_expected[] =
722 { GSM0808_IE_ENCRYPTION_INFORMATION, 0x09, 0x03, 0xaa, 0xbb,
723 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42
724 };
725 uint8_t rc_enc;
726 int rc_dec;
727
728 memset(&enc_ei, 0, sizeof(enc_ei));
729 enc_ei.perm_algo[0] = GSM0808_ALG_ID_A5_0;
730 enc_ei.perm_algo[1] = GSM0808_ALG_ID_A5_1;
731 enc_ei.perm_algo_len = 2;
732 enc_ei.key[0] = 0xaa;
733 enc_ei.key[1] = 0xbb;
734 enc_ei.key[2] = 0xcc;
735 enc_ei.key[3] = 0xdd;
736 enc_ei.key[4] = 0xee;
737 enc_ei.key[5] = 0xff;
738 enc_ei.key[6] = 0x23;
739 enc_ei.key[7] = 0x42;
740 enc_ei.key_len = 8;
741
742 msg = msgb_alloc(1024, "output buffer");
743 rc_enc = gsm0808_enc_encrypt_info(msg, &enc_ei);
744 OSMO_ASSERT(rc_enc == 11);
745 OSMO_ASSERT(memcmp(ei_enc_expected, msg->data, msg->len) == 0);
746
747 rc_dec = gsm0808_dec_encrypt_info(&dec_ei, msg->data + 2, msg->len - 2);
748 OSMO_ASSERT(rc_dec == 9);
749
750 OSMO_ASSERT(memcmp(&enc_ei, &dec_ei, sizeof(enc_ei)) == 0);
751
752 msgb_free(msg);
753}
754
Philipp Maier783047e2017-03-29 11:35:50 +0200755static void test_gsm0808_enc_dec_cell_id_list_lac()
756{
757 struct gsm0808_cell_id_list enc_cil;
758 struct gsm0808_cell_id_list dec_cil;
759 struct msgb *msg;
760 uint8_t rc_enc;
761 int rc_dec;
762
763 memset(&enc_cil, 0, sizeof(enc_cil));
764 enc_cil.id_discr = CELL_IDENT_LAC;
765 enc_cil.id_list_lac[0] = 0x0124;
766 enc_cil.id_list_lac[1] = 0xABCD;
767 enc_cil.id_list_lac[2] = 0x5678;
768 enc_cil.id_list_len = 3;
769
770 msg = msgb_alloc(1024, "output buffer");
771 rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil);
772 OSMO_ASSERT(rc_enc == 9);
773
774 rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2,
775 msg->len - 2);
776 OSMO_ASSERT(rc_dec == 7);
777
778 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
779
780 msgb_free(msg);
781}
782
783static void test_gsm0808_enc_dec_cell_id_list_single_lac()
784{
785 struct gsm0808_cell_id_list enc_cil;
786 struct gsm0808_cell_id_list dec_cil;
787 struct msgb *msg;
788 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x03,
789 0x05, 0x23, 0x42
790 };
791 uint8_t rc_enc;
792 int rc_dec;
793
794 memset(&enc_cil, 0, sizeof(enc_cil));
795 enc_cil.id_discr = CELL_IDENT_LAC;
796 enc_cil.id_list_lac[0] = 0x2342;
797 enc_cil.id_list_len = 1;
798
799 msg = msgb_alloc(1024, "output buffer");
800 rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil);
801 OSMO_ASSERT(rc_enc == 5);
802 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
803
804 rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2,
805 msg->len - 2);
806 OSMO_ASSERT(rc_dec == 3);
807
808 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
809
810 msgb_free(msg);
811}
812
813static void test_gsm0808_enc_dec_cell_id_list_bss()
814{
815 struct gsm0808_cell_id_list enc_cil;
816 struct gsm0808_cell_id_list dec_cil;
817 struct msgb *msg;
818 uint8_t rc_enc;
819 int rc_dec;
820
821 memset(&enc_cil, 0, sizeof(enc_cil));
822 enc_cil.id_discr = CELL_IDENT_LAC;
823
824 msg = msgb_alloc(1024, "output buffer");
825 rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil);
826 OSMO_ASSERT(rc_enc == 3);
827
828 rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2,
829 msg->len - 2);
830 OSMO_ASSERT(rc_dec == 1);
831
832 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
833
834 msgb_free(msg);
835}
836
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100837int main(int argc, char **argv)
838{
839 printf("Testing generation of GSM0808 messages\n");
840 test_create_layer3();
Philipp Maierfa896ab2017-03-27 16:55:32 +0200841 test_create_layer3_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100842 test_create_reset();
Philipp Maier15596e22017-04-05 17:55:27 +0200843 test_create_reset_ack();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100844 test_create_clear_command();
845 test_create_clear_complete();
Philipp Maierb478dd32017-03-29 15:50:05 +0200846 test_create_cipher();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100847 test_create_cipher_complete();
848 test_create_cipher_reject();
849 test_create_cm_u();
850 test_create_sapi_reject();
Philipp Maierc6144a22017-03-29 17:53:43 +0200851 test_create_ass();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100852 test_create_ass_compl();
Philipp Maierfa896ab2017-03-27 16:55:32 +0200853 test_create_ass_compl_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100854 test_create_ass_fail();
Philipp Maierfa896ab2017-03-27 16:55:32 +0200855 test_create_ass_fail_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100856 test_create_clear_rqst();
Philipp Maier3d48ec02017-03-29 17:37:55 +0200857 test_create_paging();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100858 test_create_dtap();
859 test_prepend_dtap();
Philipp Maier22401432017-03-24 17:59:26 +0100860 test_enc_dec_aoip_trasp_addr_v4();
861 test_enc_dec_aoip_trasp_addr_v6();
Philipp Maier6f725d62017-03-24 18:03:17 +0100862 test_gsm0808_enc_dec_speech_codec();
863 test_gsm0808_enc_dec_speech_codec_ext();
864 test_gsm0808_enc_dec_speech_codec_ext_with_cfg();
865 test_gsm0808_enc_dec_speech_codec_list();
Philipp Maiere0c65302017-03-28 17:05:40 +0200866 test_gsm0808_enc_dec_channel_type();
Philipp Maier14e76b92017-03-28 18:36:52 +0200867 test_gsm0808_enc_dec_encrypt_info();
Philipp Maier783047e2017-03-29 11:35:50 +0200868 test_gsm0808_enc_dec_cell_id_list_lac();
869 test_gsm0808_enc_dec_cell_id_list_single_lac();
870 test_gsm0808_enc_dec_cell_id_list_bss();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100871
872 printf("Done\n");
873 return EXIT_SUCCESS;
874}