blob: 15248f219477ce3026446c88e721641f8e33d1b7 [file] [log] [blame]
Holger Freytheraa0fb362008-12-28 21:55:40 +00001/* simple test for the gsm0408 formatting functions */
2/*
3 * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01007 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
Holger Freytheraa0fb362008-12-28 21:55:40 +00009 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010016 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Holger Freytheraa0fb362008-12-28 21:55:40 +000018 *
19 */
20
21#include <assert.h>
22#include <stdio.h>
23#include <stdlib.h>
Max69e9c0d2016-05-18 13:04:47 +020024#include <stdbool.h>
Harald Welteafedeab2010-03-04 10:55:40 +010025#include <arpa/inet.h>
26
Holger Freytheraa0fb362008-12-28 21:55:40 +000027#include <openbsc/gsm_04_08.h>
Holger Hans Peter Freytherca114432014-02-08 15:20:48 +010028#include <openbsc/gsm_04_11.h>
Holger Hans Peter Freyther5d0e56f2009-08-20 08:41:24 +020029#include <openbsc/gsm_subscriber.h>
30#include <openbsc/debug.h>
Jacob Erlbeck4b903b42014-01-10 17:43:41 +010031#include <openbsc/arfcn_range_encode.h>
Max59a1bf32016-04-15 16:04:46 +020032#include <openbsc/system_information.h>
33#include <openbsc/abis_rsl.h>
34
Jacob Erlbeck4b903b42014-01-10 17:43:41 +010035#include <osmocom/core/application.h>
Max59a1bf32016-04-15 16:04:46 +020036#include <osmocom/gsm/sysinfo.h>
Holger Freytheraa0fb362008-12-28 21:55:40 +000037
38#define COMPARE(result, op, value) \
39 if (!((result) op (value))) {\
40 fprintf(stderr, "Compare failed. Was %x should be %x in %s:%d\n",result, value, __FILE__, __LINE__); \
41 exit(-1); \
42 }
Holger Hans Peter Freyther5d0e56f2009-08-20 08:41:24 +020043
44#define COMPARE_STR(result, value) \
45 if (strcmp(result, value) != 0) { \
46 fprintf(stderr, "Compare failed. Was %s should be %s in %s:%d\n",result, value, __FILE__, __LINE__); \
47 exit(-1); \
48 }
Holger Freytheraa0fb362008-12-28 21:55:40 +000049
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +010050#define DBG(...)
51
52#define VERIFY(res, cmp, wanted) \
53 if (!(res cmp wanted)) { \
54 printf("ASSERT failed: %s:%d Wanted: %d %s %d\n", \
Holger Hans Peter Freytherdaaea0c2015-08-03 09:28:41 +020055 __FILE__, __LINE__, (int) res, # cmp, (int) wanted); \
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +010056 }
57
58
59
Holger Freytheraa0fb362008-12-28 21:55:40 +000060/*
61 * Test Location Area Identifier formatting. Table 10.5.3 of 04.08
62 */
63static void test_location_area_identifier(void)
64{
65 struct gsm48_loc_area_id lai48;
66
67 printf("Testing test location area identifier\n");
68
69 /*
70 * Test the default/test setup. Coming from
71 * bsc_hack.c dumps
72 */
Harald Welteafedeab2010-03-04 10:55:40 +010073 gsm48_generate_lai(&lai48, 1, 1, 1);
Holger Freytheraa0fb362008-12-28 21:55:40 +000074 COMPARE(lai48.digits[0], ==, 0x00);
75 COMPARE(lai48.digits[1], ==, 0xF1);
76 COMPARE(lai48.digits[2], ==, 0x10);
77 COMPARE(lai48.lac, ==, htons(0x0001));
78
Harald Welteafedeab2010-03-04 10:55:40 +010079 gsm48_generate_lai(&lai48, 602, 1, 15);
Holger Freytheraa0fb362008-12-28 21:55:40 +000080 COMPARE(lai48.digits[0], ==, 0x06);
81 COMPARE(lai48.digits[1], ==, 0xF2);
82 COMPARE(lai48.digits[2], ==, 0x10);
83 COMPARE(lai48.lac, ==, htons(0x000f));
84}
85
Max59a1bf32016-04-15 16:04:46 +020086static inline void add_arfcn_b(struct osmo_earfcn_si2q *e, uint16_t earfcn,
87 uint8_t bw)
88{
89 int r = osmo_earfcn_add(e, earfcn, bw);
90 if (r)
91 printf("failed to add EARFCN %u: %s\n", earfcn, strerror(r));
92 else
93 printf("added EARFCN %u - ", earfcn);
94}
95
96static inline void gen(struct gsm_bts *bts)
97{
Max69e9c0d2016-05-18 13:04:47 +020098 bts->si_valid = 0;
99 bts->si_valid |= (1 << SYSINFO_TYPE_2quater);
100 /* should be no-op as entire buffer is filled with padding: */
101 memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN);
Max59a1bf32016-04-15 16:04:46 +0200102 int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater);
Max69e9c0d2016-05-18 13:04:47 +0200103 bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater);
Max59a1bf32016-04-15 16:04:46 +0200104 if (r > 0)
Max69e9c0d2016-05-18 13:04:47 +0200105 printf("generated %s SI2quater: [%d] %s\n",
106 v ? "valid" : "invalid", r,
Max59a1bf32016-04-15 16:04:46 +0200107 osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r));
108 else
109 printf("failed to generate SI2quater: %s\n", strerror(-r));
110}
111
Maxaafff962016-04-20 15:57:14 +0200112static inline void _bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn,
113 uint16_t scramble, bool diversity)
114{
115 int r = bts_uarfcn_add(bts, arfcn, scramble, diversity);
116 if (r < 0)
117 printf("failed to add UARFCN to SI2quater: %s\n", strerror(-r));
118 else
119 gen(bts);
120}
121
Max26679e02016-04-20 15:57:13 +0200122static inline void test_si2q_u(void)
Max59a1bf32016-04-15 16:04:46 +0200123{
124 struct gsm_bts *bts;
Neels Hofmeyr27681a32016-05-14 00:45:26 +0200125 struct gsm_network *network = bsc_network_init(tall_bsc_ctx, 1, 1, NULL);
Max26679e02016-04-20 15:57:13 +0200126 printf("Testing SYSINFO_TYPE_2quater UARFCN generation:\n");
127
128 if (!network)
129 exit(1);
130 bts = gsm_bts_alloc(network);
131
Max69e9c0d2016-05-18 13:04:47 +0200132 /* first generate invalid SI as no UARFCN added */
133 gen(bts);
134 /* subsequent calls should produce valid SI if there's enough memory */
Maxaafff962016-04-20 15:57:14 +0200135 _bts_uarfcn_add(bts, 1982, 13, 1);
136 _bts_uarfcn_add(bts, 1982, 44, 0);
137 _bts_uarfcn_add(bts, 1982, 61, 1);
138 _bts_uarfcn_add(bts, 1982, 89, 1);
139 _bts_uarfcn_add(bts, 1982, 113, 0);
140 _bts_uarfcn_add(bts, 1982, 123, 0);
141 _bts_uarfcn_add(bts, 1982, 56, 1);
142 _bts_uarfcn_add(bts, 1982, 72, 1);
143 _bts_uarfcn_add(bts, 1982, 223, 1);
144 _bts_uarfcn_add(bts, 1982, 14, 0);
145 _bts_uarfcn_add(bts, 1982, 88, 0);
Max26679e02016-04-20 15:57:13 +0200146 gen(bts);
147}
148
149static inline void test_si2q_e(void)
150{
151 struct gsm_bts *bts;
Neels Hofmeyr27681a32016-05-14 00:45:26 +0200152 struct gsm_network *network = bsc_network_init(tall_bsc_ctx, 1, 1, NULL);
Max26679e02016-04-20 15:57:13 +0200153 printf("Testing SYSINFO_TYPE_2quater EARFCN generation:\n");
Max59a1bf32016-04-15 16:04:46 +0200154
155 if (!network)
156 exit(1);
157 bts = gsm_bts_alloc(network);
158
159 bts->si_common.si2quater_neigh_list.arfcn =
160 bts->si_common.data.earfcn_list;
161 bts->si_common.si2quater_neigh_list.meas_bw =
162 bts->si_common.data.meas_bw_list;
163 bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;
164 bts->si_common.si2quater_neigh_list.thresh_hi = 5;
165
166 osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);
Max69e9c0d2016-05-18 13:04:47 +0200167 /* first generate invalid SI as no EARFCN added */
168 gen(bts);
169 /* subsequent calls should produce valid SI if there's enough memory */
Max59a1bf32016-04-15 16:04:46 +0200170 add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1917, 1);
171 gen(bts);
172
173 add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1932,
174 OSMO_EARFCN_MEAS_INVALID);
175 gen(bts);
176
177 add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1937, 2);
178 gen(bts);
179
180 add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1945,
181 OSMO_EARFCN_MEAS_INVALID);
182 gen(bts);
183
184 add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1965,
185 OSMO_EARFCN_MEAS_INVALID);
186 gen(bts);
187
188 add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1967, 4);
189 gen(bts);
190
191 add_arfcn_b(&bts->si_common.si2quater_neigh_list, 1982, 3);
192 gen(bts);
193}
194
Holger Hans Peter Freyther5d0e56f2009-08-20 08:41:24 +0200195static void test_mi_functionality(void)
196{
197 const char *imsi_odd = "987654321098763";
198 const char *imsi_even = "9876543210987654";
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200199 const uint32_t tmsi = 0xfabeacd0;
200 uint8_t mi[128];
Holger Hans Peter Freyther5d0e56f2009-08-20 08:41:24 +0200201 unsigned int mi_len;
202 char mi_parsed[GSM48_MI_SIZE];
203
204 printf("Testing parsing and generating TMSI/IMSI\n");
205
206 /* tmsi code */
207 mi_len = gsm48_generate_mid_from_tmsi(mi, tmsi);
208 gsm48_mi_to_string(mi_parsed, sizeof(mi_parsed), mi + 2, mi_len - 2);
Harald Welte3ad03462016-03-17 14:41:26 +0100209 COMPARE((uint32_t)strtoul(mi_parsed, NULL, 10), ==, tmsi);
Holger Hans Peter Freyther5d0e56f2009-08-20 08:41:24 +0200210
211 /* imsi code */
212 mi_len = gsm48_generate_mid_from_imsi(mi, imsi_odd);
213 gsm48_mi_to_string(mi_parsed, sizeof(mi_parsed), mi + 2, mi_len -2);
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200214 printf("hex: %s\n", osmo_hexdump(mi, mi_len));
Holger Hans Peter Freyther5d0e56f2009-08-20 08:41:24 +0200215 COMPARE_STR(mi_parsed, imsi_odd);
216
217 mi_len = gsm48_generate_mid_from_imsi(mi, imsi_even);
218 gsm48_mi_to_string(mi_parsed, sizeof(mi_parsed), mi + 2, mi_len -2);
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200219 printf("hex: %s\n", osmo_hexdump(mi, mi_len));
Holger Hans Peter Freyther5d0e56f2009-08-20 08:41:24 +0200220 COMPARE_STR(mi_parsed, imsi_even);
221}
222
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100223struct {
224 int range;
225 int arfcns_num;
226 int arfcns[RANGE_ENC_MAX_ARFCNS];
227} arfcn_test_ranges[] = {
228 {ARFCN_RANGE_512, 12,
229 { 1, 12, 31, 51, 57, 91, 97, 98, 113, 117, 120, 125 }},
230 {ARFCN_RANGE_512, 17,
231 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }},
232 {ARFCN_RANGE_512, 18,
233 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }},
234 {ARFCN_RANGE_512, 18,
235 { 1, 17, 31, 45, 58, 79, 81, 97,
236 113, 127, 213, 277, 287, 311, 331, 391,
237 417, 511 }},
238 {ARFCN_RANGE_512, 6,
239 { 1, 17, 31, 45, 58, 79 }},
240 {ARFCN_RANGE_512, 6,
241 { 10, 17, 31, 45, 58, 79 }},
242 {ARFCN_RANGE_1024, 17,
243 { 0, 17, 31, 45, 58, 79, 81, 97,
244 113, 127, 213, 277, 287, 311, 331, 391,
245 1023 }},
246 {ARFCN_RANGE_1024, 16,
247 { 17, 31, 45, 58, 79, 81, 97, 113,
248 127, 213, 277, 287, 311, 331, 391, 1023 }},
249 {-1}
250};
251
252static int test_single_range_encoding(int range, const int *orig_arfcns,
253 int arfcns_num, int silent)
254{
255 int arfcns[RANGE_ENC_MAX_ARFCNS];
256 int w[RANGE_ENC_MAX_ARFCNS];
257 int f0_included = 0;
258 int rc, f0;
259 uint8_t chan_list[16] = {0};
260 struct gsm_sysinfo_freq dec_freq[1024] = {{0}};
261 int dec_arfcns[RANGE_ENC_MAX_ARFCNS] = {0};
262 int dec_arfcns_count = 0;
263 int arfcns_used = 0;
264 int i;
265
266 arfcns_used = arfcns_num;
267 memmove(arfcns, orig_arfcns, sizeof(arfcns));
268
Jacob Erlbeck45014a02014-01-14 10:42:58 +0100269 f0 = range == ARFCN_RANGE_1024 ? 0 : arfcns[0];
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100270 /*
271 * Manipulate the ARFCN list according to the rules in J4 depending
272 * on the selected range.
273 */
Jacob Erlbeck45014a02014-01-14 10:42:58 +0100274 arfcns_used = range_enc_filter_arfcns(arfcns, arfcns_used,
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100275 f0, &f0_included);
276
277 memset(w, 0, sizeof(w));
Max26679e02016-04-20 15:57:13 +0200278 range_enc_arfcns(range, arfcns, arfcns_used, w, 0);
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100279
280 if (!silent)
281 fprintf(stderr, "range=%d, arfcns_used=%d, f0=%d, f0_included=%d\n",
282 range, arfcns_used, f0, f0_included);
283
284 /* Select the range and the amount of bits needed */
285 switch (range) {
286 case ARFCN_RANGE_128:
Max26679e02016-04-20 15:57:13 +0200287 range_enc_range128(chan_list, f0, w);
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100288 break;
289 case ARFCN_RANGE_256:
Max26679e02016-04-20 15:57:13 +0200290 range_enc_range256(chan_list, f0, w);
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100291 break;
292 case ARFCN_RANGE_512:
Max26679e02016-04-20 15:57:13 +0200293 range_enc_range512(chan_list, f0, w);
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100294 break;
295 case ARFCN_RANGE_1024:
Max26679e02016-04-20 15:57:13 +0200296 range_enc_range1024(chan_list, f0, f0_included, w);
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100297 break;
298 default:
299 return 1;
300 };
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100301
302 if (!silent)
303 printf("chan_list = %s\n",
304 osmo_hexdump(chan_list, sizeof(chan_list)));
305
306 rc = gsm48_decode_freq_list(dec_freq, chan_list, sizeof(chan_list),
307 0xfe, 1);
308 if (rc != 0) {
309 printf("Cannot decode freq list, rc = %d\n", rc);
310 return 1;
311 }
312
313 for (i = 0; i < ARRAY_SIZE(dec_freq); i++) {
314 if (dec_freq[i].mask &&
315 dec_arfcns_count < ARRAY_SIZE(dec_arfcns))
316 dec_arfcns[dec_arfcns_count++] = i;
317 }
318
319 if (!silent) {
320 printf("Decoded freqs %d (expected %d)\n",
321 dec_arfcns_count, arfcns_num);
322 printf("Decoded: ");
323 for (i = 0; i < dec_arfcns_count; i++) {
324 printf("%d ", dec_arfcns[i]);
325 if (dec_arfcns[i] != orig_arfcns[i])
326 printf("(!= %d) ", orig_arfcns[i]);
327 }
328 printf("\n");
329 }
330
331 if (dec_arfcns_count != arfcns_num) {
332 printf("Wrong number of arfcns\n");
333 return 1;
334 }
335
336 if (memcmp(dec_arfcns, orig_arfcns, sizeof(dec_arfcns)) != 0) {
337 printf("Decoding error, got wrong freqs\n");
338 fprintf(stderr, " w = ");
339 for (i = 0; i < ARRAY_SIZE(w); i++)
340 fprintf(stderr, "%d ", w[i]);
341 fprintf(stderr, "\n");
342 return 1;
343 }
344
345 return 0;
346}
347
348static void test_random_range_encoding(int range, int max_arfcn_num)
349{
350 int arfcns_num = 0;
351 int test_idx;
352 int rc, max_count;
353 int num_tests = 1024;
354
355 printf("Random range test: range %d, max num ARFCNs %d\n",
356 range, max_arfcn_num);
357
358 srandom(1);
359
360 for (max_count = 1; max_count < max_arfcn_num; max_count++) {
361 for (test_idx = 0; test_idx < num_tests; test_idx++) {
362 int count;
363 int i;
364 int min_freq = 0;
365
366 int rnd_arfcns[RANGE_ENC_MAX_ARFCNS] = {0};
367 char rnd_arfcns_set[1024] = {0};
368
369 if (range < ARFCN_RANGE_1024)
370 min_freq = random() % (1023 - range);
371
372 for (count = max_count; count; ) {
373 int arfcn = min_freq + random() % (range + 1);
374 OSMO_ASSERT(arfcn < ARRAY_SIZE(rnd_arfcns_set));
375
376 if (!rnd_arfcns_set[arfcn]) {
377 rnd_arfcns_set[arfcn] = 1;
378 count -= 1;
379 }
380 }
381
382 arfcns_num = 0;
383 for (i = 0; i < ARRAY_SIZE(rnd_arfcns_set); i++)
384 if (rnd_arfcns_set[i])
385 rnd_arfcns[arfcns_num++] = i;
386
387 rc = test_single_range_encoding(range, rnd_arfcns,
388 arfcns_num, 1);
389 if (rc != 0) {
390 printf("Failed on test %d, range %d, num ARFCNs %d\n",
391 test_idx, range, max_count);
392 test_single_range_encoding(range, rnd_arfcns,
393 arfcns_num, 0);
394 return;
395 }
396 }
397 }
398}
399
400static void test_range_encoding()
401{
402 int *arfcns;
403 int arfcns_num = 0;
404 int test_idx;
405 int range;
406
407 for (test_idx = 0; arfcn_test_ranges[test_idx].arfcns_num > 0; test_idx++)
408 {
409 arfcns_num = arfcn_test_ranges[test_idx].arfcns_num;
410 arfcns = &arfcn_test_ranges[test_idx].arfcns[0];
411 range = arfcn_test_ranges[test_idx].range;
412
413 printf("Range test %d: range %d, num ARFCNs %d\n",
414 test_idx, range, arfcns_num);
415
416 test_single_range_encoding(range, arfcns, arfcns_num, 0);
417 }
418
419 test_random_range_encoding(ARFCN_RANGE_128, 29);
420 test_random_range_encoding(ARFCN_RANGE_256, 22);
421 test_random_range_encoding(ARFCN_RANGE_512, 18);
422 test_random_range_encoding(ARFCN_RANGE_1024, 16);
423}
424
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100425static int freqs1[] = {
426 12, 70, 121, 190, 250, 320, 401, 475, 520, 574, 634, 700, 764, 830, 905, 980
427};
428
429static int freqs2[] = {
430 402, 460, 1, 67, 131, 197, 272, 347,
431};
432
433static int freqs3[] = {
434 68, 128, 198, 279, 353, 398, 452,
435
436};
437
438static int w_out[] = {
439 122, 2, 69, 204, 75, 66, 60, 70, 83, 3, 24, 67, 54, 64, 70, 9,
440};
441
442static int range128[] = {
443 1, 1 + 127,
444};
445
446static int range256[] = {
447 1, 1 + 128,
448};
449
450static int range512[] = {
451 1, 1+ 511,
452};
453
454
455static void test_arfcn_filter()
456{
457 int arfcns[50], i, res, f0_included;
458 for (i = 0; i < ARRAY_SIZE(arfcns); ++i)
459 arfcns[i] = (i + 1) * 2;
460
461 /* check that the arfcn is taken out. f0_included is only set for Range1024 */
462 f0_included = 24;
Jacob Erlbeck45014a02014-01-14 10:42:58 +0100463 res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns),
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100464 arfcns[0], &f0_included);
465 VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1);
466 VERIFY(f0_included, ==, 1);
467 for (i = 0; i < res; ++i)
Jacob Erlbeck45014a02014-01-14 10:42:58 +0100468 VERIFY(arfcns[i], ==, ((i+2) * 2) - (2+1));
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100469
Jacob Erlbeck45014a02014-01-14 10:42:58 +0100470 /* check with range1024, ARFCN 0 is included */
471 for (i = 0; i < ARRAY_SIZE(arfcns); ++i)
472 arfcns[i] = i * 2;
473 res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns),
474 0, &f0_included);
475 VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1);
476 VERIFY(f0_included, ==, 1);
477 for (i = 0; i < res; ++i)
478 VERIFY(arfcns[i], ==, (i + 1) * 2 - 1);
479
480 /* check with range1024, ARFCN 0 not included */
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100481 for (i = 0; i < ARRAY_SIZE(arfcns); ++i)
482 arfcns[i] = (i + 1) * 2;
Jacob Erlbeck45014a02014-01-14 10:42:58 +0100483 res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns),
484 0, &f0_included);
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100485 VERIFY(res, ==, ARRAY_SIZE(arfcns));
486 VERIFY(f0_included, ==, 0);
487 for (i = 0; i < res; ++i)
488 VERIFY(arfcns[i], ==, ((i + 1) * 2) - 1);
489}
490
491static void test_print_encoding()
492{
493 int rc;
494 int w[17];
495 uint8_t chan_list[16];
496 memset(chan_list, 0x23, sizeof(chan_list));
497
498 for (rc = 0; rc < ARRAY_SIZE(w); ++rc)
499 switch (rc % 3) {
500 case 0:
501 w[rc] = 0xAAAA;
502 break;
503 case 1:
504 w[rc] = 0x5555;
505 break;
506 case 2:
507 w[rc] = 0x9696;
508 break;
509 }
510
Max26679e02016-04-20 15:57:13 +0200511 range_enc_range512(chan_list, (1 << 9) | 0x96, w);
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100512
513 printf("Range512: %s\n", osmo_hexdump(chan_list, ARRAY_SIZE(chan_list)));
514}
515
516static void test_si_range_helpers()
517{
518 int ws[(sizeof(freqs1)/sizeof(freqs1[0]))];
519 int i, f0 = 0xFFFFFF;
520
521 memset(&ws[0], 0x23, sizeof(ws));
522
523 i = range_enc_find_index(1023, freqs1, ARRAY_SIZE(freqs1));
Jacob Erlbeck1dc022c2014-01-17 09:22:57 +0100524 printf("Element is: %d => freqs[i] = %d\n", i, i >= 0 ? freqs1[i] : -1);
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100525 VERIFY(i, ==, 2);
526
527 i = range_enc_find_index(511, freqs2, ARRAY_SIZE(freqs2));
Jacob Erlbeck1dc022c2014-01-17 09:22:57 +0100528 printf("Element is: %d => freqs[i] = %d\n", i, i >= 0 ? freqs2[i] : -1);
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100529 VERIFY(i, ==, 2);
530
531 i = range_enc_find_index(511, freqs3, ARRAY_SIZE(freqs3));
Jacob Erlbeck1dc022c2014-01-17 09:22:57 +0100532 printf("Element is: %d => freqs[i] = %d\n", i, i >= 0 ? freqs3[i] : -1);
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100533 VERIFY(i, ==, 0);
534
Max26679e02016-04-20 15:57:13 +0200535 range_enc_arfcns(1023, freqs1, ARRAY_SIZE(freqs1), ws, 0);
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100536
537 for (i = 0; i < sizeof(freqs1)/sizeof(freqs1[0]); ++i) {
538 printf("w[%d]=%d\n", i, ws[i]);
539 VERIFY(ws[i], ==, w_out[i]);
540 }
541
542 i = range_enc_determine_range(range128, ARRAY_SIZE(range128), &f0);
543 VERIFY(i, ==, ARFCN_RANGE_128);
544 VERIFY(f0, ==, 1);
545
546 i = range_enc_determine_range(range256, ARRAY_SIZE(range256), &f0);
547 VERIFY(i, ==, ARFCN_RANGE_256);
548 VERIFY(f0, ==, 1);
549
550 i = range_enc_determine_range(range512, ARRAY_SIZE(range512), &f0);
551 VERIFY(i, ==, ARFCN_RANGE_512);
552 VERIFY(f0, ==, 1);
553}
554
Holger Hans Peter Freytherca114432014-02-08 15:20:48 +0100555static void test_gsm411_rp_ref_wrap(void)
556{
557 struct gsm_subscriber_connection conn;
558 int res;
559
560 printf("testing RP-Reference wrap\n");
561
562 memset(&conn, 0, sizeof(conn));
563 conn.next_rp_ref = 255;
564
565 res = sms_next_rp_msg_ref(&conn);
566 printf("Allocated reference: %d\n", res);
567 OSMO_ASSERT(res == 255);
568
569 res = sms_next_rp_msg_ref(&conn);
570 printf("Allocated reference: %d\n", res);
571 OSMO_ASSERT(res == 0);
572
573 res = sms_next_rp_msg_ref(&conn);
574 printf("Allocated reference: %d\n", res);
575 OSMO_ASSERT(res == 1);
576}
577
Holger Hans Peter Freytheradb6e1c2010-09-18 06:44:24 +0800578int main(int argc, char **argv)
Holger Freytheraa0fb362008-12-28 21:55:40 +0000579{
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100580 osmo_init_logging(&log_info);
581 log_set_log_level(osmo_stderr_target, LOGL_INFO);
582
Holger Hans Peter Freyther5d0e56f2009-08-20 08:41:24 +0200583 test_location_area_identifier();
584 test_mi_functionality();
Jacob Erlbeck9444d4f2014-01-13 14:43:40 +0100585
586 test_si_range_helpers();
587 test_arfcn_filter();
588 test_print_encoding();
Jacob Erlbeck4b903b42014-01-10 17:43:41 +0100589 test_range_encoding();
Holger Hans Peter Freytherca114432014-02-08 15:20:48 +0100590 test_gsm411_rp_ref_wrap();
Harald Welteafedeab2010-03-04 10:55:40 +0100591
Max26679e02016-04-20 15:57:13 +0200592 test_si2q_e();
593 test_si2q_u();
Holger Hans Peter Freyther300457b2012-01-06 15:03:28 +0100594 printf("Done.\n");
595 return EXIT_SUCCESS;
Holger Freytheraa0fb362008-12-28 21:55:40 +0000596}