blob: 5a6f6e06c1dbee092a55db1911abd5dda96e0566 [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.
Vadim Yanitskiy3262f822016-09-23 01:48:59 +070016 */
17
18#include <stdio.h>
19#include <errno.h>
20#include <unistd.h>
21#include <string.h>
22#include <stdlib.h>
23
24#include <osmocom/core/bits.h>
25#include <osmocom/core/utils.h>
26
27#include <osmocom/coding/gsm0503_coding.h>
28
Max458a6f52017-11-28 17:26:54 +010029#define DUMP_U_AT(b, x, u) do { \
30 printf("%s %02x %02x ", osmo_ubit_dump(b + x, 57), b[57 + x], b[58 + x]); \
31 printf("%s\n", osmo_ubit_dump(b + 59 + x, 57)); \
32 if (u <= x) \
33 return; \
34 } while(0)
35
36#define DUMP_S_AT(b, x, u) do { \
37 printf("%s %02x %02x ", osmo_hexdump(b + x, 57), b[57 + x], b[58 + x]); \
38 printf("%s\n", osmo_hexdump(b + 59 + x, 57)); \
39 if (u <= x) \
40 return; \
41 } while(0)
42
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +070043/* Similar to OSMO_ASSERT, but does not panic() */
44#define CHECK_RC_OR_RET(exp, action) \
45 if (!(exp)) { \
46 printf("%s(%s): assert %s failed\n", __func__, action, #exp); \
47 return; \
48 }
49
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +070050#ifdef DEBUG
51#define printd(fmt, args...) printf(fmt, ##args)
52#else
53#define printd(fmt, args...)
54#endif
55
Pau Espin Pedrol41911d02018-02-01 12:10:33 +010056static inline void dump_ubits(ubit_t *bursts_u, unsigned until)
Max458a6f52017-11-28 17:26:54 +010057{
58 printf("U-Bits:\n");
59 DUMP_U_AT(bursts_u, 0, until);
60 DUMP_U_AT(bursts_u, 116, until);
61 DUMP_U_AT(bursts_u, 232, until);
62 DUMP_U_AT(bursts_u, 348, until);
63 DUMP_U_AT(bursts_u, 464, until);
64 DUMP_U_AT(bursts_u, 580, until);
65 DUMP_U_AT(bursts_u, 696, until);
66 DUMP_U_AT(bursts_u, 812, until);
67}
68
Pau Espin Pedrol41911d02018-02-01 12:10:33 +010069static inline void dump_sbits(uint8_t *bursts_s, unsigned until)
Max458a6f52017-11-28 17:26:54 +010070{
71 printf("S-Bits:\n");
72 DUMP_S_AT(bursts_s, 0, until);
73 DUMP_S_AT(bursts_s, 116, until);
74 DUMP_S_AT(bursts_s, 232, until);
75 DUMP_S_AT(bursts_s, 348, until);
76 DUMP_S_AT(bursts_s, 464, until);
77 DUMP_S_AT(bursts_s, 580, until);
78 DUMP_S_AT(bursts_s, 696, until);
79 DUMP_S_AT(bursts_s, 812, until);
80}
81
Vadim Yanitskiy3262f822016-09-23 01:48:59 +070082static void test_xcch(uint8_t *l2)
83{
84 uint8_t result[23];
85 ubit_t bursts_u[116 * 4];
86 sbit_t bursts_s[116 * 4];
87 int n_errors, n_bits_total;
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +070088 int rc;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +070089
90 /* Encode L2 message */
Max0176b4a2017-11-28 18:04:23 +010091 printf("Encoding: %s\n", osmo_hexdump(l2, 23));
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +070092 rc = gsm0503_xcch_encode(bursts_u, l2);
93 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +070094
95 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +010096 osmo_ubit2sbit(bursts_s, bursts_u, 116 * 4);
Max458a6f52017-11-28 17:26:54 +010097 dump_ubits(bursts_u, 348);
98 dump_sbits((uint8_t *)bursts_s, 348);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +070099
100 /* Destroy some bits */
101 memset(bursts_s, 0, 30);
102 memset(bursts_s + 116, 0, 30);
103
104 /* Decode, correcting errors */
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700105 rc = gsm0503_xcch_decode(result, bursts_s, &n_errors, &n_bits_total);
106 CHECK_RC_OR_RET(rc == 0, "decoding");
107
Max0176b4a2017-11-28 18:04:23 +0100108 printf("Decoded: %s\n", osmo_hexdump(result, 23));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700109 printf("xcch_decode: n_errors=%d n_bits_total=%d ber=%.2f\n",
110 n_errors, n_bits_total, (float) n_errors / n_bits_total);
111
Max33dbecb2017-11-28 19:49:05 +0100112 OSMO_ASSERT(n_bits_total == 456);
113 OSMO_ASSERT(!memcmp(l2, result, 23));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700114
Max0176b4a2017-11-28 18:04:23 +0100115 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700116}
117
118static void test_rach(uint8_t bsic, uint8_t ra)
119{
Maxa4785902019-03-05 11:30:39 +0100120 int rc;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700121 uint8_t result;
122 ubit_t bursts_u[36];
123 sbit_t bursts_s[36];
124
125 /* Encode L2 message */
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700126 printd("Encoding: %02x\n", ra);
Maxa4785902019-03-05 11:30:39 +0100127 rc = gsm0503_rach_ext_encode(bursts_u, ra, bsic, false);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700128 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700129
130 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100131 osmo_ubit2sbit(bursts_s, bursts_u, 36);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700132
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700133 printd("U-Bits: %s\n", osmo_ubit_dump(bursts_u, 36));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700134
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700135 printd("S-Bits: %s\n", osmo_hexdump((uint8_t *)bursts_s, 36));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700136
137 /* Destroy some bits */
138 memset(bursts_s + 6, 0, 8);
139
140 /* Decode, correcting errors */
Maxa4785902019-03-05 11:30:39 +0100141 rc = gsm0503_rach_decode_ber(&result, bursts_s, bsic, NULL, NULL);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700142 CHECK_RC_OR_RET(rc == 0, "decoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700143
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700144 printd("Decoded: %02x\n", result);
Max32e56412017-10-16 14:58:00 +0200145 if (ra != result)
146 printf("FAIL [RACH]: encoded %u != %u decoded\n", ra, result);
147
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700148 printd("\n");
Max32e56412017-10-16 14:58:00 +0200149}
150
151static void test_rach_ext(uint8_t bsic, uint16_t ra)
152{
Maxa4785902019-03-05 11:30:39 +0100153 int rc;
Max32e56412017-10-16 14:58:00 +0200154 uint16_t result = 3000; /* Max ext. RA is 2^11 = 2048 */
155 ubit_t bursts_u[36];
156 sbit_t bursts_s[36];
157
158 /* Encode L2 message */
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700159 printd("Encoding: %02x\n", ra);
Maxa4785902019-03-05 11:30:39 +0100160 rc = gsm0503_rach_ext_encode(bursts_u, ra, bsic, true);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700161 CHECK_RC_OR_RET(rc == 0, "encoding");
Max32e56412017-10-16 14:58:00 +0200162
163 /* Prepare soft-bits */
164 osmo_ubit2sbit(bursts_s, bursts_u, 36);
165
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700166 printd("U-Bits: %s\n", osmo_ubit_dump(bursts_u, 36));
Max32e56412017-10-16 14:58:00 +0200167
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700168 printd("S-Bits: %s\n", osmo_hexdump((uint8_t *)bursts_s, 36));
Max32e56412017-10-16 14:58:00 +0200169
170 /* Destroy some bits */
171 memset(bursts_s + 9, 0, 8);
172
173 /* Decode, correcting errors */
Maxa4785902019-03-05 11:30:39 +0100174 rc = gsm0503_rach_ext_decode_ber(&result, bursts_s, bsic, NULL, NULL);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700175 CHECK_RC_OR_RET(rc == 0, "decoding");
Max32e56412017-10-16 14:58:00 +0200176
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700177 printd("Decoded: %02x\n", result);
Max32e56412017-10-16 14:58:00 +0200178 if (ra != result)
179 printf("FAIL [RACH ext]: encoded %u != %u decoded\n", ra, result);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700180
Vadim Yanitskiy0f4919e2020-03-30 18:19:17 +0700181 printd("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700182}
183
Vadim Yanitskiy41ce6752020-03-31 19:15:28 +0700184static void test_rach_11bit_sample(uint8_t bsic, const sbit_t *payload)
185{
186 int n_errors, n_bits_total;
187 uint16_t ra11;
188 int rc;
189
190 /* Decode, correcting errors */
191 rc = gsm0503_rach_ext_decode_ber(&ra11, payload, bsic, &n_errors, &n_bits_total);
192 if (rc) {
193 printf("%s(): decoding failed (rc=%d)\n", __func__, rc);
194 return;
195 }
196
197 printf("Decoded RA11: 0x%03x\n", ra11);
198}
199
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700200static void test_sch(uint8_t *info)
201{
202 uint8_t result[4];
203 ubit_t bursts_u[78];
204 sbit_t bursts_s[78];
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700205 int rc;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700206
207 /* Zero bits 25 and above */
208 info[3] &= 1;
209 result[3] = 0;
210
211 /* Encode L2 message */
Max0176b4a2017-11-28 18:04:23 +0100212 printf("Encoding: %s\n", osmo_hexdump(info, 4));
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700213 rc = gsm0503_sch_encode(bursts_u, info);
214 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700215
216 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100217 osmo_ubit2sbit(bursts_s, bursts_u, 78);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700218
Max0176b4a2017-11-28 18:04:23 +0100219 printf("U-Bits: %s\n", osmo_ubit_dump(bursts_u, 78));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700220
Max0176b4a2017-11-28 18:04:23 +0100221 printf("S-Bits: %s\n", osmo_hexdump((uint8_t *)bursts_s, 78));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700222
223 /* Destroy some bits */
224 memset(bursts_s + 6, 0, 10);
225
226 /* Decode, correcting errors */
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700227 rc = gsm0503_sch_decode(result, bursts_s);
228 CHECK_RC_OR_RET(rc == 0, "decoding");
229
Max0176b4a2017-11-28 18:04:23 +0100230 printf("Decoded: %s\n", osmo_hexdump(result, 4));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700231
Max33dbecb2017-11-28 19:49:05 +0100232 OSMO_ASSERT(!memcmp(info, result, 4));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700233
Max0176b4a2017-11-28 18:04:23 +0100234 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700235}
236
237static void test_fr(uint8_t *speech, int len)
238{
239 uint8_t result[33];
240 ubit_t bursts_u[116 * 8];
241 sbit_t bursts_s[116 * 8];
242 int n_errors, n_bits_total;
243 int rc;
244
245 memset(bursts_u, 0x23, sizeof(bursts_u));
246 memset(bursts_s, 0, sizeof(bursts_s));
247
248 /* Encode L2 message */
Max0176b4a2017-11-28 18:04:23 +0100249 printf("Encoding: %s\n", osmo_hexdump(speech, len));
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700250 rc = gsm0503_tch_fr_encode(bursts_u, speech, len, 1);
251 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700252
253 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100254 osmo_ubit2sbit(bursts_s, bursts_u, 116 * 8);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700255
Max458a6f52017-11-28 17:26:54 +0100256 dump_ubits(bursts_u, 812);
257 dump_sbits((uint8_t *)bursts_s, 812);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700258
259 /* Destroy some bits */
260 memset(bursts_s + 6, 0, 20);
261
262 /* Decode, correcting errors */
263 rc = gsm0503_tch_fr_decode(result, bursts_s, 1, len == 31,
264 &n_errors, &n_bits_total);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700265 CHECK_RC_OR_RET(rc == len, "decoding");
266
Max0176b4a2017-11-28 18:04:23 +0100267 printf("Decoded: %s\n", osmo_hexdump(result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700268 printf("tch_fr_decode: n_errors=%d n_bits_total=%d ber=%.2f\n",
269 n_errors, n_bits_total, (float)n_errors/n_bits_total);
270
Max33dbecb2017-11-28 19:49:05 +0100271 OSMO_ASSERT(!memcmp(speech, result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700272
Max0176b4a2017-11-28 18:04:23 +0100273 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700274}
275
276static void test_hr(uint8_t *speech, int len)
277{
278 uint8_t result[23];
279 ubit_t bursts_u[116 * 6];
280 sbit_t bursts_s[116 * 6];
281 int n_errors, n_bits_total;
282 int rc;
283
284 memset(bursts_u, 0x23, sizeof(bursts_u));
285 memset(bursts_s, 0, sizeof(bursts_s));
286
287 /* Encode L2 message */
Max0176b4a2017-11-28 18:04:23 +0100288 printf("Encoding: %s\n", osmo_hexdump(speech, len));
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700289 rc = gsm0503_tch_hr_encode(bursts_u, speech, len);
290 CHECK_RC_OR_RET(rc == 0, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700291
292 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100293 osmo_ubit2sbit(bursts_s, bursts_u, 116 * 6);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700294
Max458a6f52017-11-28 17:26:54 +0100295 dump_ubits(bursts_u, 580);
296 dump_sbits((uint8_t *)bursts_s, 580);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700297
298 /* Destroy some bits */
299 memset(bursts_s + 6, 0, 20);
300
301 /* Decode, correcting errors */
302 rc = gsm0503_tch_hr_decode(result, bursts_s, 0,
303 &n_errors, &n_bits_total);
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700304 CHECK_RC_OR_RET(rc == len, "decoding");
305
Max0176b4a2017-11-28 18:04:23 +0100306 printf("Decoded: %s\n", osmo_hexdump(result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700307 printf("tch_hr_decode: n_errors=%d n_bits_total=%d ber=%.2f\n",
308 n_errors, n_bits_total, (float)n_errors/n_bits_total);
309
Max33dbecb2017-11-28 19:49:05 +0100310 OSMO_ASSERT(!memcmp(speech, result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700311
Max0176b4a2017-11-28 18:04:23 +0100312 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700313}
314
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200315struct test_macblock {
316 bool is_egprs;
317 uint16_t exp_burst_bits;
318 uint16_t l2_len;
319 uint8_t l2[54];
320};
321
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200322static const struct test_macblock test_macblock[] = {
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200323 /* Random frame */
324 { false,
325 GSM0503_GPRS_BURSTS_NBITS,
326 54,
327 { 0xa3, 0xaf, 0x5f, 0xc6, 0x36, 0x43, 0x44, 0xab,
328 0xd9, 0x6d, 0x7d, 0x62, 0x24, 0xc9, 0xd2, 0x92,
329 0xfa, 0x27, 0x5d, 0x71, 0x7a, 0x59, 0xa8, 0x42,
330 0xa3, 0xaf, 0x5f, 0xc6, 0x36, 0x43, 0x44, 0xab,
331 0xa3, 0xaf, 0x5f, 0xc6, 0x36, 0x43, 0x44, 0xab,
332 0xd9, 0x6d, 0x7d, 0x62, 0x24, 0xc9, 0xd2, 0x92,
333 0xfa, 0x27, 0x5d, 0x71, 0x7a, 0xa8 }
334 },
335 /* jolly frame */
336 { false,
337 GSM0503_GPRS_BURSTS_NBITS,
338 23,
339 { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
340 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
341 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }
342 },
343/*
344GSM RLC/MAC: EGPRS DL HEADER
345 0... .... .... 0000 = DL TFI: 0
346 0... .... crumb 1 of DL TFI (decoded above)
347 .00. .... = RRBP: Reserved Block: (N+13) mod 2715648 (0)
348 ...0 0... = ES/P: RRBP field is not valid (no Polling) (0)
349 .... .111 = USF: 7
350 01.. .... 0000 0000 .... ...0 = BSN: 1
351 01.. .... crumb 2 of BSN (decoded above)
352 ..00 .... = PR: 0 dB (included) to 3 dB (excluded) less than BCCH level - P0 (0)
353 .... 0000 crumb 0 of DL TFI (decoded above)
354 0000 0000 crumb 1 of BSN (decoded above)
355 .00. .... = SPB (DL): No retransmission (0)
356 ...1 011. = CPS: MCS-1/P1 (0x0b)
357 .... ...0 crumb 0 of BSN (decoded above)
358GSM RLC/MAC: EGPRS DL DATA BLOCK 1 (BSN 1)
359 .... ..0. = FBI: Current Block is not last RLC data block in TBF
360 .... ...0 = Extension: Extension octet follows immediately
361 0000 100. = Length Indicator: 4
362 .... ...0 = Extension: Extension octet follows immediately
363 0010 000. = Length Indicator: 16
364 .... ...1 = Extension: No extension octet follows
365 data segment: LI[0]=4 indicates: (Last segment of) LLC frame (4 octets)
366 Data (4 bytes)
367 Data: 012b2b2b
368 [Length: 4]
369 data segment: LI[1]=16 indicates: (Last segment of) LLC frame (16 octets)
370 Data (16 bytes)
371 Data: 43c0012b2b2b2b2b2b2b2b2b2b2b2b2b
372 [Length: 16]
373*/
374 { true,
375 GSM0503_GPRS_BURSTS_NBITS,
376 27,
377 { 0x07, 0x40, 0x00, 0x16, 0x10, 0x42, 0x02, 0x56,
378 0x56, 0x56, 0x86, 0x80, 0x03, 0x56, 0x56, 0x56,
379 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
380 0x56, 0x56, 0x00 }
381 },
382};
383
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200384static void test_pdtch(const struct test_macblock *tmb, int len)
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700385{
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200386 uint8_t l2[len], result[len];
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700387 ubit_t bursts_u[116 * 4];
388 sbit_t bursts_s[116 * 4];
389 int n_errors, n_bits_total;
390 int rc;
391
392 /* Zero the not coded tail bits */
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200393 memcpy(l2, tmb->l2, len);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700394 switch (len) {
395 case 34:
396 case 54:
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200397 l2[len - 1] &= 0x7f;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700398 result[len - 1] &= 0x7f;
399 break;
400 case 40:
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200401 l2[len - 1] &= 0x07;
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700402 result[len - 1] &= 0x07;
403 break;
404 }
405
406 /* Encode L2 message */
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200407 printf("Encoding: %s\n", osmo_hexdump(l2, len));
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200408 if (tmb->is_egprs)
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200409 rc = gsm0503_pdtch_egprs_encode(bursts_u, l2, len);
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200410 else
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200411 rc = gsm0503_pdtch_encode(bursts_u, l2, len);
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200412 CHECK_RC_OR_RET(rc == (int)tmb->exp_burst_bits, "encoding");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700413
414 /* Prepare soft-bits */
Max29d489f2017-11-28 14:54:32 +0100415 osmo_ubit2sbit(bursts_s, bursts_u, 116 * 4);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700416
Max458a6f52017-11-28 17:26:54 +0100417 dump_ubits(bursts_u, 348);
418 dump_sbits((uint8_t *)bursts_s, 348);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700419
420 /* Decode */
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200421 if (tmb->is_egprs) {
422 /* gsm0503_pdtch_egprs_decode() is meant to decode EGPRS UL frames, so we cannot use it here */
423 rc = gsm0503_pdtch_egprs_decode(result, bursts_s, rc, NULL, &n_errors, &n_bits_total);
424 OSMO_ASSERT(rc == -EIO);
425 return;
426 } else {
427 rc = gsm0503_pdtch_decode(result, bursts_s, NULL, &n_errors, &n_bits_total);
428 }
Vadim Yanitskiyca466cf2020-03-30 18:12:19 +0700429 CHECK_RC_OR_RET(rc == len, "decoding");
430
Max0176b4a2017-11-28 18:04:23 +0100431 printf("Decoded: %s\n", osmo_hexdump(result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700432 printf("pdtch_decode: n_errors=%d n_bits_total=%d ber=%.2f\n",
433 n_errors, n_bits_total, (float)n_errors/n_bits_total);
434
Pau Espin Pedrole7d0d702020-04-09 16:16:53 +0200435 OSMO_ASSERT(!memcmp(l2, result, len));
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700436
Max0176b4a2017-11-28 18:04:23 +0100437 printf("\n");
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700438}
439
440uint8_t test_l2[][23] = {
441 /* Dummy frame */
442 { 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
445 /* Random frame */
446 { 0xa3, 0xaf, 0x5f, 0xc6, 0x36, 0x43, 0x44, 0xab,
447 0xd9, 0x6d, 0x7d, 0x62, 0x24, 0xc9, 0xd2, 0x92,
448 0xfa, 0x27, 0x5d, 0x71, 0x7a, 0x59, 0xa8 },
449 /* jolly frame */
450 { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
451 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
452 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
453};
454
Vadim Yanitskiy41ce6752020-03-31 19:15:28 +0700455/* 11-bit Access Burst soft-bits (payload only) from an EGPRS capable phone (BSIC 63) */
456static const sbit_t test_rach_11bit[6][36] = {
457 { 103, 109, -108, -110, 107, 108, -106, -120, -121,
458 -120, -105, 122, -104, -109, 108, 109, -109, -111,
459 107, 111, -105, -119, -121, -104, 122, -120, 121,
460 -99, -121, -120, -122, -106, 109, 109, -108, -111 },
461
462 { 103, 109, -109, -109, 106, 107, -106, -121, -121,
463 -120, -106, 121, -120, 117, -122, 101, 109, -122,
464 120, -120, 101, 118, 120, 102, -125, 101, 110,
465 -120, 121, -101, -121, -118, -121, -106, 108, 121 },
466
467 { -121, -122, -104, 123, -104, -108, 122, -104, -121,
468 -121, -102, 124, -105, -110, 107, 109, -108, -109,
469 121, -122, 101, 107, -121, 105, 108, -110, -107,
470 124, -104, -109, 120, -122, 100, 122, 104, -123 },
471
472 { -122, -123, -103, 123, -105, -109, 122, -105, -121,
473 -120, -104, 122, -120, 121, -101, -122, -120, -120,
474 -119, -105, 120, -106, -108, 123, -104, -113, 105,
475 122, 101, -122, 119, -122, 117, -121, 119, -122 },
476
477 { 105, 110, -109, -109, 107, 108, -108, -120, -120,
478 -121, -106, 121, -104, -107, 106, 108, -108, -108,
479 108, 107, -105, -120, -122, -104, 122, -119, 121,
480 -103, -122, -118, -120, -106, 108, 108, -110, -111 },
481
482 { 120, -103, -123, -104, 119, -121, 100, 123, 106,
483 -109, -107, 121, -122, 118, -121, 103, 108, -122,
484 120, -119, 121, -103, -121, -119, -121, -103, 124,
485 -106, -108, 122, -103, -106, 121, -120, 119, -121 },
486};
487
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700488uint8_t test_speech_fr[33];
489uint8_t test_speech_efr[31];
490uint8_t test_speech_hr[15];
491
492int main(int argc, char **argv)
493{
494 int i, len_l2, len_mb;
495
Vadim Yanitskiy88c61c32020-03-30 20:50:49 +0700496 len_l2 = ARRAY_SIZE(test_l2);
497 len_mb = ARRAY_SIZE(test_macblock);
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700498
499 for (i = 0; i < len_l2; i++)
500 test_xcch(test_l2[i]);
501
502 for (i = 0; i < 256; i++) {
503 test_rach(0x3f, i);
504 test_rach(0x00, i);
505 test_rach(0x1a, i);
506 }
507
Max32e56412017-10-16 14:58:00 +0200508 for (i = 0; i < 2048; i++) {
509 test_rach_ext(0x3f, i);
510 test_rach_ext(0x00, i);
511 test_rach_ext(0x1a, i);
512 }
513
Vadim Yanitskiy41ce6752020-03-31 19:15:28 +0700514 for (i = 0; i < ARRAY_SIZE(test_rach_11bit); i++)
515 test_rach_11bit_sample(0x3f, test_rach_11bit[i]);
516 printf("\n");
517
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700518 for (i = 0; i < len_l2; i++)
519 test_sch(test_l2[i]);
520
521 for (i = 0; i < sizeof(test_speech_fr); i++)
522 test_speech_fr[i] = i;
523 test_speech_fr[0] = 0xd0;
524 test_fr(test_speech_fr, sizeof(test_speech_fr));
525
526 for (i = 0; i < sizeof(test_speech_efr); i++)
527 test_speech_efr[i] = i;
528 test_speech_efr[0] = 0xc0;
529 test_fr(test_speech_efr, sizeof(test_speech_efr));
530
531 for (i = 0; i < len_l2; i++)
532 test_fr(test_l2[i], sizeof(test_l2[0]));
533
534 for (i = 0; i < sizeof(test_speech_hr); i++)
535 test_speech_hr[i] = i * 17;
536 test_speech_hr[0] = 0x00;
537 test_hr(test_speech_hr, sizeof(test_speech_hr));
538
539 for (i = 0; i < len_l2; i++)
540 test_hr(test_l2[i], sizeof(test_l2[0]));
541
542 for (i = 0; i < len_mb; i++) {
Pau Espin Pedrolce28d2e2020-04-07 16:30:57 +0200543 if (test_macblock[i].is_egprs) {
544 test_pdtch(&test_macblock[i], test_macblock[i].l2_len);
545 } else {
546 test_pdtch(&test_macblock[i], 23);
547 test_pdtch(&test_macblock[i], 34);
548 test_pdtch(&test_macblock[i], 40);
549 test_pdtch(&test_macblock[i], 54);
550 }
Vadim Yanitskiy3262f822016-09-23 01:48:59 +0700551 }
552
553 printf("Success\n");
554
555 return 0;
556}