blob: a0ff6d52a320ba0132d18cea072432109af33828 [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
126static void test_create_clear_command()
127{
128 static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 };
129 struct msgb *msg;
130
131 printf("Testing creating Clear Command\n");
132 msg = gsm0808_create_clear_command(0x23);
133 VERIFY(msg, res, ARRAY_SIZE(res));
134 msgb_free(msg);
135}
136
137static void test_create_clear_complete()
138{
139 static const uint8_t res[] = { 0x00, 0x01, 0x21 };
140 struct msgb *msg;
141
142 printf("Testing creating Clear Complete\n");
143 msg = gsm0808_create_clear_complete();
144 VERIFY(msg, res, ARRAY_SIZE(res));
145 msgb_free(msg);
146}
147
Philipp Maierb478dd32017-03-29 15:50:05 +0200148static void test_create_cipher()
149{
150 static const uint8_t res[] =
151 { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa,
152 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 };
153 static const uint8_t res2[] =
154 { 0x00, 0x0e, 0x53, 0x0a, 0x09, 0x03, 0xaa,
155 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42,
156 GSM0808_IE_CIPHER_RESPONSE_MODE, 0x01 };
157 struct msgb *msg;
158 struct gsm0808_encrypt_info ei;
159 uint8_t include_imeisv;
160
161 memset(&ei, 0, sizeof(ei));
162 ei.perm_algo[0] = GSM0808_ALG_ID_A5_0;
163 ei.perm_algo[1] = GSM0808_ALG_ID_A5_1;
164 ei.perm_algo_len = 2;
165 ei.key[0] = 0xaa;
166 ei.key[1] = 0xbb;
167 ei.key[2] = 0xcc;
168 ei.key[3] = 0xdd;
169 ei.key[4] = 0xee;
170 ei.key[5] = 0xff;
171 ei.key[6] = 0x23;
172 ei.key[7] = 0x42;
173 ei.key_len = 8;
174 include_imeisv = 1;
175
176 printf("Testing creating Chipher Mode Command\n");
177 msg = gsm0808_create_cipher(&ei, NULL);
178 OSMO_ASSERT(msg);
179 VERIFY(msg, res, ARRAY_SIZE(res));
180 msgb_free(msg);
181
182 msg = gsm0808_create_cipher(&ei, &include_imeisv);
183 OSMO_ASSERT(msg);
184 VERIFY(msg, res2, ARRAY_SIZE(res2));
185 msgb_free(msg);
186}
187
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100188static void test_create_cipher_complete()
189{
190 static const uint8_t res1[] = {
191 0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 };
192 static const uint8_t res2[] = { 0x00, 0x03, 0x55, 0x2c, 0x04};
193 struct msgb *l3, *msg;
194
195 printf("Testing creating Cipher Complete\n");
196 l3 = msgb_alloc_headroom(512, 128, "l3h");
197 l3->l3h = l3->data;
198 msgb_v_put(l3, 0x23);
199 msgb_v_put(l3, 0x42);
200 msgb_v_put(l3, 0x21);
201
202 /* with l3 data */
203 msg = gsm0808_create_cipher_complete(l3, 4);
204 VERIFY(msg, res1, ARRAY_SIZE(res1));
205 msgb_free(msg);
206
207 /* with l3 data but short */
208 l3->len -= 1;
209 l3->tail -= 1;
210 msg = gsm0808_create_cipher_complete(l3, 4);
211 VERIFY(msg, res2, ARRAY_SIZE(res2));
212 msgb_free(msg);
213
214 /* without l3 data */
215 msg = gsm0808_create_cipher_complete(NULL, 4);
216 VERIFY(msg, res2, ARRAY_SIZE(res2));
217 msgb_free(msg);
218
219
220 msgb_free(l3);
221}
222
223static void test_create_cipher_reject()
224{
225 static const uint8_t res[] = { 0x00, 0x02, 0x59, 0x23 };
226 struct msgb *msg;
227
228 printf("Testing creating Cipher Reject\n");
229 msg = gsm0808_create_cipher_reject(0x23);
230 VERIFY(msg, res, ARRAY_SIZE(res));
231 msgb_free(msg);
232}
233
234static void test_create_cm_u()
235{
Harald Welte07b625d2012-01-23 10:02:58 +0100236 static const uint8_t res[] = {
237 0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 };
238 static const uint8_t res2o[] = {
239 0x00, 0x04, 0x54, 0x12, 0x01, 0x23 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100240 struct msgb *msg;
Harald Welte07b625d2012-01-23 10:02:58 +0100241 const uint8_t cm2 = 0x23;
242 const uint8_t cm3 = 0x42;
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100243
244 printf("Testing creating CM U\n");
Harald Welte07b625d2012-01-23 10:02:58 +0100245 msg = gsm0808_create_classmark_update(&cm2, 1, &cm3, 1);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100246 VERIFY(msg, res, ARRAY_SIZE(res));
Harald Welte07b625d2012-01-23 10:02:58 +0100247
248 msg = gsm0808_create_classmark_update(&cm2, 1, NULL, 0);
249 VERIFY(msg, res2o, ARRAY_SIZE(res2o));
250
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100251 msgb_free(msg);
252}
253
254static void test_create_sapi_reject()
255{
256 static const uint8_t res[] = { 0x00, 0x03, 0x25, 0x03, 0x25 };
257 struct msgb *msg;
258
259 printf("Testing creating SAPI Reject\n");
260 msg = gsm0808_create_sapi_reject(3);
261 VERIFY(msg, res, ARRAY_SIZE(res));
262 msgb_free(msg);
263}
264
Philipp Maierc6144a22017-03-29 17:53:43 +0200265static void test_create_ass()
266{
267 static const uint8_t res1[] =
268 { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
269 0x04 };
270 static const uint8_t res2[] =
271 { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
272 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17,
273 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd,
274 0xef, 0xa5, 0x9f, 0xf2, GSM0808_IE_CALL_ID, 0xaa, 0xbb, 0xcc,
275 0xdd };
276
277 struct msgb *msg;
278 struct gsm0808_channel_type ct;
279 uint16_t cic = 0004;
280 struct sockaddr_storage ss;
281 struct sockaddr_in sin;
282 struct gsm0808_speech_codec_list sc_list;
283 uint32_t call_id = 0xAABBCCDD;
284
285 memset(&ct, 0, sizeof(ct));
286 ct.ch_indctr = GSM0808_CHAN_SPEECH;
287 ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF;
288 ct.perm_spch[0] = GSM0808_PERM_FR3;
289 ct.perm_spch[1] = GSM0808_PERM_HR3;
290 ct.perm_spch_len = 2;
291
292 memset(&sin, 0, sizeof(sin));
293 sin.sin_family = AF_INET;
294 sin.sin_port = htons(1234);
295 inet_aton("192.168.100.23", &sin.sin_addr);
296
297 memset(&ss, 0, sizeof(ss));
298 memcpy(&ss, &sin, sizeof(sin));
299
300 setup_codec_list(&sc_list);
301
302 printf("Testing creating Assignment Request\n");
303 msg = gsm0808_create_ass(&ct, &cic, NULL, NULL, NULL);
304 OSMO_ASSERT(msg);
305 VERIFY(msg, res1, ARRAY_SIZE(res1));
306 msgb_free(msg);
307
308 msg = gsm0808_create_ass(&ct, &cic, &ss, &sc_list, &call_id);
309 OSMO_ASSERT(msg);
310 VERIFY(msg, res2, ARRAY_SIZE(res2));
311 msgb_free(msg);
312}
313
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100314static void test_create_ass_compl()
315{
316 static const uint8_t res1[] = {
317 0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c,
318 0x11, 0x40, 0x22 };
319 static const uint8_t res2[] = {
320 0x00, 0x07, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11};
321 struct msgb *msg;
322
323 printf("Testing creating Assignment Complete\n");
324 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0x22);
325 VERIFY(msg, res1, ARRAY_SIZE(res1));
326 msgb_free(msg);
327
328 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0);
329 VERIFY(msg, res2, ARRAY_SIZE(res2));
330 msgb_free(msg);
331}
332
Philipp Maierfa896ab2017-03-27 16:55:32 +0200333static void test_create_ass_compl_aoip()
334{
335 struct sockaddr_storage ss;
336 struct sockaddr_in sin;
337 struct gsm0808_speech_codec sc;
338 struct gsm0808_speech_codec_list sc_list;
339 static const uint8_t res[] =
340 { 0x00, 0x1d, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22,
341 GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04,
342 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, 0x9a,
343 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5,
344 0x9f, 0xf2 };
345 struct msgb *msg;
346
347 memset(&sin, 0, sizeof(sin));
348 sin.sin_family = AF_INET;
349 sin.sin_port = htons(1234);
350 inet_aton("192.168.100.23", &sin.sin_addr);
351
352 memset(&ss, 0, sizeof(ss));
353 memcpy(&ss, &sin, sizeof(sin));
354
355 memset(&sc, 0, sizeof(sc));
356 sc.fi = true;
357 sc.tf = true;
358 sc.type = 0x0a;
359
360 setup_codec_list(&sc_list);
361
362 printf("Testing creating Assignment Complete (AoIP)\n");
363 msg = gsm0808_create_ass_compl(0x23, 0x42, 0x11, 0x22,
364 &ss, &sc, &sc_list);
365 VERIFY(msg, res, ARRAY_SIZE(res));
366 msgb_free(msg);
367}
368
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100369static void test_create_ass_fail()
370{
371 static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 };
372 static const uint8_t res2[] = {
373 0x00, 0x06, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02};
374 uint8_t rr_res = 2;
375 struct msgb *msg;
376
377 printf("Testing creating Assignment Failure\n");
378 msg = gsm0808_create_assignment_failure(0x23, NULL);
379 VERIFY(msg, res1, ARRAY_SIZE(res1));
380 msgb_free(msg);
381
382 msg = gsm0808_create_assignment_failure(0x23, &rr_res);
383 VERIFY(msg, res2, ARRAY_SIZE(res2));
384 msgb_free(msg);
385}
386
Philipp Maierfa896ab2017-03-27 16:55:32 +0200387static void test_create_ass_fail_aoip()
388{
389 static const uint8_t res1[] =
390 { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST,
391 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, 0x9f, 0xf2 };
392 static const uint8_t res2[] =
393 { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02,
394 GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab,
395 0xcd, 0xef, 0xa5, 0x9f, 0xf2 };
396 uint8_t rr_res = 2;
397 struct msgb *msg;
398 struct gsm0808_speech_codec_list sc_list;
399
400 setup_codec_list(&sc_list);
401
402 printf("Testing creating Assignment Failure (AoIP)\n");
403 msg = gsm0808_create_ass_fail(0x23, NULL, &sc_list);
404 VERIFY(msg, res1, ARRAY_SIZE(res1));
405 msgb_free(msg);
406
407 msg = gsm0808_create_ass_fail(0x23, &rr_res, &sc_list);
408 VERIFY(msg, res2, ARRAY_SIZE(res2));
409 msgb_free(msg);
410}
411
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100412static void test_create_clear_rqst()
413{
414 static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 };
415 struct msgb *msg;
416
417 printf("Testing creating Clear Request\n");
418 msg = gsm0808_create_clear_rqst(0x23);
419 VERIFY(msg, res, ARRAY_SIZE(res));
420 msgb_free(msg);
421}
422
Philipp Maier3d48ec02017-03-29 17:37:55 +0200423static void test_create_paging()
424{
425 static const uint8_t res[] =
426 { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
427 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 };
428 static const uint8_t res2[] =
429 { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
430 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
431 0x03, 0x05, 0x23, 0x42 };
432 static const uint8_t res3[] =
433 { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
434 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a,
435 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED,
436 RSL_CHANNEED_TCH_ForH };
437
438 struct msgb *msg;
439 struct gsm0808_cell_id_list cil;
440 uint32_t tmsi = 0x12345678;
441 uint8_t chan_needed = RSL_CHANNEED_TCH_ForH;
442
443 char imsi[] = "001010000001234";
444
445 cil.id_discr = CELL_IDENT_LAC;
446 cil.id_list_lac[0] = 0x2342;
447 cil.id_list_len = 1;
448
449 printf("Testing creating Paging Request\n");
450 msg = gsm0808_create_paging(imsi, NULL, &cil, NULL);
451 VERIFY(msg, res, ARRAY_SIZE(res));
452 msgb_free(msg);
453
454 msg = gsm0808_create_paging(imsi, &tmsi, &cil, NULL);
455 VERIFY(msg, res2, ARRAY_SIZE(res2));
456 msgb_free(msg);
457
458 msg = gsm0808_create_paging(imsi, &tmsi, &cil, &chan_needed);
459 VERIFY(msg, res3, ARRAY_SIZE(res3));
460 msgb_free(msg);
461}
462
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100463static void test_create_dtap()
464{
465 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
466 struct msgb *msg, *l3;
467
468 printf("Testing creating DTAP\n");
469 l3 = msgb_alloc_headroom(512, 128, "test");
470 l3->l3h = l3->data;
471 msgb_v_put(l3, 0x23);
472 msgb_v_put(l3, 0x42);
473
474 msg = gsm0808_create_dtap(l3, 0x3);
475 VERIFY(msg, res, ARRAY_SIZE(res));
476 msgb_free(msg);
477 msgb_free(l3);
478}
479
480static void test_prepend_dtap()
481{
482 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
483 struct msgb *in_msg;
484
485 printf("Testing prepend DTAP\n");
486
487 in_msg = msgb_alloc_headroom(512, 128, "test");
488 msgb_v_put(in_msg, 0x23);
489 msgb_v_put(in_msg, 0x42);
490
491 gsm0808_prepend_dtap_header(in_msg, 0x3);
492 in_msg->l3h = in_msg->data;
493 VERIFY(in_msg, res, ARRAY_SIZE(res));
494 msgb_free(in_msg);
495}
496
Philipp Maier22401432017-03-24 17:59:26 +0100497static void test_enc_dec_aoip_trasp_addr_v4()
498{
499 struct sockaddr_storage enc_addr;
500 struct sockaddr_storage dec_addr;
501 struct sockaddr_in enc_addr_in;
502 struct msgb *msg;
503 uint8_t rc_enc;
504 int rc_dec;
505
506 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
507 enc_addr_in.sin_family = AF_INET;
508 enc_addr_in.sin_port = htons(1234);
509 inet_aton("255.0.255.255", &enc_addr_in.sin_addr);
510
511 memset(&enc_addr, 0, sizeof(enc_addr));
512 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
513
514 msg = msgb_alloc(1024, "output buffer");
515 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
516 OSMO_ASSERT(rc_enc == 8);
517 rc_dec =
518 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
519 OSMO_ASSERT(rc_dec == 6);
520 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
521
522 msgb_free(msg);
523}
524
525static void test_enc_dec_aoip_trasp_addr_v6()
526{
527 struct sockaddr_storage enc_addr;
528 struct sockaddr_storage dec_addr;
529 struct sockaddr_in6 enc_addr_in;
530 struct msgb *msg;
531 uint8_t rc_enc;
532 int rc_dec;
533
534 memset(&enc_addr_in, 0, sizeof(enc_addr_in));
535 enc_addr_in.sin6_family = AF_INET6;
536 enc_addr_in.sin6_port = htons(4567);
537 inet_pton(AF_INET6, "2001:0db8:85a3:08d3:1319:8a2e:0370:7344",
538 &enc_addr_in.sin6_addr);
539
540 memset(&enc_addr, 0, sizeof(enc_addr));
541 memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
542
543 msg = msgb_alloc(1024, "output buffer");
544 rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
545 OSMO_ASSERT(rc_enc == 20);
546 rc_dec =
547 gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2);
548 OSMO_ASSERT(rc_dec == 18);
549 OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0);
550
551 msgb_free(msg);
552}
553
Philipp Maier6f725d62017-03-24 18:03:17 +0100554static void test_gsm0808_enc_dec_speech_codec()
555{
556 struct gsm0808_speech_codec enc_sc;
557 struct gsm0808_speech_codec dec_sc;
558 struct msgb *msg;
559 uint8_t rc_enc;
560 int rc_dec;
561
562 memset(&enc_sc, 0, sizeof(enc_sc));
563 enc_sc.fi = true;
564 enc_sc.pt = true;
565 enc_sc.type = 0x05;
566
567 msg = msgb_alloc(1024, "output buffer");
568 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
569 OSMO_ASSERT(rc_enc == 3);
570
571 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
572 OSMO_ASSERT(rc_dec == 1);
573
574 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
575
576 msgb_free(msg);
577}
578
579
580static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg()
581{
582 struct gsm0808_speech_codec enc_sc;
583 struct gsm0808_speech_codec dec_sc;
584 struct msgb *msg;
585 uint8_t rc_enc;
586 int rc_dec;
587
588 enc_sc.pi = true;
589 enc_sc.tf = true;
590 enc_sc.type = 0xab;
591 enc_sc.type_extended = true;
592 enc_sc.cfg_present = true;
593 enc_sc.cfg = 0xcdef;
594
595 msg = msgb_alloc(1024, "output buffer");
596 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
597 OSMO_ASSERT(rc_enc == 6);
598
599 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
600 OSMO_ASSERT(rc_dec == 4);
601
602 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
603
604 msgb_free(msg);
605}
606
607static void test_gsm0808_enc_dec_speech_codec_ext()
608{
609 struct gsm0808_speech_codec enc_sc;
610 struct gsm0808_speech_codec dec_sc;
611 struct msgb *msg;
612 uint8_t rc_enc;
613 int rc_dec;
614
615 enc_sc.fi = true;
616 enc_sc.tf = true;
617 enc_sc.type = 0xf2;
618 enc_sc.type_extended = true;
619 enc_sc.cfg_present = false;
620 enc_sc.cfg = 0x0000;
621
622 msg = msgb_alloc(1024, "output buffer");
623 rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
624 OSMO_ASSERT(rc_enc == 4);
625
626 rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
627 OSMO_ASSERT(rc_dec == 2);
628
629 OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0);
630
631 msgb_free(msg);
632}
633
634static void test_gsm0808_enc_dec_speech_codec_list()
635{
636 struct gsm0808_speech_codec_list enc_scl;
637 struct gsm0808_speech_codec_list dec_scl;
638 struct msgb *msg;
639 uint8_t rc_enc;
640 int rc_dec;
641
642 memset(&enc_scl, 0, sizeof(enc_scl));
643
644 enc_scl.codec[0].pi = true;
645 enc_scl.codec[0].tf = true;
646 enc_scl.codec[0].type = 0xab;
647 enc_scl.codec[0].type_extended = true;
648 enc_scl.codec[0].cfg_present = true;
649 enc_scl.codec[0].cfg = 0xcdef;
650
651 enc_scl.codec[1].fi = true;
652 enc_scl.codec[1].pt = true;
653 enc_scl.codec[1].type = 0x05;
654
655 enc_scl.codec[2].fi = true;
656 enc_scl.codec[2].tf = true;
657 enc_scl.codec[2].type = 0xf2;
658 enc_scl.codec[2].type_extended = true;
659
660 enc_scl.len = 3;
661
662 msg = msgb_alloc(1024, "output buffer");
663 rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
664 OSMO_ASSERT(rc_enc == 9);
665
666 rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
667 OSMO_ASSERT(rc_dec == 7);
668
669 OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0);
670
671 msgb_free(msg);
672}
673
Philipp Maiere0c65302017-03-28 17:05:40 +0200674static void test_gsm0808_enc_dec_channel_type()
675{
676 struct gsm0808_channel_type enc_ct;
677 struct gsm0808_channel_type dec_ct;
678 struct msgb *msg;
679 uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE,
680 0x04, 0x01, 0x0b, 0xa1, 0x25
681 };
682 uint8_t rc_enc;
683 int rc_dec;
684
685 memset(&enc_ct, 0, sizeof(enc_ct));
686 enc_ct.ch_indctr = GSM0808_CHAN_SPEECH;
687 enc_ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF;
688 enc_ct.perm_spch[0] = GSM0808_PERM_FR3;
689 enc_ct.perm_spch[1] = GSM0808_PERM_HR3;
690 enc_ct.perm_spch_len = 2;
691
692 msg = msgb_alloc(1024, "output buffer");
693 rc_enc = gsm0808_enc_channel_type(msg, &enc_ct);
694 OSMO_ASSERT(rc_enc == 6);
695 OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0);
696
697 rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2);
698 OSMO_ASSERT(rc_dec == 4);
699 OSMO_ASSERT(memcmp(&enc_ct, &dec_ct, sizeof(enc_ct)) == 0);
700
701 msgb_free(msg);
702}
703
Philipp Maier14e76b92017-03-28 18:36:52 +0200704static void test_gsm0808_enc_dec_encrypt_info()
705{
706 struct gsm0808_encrypt_info enc_ei;
707 struct gsm0808_encrypt_info dec_ei;
708 struct msgb *msg;
709 uint8_t ei_enc_expected[] =
710 { GSM0808_IE_ENCRYPTION_INFORMATION, 0x09, 0x03, 0xaa, 0xbb,
711 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42
712 };
713 uint8_t rc_enc;
714 int rc_dec;
715
716 memset(&enc_ei, 0, sizeof(enc_ei));
717 enc_ei.perm_algo[0] = GSM0808_ALG_ID_A5_0;
718 enc_ei.perm_algo[1] = GSM0808_ALG_ID_A5_1;
719 enc_ei.perm_algo_len = 2;
720 enc_ei.key[0] = 0xaa;
721 enc_ei.key[1] = 0xbb;
722 enc_ei.key[2] = 0xcc;
723 enc_ei.key[3] = 0xdd;
724 enc_ei.key[4] = 0xee;
725 enc_ei.key[5] = 0xff;
726 enc_ei.key[6] = 0x23;
727 enc_ei.key[7] = 0x42;
728 enc_ei.key_len = 8;
729
730 msg = msgb_alloc(1024, "output buffer");
731 rc_enc = gsm0808_enc_encrypt_info(msg, &enc_ei);
732 OSMO_ASSERT(rc_enc == 11);
733 OSMO_ASSERT(memcmp(ei_enc_expected, msg->data, msg->len) == 0);
734
735 rc_dec = gsm0808_dec_encrypt_info(&dec_ei, msg->data + 2, msg->len - 2);
736 OSMO_ASSERT(rc_dec == 9);
737
738 OSMO_ASSERT(memcmp(&enc_ei, &dec_ei, sizeof(enc_ei)) == 0);
739
740 msgb_free(msg);
741}
742
Philipp Maier783047e2017-03-29 11:35:50 +0200743static void test_gsm0808_enc_dec_cell_id_list_lac()
744{
745 struct gsm0808_cell_id_list enc_cil;
746 struct gsm0808_cell_id_list dec_cil;
747 struct msgb *msg;
748 uint8_t rc_enc;
749 int rc_dec;
750
751 memset(&enc_cil, 0, sizeof(enc_cil));
752 enc_cil.id_discr = CELL_IDENT_LAC;
753 enc_cil.id_list_lac[0] = 0x0124;
754 enc_cil.id_list_lac[1] = 0xABCD;
755 enc_cil.id_list_lac[2] = 0x5678;
756 enc_cil.id_list_len = 3;
757
758 msg = msgb_alloc(1024, "output buffer");
759 rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil);
760 OSMO_ASSERT(rc_enc == 9);
761
762 rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2,
763 msg->len - 2);
764 OSMO_ASSERT(rc_dec == 7);
765
766 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
767
768 msgb_free(msg);
769}
770
771static void test_gsm0808_enc_dec_cell_id_list_single_lac()
772{
773 struct gsm0808_cell_id_list enc_cil;
774 struct gsm0808_cell_id_list dec_cil;
775 struct msgb *msg;
776 uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x03,
777 0x05, 0x23, 0x42
778 };
779 uint8_t rc_enc;
780 int rc_dec;
781
782 memset(&enc_cil, 0, sizeof(enc_cil));
783 enc_cil.id_discr = CELL_IDENT_LAC;
784 enc_cil.id_list_lac[0] = 0x2342;
785 enc_cil.id_list_len = 1;
786
787 msg = msgb_alloc(1024, "output buffer");
788 rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil);
789 OSMO_ASSERT(rc_enc == 5);
790 OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0);
791
792 rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2,
793 msg->len - 2);
794 OSMO_ASSERT(rc_dec == 3);
795
796 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
797
798 msgb_free(msg);
799}
800
801static void test_gsm0808_enc_dec_cell_id_list_bss()
802{
803 struct gsm0808_cell_id_list enc_cil;
804 struct gsm0808_cell_id_list dec_cil;
805 struct msgb *msg;
806 uint8_t rc_enc;
807 int rc_dec;
808
809 memset(&enc_cil, 0, sizeof(enc_cil));
810 enc_cil.id_discr = CELL_IDENT_LAC;
811
812 msg = msgb_alloc(1024, "output buffer");
813 rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil);
814 OSMO_ASSERT(rc_enc == 3);
815
816 rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2,
817 msg->len - 2);
818 OSMO_ASSERT(rc_dec == 1);
819
820 OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0);
821
822 msgb_free(msg);
823}
824
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100825int main(int argc, char **argv)
826{
827 printf("Testing generation of GSM0808 messages\n");
828 test_create_layer3();
Philipp Maierfa896ab2017-03-27 16:55:32 +0200829 test_create_layer3_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100830 test_create_reset();
831 test_create_clear_command();
832 test_create_clear_complete();
Philipp Maierb478dd32017-03-29 15:50:05 +0200833 test_create_cipher();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100834 test_create_cipher_complete();
835 test_create_cipher_reject();
836 test_create_cm_u();
837 test_create_sapi_reject();
Philipp Maierc6144a22017-03-29 17:53:43 +0200838 test_create_ass();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100839 test_create_ass_compl();
Philipp Maierfa896ab2017-03-27 16:55:32 +0200840 test_create_ass_compl_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100841 test_create_ass_fail();
Philipp Maierfa896ab2017-03-27 16:55:32 +0200842 test_create_ass_fail_aoip();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100843 test_create_clear_rqst();
Philipp Maier3d48ec02017-03-29 17:37:55 +0200844 test_create_paging();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100845 test_create_dtap();
846 test_prepend_dtap();
Philipp Maier22401432017-03-24 17:59:26 +0100847 test_enc_dec_aoip_trasp_addr_v4();
848 test_enc_dec_aoip_trasp_addr_v6();
Philipp Maier6f725d62017-03-24 18:03:17 +0100849 test_gsm0808_enc_dec_speech_codec();
850 test_gsm0808_enc_dec_speech_codec_ext();
851 test_gsm0808_enc_dec_speech_codec_ext_with_cfg();
852 test_gsm0808_enc_dec_speech_codec_list();
Philipp Maiere0c65302017-03-28 17:05:40 +0200853 test_gsm0808_enc_dec_channel_type();
Philipp Maier14e76b92017-03-28 18:36:52 +0200854 test_gsm0808_enc_dec_encrypt_info();
Philipp Maier783047e2017-03-29 11:35:50 +0200855 test_gsm0808_enc_dec_cell_id_list_lac();
856 test_gsm0808_enc_dec_cell_id_list_single_lac();
857 test_gsm0808_enc_dec_cell_id_list_bss();
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100858
859 printf("Done\n");
860 return EXIT_SUCCESS;
861}