blob: 11459457643fb75265606cdb9089d7cd78494153 [file] [log] [blame]
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001/*
2 * EdgeTest.cpp
3 *
4 * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 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 Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include "gprs_debug.h"
24#include "gprs_coding_scheme.h"
Jacob Erlbeck61679252015-12-11 18:25:21 +010025#include "decoding.h"
Jacob Erlbeckf0e40392016-01-08 10:07:53 +010026#include "encoding.h"
Jacob Erlbeck61679252015-12-11 18:25:21 +010027#include "rlc.h"
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010028
29extern "C" {
30#include "pcu_vty.h"
31
32#include <osmocom/core/application.h>
33#include <osmocom/core/msgb.h>
34#include <osmocom/core/talloc.h>
35#include <osmocom/core/utils.h>
36#include <osmocom/vty/vty.h>
37}
38
39#include <errno.h>
Jacob Erlbeckf0e40392016-01-08 10:07:53 +010040#include <string.h>
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010041
42void *tall_pcu_ctx;
43int16_t spoof_mnc = 0, spoof_mcc = 0;
44
45static void check_coding_scheme(GprsCodingScheme& cs, GprsCodingScheme::Mode mode)
46{
47 volatile unsigned expected_size;
48 GprsCodingScheme new_cs;
49
50 OSMO_ASSERT(cs.isValid());
51 OSMO_ASSERT(cs.isCompatible(mode));
52
53 /* Check static getBySizeUL() */
Jacob Erlbeckfc1b3e62016-01-11 09:58:11 +010054 expected_size = cs.usedSizeUL();
55 if (cs.spareBitsUL() > 0 && cs.isGprs())
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010056 expected_size += 1;
57 OSMO_ASSERT(expected_size == cs.sizeUL());
58 OSMO_ASSERT(cs == GprsCodingScheme::getBySizeUL(expected_size));
59
60 /* Check static sizeUL() */
Jacob Erlbeckfc1b3e62016-01-11 09:58:11 +010061 expected_size = cs.usedSizeDL();
62 if (cs.spareBitsDL() > 0 && cs.isGprs())
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010063 expected_size += 1;
64 OSMO_ASSERT(expected_size == cs.sizeDL());
65
Jacob Erlbeck392a5452015-12-14 10:38:29 +010066 /* Check data block sizes */
67 OSMO_ASSERT(cs.maxDataBlockBytes() * cs.numDataBlocks() < cs.maxBytesDL());
68 OSMO_ASSERT(cs.maxDataBlockBytes() * cs.numDataBlocks() < cs.maxBytesUL());
69
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010070 /* Check inc/dec */
71 new_cs = cs;
72 new_cs.inc(mode);
73 OSMO_ASSERT(new_cs.isCompatible(mode));
74 if (new_cs != cs) {
75 new_cs.dec(mode);
76 OSMO_ASSERT(new_cs.isCompatible(mode));
77 OSMO_ASSERT(new_cs == cs);
78 }
79 new_cs.dec(mode);
80 OSMO_ASSERT(new_cs.isCompatible(mode));
81 if (new_cs != cs) {
82 new_cs.inc(mode);
83 OSMO_ASSERT(new_cs.isCompatible(mode));
84 OSMO_ASSERT(new_cs == cs);
85 }
86}
87
88static void test_coding_scheme()
89{
90 unsigned i;
91 unsigned last_size_UL;
92 unsigned last_size_DL;
93 GprsCodingScheme::Scheme gprs_schemes[] = {
94 GprsCodingScheme::CS1,
95 GprsCodingScheme::CS2,
96 GprsCodingScheme::CS3,
97 GprsCodingScheme::CS4
98 };
99 struct {
100 GprsCodingScheme::Scheme s;
101 bool is_gmsk;
102 } egprs_schemes[] = {
103 {GprsCodingScheme::MCS1, true},
104 {GprsCodingScheme::MCS2, true},
105 {GprsCodingScheme::MCS3, true},
106 {GprsCodingScheme::MCS4, true},
107 {GprsCodingScheme::MCS5, false},
108 {GprsCodingScheme::MCS6, false},
109 {GprsCodingScheme::MCS7, false},
110 {GprsCodingScheme::MCS8, false},
111 {GprsCodingScheme::MCS9, false},
112 };
113
114 printf("=== start %s ===\n", __func__);
115
116 GprsCodingScheme cs;
117 OSMO_ASSERT(!cs);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100118 OSMO_ASSERT(GprsCodingScheme::Scheme(cs) == GprsCodingScheme::UNKNOWN);
119 OSMO_ASSERT(cs == GprsCodingScheme(GprsCodingScheme::UNKNOWN));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100120 OSMO_ASSERT(!cs.isCompatible(GprsCodingScheme::GPRS));
121 OSMO_ASSERT(!cs.isCompatible(GprsCodingScheme::EGPRS_GMSK));
122 OSMO_ASSERT(!cs.isCompatible(GprsCodingScheme::EGPRS));
123
124 last_size_UL = 0;
125 last_size_DL = 0;
126
127 for (i = 0; i < ARRAY_SIZE(gprs_schemes); i++) {
128 GprsCodingScheme current_cs(gprs_schemes[i]);
129 OSMO_ASSERT(current_cs.isGprs());
130 OSMO_ASSERT(!current_cs.isEgprs());
131 OSMO_ASSERT(!current_cs.isEgprsGmsk());
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100132 OSMO_ASSERT(GprsCodingScheme::Scheme(current_cs) == gprs_schemes[i]);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100133 OSMO_ASSERT(current_cs == GprsCodingScheme(gprs_schemes[i]));
134
135 /* Check strong monotonicity */
136 OSMO_ASSERT(current_cs.maxBytesUL() > last_size_UL);
137 OSMO_ASSERT(current_cs.maxBytesDL() > last_size_DL);
138 last_size_UL = current_cs.maxBytesUL();
139 last_size_DL = current_cs.maxBytesDL();
140
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +0100141 /* Check header types */
142 OSMO_ASSERT(current_cs.headerTypeData() ==
143 GprsCodingScheme::HEADER_GPRS_DATA);
144 OSMO_ASSERT(current_cs.headerTypeControl() ==
145 GprsCodingScheme::HEADER_GPRS_CONTROL);
146
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100147 check_coding_scheme(current_cs, GprsCodingScheme::GPRS);
148 }
149 OSMO_ASSERT(i == 4);
150
151 last_size_UL = 0;
152 last_size_DL = 0;
153
154 for (i = 0; i < ARRAY_SIZE(egprs_schemes); i++) {
155 GprsCodingScheme current_cs(egprs_schemes[i].s);
156 OSMO_ASSERT(!current_cs.isGprs());
157 OSMO_ASSERT(current_cs.isEgprs());
158 OSMO_ASSERT(!!current_cs.isEgprsGmsk() == !!egprs_schemes[i].is_gmsk);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100159 OSMO_ASSERT(GprsCodingScheme::Scheme(current_cs) == egprs_schemes[i].s);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100160 OSMO_ASSERT(current_cs == GprsCodingScheme(egprs_schemes[i].s));
161
162 /* Check strong monotonicity */
163 OSMO_ASSERT(current_cs.maxBytesUL() > last_size_UL);
164 OSMO_ASSERT(current_cs.maxBytesDL() > last_size_DL);
165 last_size_UL = current_cs.maxBytesUL();
166 last_size_DL = current_cs.maxBytesDL();
167
168 if (egprs_schemes[i].is_gmsk)
169 check_coding_scheme(current_cs, GprsCodingScheme::EGPRS_GMSK);
170 check_coding_scheme(current_cs, GprsCodingScheme::EGPRS);
171 }
172 OSMO_ASSERT(i == 9);
173
174 printf("=== end %s ===\n", __func__);
175}
176
Jacob Erlbeck38f18692016-02-01 10:08:00 +0100177static void test_rlc_unit_decoder()
Jacob Erlbeck61679252015-12-11 18:25:21 +0100178{
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100179 struct gprs_rlc_data_block_info rdbi = {0};
Jacob Erlbeck61679252015-12-11 18:25:21 +0100180 GprsCodingScheme cs;
181 uint8_t data[74];
182 Decoding::RlcData chunks[16];
183 volatile int num_chunks = 0;
184 uint32_t tlli, tlli2;
185 unsigned int offs;
186
187
188 printf("=== start %s ===\n", __func__);
189
190 /* TS 44.060, B.1 */
191 cs = GprsCodingScheme::CS4;
192 rdbi.data_len = cs.maxDataBlockBytes();
193 rdbi.e = 0;
194 rdbi.ti = 0;
195 rdbi.cv = 15;
196 tlli = 0;
197 offs = 0;
198 data[offs++] = (11 << 2) | (1 << 1) | (0 << 0);
199 data[offs++] = (26 << 2) | (1 << 1) | (1 << 0);
200 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
201 chunks, ARRAY_SIZE(chunks), &tlli);
202 OSMO_ASSERT(num_chunks == 3);
203 OSMO_ASSERT(tlli == 0);
204 OSMO_ASSERT(chunks[0].offset == 2);
205 OSMO_ASSERT(chunks[0].length == 11);
206 OSMO_ASSERT(chunks[0].is_complete);
207 OSMO_ASSERT(chunks[1].offset == 13);
208 OSMO_ASSERT(chunks[1].length == 26);
209 OSMO_ASSERT(chunks[1].is_complete);
210 OSMO_ASSERT(chunks[2].offset == 39);
211 OSMO_ASSERT(chunks[2].length == cs.maxDataBlockBytes() - 39);
212 OSMO_ASSERT(!chunks[2].is_complete);
213
214 /* TS 44.060, B.2 */
215 cs = GprsCodingScheme::CS1;
216 rdbi.data_len = cs.maxDataBlockBytes();
217 rdbi.e = 0;
218 rdbi.ti = 0;
219 rdbi.cv = 15;
220 tlli = 0;
221 offs = 0;
222 data[offs++] = (0 << 2) | (0 << 1) | (1 << 0);
223 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
224 chunks, ARRAY_SIZE(chunks), &tlli);
225 OSMO_ASSERT(num_chunks == 1);
226 OSMO_ASSERT(tlli == 0);
227 OSMO_ASSERT(chunks[0].offset == 1);
228 OSMO_ASSERT(chunks[0].length == 19);
229 OSMO_ASSERT(!chunks[0].is_complete);
230
231 rdbi.e = 0;
232 rdbi.ti = 0;
233 rdbi.cv = 15;
234 tlli = 0;
235 offs = 0;
236 data[offs++] = (1 << 2) | (1 << 1) | (1 << 0);
237 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
238 chunks, ARRAY_SIZE(chunks), &tlli);
239 OSMO_ASSERT(num_chunks == 2);
240 OSMO_ASSERT(tlli == 0);
241 OSMO_ASSERT(chunks[0].offset == 1);
242 OSMO_ASSERT(chunks[0].length == 1);
243 OSMO_ASSERT(chunks[0].is_complete);
244 OSMO_ASSERT(chunks[1].offset == 2);
245 OSMO_ASSERT(chunks[1].length == 18);
246 OSMO_ASSERT(!chunks[1].is_complete);
247
248 /* TS 44.060, B.3 */
249 cs = GprsCodingScheme::CS1;
250 rdbi.data_len = cs.maxDataBlockBytes();
251 rdbi.e = 0;
252 rdbi.ti = 0;
253 rdbi.cv = 15;
254 tlli = 0;
255 offs = 0;
256 data[offs++] = (7 << 2) | (1 << 1) | (0 << 0);
257 data[offs++] = (11 << 2) | (0 << 1) | (1 << 0);
258 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
259 chunks, ARRAY_SIZE(chunks), &tlli);
260 OSMO_ASSERT(num_chunks == 2);
261 OSMO_ASSERT(tlli == 0);
262 OSMO_ASSERT(chunks[0].offset == 2);
263 OSMO_ASSERT(chunks[0].length == 7);
264 OSMO_ASSERT(chunks[0].is_complete);
265 OSMO_ASSERT(chunks[1].offset == 9);
266 OSMO_ASSERT(chunks[1].length == 11);
267 OSMO_ASSERT(chunks[1].is_complete);
268
269 /* TS 44.060, B.4 */
270 cs = GprsCodingScheme::CS1;
271 rdbi.data_len = cs.maxDataBlockBytes();
272 rdbi.e = 1;
273 rdbi.ti = 0;
274 rdbi.cv = 15;
275 tlli = 0;
276 offs = 0;
277 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
278 chunks, ARRAY_SIZE(chunks), &tlli);
279 OSMO_ASSERT(num_chunks == 1);
280 OSMO_ASSERT(tlli == 0);
281 OSMO_ASSERT(chunks[0].offset == 0);
282 OSMO_ASSERT(chunks[0].length == 20);
283 OSMO_ASSERT(!chunks[0].is_complete);
284
285 /* TS 44.060, B.6 */
286 cs = GprsCodingScheme::CS1;
287 rdbi.data_len = cs.maxDataBlockBytes();
288 rdbi.e = 1;
289 rdbi.ti = 0;
290 rdbi.cv = 0;
291 tlli = 0;
292 offs = 0;
293 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
294 chunks, ARRAY_SIZE(chunks), &tlli);
295 OSMO_ASSERT(num_chunks == 1);
296 OSMO_ASSERT(tlli == 0);
297 OSMO_ASSERT(chunks[0].offset == 0);
298 OSMO_ASSERT(chunks[0].length == 20);
299 OSMO_ASSERT(chunks[0].is_complete);
300
301 /* TS 44.060, B.8.1 */
302 cs = GprsCodingScheme::MCS4;
303 rdbi.data_len = cs.maxDataBlockBytes();
304 rdbi.e = 0;
305 rdbi.ti = 0;
306 rdbi.cv = 15;
307 tlli = 0;
308 offs = 0;
309 data[offs++] = (11 << 1) | (0 << 0);
310 data[offs++] = (26 << 1) | (1 << 0);
311 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
312 chunks, ARRAY_SIZE(chunks), &tlli);
313 OSMO_ASSERT(num_chunks == 3);
314 OSMO_ASSERT(tlli == 0);
315 OSMO_ASSERT(chunks[0].offset == 2);
316 OSMO_ASSERT(chunks[0].length == 11);
317 OSMO_ASSERT(chunks[0].is_complete);
318 OSMO_ASSERT(chunks[1].offset == 13);
319 OSMO_ASSERT(chunks[1].length == 26);
320 OSMO_ASSERT(chunks[1].is_complete);
321 OSMO_ASSERT(chunks[2].offset == 39);
322 OSMO_ASSERT(chunks[2].length == 5);
323 OSMO_ASSERT(!chunks[2].is_complete);
324
325 /* TS 44.060, B.8.2 */
326
327 /* Note that the spec confuses the byte numbering here, since it
328 * includes the FBI/E header bits into the N2 octet count which
329 * is not consistent with Section 10.3a.1 & 10.3a.2. */
330
331 cs = GprsCodingScheme::MCS2;
332 rdbi.data_len = cs.maxDataBlockBytes();
333 rdbi.e = 0;
334 rdbi.ti = 0;
335 rdbi.cv = 15;
336 tlli = 0;
337 offs = 0;
338 data[offs++] = (15 << 1) | (1 << 0);
339 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
340 chunks, ARRAY_SIZE(chunks), &tlli);
341 OSMO_ASSERT(num_chunks == 2);
342 OSMO_ASSERT(tlli == 0);
343 OSMO_ASSERT(chunks[0].offset == 1);
344 OSMO_ASSERT(chunks[0].length == 15);
345 OSMO_ASSERT(chunks[0].is_complete);
346 OSMO_ASSERT(chunks[1].offset == 16);
347 OSMO_ASSERT(chunks[1].length == 12);
348 OSMO_ASSERT(!chunks[1].is_complete);
349
350 rdbi.e = 0;
351 rdbi.ti = 0;
352 rdbi.cv = 15;
353 tlli = 0;
354 offs = 0;
355 data[offs++] = ( 0 << 1) | (0 << 0);
356 data[offs++] = ( 7 << 1) | (0 << 0);
357 data[offs++] = (18 << 1) | (1 << 0); /* Differs from spec's N2-11 = 17 */
358 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
359 chunks, ARRAY_SIZE(chunks), &tlli);
360 OSMO_ASSERT(num_chunks == 3);
361 OSMO_ASSERT(tlli == 0);
362 OSMO_ASSERT(chunks[0].offset == 3);
363 OSMO_ASSERT(chunks[0].length == 0);
364 OSMO_ASSERT(chunks[0].is_complete);
365 OSMO_ASSERT(chunks[1].offset == 3);
366 OSMO_ASSERT(chunks[1].length == 7);
367 OSMO_ASSERT(chunks[1].is_complete);
368 OSMO_ASSERT(chunks[2].offset == 10);
369 OSMO_ASSERT(chunks[2].length == 18);
370 OSMO_ASSERT(chunks[2].is_complete);
371
372 rdbi.e = 0;
373 rdbi.ti = 0;
374 rdbi.cv = 0;
375 tlli = 0;
376 offs = 0;
377 data[offs++] = ( 6 << 1) | (0 << 0);
378 data[offs++] = (12 << 1) | (0 << 0);
379 data[offs++] = (127 << 1) | (1 << 0);
380 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
381 chunks, ARRAY_SIZE(chunks), &tlli);
382 OSMO_ASSERT(num_chunks == 2);
383 OSMO_ASSERT(tlli == 0);
384 OSMO_ASSERT(chunks[0].offset == 3);
385 OSMO_ASSERT(chunks[0].length == 6);
386 OSMO_ASSERT(chunks[0].is_complete);
387 OSMO_ASSERT(chunks[1].offset == 9);
388 OSMO_ASSERT(chunks[1].length == 12);
389 OSMO_ASSERT(chunks[1].is_complete);
390
391 /* TS 44.060, B.8.3 */
392
393 /* Note that the spec confuses the byte numbering here, too (see above) */
394
395 cs = GprsCodingScheme::MCS2;
396 rdbi.data_len = cs.maxDataBlockBytes();
397 rdbi.e = 1;
398 rdbi.ti = 0;
399 rdbi.cv = 0;
400 tlli = 0;
401 offs = 0;
402 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
403 chunks, ARRAY_SIZE(chunks), &tlli);
404 OSMO_ASSERT(num_chunks == 1);
405 OSMO_ASSERT(tlli == 0);
406 OSMO_ASSERT(chunks[0].offset == 0);
407 OSMO_ASSERT(chunks[0].length == 28);
408 OSMO_ASSERT(chunks[0].is_complete);
409
410 /* CS-1, TLLI, last block, single chunk until the end of the block */
411 cs = GprsCodingScheme::CS1;
412 rdbi.data_len = cs.maxDataBlockBytes();
413 rdbi.e = 1;
414 rdbi.ti = 1;
415 rdbi.cv = 0;
416 tlli = 0;
417 tlli2 = 0xffeeddcc;
418 offs = 0;
419 data[offs++] = tlli2 >> 24;
420 data[offs++] = tlli2 >> 16;
421 data[offs++] = tlli2 >> 8;
422 data[offs++] = tlli2 >> 0;
423 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
424 chunks, ARRAY_SIZE(chunks), &tlli);
425 OSMO_ASSERT(num_chunks == 1);
426 OSMO_ASSERT(tlli == tlli2);
427 OSMO_ASSERT(chunks[0].offset == 4);
428 OSMO_ASSERT(chunks[0].length == 16);
429 OSMO_ASSERT(chunks[0].is_complete);
430
431 /* Like TS 44.060, B.2, first RLC block but with TLLI */
432 cs = GprsCodingScheme::CS1;
433 rdbi.data_len = cs.maxDataBlockBytes();
434 rdbi.e = 0;
435 rdbi.ti = 1;
436 rdbi.cv = 15;
437 tlli = 0;
438 tlli2 = 0xffeeddbb;
439 offs = 0;
440 data[offs++] = (0 << 2) | (0 << 1) | (1 << 0);
441 data[offs++] = tlli2 >> 24;
442 data[offs++] = tlli2 >> 16;
443 data[offs++] = tlli2 >> 8;
444 data[offs++] = tlli2 >> 0;
445 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
446 chunks, ARRAY_SIZE(chunks), &tlli);
447 OSMO_ASSERT(num_chunks == 1);
448 OSMO_ASSERT(tlli == tlli2);
449 OSMO_ASSERT(chunks[0].offset == 5);
450 OSMO_ASSERT(chunks[0].length == 15);
451 OSMO_ASSERT(!chunks[0].is_complete);
452
453 /* Like TS 44.060, B.8.1 but with TLLI */
454 cs = GprsCodingScheme::MCS4;
455 rdbi.data_len = cs.maxDataBlockBytes();
456 rdbi.e = 0;
457 rdbi.ti = 1;
458 rdbi.cv = 15;
459 tlli = 0;
460 tlli2 = 0xffeeddaa;
461 offs = 0;
462 data[offs++] = (11 << 1) | (0 << 0);
463 data[offs++] = (26 << 1) | (1 << 0);
464 /* Little endian */
465 data[offs++] = tlli2 >> 0;
466 data[offs++] = tlli2 >> 8;
467 data[offs++] = tlli2 >> 16;
468 data[offs++] = tlli2 >> 24;
469 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
470 chunks, ARRAY_SIZE(chunks), &tlli);
471 OSMO_ASSERT(num_chunks == 3);
472 OSMO_ASSERT(tlli == tlli2);
473 OSMO_ASSERT(chunks[0].offset == 6);
474 OSMO_ASSERT(chunks[0].length == 11);
475 OSMO_ASSERT(chunks[0].is_complete);
476 OSMO_ASSERT(chunks[1].offset == 17);
477 OSMO_ASSERT(chunks[1].length == 26);
478 OSMO_ASSERT(chunks[1].is_complete);
479 OSMO_ASSERT(chunks[2].offset == 43);
480 OSMO_ASSERT(chunks[2].length == 1);
481 OSMO_ASSERT(!chunks[2].is_complete);
482
483 printf("=== end %s ===\n", __func__);
484}
485
Jacob Erlbeckf0e40392016-01-08 10:07:53 +0100486static void test_rlc_unaligned_copy()
487{
488 uint8_t bits[256];
489 uint8_t saved_block[256];
490 uint8_t test_block[256];
491 uint8_t out_block[256];
492 GprsCodingScheme::Scheme scheme;
493 int pattern;
494 volatile unsigned int block_idx, i;
495
496 for (scheme = GprsCodingScheme::CS1;
497 scheme < GprsCodingScheme::NUM_SCHEMES;
498 scheme = GprsCodingScheme::Scheme(scheme + 1))
499 {
500 GprsCodingScheme cs(scheme);
501
502 for (pattern = 0; pattern <= 0xff; pattern += 0xff) {
503 /* prepare test block */
504 test_block[0] = pattern ^ 0xff;
505 for (i = 1; i + 1 < cs.maxDataBlockBytes(); i++)
506 test_block[i] = i;
507 test_block[cs.maxDataBlockBytes()-1] = pattern ^ 0xff;
508
509 for (block_idx = 0;
510 block_idx < cs.numDataBlocks();
511 block_idx++)
512 {
513 struct gprs_rlc_data_info rlc;
514 gprs_rlc_data_info_init_dl(&rlc, cs);
515
516 memset(bits, pattern, sizeof(bits));
517 Decoding::rlc_copy_to_aligned_buffer(
518 &rlc, block_idx, bits, saved_block);
519
520 fprintf(stderr,
521 "Test data block: %s\n",
522 osmo_hexdump(test_block, cs.maxDataBlockBytes()));
523
524 Encoding::rlc_copy_from_aligned_buffer(
525 &rlc, block_idx, bits, test_block);
526
527 fprintf(stderr,
528 "Encoded message block, %s, idx %d, "
529 "pattern %02x: %s\n",
530 rlc.cs.name(), block_idx, pattern,
531 osmo_hexdump(bits, cs.sizeDL()));
532
533 Decoding::rlc_copy_to_aligned_buffer(
534 &rlc, block_idx, bits, out_block);
535
536 fprintf(stderr,
537 "Out data block: %s\n",
538 osmo_hexdump(out_block, cs.maxDataBlockBytes()));
539 /* restore original bits */
540 Encoding::rlc_copy_from_aligned_buffer(
541 &rlc, block_idx, bits, saved_block);
542
543 OSMO_ASSERT(memcmp(test_block, out_block,
544 rlc.cs.maxDataBlockBytes()) == 0);
545
546 for (i = 0; i < sizeof(bits); i++)
547 OSMO_ASSERT(bits[i] == pattern);
548 }
549 }
550 }
551}
552
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +0100553static void test_rlc_info_init()
554{
555 struct gprs_rlc_data_info rlc;
556
557 printf("=== start %s ===\n", __func__);
558 gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::CS1));
559 OSMO_ASSERT(rlc.num_data_blocks == 1);
560 OSMO_ASSERT(rlc.data_offs_bits[0] == 24);
561 OSMO_ASSERT(rlc.block_info[0].data_len == 20);
562
563 gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::MCS1));
564 OSMO_ASSERT(rlc.num_data_blocks == 1);
565 OSMO_ASSERT(rlc.data_offs_bits[0] == 33);
566 OSMO_ASSERT(rlc.block_info[0].data_len == 22);
567
568 printf("=== end %s ===\n", __func__);
569}
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100570
571static const struct log_info_cat default_categories[] = {
572 {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0},
573 {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1},
574 {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1},
575 {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1},
576 {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1},
577 {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1},
578 {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1},
579 {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1},
580 {"DNS","\033[1;34m", "GPRS Network Service Protocol (NS)", LOGL_INFO , 1},
581 {"DBSSGP","\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO , 1},
582 {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1},
583};
584
585static int filter_fn(const struct log_context *ctx,
586 struct log_target *tar)
587{
588 return 1;
589}
590
591const struct log_info debug_log_info = {
592 filter_fn,
593 (struct log_info_cat*)default_categories,
594 ARRAY_SIZE(default_categories),
595};
596
597int main(int argc, char **argv)
598{
599 struct vty_app_info pcu_vty_info = {0};
600
601 tall_pcu_ctx = talloc_named_const(NULL, 1, "EdgeTest context");
602 if (!tall_pcu_ctx)
603 abort();
604
605 msgb_set_talloc_ctx(tall_pcu_ctx);
606 osmo_init_logging(&debug_log_info);
607 log_set_use_color(osmo_stderr_target, 0);
608 log_set_print_filename(osmo_stderr_target, 0);
609
610 vty_init(&pcu_vty_info);
611 pcu_vty_init(&debug_log_info);
612
613 test_coding_scheme();
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +0100614 test_rlc_info_init();
Jacob Erlbeck38f18692016-02-01 10:08:00 +0100615 test_rlc_unit_decoder();
Jacob Erlbeckf0e40392016-01-08 10:07:53 +0100616 test_rlc_unaligned_copy();
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100617
618 if (getenv("TALLOC_REPORT_FULL"))
619 talloc_report_full(tall_pcu_ctx, stderr);
620 return EXIT_SUCCESS;
621}
622
623/*
624 * stubs that should not be reached
625 */
626extern "C" {
627void l1if_pdch_req() { abort(); }
628void l1if_connect_pdch() { abort(); }
629void l1if_close_pdch() { abort(); }
630void l1if_open_pdch() { abort(); }
631}