blob: 14c5ce3807b70f1584bd61b9ff71784e35880ac6 [file] [log] [blame]
Neels Hofmeyr7dde1f42020-05-11 19:43:20 +02001/*
2 * (C) 2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
3 * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
4 * All Rights Reserved
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24#include <stdio.h>
25#include <errno.h>
26#include <strings.h>
27#include <string.h>
28
29#include <osmocom/gsm/gsm23236.h>
30#include <osmocom/core/utils.h>
31
32void *ctx;
33bool ok = true;
34
35void bitdump(uint8_t count, uint32_t val)
36{
37 uint32_t bit;
38 if (count < 1)
39 return;
40 for (bit = ((uint32_t)1) << (count - 1); bit; bit >>= 1)
41 printf("%c", (val & bit)? '1' : '0');
42}
43
44struct nri_v_get_set_test {
45 uint32_t tmsi;
46 uint8_t nri_bitlen;
47 int16_t expect_get_nri;
48 int expect_get_rc;
49 int16_t set_nri_v;
50 uint32_t expect_tmsi;
51 int expect_set_rc;
52};
53
54struct nri_v_get_set_test nri_v_get_set_tests[] = {
55 {
56 .tmsi = 0,
57 .nri_bitlen = 10,
58 .expect_get_nri = 0,
59 .set_nri_v = 0,
60 .expect_tmsi = 0,
61 },
62 {
63 .tmsi = 0,
64 .nri_bitlen = 10,
65 .expect_get_nri = 0,
66 .set_nri_v = 0x7fff,
67 .expect_tmsi = 0x00ffc000
68 },
69 {
70 .tmsi = 0xffffffff,
71 .nri_bitlen = 10,
72 .expect_get_nri = 0x3ff,
73 .set_nri_v = 0,
74 .expect_tmsi = 0xff003fff
75 },
76 {
77 .tmsi = 0xffffffff,
78 .nri_bitlen = 10,
79 .expect_get_nri = 0x3ff,
80 .set_nri_v = 0x7fff,
81 .expect_tmsi = 0xffffffff
82 },
83 {
84 .tmsi = 0,
85 .nri_bitlen = 5,
86 .expect_get_nri = 0,
87 .set_nri_v = 0,
88 .expect_tmsi = 0,
89 },
90 {
91 .tmsi = 0,
92 .nri_bitlen = 5,
93 .expect_get_nri = 0,
94 .set_nri_v = 0x7fff,
95 .expect_tmsi = 0x00f80000
96 },
97 {
98 .tmsi = 0xffffffff,
99 .nri_bitlen = 5,
100 .expect_get_nri = 0x1f,
101 .set_nri_v = 0,
102 .expect_tmsi = 0xff07ffff
103 },
104 {
105 .tmsi = 0xffffffff,
106 .nri_bitlen = 5,
107 .expect_get_nri = 0x1f,
108 .set_nri_v = 0x7fff,
109 .expect_tmsi = 0xffffffff
110 },
111 {
112 .tmsi = 0x01234567,
113 .nri_bitlen = 8,
114 .expect_get_nri = 0x23,
115 .set_nri_v = 0x42,
116 .expect_tmsi = 0x01424567
117 },
118 {
119 .tmsi = 0x01234567,
120 .nri_bitlen = 15,
121 .expect_get_nri = 0x2345 >> 1,
122 .set_nri_v = 0x7fff,
123 .expect_tmsi = 0x01ffff67
124 },
125 {
126 .tmsi = 0x01234567,
127 .nri_bitlen = 16,
128 .expect_get_rc = -1,
129 .expect_get_nri = -1,
130 .set_nri_v = 0x7fff,
131 .expect_set_rc = -1,
132 .expect_tmsi = 0x01234567,
133 },
134 {
135 .tmsi = 0x01234567,
136 .nri_bitlen = 0,
137 .expect_get_rc = -1,
138 .expect_get_nri = -1,
139 .set_nri_v = 0x7fff,
140 .expect_set_rc = -1,
141 .expect_tmsi = 0x01234567,
142 },
143};
144
145void test_nri_v_get_set()
146{
147 struct nri_v_get_set_test *t;
148
149 for (t = nri_v_get_set_tests; t < &nri_v_get_set_tests[ARRAY_SIZE(nri_v_get_set_tests)]; t++) {
150 int16_t nri_v = 0;
151 uint32_t tmsi2;
152 int rc;
153
154 rc = osmo_tmsi_nri_v_get(&nri_v, t->tmsi, t->nri_bitlen);
155 printf("\nosmo_tmsi_nri_v_get(0x%08x, %u) -> nri_v=0x%x rc=%d\n", t->tmsi, t->nri_bitlen, nri_v, rc);
156 if (!rc) {
157 printf("........|NRI->..................\n");
158 bitdump(32, t->tmsi);
159 printf(" tmsi nri_bitlen=%u\n", t->nri_bitlen);
160 printf(" ");
161 bitdump(t->nri_bitlen, nri_v);
162 printf(" = 0x%x", nri_v);
163 }
164 if (nri_v == t->expect_get_nri && rc == t->expect_get_rc) {
165 printf(" ok\n");
166 } else {
167 printf(" ERROR: expected nri_v=0x%x rc=%d\n", t->expect_get_nri, t->expect_get_rc);
168 ok = false;
169 }
170
171 tmsi2 = t->tmsi;
172 rc = osmo_tmsi_nri_v_set(&tmsi2, t->set_nri_v, t->nri_bitlen);
173 printf("osmo_tmsi_nri_v_set(0x%08x, 0x%x, %u) -> tmsi=0x%08x rc=%d\n", t->tmsi, t->set_nri_v, t->nri_bitlen,
174 tmsi2, rc);
175 if (!rc) {
176 printf(" ");
177 bitdump(t->nri_bitlen, t->set_nri_v);
178 printf("\n");
179 bitdump(32, tmsi2);
180 }
181 if (tmsi2 == t->expect_tmsi && rc == t->expect_set_rc) {
182 printf(" ok\n");
183 } else {
184 printf(" ERROR: expected tmsi=0x%08x rc=%d\n", t->expect_tmsi, t->expect_set_rc);
185 ok = false;
186 }
187 }
188}
189
190struct nri_validate_tc {
191 int16_t nri;
192 uint8_t nri_bitlen;
193 int expect_rc;
194};
195
196struct nri_validate_tc nri_validate_tests[] = {
197 { .nri = INT16_MIN, .nri_bitlen = 10, .expect_rc = -1 },
198 { .nri = -23, .nri_bitlen = 10, .expect_rc = -1 },
199 { .nri = -1, .nri_bitlen = 10, .expect_rc = -1 },
200 { .nri = 0, .nri_bitlen = 10, .expect_rc = 0 },
201 { .nri = (1 << 10) - 1, .nri_bitlen = 10, .expect_rc = 0 },
202 { .nri = (1 << 10), .nri_bitlen = 10, .expect_rc = 1 },
203 { .nri = INT16_MAX, .nri_bitlen = 10, .expect_rc = 1 },
204
205 { .nri = INT16_MIN, .nri_bitlen = 5, .expect_rc = -1 },
206 { .nri = -23, .nri_bitlen = 5, .expect_rc = -1 },
207 { .nri = -1, .nri_bitlen = 5, .expect_rc = -1 },
208 { .nri = 0, .nri_bitlen = 5, .expect_rc = 0 },
209 { .nri = (1 << 5) - 1, .nri_bitlen = 5, .expect_rc = 0 },
210 { .nri = (1 << 5), .nri_bitlen = 5, .expect_rc = 1 },
211 { .nri = INT16_MAX, .nri_bitlen = 5, .expect_rc = 1 },
212
213 { .nri = INT16_MIN, .nri_bitlen = 1, .expect_rc = -1 },
214 { .nri = -23, .nri_bitlen = 1, .expect_rc = -1 },
215 { .nri = -1, .nri_bitlen = 1, .expect_rc = -1 },
216 { .nri = 0, .nri_bitlen = 1, .expect_rc = 0 },
217 { .nri = 1, .nri_bitlen = 1, .expect_rc = 0 },
218 { .nri = 2, .nri_bitlen = 1, .expect_rc = 1 },
219 { .nri = INT16_MAX, .nri_bitlen = 1, .expect_rc = 1 },
220
221 { .nri = INT16_MIN, .nri_bitlen = 0, .expect_rc = -1 },
222 { .nri = -23, .nri_bitlen = 0, .expect_rc = -1 },
223 { .nri = -1, .nri_bitlen = 0, .expect_rc = -1 },
224 { .nri = 0, .nri_bitlen = 0, .expect_rc = 1 },
225 { .nri = 1, .nri_bitlen = 0, .expect_rc = 1 },
226 { .nri = INT16_MAX, .nri_bitlen = 0, .expect_rc = 1 },
227};
228
229void test_nri_validate()
230{
231 struct nri_validate_tc *t;
232 printf("\n%s()\n", __func__);
233 for (t = nri_validate_tests; (t - nri_validate_tests) < ARRAY_SIZE(nri_validate_tests); t++) {
234 int rc = osmo_nri_v_validate(t->nri, t->nri_bitlen);
235 printf("osmo_nri_v_validate(%d, %u) = %d ", t->nri, t->nri_bitlen, rc);
236 if (rc == t->expect_rc) {
237 printf("ok\n");
238 } else {
239 printf("ERROR, expected rc = %d\n", t->expect_rc);
240 ok = false;
241 }
242 }
243}
244
245struct nri_range_validate_tc {
246 struct osmo_nri_range range;
247 uint8_t nri_bitlen;
248 int expect_rc;
249};
250
251struct nri_range_validate_tc nri_range_validate_tests[] = {
252 { .range = { .first = INT16_MIN, .last = INT16_MIN }, .nri_bitlen = 10, .expect_rc = -1 },
253 { .range = { .first = -23, .last = -23 }, .nri_bitlen = 10, .expect_rc = -1 },
254 { .range = { .first = -1, .last = -1 }, .nri_bitlen = 10, .expect_rc = -1 },
255 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 10, .expect_rc = 0 },
256 { .range = { .first = (1 << 10) - 1, .last = (1 << 10) - 1 }, .nri_bitlen = 10, .expect_rc = 0 },
257 { .range = { .first = (1 << 10), .last = (1 << 10) }, .nri_bitlen = 10, .expect_rc = 1 },
258 { .range = { .first = INT16_MAX, .last = INT16_MAX }, .nri_bitlen = 10, .expect_rc = 1 },
259
260 { .range = { .first = INT16_MIN, .last = INT16_MIN }, .nri_bitlen = 5, .expect_rc = -1 },
261 { .range = { .first = -23, .last = -23 }, .nri_bitlen = 5, .expect_rc = -1 },
262 { .range = { .first = -1, .last = -1 }, .nri_bitlen = 5, .expect_rc = -1 },
263 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 5, .expect_rc = 0 },
264 { .range = { .first = (1 << 5) - 1, .last = (1 << 5) - 1 }, .nri_bitlen = 5, .expect_rc = 0 },
265 { .range = { .first = (1 << 5), .last = (1 << 5) }, .nri_bitlen = 5, .expect_rc = 1 },
266 { .range = { .first = INT16_MAX, .last = INT16_MAX }, .nri_bitlen = 5, .expect_rc = 1 },
267
268 { .range = { .first = INT16_MIN, .last = INT16_MIN }, .nri_bitlen = 1, .expect_rc = -1 },
269 { .range = { .first = -23, .last = -23 }, .nri_bitlen = 1, .expect_rc = -1 },
270 { .range = { .first = -1, .last = -1 }, .nri_bitlen = 1, .expect_rc = -1 },
271 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 1, .expect_rc = 0 },
272 { .range = { .first = 1, .last = 1 }, .nri_bitlen = 1, .expect_rc = 0 },
273 { .range = { .first = 2, .last = 2 }, .nri_bitlen = 1, .expect_rc = 1 },
274 { .range = { .first = INT16_MAX, .last = INT16_MAX }, .nri_bitlen = 1, .expect_rc = 1 },
275
276 { .range = { .first = INT16_MIN, .last = INT16_MIN }, .nri_bitlen = 0, .expect_rc = -1 },
277 { .range = { .first = -23, .last = -23 }, .nri_bitlen = 0, .expect_rc = -1 },
278 { .range = { .first = -1, .last = -1 }, .nri_bitlen = 0, .expect_rc = -1 },
279 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 0, .expect_rc = 1 },
280 { .range = { .first = 1, .last = 1 }, .nri_bitlen = 0, .expect_rc = 1 },
281 { .range = { .first = INT16_MAX, .last = INT16_MAX }, .nri_bitlen = 0, .expect_rc = 1 },
282
283
284 { .range = { .first = 0, .last = INT16_MIN }, .nri_bitlen = 10, .expect_rc = -2 },
285 { .range = { .first = 0, .last = -23 }, .nri_bitlen = 10, .expect_rc = -2 },
286 { .range = { .first = 0, .last = -1 }, .nri_bitlen = 10, .expect_rc = -2 },
287 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 10, .expect_rc = 0 },
288 { .range = { .first = 0, .last = (1 << 10) - 1 }, .nri_bitlen = 10, .expect_rc = 0 },
289 { .range = { .first = 0, .last = (1 << 10) }, .nri_bitlen = 10, .expect_rc = 2 },
290 { .range = { .first = 0, .last = INT16_MAX }, .nri_bitlen = 10, .expect_rc = 2 },
291
292 { .range = { .first = 0, .last = INT16_MIN }, .nri_bitlen = 5, .expect_rc = -2 },
293 { .range = { .first = 0, .last = -23 }, .nri_bitlen = 5, .expect_rc = -2 },
294 { .range = { .first = 0, .last = -1 }, .nri_bitlen = 5, .expect_rc = -2 },
295 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 5, .expect_rc = 0 },
296 { .range = { .first = 0, .last = (1 << 5) - 1 }, .nri_bitlen = 5, .expect_rc = 0 },
297 { .range = { .first = 0, .last = (1 << 5) }, .nri_bitlen = 5, .expect_rc = 2 },
298 { .range = { .first = 0, .last = INT16_MAX }, .nri_bitlen = 5, .expect_rc = 2 },
299
300 { .range = { .first = 0, .last = INT16_MIN }, .nri_bitlen = 1, .expect_rc = -2 },
301 { .range = { .first = 0, .last = -23 }, .nri_bitlen = 1, .expect_rc = -2 },
302 { .range = { .first = 0, .last = -1 }, .nri_bitlen = 1, .expect_rc = -2 },
303 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 1, .expect_rc = 0 },
304 { .range = { .first = 0, .last = 1 }, .nri_bitlen = 1, .expect_rc = 0 },
305 { .range = { .first = 0, .last = 2 }, .nri_bitlen = 1, .expect_rc = 2 },
306 { .range = { .first = 0, .last = INT16_MAX }, .nri_bitlen = 1, .expect_rc = 2 },
307
308 { .range = { .first = 0, .last = INT16_MIN }, .nri_bitlen = 0, .expect_rc = 1 },
309 { .range = { .first = 0, .last = -23 }, .nri_bitlen = 0, .expect_rc = 1 },
310 { .range = { .first = 0, .last = -1 }, .nri_bitlen = 0, .expect_rc = 1 },
311 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 0, .expect_rc = 1 },
312 { .range = { .first = 0, .last = 1 }, .nri_bitlen = 0, .expect_rc = 1 },
313 { .range = { .first = 0, .last = INT16_MAX }, .nri_bitlen = 0, .expect_rc = 1 },
314
315
316 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 10, .expect_rc = 0 },
317 { .range = { .first = 1, .last = 0 }, .nri_bitlen = 10, .expect_rc = -3 },
318 { .range = { .first = (1 << 10) - 1, .last = (1 << 10) - 1 }, .nri_bitlen = 10, .expect_rc = 0 },
319 { .range = { .first = (1 << 10) - 1, .last = (1 << 10) - 2 }, .nri_bitlen = 10, .expect_rc = -3 },
320 { .range = { .first = (1 << 10) - 1, .last = 0 }, .nri_bitlen = 10, .expect_rc = -3 },
321
322 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 5, .expect_rc = 0 },
323 { .range = { .first = 1, .last = 0 }, .nri_bitlen = 5, .expect_rc = -3 },
324 { .range = { .first = (1 << 5) - 1, .last = (1 << 5) - 1 }, .nri_bitlen = 5, .expect_rc = 0 },
325 { .range = { .first = (1 << 5) - 1, .last = (1 << 5) - 2 }, .nri_bitlen = 5, .expect_rc = -3 },
326 { .range = { .first = (1 << 5) - 1, .last = 0 }, .nri_bitlen = 5, .expect_rc = -3 },
327
328 { .range = { .first = 0, .last = 0 }, .nri_bitlen = 1, .expect_rc = 0 },
329 { .range = { .first = 1, .last = 1 }, .nri_bitlen = 1, .expect_rc = 0 },
330 { .range = { .first = 1, .last = 0 }, .nri_bitlen = 1, .expect_rc = -3 },
331
332};
333
334void test_nri_range_validate()
335{
336 struct nri_range_validate_tc *t;
337 printf("\n%s()\n", __func__);
338 for (t = nri_range_validate_tests; (t - nri_range_validate_tests) < ARRAY_SIZE(nri_range_validate_tests); t++) {
339 int rc = osmo_nri_range_validate(&t->range, t->nri_bitlen);
340 printf("osmo_nri_range_validate({%d,%d}, %u) = %d ", t->range.first, t->range.last, t->nri_bitlen, rc);
341 if (rc == t->expect_rc) {
342 printf("ok\n");
343 } else {
344 printf("ERROR, expected rc = %d\n", t->expect_rc);
345 ok = false;
346 }
347 }
348}
349
350void dump_list(const struct osmo_nri_ranges *nri_ranges)
351{
352 struct osmo_nri_range *r;
353 printf("nri_ranges = {\n");
354 llist_for_each_entry(r, &nri_ranges->entries, entry) {
355 printf(" { %d, %d },\n", r->first, r->last);
356 if (osmo_nri_range_validate(r, 255)) {
357 ok = false;
358 printf(" ^^^^^ ERROR: invalid range\n");
359 }
360 }
361 printf("};\n");
362}
363
364void test_nri_list()
365{
366 struct osmo_nri_ranges *nri_ranges = osmo_nri_ranges_alloc(ctx);
367 printf("\n%s()\n", __func__);
368
369#define ADD(FIRST, LAST) do { \
370 struct osmo_nri_range r = { .first = FIRST, .last = LAST }; \
371 int rc; \
372 rc = osmo_nri_ranges_add(nri_ranges, &r); \
373 printf("osmo_nri_ranges_add(%d, %d) -> %d\n", r.first, r.last, rc); \
374 dump_list(nri_ranges); \
375 } while(0)
376
377#define DEL(FIRST, LAST) do { \
378 struct osmo_nri_range r = { .first = FIRST, .last = LAST }; \
379 int rc; \
380 rc = osmo_nri_ranges_del(nri_ranges, &r); \
381 printf("osmo_nri_ranges_del(%d, %d) -> %d\n", r.first, r.last, rc); \
382 dump_list(nri_ranges); \
383 } while(0)
384
385#define MATCHES(NRI, EXPECT_MATCH) do { \
386 bool matches = osmo_nri_v_matches_ranges(NRI, nri_ranges); \
387 printf("osmo_nri_v_matches_ranges(%d) -> %s\n", NRI, matches ? "true" : "false"); \
388 if (matches != EXPECT_MATCH) { \
389 ok = false; \
390 printf(" ^ ERROR: expected " #EXPECT_MATCH "\n"); \
391 } \
392 } while(0)
393
394#define OVERLAPS(FIRST, LAST, EXPECT_OVERLAP) do { \
395 struct osmo_nri_range r = { .first = FIRST, .last = LAST }; \
396 bool overlaps = osmo_nri_range_overlaps_ranges(&r, nri_ranges); \
397 printf("osmo_nri_range_overlaps_ranges(%d, %d) -> %s\n", r.first, r.last, overlaps ? "true" : "false"); \
398 if (overlaps != EXPECT_OVERLAP) { \
399 ok = false; \
400 printf(" ^ ERROR: expected " #EXPECT_OVERLAP "\n"); \
401 } \
402 } while(0)
403
404 dump_list(nri_ranges);
405 MATCHES(INT16_MIN, false);
406 MATCHES(-1, false);
407 MATCHES(0, false);
408 MATCHES(INT16_MAX, false);
409 MATCHES(100, false);
410 OVERLAPS(INT16_MIN, -1, false);
411 OVERLAPS(-100, 100, false);
412 OVERLAPS(10, 20, false);
413
414 ADD(100, 200);
415 MATCHES(INT16_MIN, false);
416 MATCHES(-1, false);
417 MATCHES(0, false);
418 MATCHES(INT16_MAX, false);
419 MATCHES(99, false);
420 MATCHES(100, true);
421 MATCHES(101, true);
422 MATCHES(199, true);
423 MATCHES(200, true);
424 MATCHES(201, false);
425 OVERLAPS(INT16_MIN, -1, false);
426 OVERLAPS(-100, 100, true);
427 OVERLAPS(10, 20, false);
428 OVERLAPS(10, 99, false);
429 OVERLAPS(10, 100, true);
430 OVERLAPS(10, 150, true);
431 OVERLAPS(99, 99, false);
432 OVERLAPS(100, 100, true);
433 OVERLAPS(150, 300, true);
434 OVERLAPS(200, 300, true);
435 OVERLAPS(201, 300, false);
436
437 printf("\ndel from start:\n");
438 DEL(0, 110);
439 DEL(111, 111);
440 DEL(112, 199);
441 MATCHES(INT16_MIN, false);
442 MATCHES(-1, false);
443 MATCHES(0, false);
444 MATCHES(INT16_MAX, false);
445 MATCHES(199, false);
446 MATCHES(200, true);
447 MATCHES(201, false);
448 OVERLAPS(INT16_MIN, -1, false);
449 OVERLAPS(-1000, 1000, true);
450 OVERLAPS(0, 199, false);
451 OVERLAPS(0, 200, true);
452 OVERLAPS(0, 201, true);
453 OVERLAPS(0, 1000, true);
454 OVERLAPS(199, 199, false);
455 OVERLAPS(200, 200, true);
456 OVERLAPS(201, 201, false);
457
458 printf("\ndel from end:\n");
459 ADD(100, 200);
460 DEL(190, INT16_MAX);
461 DEL(189, 189);
462 DEL(101, 188);
463 MATCHES(INT16_MIN, false);
464 MATCHES(-1, false);
465 MATCHES(0, false);
466 MATCHES(INT16_MAX, false);
467 MATCHES(99, false);
468 MATCHES(100, true);
469 MATCHES(101, false);
470
471 printf("\ndel from middle:\n");
472 ADD(100, 200);
473 DEL(150, 160);
474 DEL(110, 120);
475 DEL(130, 130);
476 DEL(180, 190);
477 MATCHES(INT16_MIN, false);
478 MATCHES(-1, false);
479 MATCHES(0, false);
480 MATCHES(INT16_MAX, false);
481 MATCHES(99, false);
482 MATCHES(100, true);
483 MATCHES(109, true);
484 MATCHES(110, false);
485 MATCHES(120, false);
486 MATCHES(121, true);
487 MATCHES(129, true);
488 MATCHES(130, false);
489 MATCHES(131, true);
490 MATCHES(148, true);
491 MATCHES(149, true);
492 MATCHES(150, false);
493 MATCHES(160, false);
494 MATCHES(161, true);
495 MATCHES(170, true);
496 MATCHES(179, true);
497 MATCHES(180, false);
498 MATCHES(185, false);
499 MATCHES(190, false);
500 MATCHES(191, true);
501 MATCHES(195, true);
502 MATCHES(200, true);
503 MATCHES(201, false);
504 MATCHES(1000, false);
505 OVERLAPS(110, 120, false);
506 OVERLAPS(110, 130, true);
507 OVERLAPS(100, 200, true);
508
509 printf("\ndel across whole chunks:\n");
510 DEL(115, 185);
511 DEL(105, 195);
512 DEL(0, 1000);
513
514 printf("\nadd to join chunks:\n");
515 ADD(0, 100);
516 DEL(11, 19);
517 DEL(23, 23);
518 DEL(30, 41);
519 ADD(23, 23);
520 ADD(11, 41);
521 MATCHES(0, true);
522 MATCHES(10, true);
523 MATCHES(11, true);
524 MATCHES(24, true);
525 MATCHES(41, true);
526 MATCHES(42, true);
527 MATCHES(100, true);
528 MATCHES(101, false);
529
530 printf("\nborder cases:\n");
531 ADD(0, 0);
532 ADD(INT16_MAX, INT16_MAX);
533 ADD(1, INT16_MAX - 1);
534 MATCHES(INT16_MIN, false);
535 MATCHES(-1, false);
536 MATCHES(0, true);
537 MATCHES(INT16_MAX, true);
538 DEL(0, 0);
539 DEL(INT16_MAX, INT16_MAX);
540 DEL(1, INT16_MAX - 1);
541
542 printf("\nrange errors:\n");
543 ADD(-1, -1);
544 ADD(-20, -10);
545 ADD(100, 1);
546 ADD(0, INT16_MAX);
547 DEL(-1, -1);
548 DEL(-20, -10);
549 DEL(100, 1);
550}
551
552void test_nri_limit_by_ranges()
553{
554 const uint8_t nri_bitlen = 8;
555 const int16_t expect_nri_vals[] = { 10, 20, 21, 30, 31, 32 };
556 int i;
557 struct osmo_nri_ranges *nri_ranges = osmo_nri_ranges_alloc(ctx);
558 printf("\n%s()\n", __func__);
559
560 ADD(10, 10);
561 ADD(20, 21);
562 ADD(30, 32);
563
564 for (i = 0; i < 19; i++) {
565 int rc;
566 int16_t nri_v;
567 int16_t expect_nri_v = expect_nri_vals[i % ARRAY_SIZE(expect_nri_vals)];
568
569 nri_v = i;
570 rc = osmo_nri_v_limit_by_ranges(&nri_v, nri_ranges, nri_bitlen);
571 printf("osmo_nri_v_limit_by_ranges(%d) -> nri_v=%d rc=%d", i, nri_v, rc);
572 if (!rc && nri_v == expect_nri_v) {
573 printf(" ok\n");
574 } else {
575 printf(" ERROR: expected nri_v=%d rc=0\n", expect_nri_v);
576 ok = false;
577 }
578 }
579 for (i = 0; i < 19; i++) {
580 int rc;
581 int16_t nri_v;
582 uint32_t tmsi, tmsi2;
583 int16_t expect_nri_v = expect_nri_vals[i % ARRAY_SIZE(expect_nri_vals)];
584
585 tmsi = 0;
586 osmo_tmsi_nri_v_set(&tmsi, i, nri_bitlen);
587 tmsi2 = tmsi;
588 rc = osmo_tmsi_nri_v_limit_by_ranges(&tmsi2, nri_ranges, nri_bitlen);
589 osmo_tmsi_nri_v_get(&nri_v, tmsi2, nri_bitlen);
590 printf("osmo_tmsi_nri_v_limit_by_ranges(0x%08x, %u) -> tmsi=0x%08x nri_v=%d rc=%d",
591 tmsi, nri_bitlen, tmsi2, nri_v, rc);
592 if (!rc && nri_v == expect_nri_v) {
593 printf(" ok\n");
594 } else {
595 printf(" ERROR: expected nri_v=%d rc=0\n", expect_nri_v);
596 ok = false;
597 }
598 }
599}
600
601int main()
602{
603 ctx = talloc_named_const(NULL, 0, "nri_test");
604
605 test_nri_v_get_set();
606 test_nri_validate();
607 test_nri_range_validate();
608 test_nri_list();
609 test_nri_limit_by_ranges();
610
611 talloc_free(ctx);
612 if (!ok) {
613 printf("\nFAIL\n");
614 return -1;
615 }
616
617 printf("\npass\n");
618 return 0;
619}
620