blob: 96ea0c12b9640a378fa8f4699c43eba2f2a08c76 [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 Erlbeck14bb0942016-01-12 11:58:13 +010028#include "llc.h"
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010029
30extern "C" {
31#include "pcu_vty.h"
32
33#include <osmocom/core/application.h>
34#include <osmocom/core/msgb.h>
35#include <osmocom/core/talloc.h>
36#include <osmocom/core/utils.h>
37#include <osmocom/vty/vty.h>
38}
39
40#include <errno.h>
Jacob Erlbeckf0e40392016-01-08 10:07:53 +010041#include <string.h>
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010042
43void *tall_pcu_ctx;
44int16_t spoof_mnc = 0, spoof_mcc = 0;
45
46static void check_coding_scheme(GprsCodingScheme& cs, GprsCodingScheme::Mode mode)
47{
48 volatile unsigned expected_size;
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010049 bool need_padding;
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010050 GprsCodingScheme new_cs;
51
52 OSMO_ASSERT(cs.isValid());
53 OSMO_ASSERT(cs.isCompatible(mode));
54
55 /* Check static getBySizeUL() */
Jacob Erlbeckfc1b3e62016-01-11 09:58:11 +010056 expected_size = cs.usedSizeUL();
57 if (cs.spareBitsUL() > 0 && cs.isGprs())
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010058 expected_size += 1;
59 OSMO_ASSERT(expected_size == cs.sizeUL());
60 OSMO_ASSERT(cs == GprsCodingScheme::getBySizeUL(expected_size));
61
62 /* Check static sizeUL() */
Jacob Erlbeckfc1b3e62016-01-11 09:58:11 +010063 expected_size = cs.usedSizeDL();
64 if (cs.spareBitsDL() > 0 && cs.isGprs())
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010065 expected_size += 1;
66 OSMO_ASSERT(expected_size == cs.sizeDL());
67
Jacob Erlbeck392a5452015-12-14 10:38:29 +010068 /* Check data block sizes */
69 OSMO_ASSERT(cs.maxDataBlockBytes() * cs.numDataBlocks() < cs.maxBytesDL());
70 OSMO_ASSERT(cs.maxDataBlockBytes() * cs.numDataBlocks() < cs.maxBytesUL());
71
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010072 /* Check inc/dec */
73 new_cs = cs;
74 new_cs.inc(mode);
75 OSMO_ASSERT(new_cs.isCompatible(mode));
76 if (new_cs != cs) {
77 new_cs.dec(mode);
78 OSMO_ASSERT(new_cs.isCompatible(mode));
79 OSMO_ASSERT(new_cs == cs);
80 }
81 new_cs.dec(mode);
82 OSMO_ASSERT(new_cs.isCompatible(mode));
83 if (new_cs != cs) {
84 new_cs.inc(mode);
85 OSMO_ASSERT(new_cs.isCompatible(mode));
86 OSMO_ASSERT(new_cs == cs);
87 }
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010088
89 new_cs = cs;
90 new_cs.decToSingleBlock(&need_padding);
91 OSMO_ASSERT(new_cs.isFamilyCompatible(cs));
92 OSMO_ASSERT(cs.isFamilyCompatible(new_cs));
93 OSMO_ASSERT(cs.isCompatible(new_cs));
94 if (need_padding) {
Jacob Erlbeck215e18c2016-02-03 18:22:34 +010095 OSMO_ASSERT(new_cs.maxDataBlockBytes() ==
96 new_cs.optionalPaddingBits()/8 + cs.maxDataBlockBytes());
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010097 } else {
98 OSMO_ASSERT(new_cs.maxDataBlockBytes() == cs.maxDataBlockBytes());
99 }
100
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100101}
102
103static void test_coding_scheme()
104{
105 unsigned i;
106 unsigned last_size_UL;
107 unsigned last_size_DL;
108 GprsCodingScheme::Scheme gprs_schemes[] = {
109 GprsCodingScheme::CS1,
110 GprsCodingScheme::CS2,
111 GprsCodingScheme::CS3,
112 GprsCodingScheme::CS4
113 };
114 struct {
115 GprsCodingScheme::Scheme s;
116 bool is_gmsk;
117 } egprs_schemes[] = {
118 {GprsCodingScheme::MCS1, true},
119 {GprsCodingScheme::MCS2, true},
120 {GprsCodingScheme::MCS3, true},
121 {GprsCodingScheme::MCS4, true},
122 {GprsCodingScheme::MCS5, false},
123 {GprsCodingScheme::MCS6, false},
124 {GprsCodingScheme::MCS7, false},
125 {GprsCodingScheme::MCS8, false},
126 {GprsCodingScheme::MCS9, false},
127 };
128
129 printf("=== start %s ===\n", __func__);
130
131 GprsCodingScheme cs;
132 OSMO_ASSERT(!cs);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100133 OSMO_ASSERT(GprsCodingScheme::Scheme(cs) == GprsCodingScheme::UNKNOWN);
134 OSMO_ASSERT(cs == GprsCodingScheme(GprsCodingScheme::UNKNOWN));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100135 OSMO_ASSERT(!cs.isCompatible(GprsCodingScheme::GPRS));
136 OSMO_ASSERT(!cs.isCompatible(GprsCodingScheme::EGPRS_GMSK));
137 OSMO_ASSERT(!cs.isCompatible(GprsCodingScheme::EGPRS));
138
139 last_size_UL = 0;
140 last_size_DL = 0;
141
142 for (i = 0; i < ARRAY_SIZE(gprs_schemes); i++) {
143 GprsCodingScheme current_cs(gprs_schemes[i]);
144 OSMO_ASSERT(current_cs.isGprs());
145 OSMO_ASSERT(!current_cs.isEgprs());
146 OSMO_ASSERT(!current_cs.isEgprsGmsk());
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100147 OSMO_ASSERT(GprsCodingScheme::Scheme(current_cs) == gprs_schemes[i]);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100148 OSMO_ASSERT(current_cs == GprsCodingScheme(gprs_schemes[i]));
149
150 /* Check strong monotonicity */
151 OSMO_ASSERT(current_cs.maxBytesUL() > last_size_UL);
152 OSMO_ASSERT(current_cs.maxBytesDL() > last_size_DL);
153 last_size_UL = current_cs.maxBytesUL();
154 last_size_DL = current_cs.maxBytesDL();
155
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +0100156 /* Check header types */
157 OSMO_ASSERT(current_cs.headerTypeData() ==
158 GprsCodingScheme::HEADER_GPRS_DATA);
159 OSMO_ASSERT(current_cs.headerTypeControl() ==
160 GprsCodingScheme::HEADER_GPRS_CONTROL);
161
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100162 check_coding_scheme(current_cs, GprsCodingScheme::GPRS);
163 }
164 OSMO_ASSERT(i == 4);
165
166 last_size_UL = 0;
167 last_size_DL = 0;
168
169 for (i = 0; i < ARRAY_SIZE(egprs_schemes); i++) {
170 GprsCodingScheme current_cs(egprs_schemes[i].s);
171 OSMO_ASSERT(!current_cs.isGprs());
172 OSMO_ASSERT(current_cs.isEgprs());
173 OSMO_ASSERT(!!current_cs.isEgprsGmsk() == !!egprs_schemes[i].is_gmsk);
Jacob Erlbeck4c9e5492016-01-04 16:00:05 +0100174 OSMO_ASSERT(GprsCodingScheme::Scheme(current_cs) == egprs_schemes[i].s);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100175 OSMO_ASSERT(current_cs == GprsCodingScheme(egprs_schemes[i].s));
176
177 /* Check strong monotonicity */
178 OSMO_ASSERT(current_cs.maxBytesUL() > last_size_UL);
179 OSMO_ASSERT(current_cs.maxBytesDL() > last_size_DL);
180 last_size_UL = current_cs.maxBytesUL();
181 last_size_DL = current_cs.maxBytesDL();
182
183 if (egprs_schemes[i].is_gmsk)
184 check_coding_scheme(current_cs, GprsCodingScheme::EGPRS_GMSK);
185 check_coding_scheme(current_cs, GprsCodingScheme::EGPRS);
186 }
187 OSMO_ASSERT(i == 9);
188
189 printf("=== end %s ===\n", __func__);
190}
191
Jacob Erlbeck38f18692016-02-01 10:08:00 +0100192static void test_rlc_unit_decoder()
Jacob Erlbeck61679252015-12-11 18:25:21 +0100193{
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100194 struct gprs_rlc_data_block_info rdbi = {0};
Jacob Erlbeck61679252015-12-11 18:25:21 +0100195 GprsCodingScheme cs;
196 uint8_t data[74];
197 Decoding::RlcData chunks[16];
198 volatile int num_chunks = 0;
199 uint32_t tlli, tlli2;
200 unsigned int offs;
201
202
203 printf("=== start %s ===\n", __func__);
204
205 /* TS 44.060, B.1 */
206 cs = GprsCodingScheme::CS4;
207 rdbi.data_len = cs.maxDataBlockBytes();
208 rdbi.e = 0;
209 rdbi.ti = 0;
210 rdbi.cv = 15;
211 tlli = 0;
212 offs = 0;
213 data[offs++] = (11 << 2) | (1 << 1) | (0 << 0);
214 data[offs++] = (26 << 2) | (1 << 1) | (1 << 0);
215 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
216 chunks, ARRAY_SIZE(chunks), &tlli);
217 OSMO_ASSERT(num_chunks == 3);
218 OSMO_ASSERT(tlli == 0);
219 OSMO_ASSERT(chunks[0].offset == 2);
220 OSMO_ASSERT(chunks[0].length == 11);
221 OSMO_ASSERT(chunks[0].is_complete);
222 OSMO_ASSERT(chunks[1].offset == 13);
223 OSMO_ASSERT(chunks[1].length == 26);
224 OSMO_ASSERT(chunks[1].is_complete);
225 OSMO_ASSERT(chunks[2].offset == 39);
226 OSMO_ASSERT(chunks[2].length == cs.maxDataBlockBytes() - 39);
227 OSMO_ASSERT(!chunks[2].is_complete);
228
229 /* TS 44.060, B.2 */
230 cs = GprsCodingScheme::CS1;
231 rdbi.data_len = cs.maxDataBlockBytes();
232 rdbi.e = 0;
233 rdbi.ti = 0;
234 rdbi.cv = 15;
235 tlli = 0;
236 offs = 0;
237 data[offs++] = (0 << 2) | (0 << 1) | (1 << 0);
238 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
239 chunks, ARRAY_SIZE(chunks), &tlli);
240 OSMO_ASSERT(num_chunks == 1);
241 OSMO_ASSERT(tlli == 0);
242 OSMO_ASSERT(chunks[0].offset == 1);
243 OSMO_ASSERT(chunks[0].length == 19);
244 OSMO_ASSERT(!chunks[0].is_complete);
245
246 rdbi.e = 0;
247 rdbi.ti = 0;
248 rdbi.cv = 15;
249 tlli = 0;
250 offs = 0;
251 data[offs++] = (1 << 2) | (1 << 1) | (1 << 0);
252 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
253 chunks, ARRAY_SIZE(chunks), &tlli);
254 OSMO_ASSERT(num_chunks == 2);
255 OSMO_ASSERT(tlli == 0);
256 OSMO_ASSERT(chunks[0].offset == 1);
257 OSMO_ASSERT(chunks[0].length == 1);
258 OSMO_ASSERT(chunks[0].is_complete);
259 OSMO_ASSERT(chunks[1].offset == 2);
260 OSMO_ASSERT(chunks[1].length == 18);
261 OSMO_ASSERT(!chunks[1].is_complete);
262
263 /* TS 44.060, B.3 */
264 cs = GprsCodingScheme::CS1;
265 rdbi.data_len = cs.maxDataBlockBytes();
266 rdbi.e = 0;
267 rdbi.ti = 0;
268 rdbi.cv = 15;
269 tlli = 0;
270 offs = 0;
271 data[offs++] = (7 << 2) | (1 << 1) | (0 << 0);
272 data[offs++] = (11 << 2) | (0 << 1) | (1 << 0);
273 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
274 chunks, ARRAY_SIZE(chunks), &tlli);
275 OSMO_ASSERT(num_chunks == 2);
276 OSMO_ASSERT(tlli == 0);
277 OSMO_ASSERT(chunks[0].offset == 2);
278 OSMO_ASSERT(chunks[0].length == 7);
279 OSMO_ASSERT(chunks[0].is_complete);
280 OSMO_ASSERT(chunks[1].offset == 9);
281 OSMO_ASSERT(chunks[1].length == 11);
282 OSMO_ASSERT(chunks[1].is_complete);
283
284 /* TS 44.060, B.4 */
285 cs = GprsCodingScheme::CS1;
286 rdbi.data_len = cs.maxDataBlockBytes();
287 rdbi.e = 1;
288 rdbi.ti = 0;
289 rdbi.cv = 15;
290 tlli = 0;
291 offs = 0;
292 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
293 chunks, ARRAY_SIZE(chunks), &tlli);
294 OSMO_ASSERT(num_chunks == 1);
295 OSMO_ASSERT(tlli == 0);
296 OSMO_ASSERT(chunks[0].offset == 0);
297 OSMO_ASSERT(chunks[0].length == 20);
298 OSMO_ASSERT(!chunks[0].is_complete);
299
300 /* TS 44.060, B.6 */
301 cs = GprsCodingScheme::CS1;
302 rdbi.data_len = cs.maxDataBlockBytes();
303 rdbi.e = 1;
304 rdbi.ti = 0;
305 rdbi.cv = 0;
306 tlli = 0;
307 offs = 0;
308 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
309 chunks, ARRAY_SIZE(chunks), &tlli);
310 OSMO_ASSERT(num_chunks == 1);
311 OSMO_ASSERT(tlli == 0);
312 OSMO_ASSERT(chunks[0].offset == 0);
313 OSMO_ASSERT(chunks[0].length == 20);
314 OSMO_ASSERT(chunks[0].is_complete);
315
316 /* TS 44.060, B.8.1 */
317 cs = GprsCodingScheme::MCS4;
318 rdbi.data_len = cs.maxDataBlockBytes();
319 rdbi.e = 0;
320 rdbi.ti = 0;
321 rdbi.cv = 15;
322 tlli = 0;
323 offs = 0;
324 data[offs++] = (11 << 1) | (0 << 0);
325 data[offs++] = (26 << 1) | (1 << 0);
326 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
327 chunks, ARRAY_SIZE(chunks), &tlli);
328 OSMO_ASSERT(num_chunks == 3);
329 OSMO_ASSERT(tlli == 0);
330 OSMO_ASSERT(chunks[0].offset == 2);
331 OSMO_ASSERT(chunks[0].length == 11);
332 OSMO_ASSERT(chunks[0].is_complete);
333 OSMO_ASSERT(chunks[1].offset == 13);
334 OSMO_ASSERT(chunks[1].length == 26);
335 OSMO_ASSERT(chunks[1].is_complete);
336 OSMO_ASSERT(chunks[2].offset == 39);
337 OSMO_ASSERT(chunks[2].length == 5);
338 OSMO_ASSERT(!chunks[2].is_complete);
339
340 /* TS 44.060, B.8.2 */
341
342 /* Note that the spec confuses the byte numbering here, since it
343 * includes the FBI/E header bits into the N2 octet count which
344 * is not consistent with Section 10.3a.1 & 10.3a.2. */
345
346 cs = GprsCodingScheme::MCS2;
347 rdbi.data_len = cs.maxDataBlockBytes();
348 rdbi.e = 0;
349 rdbi.ti = 0;
350 rdbi.cv = 15;
351 tlli = 0;
352 offs = 0;
353 data[offs++] = (15 << 1) | (1 << 0);
354 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
355 chunks, ARRAY_SIZE(chunks), &tlli);
356 OSMO_ASSERT(num_chunks == 2);
357 OSMO_ASSERT(tlli == 0);
358 OSMO_ASSERT(chunks[0].offset == 1);
359 OSMO_ASSERT(chunks[0].length == 15);
360 OSMO_ASSERT(chunks[0].is_complete);
361 OSMO_ASSERT(chunks[1].offset == 16);
362 OSMO_ASSERT(chunks[1].length == 12);
363 OSMO_ASSERT(!chunks[1].is_complete);
364
365 rdbi.e = 0;
366 rdbi.ti = 0;
367 rdbi.cv = 15;
368 tlli = 0;
369 offs = 0;
370 data[offs++] = ( 0 << 1) | (0 << 0);
371 data[offs++] = ( 7 << 1) | (0 << 0);
372 data[offs++] = (18 << 1) | (1 << 0); /* Differs from spec's N2-11 = 17 */
373 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
374 chunks, ARRAY_SIZE(chunks), &tlli);
375 OSMO_ASSERT(num_chunks == 3);
376 OSMO_ASSERT(tlli == 0);
377 OSMO_ASSERT(chunks[0].offset == 3);
378 OSMO_ASSERT(chunks[0].length == 0);
379 OSMO_ASSERT(chunks[0].is_complete);
380 OSMO_ASSERT(chunks[1].offset == 3);
381 OSMO_ASSERT(chunks[1].length == 7);
382 OSMO_ASSERT(chunks[1].is_complete);
383 OSMO_ASSERT(chunks[2].offset == 10);
384 OSMO_ASSERT(chunks[2].length == 18);
385 OSMO_ASSERT(chunks[2].is_complete);
386
387 rdbi.e = 0;
388 rdbi.ti = 0;
389 rdbi.cv = 0;
390 tlli = 0;
391 offs = 0;
392 data[offs++] = ( 6 << 1) | (0 << 0);
393 data[offs++] = (12 << 1) | (0 << 0);
394 data[offs++] = (127 << 1) | (1 << 0);
395 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
396 chunks, ARRAY_SIZE(chunks), &tlli);
397 OSMO_ASSERT(num_chunks == 2);
398 OSMO_ASSERT(tlli == 0);
399 OSMO_ASSERT(chunks[0].offset == 3);
400 OSMO_ASSERT(chunks[0].length == 6);
401 OSMO_ASSERT(chunks[0].is_complete);
402 OSMO_ASSERT(chunks[1].offset == 9);
403 OSMO_ASSERT(chunks[1].length == 12);
404 OSMO_ASSERT(chunks[1].is_complete);
405
406 /* TS 44.060, B.8.3 */
407
408 /* Note that the spec confuses the byte numbering here, too (see above) */
409
410 cs = GprsCodingScheme::MCS2;
411 rdbi.data_len = cs.maxDataBlockBytes();
412 rdbi.e = 1;
413 rdbi.ti = 0;
414 rdbi.cv = 0;
415 tlli = 0;
416 offs = 0;
417 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
418 chunks, ARRAY_SIZE(chunks), &tlli);
419 OSMO_ASSERT(num_chunks == 1);
420 OSMO_ASSERT(tlli == 0);
421 OSMO_ASSERT(chunks[0].offset == 0);
422 OSMO_ASSERT(chunks[0].length == 28);
423 OSMO_ASSERT(chunks[0].is_complete);
424
425 /* CS-1, TLLI, last block, single chunk until the end of the block */
426 cs = GprsCodingScheme::CS1;
427 rdbi.data_len = cs.maxDataBlockBytes();
428 rdbi.e = 1;
429 rdbi.ti = 1;
430 rdbi.cv = 0;
431 tlli = 0;
432 tlli2 = 0xffeeddcc;
433 offs = 0;
434 data[offs++] = tlli2 >> 24;
435 data[offs++] = tlli2 >> 16;
436 data[offs++] = tlli2 >> 8;
437 data[offs++] = tlli2 >> 0;
438 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
439 chunks, ARRAY_SIZE(chunks), &tlli);
440 OSMO_ASSERT(num_chunks == 1);
441 OSMO_ASSERT(tlli == tlli2);
442 OSMO_ASSERT(chunks[0].offset == 4);
443 OSMO_ASSERT(chunks[0].length == 16);
444 OSMO_ASSERT(chunks[0].is_complete);
445
446 /* Like TS 44.060, B.2, first RLC block but with TLLI */
447 cs = GprsCodingScheme::CS1;
448 rdbi.data_len = cs.maxDataBlockBytes();
449 rdbi.e = 0;
450 rdbi.ti = 1;
451 rdbi.cv = 15;
452 tlli = 0;
453 tlli2 = 0xffeeddbb;
454 offs = 0;
455 data[offs++] = (0 << 2) | (0 << 1) | (1 << 0);
456 data[offs++] = tlli2 >> 24;
457 data[offs++] = tlli2 >> 16;
458 data[offs++] = tlli2 >> 8;
459 data[offs++] = tlli2 >> 0;
460 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
461 chunks, ARRAY_SIZE(chunks), &tlli);
462 OSMO_ASSERT(num_chunks == 1);
463 OSMO_ASSERT(tlli == tlli2);
464 OSMO_ASSERT(chunks[0].offset == 5);
465 OSMO_ASSERT(chunks[0].length == 15);
466 OSMO_ASSERT(!chunks[0].is_complete);
467
468 /* Like TS 44.060, B.8.1 but with TLLI */
469 cs = GprsCodingScheme::MCS4;
470 rdbi.data_len = cs.maxDataBlockBytes();
471 rdbi.e = 0;
472 rdbi.ti = 1;
473 rdbi.cv = 15;
474 tlli = 0;
475 tlli2 = 0xffeeddaa;
476 offs = 0;
477 data[offs++] = (11 << 1) | (0 << 0);
478 data[offs++] = (26 << 1) | (1 << 0);
479 /* Little endian */
480 data[offs++] = tlli2 >> 0;
481 data[offs++] = tlli2 >> 8;
482 data[offs++] = tlli2 >> 16;
483 data[offs++] = tlli2 >> 24;
484 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
485 chunks, ARRAY_SIZE(chunks), &tlli);
486 OSMO_ASSERT(num_chunks == 3);
487 OSMO_ASSERT(tlli == tlli2);
488 OSMO_ASSERT(chunks[0].offset == 6);
489 OSMO_ASSERT(chunks[0].length == 11);
490 OSMO_ASSERT(chunks[0].is_complete);
491 OSMO_ASSERT(chunks[1].offset == 17);
492 OSMO_ASSERT(chunks[1].length == 26);
493 OSMO_ASSERT(chunks[1].is_complete);
494 OSMO_ASSERT(chunks[2].offset == 43);
495 OSMO_ASSERT(chunks[2].length == 1);
496 OSMO_ASSERT(!chunks[2].is_complete);
497
498 printf("=== end %s ===\n", __func__);
499}
500
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100501static void test_rlc_unit_encoder()
502{
503 struct gprs_rlc_data_block_info rdbi = {0};
504 GprsCodingScheme cs;
505 uint8_t data[74];
506 uint8_t llc_data[1500] = {0,};
507 int num_chunks = 0;
508 int write_offset;
509 struct gprs_llc llc;
510 Encoding::AppendResult ar;
511
512 printf("=== start %s ===\n", __func__);
513
514 llc.init();
515
516 /* TS 44.060, B.1 */
517 cs = GprsCodingScheme::CS4;
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100518 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100519 num_chunks = 0;
520 write_offset = 0;
521 memset(data, 0, sizeof(data));
522
523 llc.reset();
524 llc.put_frame(llc_data, 11);
525
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100526 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100527 &llc, &write_offset, &num_chunks, data, false);
528
529 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
530 OSMO_ASSERT(rdbi.e == 0);
531 OSMO_ASSERT(write_offset == 1 + 11);
532 OSMO_ASSERT(num_chunks == 1);
533
534 llc.reset();
535 llc.put_frame(llc_data, 26);
536
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100537 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100538 &llc, &write_offset, &num_chunks, data, false);
539
540 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
541 OSMO_ASSERT(rdbi.e == 0);
542 OSMO_ASSERT(write_offset == 2 + 11 + 26);
543 OSMO_ASSERT(num_chunks == 2);
544
545 llc.reset();
546 llc.put_frame(llc_data, 99);
547
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100548 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100549 &llc, &write_offset, &num_chunks, data, false);
550
551 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
552 OSMO_ASSERT(rdbi.e == 0);
553 OSMO_ASSERT(rdbi.cv != 0);
554 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
555 OSMO_ASSERT(num_chunks == 3);
556
557 OSMO_ASSERT(data[0] == ((11 << 2) | (1 << 1) | (0 << 0)));
558 OSMO_ASSERT(data[1] == ((26 << 2) | (1 << 1) | (1 << 0)));
559 OSMO_ASSERT(data[2] == 0);
560
561 /* TS 44.060, B.2 */
562 cs = GprsCodingScheme::CS1;
563
564 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100565 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100566 num_chunks = 0;
567 write_offset = 0;
568 memset(data, 0, sizeof(data));
569
570 llc.reset();
571 llc.put_frame(llc_data, 20);
572
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100573 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100574 &llc, &write_offset, &num_chunks, data, false);
575
576 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
577 OSMO_ASSERT(rdbi.e == 0);
578 OSMO_ASSERT(write_offset == 1 + 19);
579 OSMO_ASSERT(num_chunks == 1);
580
581 OSMO_ASSERT(data[0] == ((0 << 2) | (0 << 1) | (1 << 0)));
582 OSMO_ASSERT(data[1] == 0);
583
584 /* Block 2 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100585 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100586 num_chunks = 0;
587 write_offset = 0;
588 memset(data, 0, sizeof(data));
589
590 OSMO_ASSERT(llc.chunk_size() == 1);
591
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100592 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100593 &llc, &write_offset, &num_chunks, data, false);
594
595 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
596 OSMO_ASSERT(rdbi.e == 0);
597 OSMO_ASSERT(write_offset == 1 + 1);
598 OSMO_ASSERT(num_chunks == 1);
599
600 llc.reset();
601 llc.put_frame(llc_data, 99);
602
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100603 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100604 &llc, &write_offset, &num_chunks, data, false);
605
606 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
607 OSMO_ASSERT(rdbi.e == 0);
608 OSMO_ASSERT(write_offset == 1 + 1 + 18);
609 OSMO_ASSERT(num_chunks == 2);
610
611 OSMO_ASSERT(data[0] == ((1 << 2) | (1 << 1) | (1 << 0)));
612 OSMO_ASSERT(data[1] == 0);
613
614 /* TS 44.060, B.3 */
615 cs = GprsCodingScheme::CS1;
616
617 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100618 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100619 num_chunks = 0;
620 write_offset = 0;
621 memset(data, 0, sizeof(data));
622
623 llc.reset();
624 llc.put_frame(llc_data, 7);
625
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100626 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100627 &llc, &write_offset, &num_chunks, data, false);
628
629 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
630 OSMO_ASSERT(rdbi.e == 0);
631 OSMO_ASSERT(write_offset == 1 + 7);
632 OSMO_ASSERT(num_chunks == 1);
633
634 llc.reset();
635 llc.put_frame(llc_data, 11);
636
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100637 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100638 &llc, &write_offset, &num_chunks, data, false);
639
640 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
641 OSMO_ASSERT(rdbi.e == 0);
642 OSMO_ASSERT(write_offset == 2 + 7 + 11);
643 OSMO_ASSERT(num_chunks == 2);
644
645 OSMO_ASSERT(data[0] == ((7 << 2) | (1 << 1) | (0 << 0)));
646 OSMO_ASSERT(data[1] == ((11 << 2) | (0 << 1) | (1 << 0)));
647 OSMO_ASSERT(data[2] == 0);
648
649 /* TS 44.060, B.4 */
650 cs = GprsCodingScheme::CS1;
651
652 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100653 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100654 num_chunks = 0;
655 write_offset = 0;
656 memset(data, 0, sizeof(data));
657
658 llc.reset();
659 llc.put_frame(llc_data, 99);
660
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100661 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100662 &llc, &write_offset, &num_chunks, data, false);
663
664 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
665 OSMO_ASSERT(rdbi.e == 1);
666 OSMO_ASSERT(write_offset == 20);
667 OSMO_ASSERT(num_chunks == 1);
668 OSMO_ASSERT(rdbi.cv != 0);
669
670 OSMO_ASSERT(data[0] == 0);
671
672 /* TS 44.060, B.5 */
673 cs = GprsCodingScheme::CS1;
674
675 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100676 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100677 num_chunks = 0;
678 write_offset = 0;
679 memset(data, 0, sizeof(data));
680
681 llc.reset();
682 llc.put_frame(llc_data, 20);
683
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100684 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100685 &llc, &write_offset, &num_chunks, data, true);
686
687 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
688 OSMO_ASSERT(rdbi.e == 1);
689 OSMO_ASSERT(write_offset == 20);
690 OSMO_ASSERT(num_chunks == 1);
691 OSMO_ASSERT(rdbi.cv == 0);
692
693 OSMO_ASSERT(data[0] == 0);
694
695 /* TS 44.060, B.7 */
696 cs = GprsCodingScheme::CS1;
697
698 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100699 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100700 num_chunks = 0;
701 write_offset = 0;
702 memset(data, 0, sizeof(data));
703
704 llc.reset();
705 llc.put_frame(llc_data, 30);
706
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100707 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100708 &llc, &write_offset, &num_chunks, data, false);
709
710 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
711 OSMO_ASSERT(rdbi.e == 1);
712 OSMO_ASSERT(write_offset == 20);
713 OSMO_ASSERT(num_chunks == 1);
714
715 OSMO_ASSERT(data[0] == 0);
716
717 /* Block 2 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100718 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100719 num_chunks = 0;
720 write_offset = 0;
721 memset(data, 0, sizeof(data));
722
723 OSMO_ASSERT(llc.chunk_size() == 10);
724
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100725 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100726 &llc, &write_offset, &num_chunks, data, false);
727
728 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
729 OSMO_ASSERT(rdbi.e == 0);
730 OSMO_ASSERT(write_offset == 1 + 10);
731 OSMO_ASSERT(num_chunks == 1);
732
733 llc.reset();
734 llc.put_frame(llc_data, 99);
735
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100736 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100737 &llc, &write_offset, &num_chunks, data, false);
738
739 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
740 OSMO_ASSERT(rdbi.e == 0);
741 OSMO_ASSERT(write_offset == 1 + 10 + 9);
742 OSMO_ASSERT(num_chunks == 2);
743
744 OSMO_ASSERT(data[0] == ((10 << 2) | (1 << 1) | (1 << 0)));
745 OSMO_ASSERT(data[1] == 0);
746
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100747 /* TS 44.060, B.8.1 */
748 cs = GprsCodingScheme::MCS4;
749
750 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100751 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100752 num_chunks = 0;
753 write_offset = 0;
754 memset(data, 0, sizeof(data));
755
756 llc.reset();
757 llc.put_frame(llc_data, 11);
758
759 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
760 &llc, &write_offset, &num_chunks, data, false);
761
762 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
763 OSMO_ASSERT(rdbi.e == 0);
764 OSMO_ASSERT(write_offset == 1 + 11);
765 OSMO_ASSERT(num_chunks == 1);
766
767 llc.reset();
768 llc.put_frame(llc_data, 26);
769
770 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
771 &llc, &write_offset, &num_chunks, data, false);
772
773 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
774 OSMO_ASSERT(rdbi.e == 0);
775 OSMO_ASSERT(write_offset == 2 + 11 + 26);
776 OSMO_ASSERT(num_chunks == 2);
777
778 llc.reset();
779 llc.put_frame(llc_data, 99);
780
781 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
782 &llc, &write_offset, &num_chunks, data, false);
783
784 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
785 OSMO_ASSERT(rdbi.e == 0);
786 OSMO_ASSERT(rdbi.cv != 0);
787 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
788 OSMO_ASSERT(num_chunks == 3);
789
790 OSMO_ASSERT(data[0] == ((11 << 1) | (0 << 0)));
791 OSMO_ASSERT(data[1] == ((26 << 1) | (1 << 0)));
792 OSMO_ASSERT(data[2] == 0);
793
794 /* TS 44.060, B.8.2 */
795
796 /* Note that the spec confuses the byte numbering here, since it
797 * includes the FBI/E header bits into the N2 octet count which
798 * is not consistent with Section 10.3a.1 & 10.3a.2. */
799
800 cs = GprsCodingScheme::MCS2;
801
802 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100803 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100804 num_chunks = 0;
805 write_offset = 0;
806 memset(data, 0, sizeof(data));
807
808 llc.reset();
809 llc.put_frame(llc_data, 15);
810
811 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
812 &llc, &write_offset, &num_chunks, data, false);
813
814 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
815 OSMO_ASSERT(rdbi.e == 0);
816 OSMO_ASSERT(write_offset == 1 + 15);
817 OSMO_ASSERT(num_chunks == 1);
818
819 llc.reset();
820 llc.put_frame(llc_data, 12);
821
822 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
823 &llc, &write_offset, &num_chunks, data, false);
824
825 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
826 OSMO_ASSERT(rdbi.e == 0);
827 OSMO_ASSERT(rdbi.cv != 0);
828 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
829 OSMO_ASSERT(num_chunks == 2);
830
831 OSMO_ASSERT(data[0] == ((15 << 1) | (1 << 0)));
832 OSMO_ASSERT(data[1] == 0);
833
834 /* Block 2 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100835 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100836 num_chunks = 0;
837 write_offset = 0;
838 memset(data, 0, sizeof(data));
839
840 OSMO_ASSERT(llc.chunk_size() == 0);
841
842 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
843 &llc, &write_offset, &num_chunks, data, false);
844
845 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
846 OSMO_ASSERT(rdbi.e == 0);
847 OSMO_ASSERT(write_offset == 1 + 0);
848 OSMO_ASSERT(num_chunks == 1);
849
850 llc.reset();
851 llc.put_frame(llc_data, 7);
852
853 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
854 &llc, &write_offset, &num_chunks, data, false);
855
856 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
857 OSMO_ASSERT(rdbi.e == 0);
858 OSMO_ASSERT(rdbi.cv != 0);
859 OSMO_ASSERT(write_offset == 2 + 0 + 7);
860 OSMO_ASSERT(num_chunks == 2);
861
862 llc.reset();
863 llc.put_frame(llc_data, 18);
864
865 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
866 &llc, &write_offset, &num_chunks, data, false);
867
868 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
869 OSMO_ASSERT(rdbi.e == 0);
870 OSMO_ASSERT(rdbi.cv != 0);
871 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
872 OSMO_ASSERT(num_chunks == 3);
873
874 OSMO_ASSERT(data[0] == ((0 << 1) | (0 << 0)));
875 OSMO_ASSERT(data[1] == ((7 << 1) | (0 << 0)));
876 OSMO_ASSERT(data[2] == ((18 << 1) | (1 << 0)));
877 OSMO_ASSERT(data[3] == 0);
878
879 /* Block 3 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100880 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100881 num_chunks = 0;
882 write_offset = 0;
883 memset(data, 0, sizeof(data));
884
885 llc.reset();
886 llc.put_frame(llc_data, 6);
887
888 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
889 &llc, &write_offset, &num_chunks, data, false);
890
891 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
892 OSMO_ASSERT(rdbi.e == 0);
893 OSMO_ASSERT(write_offset == 1 + 6);
894 OSMO_ASSERT(num_chunks == 1);
895
896 llc.reset();
897 llc.put_frame(llc_data, 12);
898
899 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
900 &llc, &write_offset, &num_chunks, data, true);
901
902 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
903 OSMO_ASSERT(rdbi.e == 0);
904 OSMO_ASSERT(rdbi.cv == 0);
905 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
906 OSMO_ASSERT(num_chunks == 3);
907
908 OSMO_ASSERT(data[0] == ((6 << 1) | (0 << 0)));
909 OSMO_ASSERT(data[1] == ((12 << 1) | (0 << 0)));
910 OSMO_ASSERT(data[2] == ((127 << 1) | (1 << 0)));
911 OSMO_ASSERT(data[3] == 0);
912
913 /* TS 44.060, B.8.3 */
914
915 /* Note that the spec confuses the byte numbering here, too (see above) */
916
917 cs = GprsCodingScheme::MCS2;
918
919 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100920 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100921 num_chunks = 0;
922 write_offset = 0;
923 memset(data, 0, sizeof(data));
924
925 llc.reset();
926 llc.put_frame(llc_data, rdbi.data_len);
927
928 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
929 &llc, &write_offset, &num_chunks, data, true);
930
931 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
932 OSMO_ASSERT(rdbi.e == 1);
933 OSMO_ASSERT(rdbi.cv == 0);
934 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
935 OSMO_ASSERT(num_chunks == 1);
936
937 OSMO_ASSERT(data[0] == 0);
938
939 /* Final block with an LLC of size data_len-1 */
940
941 cs = GprsCodingScheme::MCS2;
942
943 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100944 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100945 num_chunks = 0;
946 write_offset = 0;
947 memset(data, 0, sizeof(data));
948
949 llc.reset();
950 llc.put_frame(llc_data, rdbi.data_len - 1);
951
952 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
953 &llc, &write_offset, &num_chunks, data, true);
954
955 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
956 OSMO_ASSERT(rdbi.e == 0);
957 OSMO_ASSERT(rdbi.cv == 0);
958 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
959 OSMO_ASSERT(num_chunks == 1);
960
961 OSMO_ASSERT(data[0] == (((rdbi.data_len-1) << 1) | (1 << 0)));
962 OSMO_ASSERT(data[1] == 0);
963
964 /* Final block with an LLC of size data_len-2 */
965
966 cs = GprsCodingScheme::MCS2;
967
968 /* Block 1 */
Jacob Erlbeckb55f3132016-02-03 18:28:04 +0100969 gprs_rlc_data_block_info_init(&rdbi, cs, false);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100970 num_chunks = 0;
971 write_offset = 0;
972 memset(data, 0, sizeof(data));
973
974 llc.reset();
975 llc.put_frame(llc_data, rdbi.data_len - 2);
976
977 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
978 &llc, &write_offset, &num_chunks, data, true);
979
980 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
981 OSMO_ASSERT(rdbi.e == 0);
982 OSMO_ASSERT(rdbi.cv == 0);
983 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
984 OSMO_ASSERT(num_chunks == 2);
985
986 OSMO_ASSERT(data[0] == (((rdbi.data_len-2) << 1) | (0 << 0)));
987 OSMO_ASSERT(data[1] == ((127 << 1) | (1 << 0)));
988 OSMO_ASSERT(data[2] == 0);
989
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100990 printf("=== end %s ===\n", __func__);
991}
992
Jacob Erlbeckf0e40392016-01-08 10:07:53 +0100993static void test_rlc_unaligned_copy()
994{
995 uint8_t bits[256];
996 uint8_t saved_block[256];
997 uint8_t test_block[256];
998 uint8_t out_block[256];
999 GprsCodingScheme::Scheme scheme;
1000 int pattern;
1001 volatile unsigned int block_idx, i;
1002
1003 for (scheme = GprsCodingScheme::CS1;
1004 scheme < GprsCodingScheme::NUM_SCHEMES;
1005 scheme = GprsCodingScheme::Scheme(scheme + 1))
1006 {
1007 GprsCodingScheme cs(scheme);
1008
1009 for (pattern = 0; pattern <= 0xff; pattern += 0xff) {
1010 /* prepare test block */
1011 test_block[0] = pattern ^ 0xff;
1012 for (i = 1; i + 1 < cs.maxDataBlockBytes(); i++)
1013 test_block[i] = i;
1014 test_block[cs.maxDataBlockBytes()-1] = pattern ^ 0xff;
1015
1016 for (block_idx = 0;
1017 block_idx < cs.numDataBlocks();
1018 block_idx++)
1019 {
1020 struct gprs_rlc_data_info rlc;
Jacob Erlbeckb55f3132016-02-03 18:28:04 +01001021 gprs_rlc_data_info_init_dl(&rlc, cs, false);
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001022
1023 memset(bits, pattern, sizeof(bits));
1024 Decoding::rlc_copy_to_aligned_buffer(
1025 &rlc, block_idx, bits, saved_block);
1026
1027 fprintf(stderr,
1028 "Test data block: %s\n",
1029 osmo_hexdump(test_block, cs.maxDataBlockBytes()));
1030
1031 Encoding::rlc_copy_from_aligned_buffer(
1032 &rlc, block_idx, bits, test_block);
1033
1034 fprintf(stderr,
1035 "Encoded message block, %s, idx %d, "
1036 "pattern %02x: %s\n",
1037 rlc.cs.name(), block_idx, pattern,
1038 osmo_hexdump(bits, cs.sizeDL()));
1039
1040 Decoding::rlc_copy_to_aligned_buffer(
1041 &rlc, block_idx, bits, out_block);
1042
1043 fprintf(stderr,
1044 "Out data block: %s\n",
1045 osmo_hexdump(out_block, cs.maxDataBlockBytes()));
1046 /* restore original bits */
1047 Encoding::rlc_copy_from_aligned_buffer(
1048 &rlc, block_idx, bits, saved_block);
1049
1050 OSMO_ASSERT(memcmp(test_block, out_block,
1051 rlc.cs.maxDataBlockBytes()) == 0);
1052
1053 for (i = 0; i < sizeof(bits); i++)
1054 OSMO_ASSERT(bits[i] == pattern);
1055 }
1056 }
1057 }
1058}
1059
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +01001060static void test_rlc_info_init()
1061{
1062 struct gprs_rlc_data_info rlc;
1063
1064 printf("=== start %s ===\n", __func__);
Jacob Erlbeckb55f3132016-02-03 18:28:04 +01001065 gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::CS1), false);
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +01001066 OSMO_ASSERT(rlc.num_data_blocks == 1);
1067 OSMO_ASSERT(rlc.data_offs_bits[0] == 24);
1068 OSMO_ASSERT(rlc.block_info[0].data_len == 20);
1069
Jacob Erlbeckb55f3132016-02-03 18:28:04 +01001070 gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::MCS1), false);
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +01001071 OSMO_ASSERT(rlc.num_data_blocks == 1);
1072 OSMO_ASSERT(rlc.data_offs_bits[0] == 33);
1073 OSMO_ASSERT(rlc.block_info[0].data_len == 22);
1074
1075 printf("=== end %s ===\n", __func__);
1076}
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001077
1078static const struct log_info_cat default_categories[] = {
1079 {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0},
1080 {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1},
1081 {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1},
1082 {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1},
1083 {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1},
1084 {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1},
1085 {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1},
1086 {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1},
1087 {"DNS","\033[1;34m", "GPRS Network Service Protocol (NS)", LOGL_INFO , 1},
1088 {"DBSSGP","\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO , 1},
1089 {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1},
1090};
1091
1092static int filter_fn(const struct log_context *ctx,
1093 struct log_target *tar)
1094{
1095 return 1;
1096}
1097
1098const struct log_info debug_log_info = {
1099 filter_fn,
1100 (struct log_info_cat*)default_categories,
1101 ARRAY_SIZE(default_categories),
1102};
1103
1104int main(int argc, char **argv)
1105{
1106 struct vty_app_info pcu_vty_info = {0};
1107
1108 tall_pcu_ctx = talloc_named_const(NULL, 1, "EdgeTest context");
1109 if (!tall_pcu_ctx)
1110 abort();
1111
1112 msgb_set_talloc_ctx(tall_pcu_ctx);
1113 osmo_init_logging(&debug_log_info);
1114 log_set_use_color(osmo_stderr_target, 0);
1115 log_set_print_filename(osmo_stderr_target, 0);
1116
1117 vty_init(&pcu_vty_info);
1118 pcu_vty_init(&debug_log_info);
1119
1120 test_coding_scheme();
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +01001121 test_rlc_info_init();
Jacob Erlbeck38f18692016-02-01 10:08:00 +01001122 test_rlc_unit_decoder();
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001123 test_rlc_unaligned_copy();
Jacob Erlbeck14bb0942016-01-12 11:58:13 +01001124 test_rlc_unit_encoder();
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001125
1126 if (getenv("TALLOC_REPORT_FULL"))
1127 talloc_report_full(tall_pcu_ctx, stderr);
1128 return EXIT_SUCCESS;
1129}
1130
1131/*
1132 * stubs that should not be reached
1133 */
1134extern "C" {
1135void l1if_pdch_req() { abort(); }
1136void l1if_connect_pdch() { abort(); }
1137void l1if_close_pdch() { abort(); }
1138void l1if_open_pdch() { abort(); }
1139}