blob: bdfe30026ebe07bd79e30a0db35f9f779987b6c6 [file] [log] [blame]
Vadim Yanitskiy3262f822016-09-23 01:48:59 +07001/*
2 * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
3 * (C) 2015 by Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include <stdio.h>
23#include <errno.h>
24#include <unistd.h>
25#include <string.h>
26#include <stdlib.h>
27
28#include <osmocom/core/bits.h>
29#include <osmocom/core/utils.h>
30
31#include <osmocom/coding/gsm0503_coding.h>
32
Max458a6f52017-11-28 17:26:54 +010033#define DUMP_U_AT(b, x, u) do { \
34 printf("%s %02x %02x ", osmo_ubit_dump(b + x, 57), b[57 + x], b[58 + x]); \
35 printf("%s\n", osmo_ubit_dump(b + 59 + x, 57)); \
36 if (u <= x) \
37 return; \
38 } while(0)
39
40#define DUMP_S_AT(b, x, u) do { \
41 printf("%s %02x %02x ", osmo_hexdump(b + x, 57), b[57 + x], b[58 + x]); \
42 printf("%s\n", osmo_hexdump(b + 59 + x, 57)); \
43 if (u <= x) \
44 return; \
45 } while(0)
46
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +070047/* Similar to OSMO_ASSERT, but does not panic() */
48#define CHECK_RC_OR_RET(exp, action) \
49 if (!(exp)) { \
50 printf("%s(%s): assert %s failed\n", __func__, action, #exp); \
51 return; \
52 }
53
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +070054#ifdef DEBUG
55#define printd(fmt, args...) printf(fmt, ##args)
56#else
57#define printd(fmt, args...)
58#endif
59
Pau Espin Pedrol41911d02018-02-01 12:10:33 +010060static inline void dump_ubits(ubit_t *bursts_u, unsigned until)
Max458a6f52017-11-28 17:26:54 +010061{
62 printf("U-Bits:\n");
63 DUMP_U_AT(bursts_u, 0, until);
64 DUMP_U_AT(bursts_u, 116, until);
65 DUMP_U_AT(bursts_u, 232, until);
66 DUMP_U_AT(bursts_u, 348, until);
67 DUMP_U_AT(bursts_u, 464, until);
68 DUMP_U_AT(bursts_u, 580, until);
69 DUMP_U_AT(bursts_u, 696, until);
70 DUMP_U_AT(bursts_u, 812, until);
71}
72
Pau Espin Pedrol41911d02018-02-01 12:10:33 +010073static inline void dump_sbits(uint8_t *bursts_s, unsigned until)
Max458a6f52017-11-28 17:26:54 +010074{
75 printf("S-Bits:\n");
76 DUMP_S_AT(bursts_s, 0, until);
77 DUMP_S_AT(bursts_s, 116, until);
78 DUMP_S_AT(bursts_s, 232, until);
79 DUMP_S_AT(bursts_s, 348, until);
80 DUMP_S_AT(bursts_s, 464, until);
81 DUMP_S_AT(bursts_s, 580, until);
82 DUMP_S_AT(bursts_s, 696, until);
83 DUMP_S_AT(bursts_s, 812, until);
84}
85
Vadim Yanitskiy3262f822016-09-23 01:48:59 +070086static void test_xcch(uint8_t *l2)
87{
88 uint8_t result[23];
89 ubit_t bursts_u[116 * 4];
90 sbit_t bursts_s[116 * 4];
91 int n_errors, n_bits_total;
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +070092 int rc;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +070093
94 /* Encode L2 message */
Max0176b4a2017-11-28 18:04:23 +010095 printf("Encoding: %s\n", osmo_hexdump(l2, 23));
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +070096 rc = gsm0503_xcch_encode(bursts_u, l2);
97 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +070098
99 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100100 osmo_ubit2sbit(bursts_s, bursts_u, 116 * 4);
Max458a6f52017-11-28 17:26:54 +0100101 dump_ubits(bursts_u, 348);
102 dump_sbits((uint8_t *)bursts_s, 348);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700103
104 /* Destroy some bits */
105 memset(bursts_s, 0, 30);
106 memset(bursts_s + 116, 0, 30);
107
108 /* Decode, correcting errors */
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700109 rc = gsm0503_xcch_decode(result, bursts_s, &n_errors, &n_bits_total);
110 CHECK_RC_OR_RET(rc == 0, "decoding");
111
Max0176b4a2017-11-28 18:04:23 +0100112 printf("Decoded: %s\n", osmo_hexdump(result, 23));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700113 printf("xcch_decode: n_errors=%d n_bits_total=%d ber=%.2f\n",
114 n_errors, n_bits_total, (float) n_errors / n_bits_total);
115
Max33dbecb2017-11-28 19:49:05 +0100116 OSMO_ASSERT(n_bits_total == 456);
117 OSMO_ASSERT(!memcmp(l2, result, 23));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700118
Max0176b4a2017-11-28 18:04:23 +0100119 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700120}
121
122static void test_rach(uint8_t bsic, uint8_t ra)
123{
Maxa4785902019-03-05 11:30:39 +0100124 int rc;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700125 uint8_t result;
126 ubit_t bursts_u[36];
127 sbit_t bursts_s[36];
128
129 /* Encode L2 message */
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700130 printd("Encoding: %02x\n", ra);
Maxa4785902019-03-05 11:30:39 +0100131 rc = gsm0503_rach_ext_encode(bursts_u, ra, bsic, false);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700132 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700133
134 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100135 osmo_ubit2sbit(bursts_s, bursts_u, 36);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700136
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700137 printd("U-Bits: %s\n", osmo_ubit_dump(bursts_u, 36));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700138
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700139 printd("S-Bits: %s\n", osmo_hexdump((uint8_t *)bursts_s, 36));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700140
141 /* Destroy some bits */
142 memset(bursts_s + 6, 0, 8);
143
144 /* Decode, correcting errors */
Maxa4785902019-03-05 11:30:39 +0100145 rc = gsm0503_rach_decode_ber(&result, bursts_s, bsic, NULL, NULL);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700146 CHECK_RC_OR_RET(rc == 0, "decoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700147
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700148 printd("Decoded: %02x\n", result);
Max32e56412017-10-16 14:58:00 +0200149 if (ra != result)
150 printf("FAIL [RACH]: encoded %u != %u decoded\n", ra, result);
151
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700152 printd("\n");
Max32e56412017-10-16 14:58:00 +0200153}
154
155static void test_rach_ext(uint8_t bsic, uint16_t ra)
156{
Maxa4785902019-03-05 11:30:39 +0100157 int rc;
Max32e56412017-10-16 14:58:00 +0200158 uint16_t result = 3000; /* Max ext. RA is 2^11 = 2048 */
159 ubit_t bursts_u[36];
160 sbit_t bursts_s[36];
161
162 /* Encode L2 message */
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700163 printd("Encoding: %02x\n", ra);
Maxa4785902019-03-05 11:30:39 +0100164 rc = gsm0503_rach_ext_encode(bursts_u, ra, bsic, true);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700165 CHECK_RC_OR_RET(rc == 0, "encoding");
Max32e56412017-10-16 14:58:00 +0200166
167 /* Prepare soft-bits */
168 osmo_ubit2sbit(bursts_s, bursts_u, 36);
169
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700170 printd("U-Bits: %s\n", osmo_ubit_dump(bursts_u, 36));
Max32e56412017-10-16 14:58:00 +0200171
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700172 printd("S-Bits: %s\n", osmo_hexdump((uint8_t *)bursts_s, 36));
Max32e56412017-10-16 14:58:00 +0200173
174 /* Destroy some bits */
175 memset(bursts_s + 9, 0, 8);
176
177 /* Decode, correcting errors */
Maxa4785902019-03-05 11:30:39 +0100178 rc = gsm0503_rach_ext_decode_ber(&result, bursts_s, bsic, NULL, NULL);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700179 CHECK_RC_OR_RET(rc == 0, "decoding");
Max32e56412017-10-16 14:58:00 +0200180
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700181 printd("Decoded: %02x\n", result);
Max32e56412017-10-16 14:58:00 +0200182 if (ra != result)
183 printf("FAIL [RACH ext]: encoded %u != %u decoded\n", ra, result);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700184
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700185 printd("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700186}
187
Vadim Yanitskiy41ce6752020-03-31 19:15:28 +0700188static void test_rach_11bit_sample(uint8_t bsic, const sbit_t *payload)
189{
190 int n_errors, n_bits_total;
191 uint16_t ra11;
192 int rc;
193
194 /* Decode, correcting errors */
195 rc = gsm0503_rach_ext_decode_ber(&ra11, payload, bsic, &n_errors, &n_bits_total);
196 if (rc) {
197 printf("%s(): decoding failed (rc=%d)\n", __func__, rc);
198 return;
199 }
200
201 printf("Decoded RA11: 0x%03x\n", ra11);
202}
203
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700204static void test_sch(uint8_t *info)
205{
206 uint8_t result[4];
207 ubit_t bursts_u[78];
208 sbit_t bursts_s[78];
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700209 int rc;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700210
211 /* Zero bits 25 and above */
212 info[3] &= 1;
213 result[3] = 0;
214
215 /* Encode L2 message */
Max0176b4a2017-11-28 18:04:23 +0100216 printf("Encoding: %s\n", osmo_hexdump(info, 4));
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700217 rc = gsm0503_sch_encode(bursts_u, info);
218 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700219
220 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100221 osmo_ubit2sbit(bursts_s, bursts_u, 78);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700222
Max0176b4a2017-11-28 18:04:23 +0100223 printf("U-Bits: %s\n", osmo_ubit_dump(bursts_u, 78));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700224
Max0176b4a2017-11-28 18:04:23 +0100225 printf("S-Bits: %s\n", osmo_hexdump((uint8_t *)bursts_s, 78));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700226
227 /* Destroy some bits */
228 memset(bursts_s + 6, 0, 10);
229
230 /* Decode, correcting errors */
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700231 rc = gsm0503_sch_decode(result, bursts_s);
232 CHECK_RC_OR_RET(rc == 0, "decoding");
233
Max0176b4a2017-11-28 18:04:23 +0100234 printf("Decoded: %s\n", osmo_hexdump(result, 4));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700235
Max33dbecb2017-11-28 19:49:05 +0100236 OSMO_ASSERT(!memcmp(info, result, 4));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700237
Max0176b4a2017-11-28 18:04:23 +0100238 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700239}
240
241static void test_fr(uint8_t *speech, int len)
242{
243 uint8_t result[33];
244 ubit_t bursts_u[116 * 8];
245 sbit_t bursts_s[116 * 8];
246 int n_errors, n_bits_total;
247 int rc;
248
249 memset(bursts_u, 0x23, sizeof(bursts_u));
250 memset(bursts_s, 0, sizeof(bursts_s));
251
252 /* Encode L2 message */
Max0176b4a2017-11-28 18:04:23 +0100253 printf("Encoding: %s\n", osmo_hexdump(speech, len));
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700254 rc = gsm0503_tch_fr_encode(bursts_u, speech, len, 1);
255 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700256
257 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100258 osmo_ubit2sbit(bursts_s, bursts_u, 116 * 8);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700259
Max458a6f52017-11-28 17:26:54 +0100260 dump_ubits(bursts_u, 812);
261 dump_sbits((uint8_t *)bursts_s, 812);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700262
263 /* Destroy some bits */
264 memset(bursts_s + 6, 0, 20);
265
266 /* Decode, correcting errors */
267 rc = gsm0503_tch_fr_decode(result, bursts_s, 1, len == 31,
268 &n_errors, &n_bits_total);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700269 CHECK_RC_OR_RET(rc == len, "decoding");
270
Max0176b4a2017-11-28 18:04:23 +0100271 printf("Decoded: %s\n", osmo_hexdump(result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700272 printf("tch_fr_decode: n_errors=%d n_bits_total=%d ber=%.2f\n",
273 n_errors, n_bits_total, (float)n_errors/n_bits_total);
274
Max33dbecb2017-11-28 19:49:05 +0100275 OSMO_ASSERT(!memcmp(speech, result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700276
Max0176b4a2017-11-28 18:04:23 +0100277 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700278}
279
280static void test_hr(uint8_t *speech, int len)
281{
282 uint8_t result[23];
283 ubit_t bursts_u[116 * 6];
284 sbit_t bursts_s[116 * 6];
285 int n_errors, n_bits_total;
286 int rc;
287
288 memset(bursts_u, 0x23, sizeof(bursts_u));
289 memset(bursts_s, 0, sizeof(bursts_s));
290
291 /* Encode L2 message */
Max0176b4a2017-11-28 18:04:23 +0100292 printf("Encoding: %s\n", osmo_hexdump(speech, len));
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700293 rc = gsm0503_tch_hr_encode(bursts_u, speech, len);
294 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700295
296 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100297 osmo_ubit2sbit(bursts_s, bursts_u, 116 * 6);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700298
Max458a6f52017-11-28 17:26:54 +0100299 dump_ubits(bursts_u, 580);
300 dump_sbits((uint8_t *)bursts_s, 580);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700301
302 /* Destroy some bits */
303 memset(bursts_s + 6, 0, 20);
304
305 /* Decode, correcting errors */
306 rc = gsm0503_tch_hr_decode(result, bursts_s, 0,
307 &n_errors, &n_bits_total);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700308 CHECK_RC_OR_RET(rc == len, "decoding");
309
Max0176b4a2017-11-28 18:04:23 +0100310 printf("Decoded: %s\n", osmo_hexdump(result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700311 printf("tch_hr_decode: n_errors=%d n_bits_total=%d ber=%.2f\n",
312 n_errors, n_bits_total, (float)n_errors/n_bits_total);
313
Max33dbecb2017-11-28 19:49:05 +0100314 OSMO_ASSERT(!memcmp(speech, result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700315
Max0176b4a2017-11-28 18:04:23 +0100316 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700317}
318
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200319struct test_macblock {
320 bool is_egprs;
321 uint16_t exp_burst_bits;
322 uint16_t l2_len;
323 uint8_t l2[54];
324};
325
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200326static const struct test_macblock test_macblock[] = {
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200327 /* Random frame */
328 { false,
329 GSM0503_GPRS_BURSTS_NBITS,
330 54,
331 { 0xa3, 0xaf, 0x5f, 0xc6, 0x36, 0x43, 0x44, 0xab,
332 0xd9, 0x6d, 0x7d, 0x62, 0x24, 0xc9, 0xd2, 0x92,
333 0xfa, 0x27, 0x5d, 0x71, 0x7a, 0x59, 0xa8, 0x42,
334 0xa3, 0xaf, 0x5f, 0xc6, 0x36, 0x43, 0x44, 0xab,
335 0xa3, 0xaf, 0x5f, 0xc6, 0x36, 0x43, 0x44, 0xab,
336 0xd9, 0x6d, 0x7d, 0x62, 0x24, 0xc9, 0xd2, 0x92,
337 0xfa, 0x27, 0x5d, 0x71, 0x7a, 0xa8 }
338 },
339 /* jolly frame */
340 { false,
341 GSM0503_GPRS_BURSTS_NBITS,
342 23,
343 { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
344 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
345 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }
346 },
347/*
348GSM RLC/MAC: EGPRS DL HEADER
349 0... .... .... 0000 = DL TFI: 0
350 0... .... crumb 1 of DL TFI (decoded above)
351 .00. .... = RRBP: Reserved Block: (N+13) mod 2715648 (0)
352 ...0 0... = ES/P: RRBP field is not valid (no Polling) (0)
353 .... .111 = USF: 7
354 01.. .... 0000 0000 .... ...0 = BSN: 1
355 01.. .... crumb 2 of BSN (decoded above)
356 ..00 .... = PR: 0 dB (included) to 3 dB (excluded) less than BCCH level - P0 (0)
357 .... 0000 crumb 0 of DL TFI (decoded above)
358 0000 0000 crumb 1 of BSN (decoded above)
359 .00. .... = SPB (DL): No retransmission (0)
360 ...1 011. = CPS: MCS-1/P1 (0x0b)
361 .... ...0 crumb 0 of BSN (decoded above)
362GSM RLC/MAC: EGPRS DL DATA BLOCK 1 (BSN 1)
363 .... ..0. = FBI: Current Block is not last RLC data block in TBF
364 .... ...0 = Extension: Extension octet follows immediately
365 0000 100. = Length Indicator: 4
366 .... ...0 = Extension: Extension octet follows immediately
367 0010 000. = Length Indicator: 16
368 .... ...1 = Extension: No extension octet follows
369 data segment: LI[0]=4 indicates: (Last segment of) LLC frame (4 octets)
370 Data (4 bytes)
371 Data: 012b2b2b
372 [Length: 4]
373 data segment: LI[1]=16 indicates: (Last segment of) LLC frame (16 octets)
374 Data (16 bytes)
375 Data: 43c0012b2b2b2b2b2b2b2b2b2b2b2b2b
376 [Length: 16]
377*/
378 { true,
379 GSM0503_GPRS_BURSTS_NBITS,
380 27,
381 { 0x07, 0x40, 0x00, 0x16, 0x10, 0x42, 0x02, 0x56,
382 0x56, 0x56, 0x86, 0x80, 0x03, 0x56, 0x56, 0x56,
383 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
384 0x56, 0x56, 0x00 }
385 },
386};
387
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200388static void test_pdtch(const struct test_macblock *tmb, int len)
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700389{
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200390 uint8_t l2[len], result[len];
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700391 ubit_t bursts_u[116 * 4];
392 sbit_t bursts_s[116 * 4];
393 int n_errors, n_bits_total;
394 int rc;
395
396 /* Zero the not coded tail bits */
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200397 memcpy(l2, tmb->l2, len);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700398 switch (len) {
399 case 34:
400 case 54:
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200401 l2[len - 1] &= 0x7f;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700402 result[len - 1] &= 0x7f;
403 break;
404 case 40:
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200405 l2[len - 1] &= 0x07;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700406 result[len - 1] &= 0x07;
407 break;
408 }
409
410 /* Encode L2 message */
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200411 printf("Encoding: %s\n", osmo_hexdump(l2, len));
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200412 if (tmb->is_egprs)
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200413 rc = gsm0503_pdtch_egprs_encode(bursts_u, l2, len);
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200414 else
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200415 rc = gsm0503_pdtch_encode(bursts_u, l2, len);
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200416 CHECK_RC_OR_RET(rc == (int)tmb->exp_burst_bits, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700417
418 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100419 osmo_ubit2sbit(bursts_s, bursts_u, 116 * 4);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700420
Max458a6f52017-11-28 17:26:54 +0100421 dump_ubits(bursts_u, 348);
422 dump_sbits((uint8_t *)bursts_s, 348);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700423
424 /* Decode */
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200425 if (tmb->is_egprs) {
426 /* gsm0503_pdtch_egprs_decode() is meant to decode EGPRS UL frames, so we cannot use it here */
427 rc = gsm0503_pdtch_egprs_decode(result, bursts_s, rc, NULL, &n_errors, &n_bits_total);
428 OSMO_ASSERT(rc == -EIO);
429 return;
430 } else {
431 rc = gsm0503_pdtch_decode(result, bursts_s, NULL, &n_errors, &n_bits_total);
432 }
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700433 CHECK_RC_OR_RET(rc == len, "decoding");
434
Max0176b4a2017-11-28 18:04:23 +0100435 printf("Decoded: %s\n", osmo_hexdump(result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700436 printf("pdtch_decode: n_errors=%d n_bits_total=%d ber=%.2f\n",
437 n_errors, n_bits_total, (float)n_errors/n_bits_total);
438
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200439 OSMO_ASSERT(!memcmp(l2, result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700440
Max0176b4a2017-11-28 18:04:23 +0100441 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700442}
443
444uint8_t test_l2[][23] = {
445 /* Dummy frame */
446 { 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
449 /* Random frame */
450 { 0xa3, 0xaf, 0x5f, 0xc6, 0x36, 0x43, 0x44, 0xab,
451 0xd9, 0x6d, 0x7d, 0x62, 0x24, 0xc9, 0xd2, 0x92,
452 0xfa, 0x27, 0x5d, 0x71, 0x7a, 0x59, 0xa8 },
453 /* jolly frame */
454 { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
455 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
456 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
457};
458
Vadim Yanitskiy41ce6752020-03-31 19:15:28 +0700459/* 11-bit Access Burst soft-bits (payload only) from an EGPRS capable phone (BSIC 63) */
460static const sbit_t test_rach_11bit[6][36] = {
461 { 103, 109, -108, -110, 107, 108, -106, -120, -121,
462 -120, -105, 122, -104, -109, 108, 109, -109, -111,
463 107, 111, -105, -119, -121, -104, 122, -120, 121,
464 -99, -121, -120, -122, -106, 109, 109, -108, -111 },
465
466 { 103, 109, -109, -109, 106, 107, -106, -121, -121,
467 -120, -106, 121, -120, 117, -122, 101, 109, -122,
468 120, -120, 101, 118, 120, 102, -125, 101, 110,
469 -120, 121, -101, -121, -118, -121, -106, 108, 121 },
470
471 { -121, -122, -104, 123, -104, -108, 122, -104, -121,
472 -121, -102, 124, -105, -110, 107, 109, -108, -109,
473 121, -122, 101, 107, -121, 105, 108, -110, -107,
474 124, -104, -109, 120, -122, 100, 122, 104, -123 },
475
476 { -122, -123, -103, 123, -105, -109, 122, -105, -121,
477 -120, -104, 122, -120, 121, -101, -122, -120, -120,
478 -119, -105, 120, -106, -108, 123, -104, -113, 105,
479 122, 101, -122, 119, -122, 117, -121, 119, -122 },
480
481 { 105, 110, -109, -109, 107, 108, -108, -120, -120,
482 -121, -106, 121, -104, -107, 106, 108, -108, -108,
483 108, 107, -105, -120, -122, -104, 122, -119, 121,
484 -103, -122, -118, -120, -106, 108, 108, -110, -111 },
485
486 { 120, -103, -123, -104, 119, -121, 100, 123, 106,
487 -109, -107, 121, -122, 118, -121, 103, 108, -122,
488 120, -119, 121, -103, -121, -119, -121, -103, 124,
489 -106, -108, 122, -103, -106, 121, -120, 119, -121 },
490};
491
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700492uint8_t test_speech_fr[33];
493uint8_t test_speech_efr[31];
494uint8_t test_speech_hr[15];
495
496int main(int argc, char **argv)
497{
498 int i, len_l2, len_mb;
499
Vadim Yanitskiy88c61c32020-03-30 20:50:49 +0700500 len_l2 = ARRAY_SIZE(test_l2);
501 len_mb = ARRAY_SIZE(test_macblock);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700502
503 for (i = 0; i < len_l2; i++)
504 test_xcch(test_l2[i]);
505
506 for (i = 0; i < 256; i++) {
507 test_rach(0x3f, i);
508 test_rach(0x00, i);
509 test_rach(0x1a, i);
510 }
511
Max32e56412017-10-16 14:58:00 +0200512 for (i = 0; i < 2048; i++) {
513 test_rach_ext(0x3f, i);
514 test_rach_ext(0x00, i);
515 test_rach_ext(0x1a, i);
516 }
517
Vadim Yanitskiy41ce6752020-03-31 19:15:28 +0700518 for (i = 0; i < ARRAY_SIZE(test_rach_11bit); i++)
519 test_rach_11bit_sample(0x3f, test_rach_11bit[i]);
520 printf("\n");
521
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700522 for (i = 0; i < len_l2; i++)
523 test_sch(test_l2[i]);
524
525 for (i = 0; i < sizeof(test_speech_fr); i++)
526 test_speech_fr[i] = i;
527 test_speech_fr[0] = 0xd0;
528 test_fr(test_speech_fr, sizeof(test_speech_fr));
529
530 for (i = 0; i < sizeof(test_speech_efr); i++)
531 test_speech_efr[i] = i;
532 test_speech_efr[0] = 0xc0;
533 test_fr(test_speech_efr, sizeof(test_speech_efr));
534
535 for (i = 0; i < len_l2; i++)
536 test_fr(test_l2[i], sizeof(test_l2[0]));
537
538 for (i = 0; i < sizeof(test_speech_hr); i++)
539 test_speech_hr[i] = i * 17;
540 test_speech_hr[0] = 0x00;
541 test_hr(test_speech_hr, sizeof(test_speech_hr));
542
543 for (i = 0; i < len_l2; i++)
544 test_hr(test_l2[i], sizeof(test_l2[0]));
545
546 for (i = 0; i < len_mb; i++) {
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200547 if (test_macblock[i].is_egprs) {
548 test_pdtch(&test_macblock[i], test_macblock[i].l2_len);
549 } else {
550 test_pdtch(&test_macblock[i], 23);
551 test_pdtch(&test_macblock[i], 34);
552 test_pdtch(&test_macblock[i], 40);
553 test_pdtch(&test_macblock[i], 54);
554 }
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700555 }
556
557 printf("Success\n");
558
559 return 0;
560}