blob: 02a356835ef7994aefe7dbf50196c53269d955df [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"
Jacob Erlbeck61679252015-12-11 18:25:21 +010024#include "decoding.h"
Jacob Erlbeckf0e40392016-01-08 10:07:53 +010025#include "encoding.h"
Jacob Erlbeck61679252015-12-11 18:25:21 +010026#include "rlc.h"
Jacob Erlbeck14bb0942016-01-12 11:58:13 +010027#include "llc.h"
Aravind Sirsikar189742b2016-06-14 19:01:14 +053028#include "bts.h"
Max1187a772018-01-26 13:31:42 +010029#include <gprs_rlcmac.h>
30
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010031extern "C" {
32#include "pcu_vty.h"
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020033#include "coding_scheme.h"
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010034
35#include <osmocom/core/application.h>
36#include <osmocom/core/msgb.h>
37#include <osmocom/core/talloc.h>
38#include <osmocom/core/utils.h>
39#include <osmocom/vty/vty.h>
Tom Tsoudf698092016-07-11 17:05:19 -070040#include <osmocom/gprs/protocol/gsm_04_60.h>
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010041}
42
43#include <errno.h>
Jacob Erlbeckf0e40392016-01-08 10:07:53 +010044#include <string.h>
Neels Hofmeyrd34646a2017-02-08 17:07:40 +010045#include <limits.h>
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010046
47void *tall_pcu_ctx;
48int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010049bool spoof_mnc_3_digits = false;
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010050
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020051static void check_coding_scheme(enum CodingScheme& cs, enum mcs_kind mode)
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010052{
53 volatile unsigned expected_size;
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010054 bool need_padding;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020055 enum CodingScheme new_cs;
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010056
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020057 OSMO_ASSERT(mcs_is_valid(cs));
58 OSMO_ASSERT(mcs_is_compat_kind(cs, mode));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010059
60 /* Check static getBySizeUL() */
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020061 expected_size = mcs_used_size_ul(cs);
62 if (mcs_spare_bits_ul(cs) > 0 && mcs_is_gprs(cs))
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010063 expected_size += 1;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020064 OSMO_ASSERT(expected_size == mcs_size_ul(cs));
65 OSMO_ASSERT(cs == mcs_get_by_size_ul(expected_size));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010066
67 /* Check static sizeUL() */
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020068 expected_size = mcs_used_size_dl(cs);
69 if (mcs_spare_bits_dl(cs) > 0 && mcs_is_gprs(cs))
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010070 expected_size += 1;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020071 OSMO_ASSERT(expected_size == mcs_size_dl(cs));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010072
Jacob Erlbeck392a5452015-12-14 10:38:29 +010073 /* Check data block sizes */
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020074 OSMO_ASSERT(mcs_max_data_block_bytes(cs) * num_data_blocks(mcs_header_type(cs)) < mcs_max_bytes_dl(cs));
75 OSMO_ASSERT(mcs_max_data_block_bytes(cs) * num_data_blocks(mcs_header_type(cs)) < mcs_max_bytes_ul(cs));
Jacob Erlbeck392a5452015-12-14 10:38:29 +010076
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010077 /* Check inc/dec */
78 new_cs = cs;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020079 mcs_inc_kind(&new_cs, mode);
80 OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010081 if (new_cs != cs) {
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020082 mcs_dec_kind(&new_cs, mode);
83 OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010084 OSMO_ASSERT(new_cs == cs);
85 }
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020086 mcs_dec_kind(&new_cs, mode);
87 OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010088 if (new_cs != cs) {
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020089 mcs_inc_kind(&new_cs, mode);
90 OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +010091 OSMO_ASSERT(new_cs == cs);
92 }
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010093
94 new_cs = cs;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020095 mcs_dec_to_single_block(&new_cs, &need_padding);
96 OSMO_ASSERT(mcs_is_family_compat(new_cs, cs));
97 OSMO_ASSERT(mcs_is_family_compat(cs, new_cs));
98 OSMO_ASSERT(mcs_is_compat(cs, new_cs));
Jacob Erlbeck2305afd2016-02-03 15:25:04 +010099 if (need_padding) {
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200100 OSMO_ASSERT(mcs_max_data_block_bytes(new_cs) ==
101 mcs_opt_padding_bits(new_cs)/8 + mcs_max_data_block_bytes(cs));
Jacob Erlbeck2305afd2016-02-03 15:25:04 +0100102 } else {
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200103 OSMO_ASSERT(mcs_max_data_block_bytes(new_cs) == mcs_max_data_block_bytes(cs));
Jacob Erlbeck2305afd2016-02-03 15:25:04 +0100104 }
105
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100106}
107
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200108static bool check_strong_monotonicity(const enum CodingScheme cs, uint8_t last_UL, uint8_t last_DL)
Max360e0212019-02-26 17:20:41 +0100109{
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200110 if (mcs_max_bytes_ul(cs) <= last_UL)
Max360e0212019-02-26 17:20:41 +0100111 return false;
112
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200113 if (mcs_max_bytes_dl(cs) <= last_DL)
Max360e0212019-02-26 17:20:41 +0100114 return false;
115
116 return true;
117}
118
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100119static void test_coding_scheme()
120{
121 unsigned i;
Max360e0212019-02-26 17:20:41 +0100122 uint8_t last_size_UL;
123 uint8_t last_size_DL;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200124 enum CodingScheme gprs_schemes[] = {
Maxbea2edb2019-03-06 17:04:59 +0100125 CS1,
126 CS2,
127 CS3,
128 CS4
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100129 };
130 struct {
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200131 enum CodingScheme s;
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100132 bool is_gmsk;
133 } egprs_schemes[] = {
Maxbea2edb2019-03-06 17:04:59 +0100134 { MCS1, true},
135 { MCS2, true},
136 { MCS3, true},
137 { MCS4, true},
138 { MCS5, false},
139 { MCS6, false},
140 { MCS7, false},
141 { MCS8, false},
142 { MCS9, false},
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100143 };
144
145 printf("=== start %s ===\n", __func__);
146
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200147 enum CodingScheme cs = UNKNOWN;
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100148 OSMO_ASSERT(!cs);
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200149 OSMO_ASSERT(!mcs_is_compat_kind(cs, GPRS));
150 OSMO_ASSERT(!mcs_is_compat_kind(cs, EGPRS_GMSK));
151 OSMO_ASSERT(!mcs_is_compat_kind(cs, EGPRS));
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100152
153 last_size_UL = 0;
154 last_size_DL = 0;
155
156 for (i = 0; i < ARRAY_SIZE(gprs_schemes); i++) {
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200157 enum CodingScheme current_cs = gprs_schemes[i];
Max8a8e0fb2019-03-25 16:32:50 +0100158 OSMO_ASSERT(mcs_is_gprs(current_cs));
159 OSMO_ASSERT(!mcs_is_edge(current_cs));
160 OSMO_ASSERT(!mcs_is_edge_gmsk(current_cs));
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200161 OSMO_ASSERT(current_cs == gprs_schemes[i]);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100162
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200163 OSMO_ASSERT(check_strong_monotonicity(current_cs, last_size_UL, last_size_DL));
164 last_size_UL = mcs_max_bytes_ul(current_cs);
165 last_size_DL = mcs_max_bytes_dl(current_cs);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100166
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +0100167 /* Check header types */
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200168 OSMO_ASSERT(mcs_header_type(current_cs) == HEADER_GPRS_DATA);
Jacob Erlbeck6c3dc612015-12-14 10:21:26 +0100169
Maxa4de02d2019-03-13 16:35:09 +0100170 check_coding_scheme(current_cs, GPRS);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100171 }
172 OSMO_ASSERT(i == 4);
173
174 last_size_UL = 0;
175 last_size_DL = 0;
176
177 for (i = 0; i < ARRAY_SIZE(egprs_schemes); i++) {
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200178 enum CodingScheme current_cs = egprs_schemes[i].s;
Max8a8e0fb2019-03-25 16:32:50 +0100179 OSMO_ASSERT(!mcs_is_gprs(current_cs));
180 OSMO_ASSERT(mcs_is_edge(current_cs));
181 OSMO_ASSERT(mcs_is_edge_gmsk(current_cs) == !!egprs_schemes[i].is_gmsk);
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200182 OSMO_ASSERT(current_cs == egprs_schemes[i].s);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100183
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200184 OSMO_ASSERT(check_strong_monotonicity(current_cs, last_size_UL, last_size_DL));
185 last_size_UL = mcs_max_bytes_ul(current_cs);
186 last_size_DL = mcs_max_bytes_dl(current_cs);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100187
188 if (egprs_schemes[i].is_gmsk)
Maxa4de02d2019-03-13 16:35:09 +0100189 check_coding_scheme(current_cs, EGPRS_GMSK);
190 check_coding_scheme(current_cs, EGPRS);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +0100191 }
192 OSMO_ASSERT(i == 9);
193
194 printf("=== end %s ===\n", __func__);
195}
196
Jacob Erlbeck38f18692016-02-01 10:08:00 +0100197static void test_rlc_unit_decoder()
Jacob Erlbeck61679252015-12-11 18:25:21 +0100198{
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100199 struct gprs_rlc_data_block_info rdbi = {0};
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200200 enum CodingScheme cs;
Jacob Erlbeck61679252015-12-11 18:25:21 +0100201 uint8_t data[74];
202 Decoding::RlcData chunks[16];
203 volatile int num_chunks = 0;
204 uint32_t tlli, tlli2;
205 unsigned int offs;
206
207
208 printf("=== start %s ===\n", __func__);
209
210 /* TS 44.060, B.1 */
Maxbea2edb2019-03-06 17:04:59 +0100211 cs = CS4;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200212 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100213 rdbi.e = 0;
214 rdbi.ti = 0;
215 rdbi.cv = 15;
216 tlli = 0;
217 offs = 0;
218 data[offs++] = (11 << 2) | (1 << 1) | (0 << 0);
219 data[offs++] = (26 << 2) | (1 << 1) | (1 << 0);
220 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
221 chunks, ARRAY_SIZE(chunks), &tlli);
222 OSMO_ASSERT(num_chunks == 3);
223 OSMO_ASSERT(tlli == 0);
224 OSMO_ASSERT(chunks[0].offset == 2);
225 OSMO_ASSERT(chunks[0].length == 11);
226 OSMO_ASSERT(chunks[0].is_complete);
227 OSMO_ASSERT(chunks[1].offset == 13);
228 OSMO_ASSERT(chunks[1].length == 26);
229 OSMO_ASSERT(chunks[1].is_complete);
230 OSMO_ASSERT(chunks[2].offset == 39);
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200231 OSMO_ASSERT(chunks[2].length == mcs_max_data_block_bytes(cs) - 39);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100232 OSMO_ASSERT(!chunks[2].is_complete);
233
234 /* TS 44.060, B.2 */
Maxbea2edb2019-03-06 17:04:59 +0100235 cs = CS1;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200236 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100237 rdbi.e = 0;
238 rdbi.ti = 0;
239 rdbi.cv = 15;
240 tlli = 0;
241 offs = 0;
242 data[offs++] = (0 << 2) | (0 << 1) | (1 << 0);
243 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
244 chunks, ARRAY_SIZE(chunks), &tlli);
245 OSMO_ASSERT(num_chunks == 1);
246 OSMO_ASSERT(tlli == 0);
247 OSMO_ASSERT(chunks[0].offset == 1);
248 OSMO_ASSERT(chunks[0].length == 19);
249 OSMO_ASSERT(!chunks[0].is_complete);
250
251 rdbi.e = 0;
252 rdbi.ti = 0;
253 rdbi.cv = 15;
254 tlli = 0;
255 offs = 0;
256 data[offs++] = (1 << 2) | (1 << 1) | (1 << 0);
257 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
258 chunks, ARRAY_SIZE(chunks), &tlli);
259 OSMO_ASSERT(num_chunks == 2);
260 OSMO_ASSERT(tlli == 0);
261 OSMO_ASSERT(chunks[0].offset == 1);
262 OSMO_ASSERT(chunks[0].length == 1);
263 OSMO_ASSERT(chunks[0].is_complete);
264 OSMO_ASSERT(chunks[1].offset == 2);
265 OSMO_ASSERT(chunks[1].length == 18);
266 OSMO_ASSERT(!chunks[1].is_complete);
267
268 /* TS 44.060, B.3 */
Maxbea2edb2019-03-06 17:04:59 +0100269 cs = CS1;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200270 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100271 rdbi.e = 0;
272 rdbi.ti = 0;
273 rdbi.cv = 15;
274 tlli = 0;
275 offs = 0;
276 data[offs++] = (7 << 2) | (1 << 1) | (0 << 0);
277 data[offs++] = (11 << 2) | (0 << 1) | (1 << 0);
278 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
279 chunks, ARRAY_SIZE(chunks), &tlli);
280 OSMO_ASSERT(num_chunks == 2);
281 OSMO_ASSERT(tlli == 0);
282 OSMO_ASSERT(chunks[0].offset == 2);
283 OSMO_ASSERT(chunks[0].length == 7);
284 OSMO_ASSERT(chunks[0].is_complete);
285 OSMO_ASSERT(chunks[1].offset == 9);
286 OSMO_ASSERT(chunks[1].length == 11);
287 OSMO_ASSERT(chunks[1].is_complete);
288
289 /* TS 44.060, B.4 */
Maxbea2edb2019-03-06 17:04:59 +0100290 cs = CS1;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200291 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100292 rdbi.e = 1;
293 rdbi.ti = 0;
294 rdbi.cv = 15;
295 tlli = 0;
296 offs = 0;
297 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
298 chunks, ARRAY_SIZE(chunks), &tlli);
299 OSMO_ASSERT(num_chunks == 1);
300 OSMO_ASSERT(tlli == 0);
301 OSMO_ASSERT(chunks[0].offset == 0);
302 OSMO_ASSERT(chunks[0].length == 20);
303 OSMO_ASSERT(!chunks[0].is_complete);
304
305 /* TS 44.060, B.6 */
Maxbea2edb2019-03-06 17:04:59 +0100306 cs = CS1;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200307 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100308 rdbi.e = 1;
309 rdbi.ti = 0;
310 rdbi.cv = 0;
311 tlli = 0;
312 offs = 0;
313 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
314 chunks, ARRAY_SIZE(chunks), &tlli);
315 OSMO_ASSERT(num_chunks == 1);
316 OSMO_ASSERT(tlli == 0);
317 OSMO_ASSERT(chunks[0].offset == 0);
318 OSMO_ASSERT(chunks[0].length == 20);
319 OSMO_ASSERT(chunks[0].is_complete);
320
321 /* TS 44.060, B.8.1 */
Maxbea2edb2019-03-06 17:04:59 +0100322 cs = MCS4;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200323 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100324 rdbi.e = 0;
325 rdbi.ti = 0;
326 rdbi.cv = 15;
327 tlli = 0;
328 offs = 0;
329 data[offs++] = (11 << 1) | (0 << 0);
330 data[offs++] = (26 << 1) | (1 << 0);
331 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
332 chunks, ARRAY_SIZE(chunks), &tlli);
333 OSMO_ASSERT(num_chunks == 3);
334 OSMO_ASSERT(tlli == 0);
335 OSMO_ASSERT(chunks[0].offset == 2);
336 OSMO_ASSERT(chunks[0].length == 11);
337 OSMO_ASSERT(chunks[0].is_complete);
338 OSMO_ASSERT(chunks[1].offset == 13);
339 OSMO_ASSERT(chunks[1].length == 26);
340 OSMO_ASSERT(chunks[1].is_complete);
341 OSMO_ASSERT(chunks[2].offset == 39);
342 OSMO_ASSERT(chunks[2].length == 5);
343 OSMO_ASSERT(!chunks[2].is_complete);
344
345 /* TS 44.060, B.8.2 */
346
347 /* Note that the spec confuses the byte numbering here, since it
348 * includes the FBI/E header bits into the N2 octet count which
349 * is not consistent with Section 10.3a.1 & 10.3a.2. */
350
Maxbea2edb2019-03-06 17:04:59 +0100351 cs = MCS2;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200352 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100353 rdbi.e = 0;
354 rdbi.ti = 0;
355 rdbi.cv = 15;
356 tlli = 0;
357 offs = 0;
358 data[offs++] = (15 << 1) | (1 << 0);
359 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
360 chunks, ARRAY_SIZE(chunks), &tlli);
361 OSMO_ASSERT(num_chunks == 2);
362 OSMO_ASSERT(tlli == 0);
363 OSMO_ASSERT(chunks[0].offset == 1);
364 OSMO_ASSERT(chunks[0].length == 15);
365 OSMO_ASSERT(chunks[0].is_complete);
366 OSMO_ASSERT(chunks[1].offset == 16);
367 OSMO_ASSERT(chunks[1].length == 12);
368 OSMO_ASSERT(!chunks[1].is_complete);
369
370 rdbi.e = 0;
371 rdbi.ti = 0;
372 rdbi.cv = 15;
373 tlli = 0;
374 offs = 0;
375 data[offs++] = ( 0 << 1) | (0 << 0);
376 data[offs++] = ( 7 << 1) | (0 << 0);
377 data[offs++] = (18 << 1) | (1 << 0); /* Differs from spec's N2-11 = 17 */
378 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
379 chunks, ARRAY_SIZE(chunks), &tlli);
380 OSMO_ASSERT(num_chunks == 3);
381 OSMO_ASSERT(tlli == 0);
382 OSMO_ASSERT(chunks[0].offset == 3);
383 OSMO_ASSERT(chunks[0].length == 0);
384 OSMO_ASSERT(chunks[0].is_complete);
385 OSMO_ASSERT(chunks[1].offset == 3);
386 OSMO_ASSERT(chunks[1].length == 7);
387 OSMO_ASSERT(chunks[1].is_complete);
388 OSMO_ASSERT(chunks[2].offset == 10);
389 OSMO_ASSERT(chunks[2].length == 18);
390 OSMO_ASSERT(chunks[2].is_complete);
391
392 rdbi.e = 0;
393 rdbi.ti = 0;
394 rdbi.cv = 0;
395 tlli = 0;
396 offs = 0;
397 data[offs++] = ( 6 << 1) | (0 << 0);
398 data[offs++] = (12 << 1) | (0 << 0);
399 data[offs++] = (127 << 1) | (1 << 0);
400 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
401 chunks, ARRAY_SIZE(chunks), &tlli);
402 OSMO_ASSERT(num_chunks == 2);
403 OSMO_ASSERT(tlli == 0);
404 OSMO_ASSERT(chunks[0].offset == 3);
405 OSMO_ASSERT(chunks[0].length == 6);
406 OSMO_ASSERT(chunks[0].is_complete);
407 OSMO_ASSERT(chunks[1].offset == 9);
408 OSMO_ASSERT(chunks[1].length == 12);
409 OSMO_ASSERT(chunks[1].is_complete);
410
411 /* TS 44.060, B.8.3 */
412
413 /* Note that the spec confuses the byte numbering here, too (see above) */
414
Maxbea2edb2019-03-06 17:04:59 +0100415 cs = MCS2;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200416 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100417 rdbi.e = 1;
418 rdbi.ti = 0;
419 rdbi.cv = 0;
420 tlli = 0;
421 offs = 0;
422 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
423 chunks, ARRAY_SIZE(chunks), &tlli);
424 OSMO_ASSERT(num_chunks == 1);
425 OSMO_ASSERT(tlli == 0);
426 OSMO_ASSERT(chunks[0].offset == 0);
427 OSMO_ASSERT(chunks[0].length == 28);
428 OSMO_ASSERT(chunks[0].is_complete);
429
430 /* CS-1, TLLI, last block, single chunk until the end of the block */
Maxbea2edb2019-03-06 17:04:59 +0100431 cs = CS1;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200432 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100433 rdbi.e = 1;
434 rdbi.ti = 1;
435 rdbi.cv = 0;
436 tlli = 0;
437 tlli2 = 0xffeeddcc;
438 offs = 0;
439 data[offs++] = tlli2 >> 24;
440 data[offs++] = tlli2 >> 16;
441 data[offs++] = tlli2 >> 8;
442 data[offs++] = tlli2 >> 0;
443 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
444 chunks, ARRAY_SIZE(chunks), &tlli);
445 OSMO_ASSERT(num_chunks == 1);
446 OSMO_ASSERT(tlli == tlli2);
447 OSMO_ASSERT(chunks[0].offset == 4);
448 OSMO_ASSERT(chunks[0].length == 16);
449 OSMO_ASSERT(chunks[0].is_complete);
450
451 /* Like TS 44.060, B.2, first RLC block but with TLLI */
Maxbea2edb2019-03-06 17:04:59 +0100452 cs = CS1;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200453 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100454 rdbi.e = 0;
455 rdbi.ti = 1;
456 rdbi.cv = 15;
457 tlli = 0;
458 tlli2 = 0xffeeddbb;
459 offs = 0;
460 data[offs++] = (0 << 2) | (0 << 1) | (1 << 0);
461 data[offs++] = tlli2 >> 24;
462 data[offs++] = tlli2 >> 16;
463 data[offs++] = tlli2 >> 8;
464 data[offs++] = tlli2 >> 0;
465 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
466 chunks, ARRAY_SIZE(chunks), &tlli);
467 OSMO_ASSERT(num_chunks == 1);
468 OSMO_ASSERT(tlli == tlli2);
469 OSMO_ASSERT(chunks[0].offset == 5);
470 OSMO_ASSERT(chunks[0].length == 15);
471 OSMO_ASSERT(!chunks[0].is_complete);
472
473 /* Like TS 44.060, B.8.1 but with TLLI */
Maxbea2edb2019-03-06 17:04:59 +0100474 cs = MCS4;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200475 rdbi.data_len = mcs_max_data_block_bytes(cs);
Jacob Erlbeck61679252015-12-11 18:25:21 +0100476 rdbi.e = 0;
477 rdbi.ti = 1;
478 rdbi.cv = 15;
479 tlli = 0;
480 tlli2 = 0xffeeddaa;
481 offs = 0;
482 data[offs++] = (11 << 1) | (0 << 0);
483 data[offs++] = (26 << 1) | (1 << 0);
484 /* Little endian */
485 data[offs++] = tlli2 >> 0;
486 data[offs++] = tlli2 >> 8;
487 data[offs++] = tlli2 >> 16;
488 data[offs++] = tlli2 >> 24;
489 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
490 chunks, ARRAY_SIZE(chunks), &tlli);
491 OSMO_ASSERT(num_chunks == 3);
492 OSMO_ASSERT(tlli == tlli2);
493 OSMO_ASSERT(chunks[0].offset == 6);
494 OSMO_ASSERT(chunks[0].length == 11);
495 OSMO_ASSERT(chunks[0].is_complete);
496 OSMO_ASSERT(chunks[1].offset == 17);
497 OSMO_ASSERT(chunks[1].length == 26);
498 OSMO_ASSERT(chunks[1].is_complete);
499 OSMO_ASSERT(chunks[2].offset == 43);
500 OSMO_ASSERT(chunks[2].length == 1);
501 OSMO_ASSERT(!chunks[2].is_complete);
502
Aravind Sirsikar3463bd42016-09-15 17:19:54 +0530503 rdbi.e = 0;
504 rdbi.ti = 0;
505 rdbi.cv = 1;
506 tlli = 0;
507 offs = 0;
508 data[offs++] = 1;
509 num_chunks = Decoding::rlc_data_from_ul_data(&rdbi, cs, data,
510 chunks, ARRAY_SIZE(chunks), &tlli);
511
Aravind Sirsikar22a90192016-09-15 17:24:49 +0530512 OSMO_ASSERT(num_chunks == 2);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +0530513 OSMO_ASSERT(chunks[0].offset == 1);
Aravind Sirsikar22a90192016-09-15 17:24:49 +0530514 OSMO_ASSERT(chunks[0].length == 0);
515 OSMO_ASSERT(chunks[0].is_complete);
516
517 OSMO_ASSERT(chunks[1].offset == 1);
518 OSMO_ASSERT(chunks[1].length == 43);
519 OSMO_ASSERT(!chunks[1].is_complete);
Aravind Sirsikar3463bd42016-09-15 17:19:54 +0530520
Jacob Erlbeck61679252015-12-11 18:25:21 +0100521 printf("=== end %s ===\n", __func__);
522}
523
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100524static void test_rlc_unit_encoder()
525{
526 struct gprs_rlc_data_block_info rdbi = {0};
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200527 enum CodingScheme cs;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100528 uint8_t data[74];
529 uint8_t llc_data[1500] = {0,};
530 int num_chunks = 0;
531 int write_offset;
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200532 int count_payload;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100533 struct gprs_llc llc;
534 Encoding::AppendResult ar;
535
536 printf("=== start %s ===\n", __func__);
537
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200538 llc_init(&llc);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100539
540 /* TS 44.060, B.1 */
Maxbea2edb2019-03-06 17:04:59 +0100541 cs = CS4;
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530542 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100543 num_chunks = 0;
544 write_offset = 0;
545 memset(data, 0, sizeof(data));
546
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200547 llc_reset(&llc);
548 llc_put_frame(&llc, llc_data, 11);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200549 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100550
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100551 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200552 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100553
554 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
555 OSMO_ASSERT(rdbi.e == 0);
556 OSMO_ASSERT(write_offset == 1 + 11);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200557 OSMO_ASSERT(count_payload == 11);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100558 OSMO_ASSERT(num_chunks == 1);
559
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200560 llc_reset(&llc);
561 llc_put_frame(&llc, llc_data, 26);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200562 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100563
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100564 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200565 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100566
567 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
568 OSMO_ASSERT(rdbi.e == 0);
569 OSMO_ASSERT(write_offset == 2 + 11 + 26);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200570 OSMO_ASSERT(count_payload == 26);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100571 OSMO_ASSERT(num_chunks == 2);
572
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200573 llc_reset(&llc);
574 llc_put_frame(&llc, llc_data, 99);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200575 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100576
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100577 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200578 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100579
580 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
581 OSMO_ASSERT(rdbi.e == 0);
582 OSMO_ASSERT(rdbi.cv != 0);
583 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200584 OSMO_ASSERT(count_payload == 11);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100585 OSMO_ASSERT(num_chunks == 3);
586
587 OSMO_ASSERT(data[0] == ((11 << 2) | (1 << 1) | (0 << 0)));
588 OSMO_ASSERT(data[1] == ((26 << 2) | (1 << 1) | (1 << 0)));
589 OSMO_ASSERT(data[2] == 0);
590
591 /* TS 44.060, B.2 */
Maxbea2edb2019-03-06 17:04:59 +0100592 cs = CS1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100593
594 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530595 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100596 num_chunks = 0;
597 write_offset = 0;
598 memset(data, 0, sizeof(data));
599
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200600 llc_reset(&llc);
601 llc_put_frame(&llc, llc_data, 20);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200602 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100603
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100604 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200605 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100606
607 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
608 OSMO_ASSERT(rdbi.e == 0);
609 OSMO_ASSERT(write_offset == 1 + 19);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200610 OSMO_ASSERT(count_payload == 19);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100611 OSMO_ASSERT(num_chunks == 1);
612
613 OSMO_ASSERT(data[0] == ((0 << 2) | (0 << 1) | (1 << 0)));
614 OSMO_ASSERT(data[1] == 0);
615
616 /* Block 2 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530617 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100618 num_chunks = 0;
619 write_offset = 0;
620 memset(data, 0, sizeof(data));
621
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100622 OSMO_ASSERT(llc_chunk_size(&llc) == 1);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100623
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200624 count_payload = -1;
625
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100626 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200627 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100628
629 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
630 OSMO_ASSERT(rdbi.e == 0);
631 OSMO_ASSERT(write_offset == 1 + 1);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200632 OSMO_ASSERT(count_payload == 1);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100633 OSMO_ASSERT(num_chunks == 1);
634
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200635 llc_reset(&llc);
636 llc_put_frame(&llc, llc_data, 99);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200637 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100638
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100639 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200640 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100641
642 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
643 OSMO_ASSERT(rdbi.e == 0);
644 OSMO_ASSERT(write_offset == 1 + 1 + 18);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200645 OSMO_ASSERT(count_payload == 18);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100646 OSMO_ASSERT(num_chunks == 2);
647
648 OSMO_ASSERT(data[0] == ((1 << 2) | (1 << 1) | (1 << 0)));
649 OSMO_ASSERT(data[1] == 0);
650
651 /* TS 44.060, B.3 */
Maxbea2edb2019-03-06 17:04:59 +0100652 cs = CS1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100653
654 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530655 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100656 num_chunks = 0;
657 write_offset = 0;
658 memset(data, 0, sizeof(data));
659
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200660 llc_reset(&llc);
661 llc_put_frame(&llc, llc_data, 7);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200662 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100663
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100664 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200665 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100666
667 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
668 OSMO_ASSERT(rdbi.e == 0);
669 OSMO_ASSERT(write_offset == 1 + 7);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200670 OSMO_ASSERT(count_payload == 7);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100671 OSMO_ASSERT(num_chunks == 1);
672
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200673 llc_reset(&llc);
674 llc_put_frame(&llc, llc_data, 11);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200675 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100676
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100677 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200678 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100679
680 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
681 OSMO_ASSERT(rdbi.e == 0);
682 OSMO_ASSERT(write_offset == 2 + 7 + 11);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200683 OSMO_ASSERT(count_payload == 11);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100684 OSMO_ASSERT(num_chunks == 2);
685
686 OSMO_ASSERT(data[0] == ((7 << 2) | (1 << 1) | (0 << 0)));
687 OSMO_ASSERT(data[1] == ((11 << 2) | (0 << 1) | (1 << 0)));
688 OSMO_ASSERT(data[2] == 0);
689
690 /* TS 44.060, B.4 */
Maxbea2edb2019-03-06 17:04:59 +0100691 cs = CS1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100692
693 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530694 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100695 num_chunks = 0;
696 write_offset = 0;
697 memset(data, 0, sizeof(data));
698
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200699 llc_reset(&llc);
700 llc_put_frame(&llc, llc_data, 99);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200701 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100702
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100703 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200704 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100705
706 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
707 OSMO_ASSERT(rdbi.e == 1);
708 OSMO_ASSERT(write_offset == 20);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200709 OSMO_ASSERT(count_payload == 20);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100710 OSMO_ASSERT(num_chunks == 1);
711 OSMO_ASSERT(rdbi.cv != 0);
712
713 OSMO_ASSERT(data[0] == 0);
714
715 /* TS 44.060, B.5 */
Maxbea2edb2019-03-06 17:04:59 +0100716 cs = CS1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100717
718 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530719 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100720 num_chunks = 0;
721 write_offset = 0;
722 memset(data, 0, sizeof(data));
723
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200724 llc_reset(&llc);
725 llc_put_frame(&llc, llc_data, 20);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200726 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100727
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100728 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200729 &llc, &write_offset, &num_chunks, data, true, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100730
731 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
732 OSMO_ASSERT(rdbi.e == 1);
733 OSMO_ASSERT(write_offset == 20);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200734 OSMO_ASSERT(count_payload == 20);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100735 OSMO_ASSERT(num_chunks == 1);
736 OSMO_ASSERT(rdbi.cv == 0);
737
738 OSMO_ASSERT(data[0] == 0);
739
740 /* TS 44.060, B.7 */
Maxbea2edb2019-03-06 17:04:59 +0100741 cs = CS1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100742
743 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530744 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100745 num_chunks = 0;
746 write_offset = 0;
747 memset(data, 0, sizeof(data));
748
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200749 llc_reset(&llc);
750 llc_put_frame(&llc, llc_data, 30);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200751 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100752
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100753 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200754 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100755
756 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
757 OSMO_ASSERT(rdbi.e == 1);
758 OSMO_ASSERT(write_offset == 20);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200759 OSMO_ASSERT(count_payload == 20);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100760 OSMO_ASSERT(num_chunks == 1);
761
762 OSMO_ASSERT(data[0] == 0);
763
764 /* Block 2 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530765 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100766 num_chunks = 0;
767 write_offset = 0;
768 memset(data, 0, sizeof(data));
769
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100770 OSMO_ASSERT(llc_chunk_size(&llc) == 10);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200771 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100772
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100773 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200774 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100775
776 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
777 OSMO_ASSERT(rdbi.e == 0);
778 OSMO_ASSERT(write_offset == 1 + 10);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200779 OSMO_ASSERT(count_payload == 10);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100780 OSMO_ASSERT(num_chunks == 1);
781
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200782 llc_reset(&llc);
783 llc_put_frame(&llc, llc_data, 99);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200784 count_payload = -1;
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100785
Jacob Erlbeck5058bd62016-01-13 10:51:25 +0100786 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200787 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100788
789 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
790 OSMO_ASSERT(rdbi.e == 0);
791 OSMO_ASSERT(write_offset == 1 + 10 + 9);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200792 OSMO_ASSERT(count_payload == 9);
Jacob Erlbeck14bb0942016-01-12 11:58:13 +0100793 OSMO_ASSERT(num_chunks == 2);
794
795 OSMO_ASSERT(data[0] == ((10 << 2) | (1 << 1) | (1 << 0)));
796 OSMO_ASSERT(data[1] == 0);
797
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100798 /* TS 44.060, B.8.1 */
Maxbea2edb2019-03-06 17:04:59 +0100799 cs = MCS4;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100800
801 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530802 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100803 num_chunks = 0;
804 write_offset = 0;
805 memset(data, 0, sizeof(data));
806
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200807 llc_reset(&llc);
808 llc_put_frame(&llc, llc_data, 11);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200809 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100810
811 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200812 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100813
814 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
815 OSMO_ASSERT(rdbi.e == 0);
816 OSMO_ASSERT(write_offset == 1 + 11);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200817 OSMO_ASSERT(count_payload == 11);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100818 OSMO_ASSERT(num_chunks == 1);
819
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200820 llc_reset(&llc);
821 llc_put_frame(&llc, llc_data, 26);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200822 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100823
824 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200825 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100826
827 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
828 OSMO_ASSERT(rdbi.e == 0);
829 OSMO_ASSERT(write_offset == 2 + 11 + 26);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200830 OSMO_ASSERT(count_payload == 26);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100831 OSMO_ASSERT(num_chunks == 2);
832
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200833 llc_reset(&llc);
834 llc_put_frame(&llc, llc_data, 99);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200835 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100836
837 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200838 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100839
840 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
841 OSMO_ASSERT(rdbi.e == 0);
842 OSMO_ASSERT(rdbi.cv != 0);
843 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200844 OSMO_ASSERT(count_payload == 5);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100845 OSMO_ASSERT(num_chunks == 3);
846
847 OSMO_ASSERT(data[0] == ((11 << 1) | (0 << 0)));
848 OSMO_ASSERT(data[1] == ((26 << 1) | (1 << 0)));
849 OSMO_ASSERT(data[2] == 0);
850
851 /* TS 44.060, B.8.2 */
852
853 /* Note that the spec confuses the byte numbering here, since it
854 * includes the FBI/E header bits into the N2 octet count which
855 * is not consistent with Section 10.3a.1 & 10.3a.2. */
856
Maxbea2edb2019-03-06 17:04:59 +0100857 cs = MCS2;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100858
859 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530860 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100861 num_chunks = 0;
862 write_offset = 0;
863 memset(data, 0, sizeof(data));
864
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200865 llc_reset(&llc);
866 llc_put_frame(&llc, llc_data, 15);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200867 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100868
869 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200870 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100871
872 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
873 OSMO_ASSERT(rdbi.e == 0);
874 OSMO_ASSERT(write_offset == 1 + 15);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200875 OSMO_ASSERT(count_payload == 15);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100876 OSMO_ASSERT(num_chunks == 1);
877
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200878 llc_reset(&llc);
879 llc_put_frame(&llc, llc_data, 12);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200880 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100881
882 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200883 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100884
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200885 /* no LI here, becaues there are exact 12 bytes left. Put LI into next frame */
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100886 OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS);
887 OSMO_ASSERT(rdbi.e == 0);
888 OSMO_ASSERT(rdbi.cv != 0);
889 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200890 OSMO_ASSERT(count_payload == 12);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100891 OSMO_ASSERT(num_chunks == 2);
892
893 OSMO_ASSERT(data[0] == ((15 << 1) | (1 << 0)));
894 OSMO_ASSERT(data[1] == 0);
895
896 /* Block 2 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530897 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100898 num_chunks = 0;
899 write_offset = 0;
900 memset(data, 0, sizeof(data));
901
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100902 OSMO_ASSERT(llc_chunk_size(&llc) == 0);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200903 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100904
905 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200906 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100907
908 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
909 OSMO_ASSERT(rdbi.e == 0);
910 OSMO_ASSERT(write_offset == 1 + 0);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200911 OSMO_ASSERT(count_payload == 0);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100912 OSMO_ASSERT(num_chunks == 1);
913
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200914 llc_reset(&llc);
915 llc_put_frame(&llc, llc_data, 7);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200916 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100917
918 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200919 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100920
921 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
922 OSMO_ASSERT(rdbi.e == 0);
923 OSMO_ASSERT(rdbi.cv != 0);
924 OSMO_ASSERT(write_offset == 2 + 0 + 7);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200925 OSMO_ASSERT(count_payload == 7);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100926 OSMO_ASSERT(num_chunks == 2);
927
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200928 llc_reset(&llc);
929 llc_put_frame(&llc, llc_data, 18);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200930 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100931
932 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200933 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100934
935 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
936 OSMO_ASSERT(rdbi.e == 0);
937 OSMO_ASSERT(rdbi.cv != 0);
938 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200939 OSMO_ASSERT(count_payload == 18);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100940 OSMO_ASSERT(num_chunks == 3);
941
942 OSMO_ASSERT(data[0] == ((0 << 1) | (0 << 0)));
943 OSMO_ASSERT(data[1] == ((7 << 1) | (0 << 0)));
944 OSMO_ASSERT(data[2] == ((18 << 1) | (1 << 0)));
945 OSMO_ASSERT(data[3] == 0);
946
947 /* Block 3 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530948 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100949 num_chunks = 0;
950 write_offset = 0;
951 memset(data, 0, sizeof(data));
952
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200953 llc_reset(&llc);
954 llc_put_frame(&llc, llc_data, 6);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200955 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100956
957 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200958 &llc, &write_offset, &num_chunks, data, false, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100959
960 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT);
961 OSMO_ASSERT(rdbi.e == 0);
962 OSMO_ASSERT(write_offset == 1 + 6);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200963 OSMO_ASSERT(count_payload == 6);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100964 OSMO_ASSERT(num_chunks == 1);
965
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200966 llc_reset(&llc);
967 llc_put_frame(&llc, llc_data, 12);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200968 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100969
970 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200971 &llc, &write_offset, &num_chunks, data, true, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100972
973 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
974 OSMO_ASSERT(rdbi.e == 0);
975 OSMO_ASSERT(rdbi.cv == 0);
976 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200977 OSMO_ASSERT(count_payload == 12);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100978 OSMO_ASSERT(num_chunks == 3);
979
980 OSMO_ASSERT(data[0] == ((6 << 1) | (0 << 0)));
981 OSMO_ASSERT(data[1] == ((12 << 1) | (0 << 0)));
982 OSMO_ASSERT(data[2] == ((127 << 1) | (1 << 0)));
983 OSMO_ASSERT(data[3] == 0);
984
985 /* TS 44.060, B.8.3 */
986
987 /* Note that the spec confuses the byte numbering here, too (see above) */
988
Maxbea2edb2019-03-06 17:04:59 +0100989 cs = MCS2;
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100990
991 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530992 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbecka88d0652016-01-13 11:28:10 +0100993 num_chunks = 0;
994 write_offset = 0;
995 memset(data, 0, sizeof(data));
996
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +0200997 llc_reset(&llc);
998 llc_put_frame(&llc, llc_data, rdbi.data_len);
Alexander Couzens6f0dc962016-05-30 19:30:21 +0200999 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001000
1001 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +02001002 &llc, &write_offset, &num_chunks, data, true, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001003
1004 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
1005 OSMO_ASSERT(rdbi.e == 1);
1006 OSMO_ASSERT(rdbi.cv == 0);
1007 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001008 OSMO_ASSERT(rdbi.data_len <= INT_MAX && count_payload == (int)rdbi.data_len);
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001009 OSMO_ASSERT(num_chunks == 1);
1010
1011 OSMO_ASSERT(data[0] == 0);
1012
1013 /* Final block with an LLC of size data_len-1 */
1014
Maxbea2edb2019-03-06 17:04:59 +01001015 cs = MCS2;
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001016
1017 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +05301018 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001019 num_chunks = 0;
1020 write_offset = 0;
1021 memset(data, 0, sizeof(data));
1022
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +02001023 llc_reset(&llc);
1024 llc_put_frame(&llc, llc_data, rdbi.data_len - 1);
Alexander Couzens6f0dc962016-05-30 19:30:21 +02001025 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001026
1027 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +02001028 &llc, &write_offset, &num_chunks, data, true, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001029
1030 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
1031 OSMO_ASSERT(rdbi.e == 0);
1032 OSMO_ASSERT(rdbi.cv == 0);
1033 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001034 OSMO_ASSERT((rdbi.data_len - 1) <= INT_MAX
1035 && count_payload == (int)(rdbi.data_len - 1));
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001036 OSMO_ASSERT(num_chunks == 1);
1037
1038 OSMO_ASSERT(data[0] == (((rdbi.data_len-1) << 1) | (1 << 0)));
1039 OSMO_ASSERT(data[1] == 0);
1040
1041 /* Final block with an LLC of size data_len-2 */
1042
Maxbea2edb2019-03-06 17:04:59 +01001043 cs = MCS2;
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001044
1045 /* Block 1 */
Aravind Sirsikar50b09702016-08-22 17:21:10 +05301046 gprs_rlc_data_block_info_init(&rdbi, cs, false, 0);
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001047 num_chunks = 0;
1048 write_offset = 0;
1049 memset(data, 0, sizeof(data));
1050
Pau Espin Pedrol4f8384b2022-03-31 19:36:12 +02001051 llc_reset(&llc);
1052 llc_put_frame(&llc, llc_data, rdbi.data_len - 2);
Alexander Couzens6f0dc962016-05-30 19:30:21 +02001053 count_payload = -1;
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001054
1055 ar = Encoding::rlc_data_to_dl_append(&rdbi, cs,
Alexander Couzens6f0dc962016-05-30 19:30:21 +02001056 &llc, &write_offset, &num_chunks, data, true, &count_payload);
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001057
1058 OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED);
1059 OSMO_ASSERT(rdbi.e == 0);
1060 OSMO_ASSERT(rdbi.cv == 0);
1061 OSMO_ASSERT(write_offset == (int)rdbi.data_len);
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001062 OSMO_ASSERT((rdbi.data_len - 2) <= INT_MAX
1063 && count_payload == (int)(rdbi.data_len - 2));
Jacob Erlbecka88d0652016-01-13 11:28:10 +01001064 OSMO_ASSERT(num_chunks == 2);
1065
1066 OSMO_ASSERT(data[0] == (((rdbi.data_len-2) << 1) | (0 << 0)));
1067 OSMO_ASSERT(data[1] == ((127 << 1) | (1 << 0)));
1068 OSMO_ASSERT(data[2] == 0);
1069
Jacob Erlbeck14bb0942016-01-12 11:58:13 +01001070 printf("=== end %s ===\n", __func__);
1071}
1072
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001073static void test_rlc_unaligned_copy()
1074{
1075 uint8_t bits[256];
1076 uint8_t saved_block[256];
1077 uint8_t test_block[256];
1078 uint8_t out_block[256];
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001079 enum CodingScheme cs;
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001080 int pattern;
1081 volatile unsigned int block_idx, i;
1082
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001083 for (cs = CS1; cs < NUM_SCHEMES; cs = static_cast<enum CodingScheme>(cs + 1))
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001084 {
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001085 for (pattern = 0; pattern <= 0xff; pattern += 0xff) {
1086 /* prepare test block */
1087 test_block[0] = pattern ^ 0xff;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001088 for (i = 1; i + 1 < mcs_max_data_block_bytes(cs); i++)
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001089 test_block[i] = i;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001090 test_block[mcs_max_data_block_bytes(cs)-1] = pattern ^ 0xff;
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001091
1092 for (block_idx = 0;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001093 block_idx < num_data_blocks(mcs_header_type(cs));
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001094 block_idx++)
1095 {
1096 struct gprs_rlc_data_info rlc;
Aravind Sirsikar50b09702016-08-22 17:21:10 +05301097 gprs_rlc_data_info_init_dl(&rlc, cs, false, 0);
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001098
1099 memset(bits, pattern, sizeof(bits));
1100 Decoding::rlc_copy_to_aligned_buffer(
1101 &rlc, block_idx, bits, saved_block);
1102
1103 fprintf(stderr,
1104 "Test data block: %s\n",
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001105 osmo_hexdump(test_block, mcs_max_data_block_bytes(cs)));
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001106
1107 Encoding::rlc_copy_from_aligned_buffer(
1108 &rlc, block_idx, bits, test_block);
1109
1110 fprintf(stderr,
1111 "Encoded message block, %s, idx %d, "
1112 "pattern %02x: %s\n",
Max136ebcc2019-03-05 14:59:03 +01001113 mcs_name(rlc.cs), block_idx, pattern,
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001114 osmo_hexdump(bits, mcs_size_dl(cs)));
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001115
1116 Decoding::rlc_copy_to_aligned_buffer(
1117 &rlc, block_idx, bits, out_block);
1118
1119 fprintf(stderr,
1120 "Out data block: %s\n",
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001121 osmo_hexdump(out_block, mcs_max_data_block_bytes(cs)));
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001122 /* restore original bits */
1123 Encoding::rlc_copy_from_aligned_buffer(
1124 &rlc, block_idx, bits, saved_block);
1125
1126 OSMO_ASSERT(memcmp(test_block, out_block,
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001127 mcs_max_data_block_bytes(rlc.cs)) == 0);
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001128
1129 for (i = 0; i < sizeof(bits); i++)
1130 OSMO_ASSERT(bits[i] == pattern);
1131 }
1132 }
1133 }
1134}
1135
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +01001136static void test_rlc_info_init()
1137{
1138 struct gprs_rlc_data_info rlc;
1139
1140 printf("=== start %s ===\n", __func__);
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001141 gprs_rlc_data_info_init_dl(&rlc, CS1, false, 0);
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +01001142 OSMO_ASSERT(rlc.num_data_blocks == 1);
1143 OSMO_ASSERT(rlc.data_offs_bits[0] == 24);
1144 OSMO_ASSERT(rlc.block_info[0].data_len == 20);
1145
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001146 gprs_rlc_data_info_init_dl(&rlc, MCS1, false, 0);
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +01001147 OSMO_ASSERT(rlc.num_data_blocks == 1);
1148 OSMO_ASSERT(rlc.data_offs_bits[0] == 33);
1149 OSMO_ASSERT(rlc.block_info[0].data_len == 22);
1150
1151 printf("=== end %s ===\n", __func__);
1152}
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001153
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001154static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301155{
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301156 gprs_rlcmac_trx *trx;
1157
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001158 the_pcu->alloc_algorithm = alloc_algorithm_a;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301159 bts->initial_cs_dl = cs;
1160 bts->initial_cs_ul = cs;
1161 trx = &bts->trx[0];
1162 trx->pdch[ts_no].enable();
1163}
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001164static void uplink_header_type_2_parsing_test(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301165 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1166 uint8_t ms_class)
1167{
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301168 int tfi = 0;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301169 uint8_t data[79] = {0};
1170 struct gprs_rlc_ul_header_egprs_2 *egprs2 = NULL;
1171
1172 egprs2 = (struct gprs_rlc_ul_header_egprs_2 *) data;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301173
1174 tfi = 1;
1175
1176 struct gprs_rlc_data_info rlc;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001177 enum CodingScheme cs;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301178 int rc, offs;
1179
1180 /*without padding*/
Maxbea2edb2019-03-06 17:04:59 +01001181 cs = MCS5;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301182 egprs2 = (struct gprs_rlc_ul_header_egprs_2 *) data;
1183 egprs2->r = 1;
1184 egprs2->si = 1;
1185 egprs2->cv = 7;
Tom Tsoudf698092016-07-11 17:05:19 -07001186 egprs2->tfi_hi = tfi & 0x03;
1187 egprs2->tfi_lo = (tfi & 0x1c) >> 2;
1188 egprs2->bsn1_hi = 0;
1189 egprs2->bsn1_lo = 0;
1190 egprs2->cps_hi = 3;
1191 egprs2->cps_lo = 0;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301192 egprs2->rsb = 0;
1193 egprs2->pi = 0;
1194 data[4] = 0x20; /* Setting E field */
1195 rc = Decoding::rlc_parse_ul_data_header(&rlc, data, cs);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01001196 OSMO_ASSERT(rc == 487);
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301197 offs = rlc.data_offs_bits[0] / 8;
1198 OSMO_ASSERT(offs == 4);
1199 OSMO_ASSERT(rlc.tfi == 1);
1200 OSMO_ASSERT(rlc.num_data_blocks == 1);
1201 OSMO_ASSERT(rlc.block_info[0].e == 1);
1202 OSMO_ASSERT(rlc.block_info[0].ti == 0);
1203 OSMO_ASSERT(rlc.block_info[0].bsn == 0);
1204
1205 /* with padding case */
Maxbea2edb2019-03-06 17:04:59 +01001206 cs = MCS6;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301207 egprs2 = (struct gprs_rlc_ul_header_egprs_2 *) data;
1208 egprs2->r = 1;
1209 egprs2->si = 1;
1210 egprs2->cv = 7;
Tom Tsoudf698092016-07-11 17:05:19 -07001211 egprs2->tfi_hi = tfi & 0x03;
1212 egprs2->tfi_lo = (tfi & 0x1c) >> 2;
1213 egprs2->bsn1_hi = 0;
1214 egprs2->bsn1_lo = 0;
1215 egprs2->cps_hi = 3;
1216 egprs2->cps_lo = 0;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301217 egprs2->rsb = 0;
1218 egprs2->pi = 0;
1219 data[10] = 0x20; /* Setting E field */
1220 rc = Decoding::rlc_parse_ul_data_header(&rlc, data, cs);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01001221 OSMO_ASSERT(rc == 679);
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301222 offs = rlc.data_offs_bits[0] / 8;
1223 OSMO_ASSERT(offs == 10);
1224 OSMO_ASSERT(rlc.num_data_blocks == 1);
1225 OSMO_ASSERT(rlc.tfi == 1);
1226 OSMO_ASSERT(rlc.block_info[0].e == 1);
1227 OSMO_ASSERT(rlc.block_info[0].ti == 0);
1228 OSMO_ASSERT(rlc.block_info[0].bsn == 0);
1229
1230 egprs2->r = 1;
1231 egprs2->si = 1;
1232 egprs2->cv = 7;
Tom Tsoudf698092016-07-11 17:05:19 -07001233 egprs2->tfi_hi = tfi & 0x03;
1234 egprs2->tfi_lo = (tfi & 0x1c) >> 2;
1235 egprs2->bsn1_hi = 1;
1236 egprs2->bsn1_lo = 0;
1237 egprs2->cps_hi = 2;
1238 egprs2->cps_lo = 0;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301239 egprs2->rsb = 0;
1240 egprs2->pi = 0;
1241 data[10] = 0x20; /* Setting E field */
1242 rc = Decoding::rlc_parse_ul_data_header(&rlc, data, cs);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01001243 OSMO_ASSERT(rc == 679);
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301244 offs = rlc.data_offs_bits[0] / 8;
1245 OSMO_ASSERT(offs == 10);
1246 OSMO_ASSERT(rlc.tfi == 1);
1247 OSMO_ASSERT(rlc.num_data_blocks == 1);
1248 OSMO_ASSERT(rlc.block_info[0].e == 1);
1249 OSMO_ASSERT(rlc.block_info[0].ti == 0);
1250 OSMO_ASSERT(rlc.block_info[0].bsn == 1);
1251}
1252
1253static void uplink_header_type2_test(void)
1254{
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001255 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301256 int ts_no = 7;
1257 uint32_t fn = 2654218;
1258 uint16_t qta = 31;
1259 uint32_t tlli = 0xf1223344;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301260 uint8_t ms_class = 1;
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301261
1262 printf("=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001263 setup_bts(bts, ts_no, 10);
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301264
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001265 uplink_header_type_2_parsing_test(bts, ts_no,
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301266 tlli, &fn, qta, ms_class);
1267 printf("=== end %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001268 talloc_free(bts);
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301269}
1270
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001271static void uplink_header_type_1_parsing_test(struct gprs_rlcmac_bts *bts,
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301272 uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
1273 uint8_t ms_class)
1274{
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301275 int tfi = 0;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301276 uint8_t data[155] = {0};
1277 struct gprs_rlc_ul_header_egprs_1 *egprs1 = NULL;
1278 struct gprs_rlc_data_info rlc;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +02001279 enum CodingScheme cs;
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01001280 int rc;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301281
1282 egprs1 = (struct gprs_rlc_ul_header_egprs_1 *) data;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301283
1284 tfi = 1;
1285
1286 /* MCS 7 */
Maxbea2edb2019-03-06 17:04:59 +01001287 cs = MCS7;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301288 egprs1 = (struct gprs_rlc_ul_header_egprs_1 *) data;
1289 egprs1->si = 1;
1290 egprs1->r = 1;
1291 egprs1->cv = 7;
Tom Tsoudf698092016-07-11 17:05:19 -07001292 egprs1->tfi_hi = tfi & 0x03;
1293 egprs1->tfi_lo = (tfi & 0x1c) >> 2;
1294 egprs1->bsn1_hi = 0;
1295 egprs1->bsn1_lo = 0;
1296 egprs1->bsn2_hi = 1;
1297 egprs1->bsn2_lo = 0;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301298 egprs1->cps = 15;
1299 egprs1->rsb = 0;
1300 egprs1->pi = 0;
1301 data[5] = 0xc0;
1302 data[5 + 57] = 1;
1303 rc = Decoding::rlc_parse_ul_data_header(&rlc, data, cs);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01001304 OSMO_ASSERT(rc == 946);
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301305 OSMO_ASSERT(rlc.num_data_blocks == 2);
1306 OSMO_ASSERT(rlc.block_info[0].e == 1);
1307 OSMO_ASSERT(rlc.block_info[0].ti == 1);
1308 OSMO_ASSERT(rlc.block_info[1].e == 1);
1309 OSMO_ASSERT(rlc.block_info[1].ti == 0);
1310 OSMO_ASSERT(rlc.block_info[0].bsn == 0);
1311 OSMO_ASSERT(rlc.block_info[1].bsn == 1);
1312 OSMO_ASSERT(rlc.tfi == 1);
1313
1314 /* MCS 8 */
Maxbea2edb2019-03-06 17:04:59 +01001315 cs = MCS8;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301316 egprs1 = (struct gprs_rlc_ul_header_egprs_1 *) data;
1317 egprs1->si = 1;
1318 egprs1->r = 1;
1319 egprs1->cv = 7;
Tom Tsoudf698092016-07-11 17:05:19 -07001320 egprs1->tfi_hi = tfi & 0x03;
1321 egprs1->tfi_lo = (tfi & 0x1c) >> 2;
1322 egprs1->bsn1_hi = 0;
1323 egprs1->bsn1_lo = 0;
1324 egprs1->bsn2_hi = 1;
1325 egprs1->bsn2_lo = 0;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301326 egprs1->cps = 15;
1327 egprs1->rsb = 0;
1328 egprs1->pi = 0;
1329 data[5] = 0xc0;
1330 data[5 + 69] = 1;
1331 rc = Decoding::rlc_parse_ul_data_header(&rlc, data, cs);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01001332 OSMO_ASSERT(rc == 1138);
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301333 OSMO_ASSERT(rlc.num_data_blocks == 2);
1334 OSMO_ASSERT(rlc.block_info[0].e == 1);
1335 OSMO_ASSERT(rlc.block_info[0].ti == 1);
1336 OSMO_ASSERT(rlc.block_info[1].e == 1);
1337 OSMO_ASSERT(rlc.block_info[1].ti == 0);
1338 OSMO_ASSERT(rlc.block_info[0].bsn == 0);
1339 OSMO_ASSERT(rlc.block_info[1].bsn == 1);
1340 OSMO_ASSERT(rlc.tfi == 1);
1341
1342 /* MCS 9 */
Maxbea2edb2019-03-06 17:04:59 +01001343 cs = MCS9;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301344 egprs1 = (struct gprs_rlc_ul_header_egprs_1 *) data;
1345 egprs1->si = 1;
1346 egprs1->r = 1;
1347 egprs1->cv = 7;
Tom Tsoudf698092016-07-11 17:05:19 -07001348 egprs1->tfi_hi = tfi & 0x03;
1349 egprs1->tfi_lo = (tfi & 0x1c) >> 2;
1350 egprs1->bsn1_hi = 0;
1351 egprs1->bsn1_lo = 0;
1352 egprs1->bsn2_hi = 1;
1353 egprs1->bsn2_lo = 0;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301354 egprs1->cps = 15;
1355 egprs1->rsb = 0;
1356 egprs1->pi = 0;
1357 data[5] = 0xc0;
1358 data[5 + 75] = 1;
1359 rc = Decoding::rlc_parse_ul_data_header(&rlc, data, cs);
Neels Hofmeyrde9da392017-02-08 17:34:56 +01001360 OSMO_ASSERT(rc == 1234);
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301361 OSMO_ASSERT(rlc.num_data_blocks == 2);
1362 OSMO_ASSERT(rlc.block_info[0].e == 1);
1363 OSMO_ASSERT(rlc.block_info[0].ti == 1);
1364 OSMO_ASSERT(rlc.block_info[1].e == 1);
1365 OSMO_ASSERT(rlc.block_info[1].ti == 0);
1366 OSMO_ASSERT(rlc.block_info[0].bsn == 0);
1367 OSMO_ASSERT(rlc.block_info[1].bsn == 1);
1368 OSMO_ASSERT(rlc.tfi == 1);
1369}
1370
1371void uplink_header_type1_test(void)
1372{
Pau Espin Pedrold1049dc2021-01-18 17:14:14 +01001373 struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301374 int ts_no = 7;
1375 uint32_t fn = 2654218;
1376 uint16_t qta = 31;
1377 uint32_t tlli = 0xf1223344;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301378 uint8_t ms_class = 1;
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301379
1380 printf("=== start %s ===\n", __func__);
Pau Espin Pedrol2182e622021-01-14 16:48:38 +01001381 setup_bts(bts, ts_no, 12);
1382 uplink_header_type_1_parsing_test(bts, ts_no, tlli, &fn,
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301383 qta, ms_class);
1384 printf("=== end %s ===\n", __func__);
1385}
1386
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001387int main(int argc, char **argv)
1388{
1389 struct vty_app_info pcu_vty_info = {0};
1390
1391 tall_pcu_ctx = talloc_named_const(NULL, 1, "EdgeTest context");
1392 if (!tall_pcu_ctx)
1393 abort();
1394
Neels Hofmeyr78ce5912017-02-08 17:07:31 +01001395 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +02001396 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001397 log_set_use_color(osmo_stderr_target, 0);
Pau Espin Pedrol00f52cc2021-02-19 14:01:52 +01001398 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedrolb18d2a52021-02-19 14:00:48 +01001399 log_set_print_category(osmo_stderr_target, 0);
1400 log_set_print_category_hex(osmo_stderr_target, 0);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001401
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001402 the_pcu = gprs_pcu_alloc(tall_pcu_ctx);
1403
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001404 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02001405 pcu_vty_init();
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001406
1407 test_coding_scheme();
Jacob Erlbeck6e9f9c22016-01-11 11:15:45 +01001408 test_rlc_info_init();
Jacob Erlbeck38f18692016-02-01 10:08:00 +01001409 test_rlc_unit_decoder();
Jacob Erlbeckf0e40392016-01-08 10:07:53 +01001410 test_rlc_unaligned_copy();
Jacob Erlbeck14bb0942016-01-12 11:58:13 +01001411 test_rlc_unit_encoder();
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001412
Aravind Sirsikar189742b2016-06-14 19:01:14 +05301413 uplink_header_type2_test();
Aravind Sirsikar2c9f9802016-06-14 19:01:56 +05301414 uplink_header_type1_test();
1415
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001416 if (getenv("TALLOC_REPORT_FULL"))
1417 talloc_report_full(tall_pcu_ctx, stderr);
Pau Espin Pedrolac3fd122021-01-13 18:54:38 +01001418
1419 talloc_free(the_pcu);
Jacob Erlbeckd0222cf2015-12-07 12:23:35 +01001420 return EXIT_SUCCESS;
1421}
1422
1423/*
1424 * stubs that should not be reached
1425 */
1426extern "C" {
1427void l1if_pdch_req() { abort(); }
1428void l1if_connect_pdch() { abort(); }
1429void l1if_close_pdch() { abort(); }
1430void l1if_open_pdch() { abort(); }
1431}