blob: afbba88dd3ce337fb03841c1596f35dc39aba715 [file] [log] [blame]
Piotr Krysik70c25a12017-01-03 08:01:23 +01001/*
2 * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
3 * (C) 2015 by Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
4 * (C) 2016 by Tom Tsou <tom.tsou@ettus.com>
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 General Public License as published by
10 * the Free Software Foundation; either version 2 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 General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#include <stdio.h>
24#include <stdint.h>
25#include <string.h>
26#include <stdlib.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#include <osmocom/core/bits.h>
33#include <osmocom/core/conv.h>
34#include <osmocom/core/utils.h>
35#include <osmocom/core/crcgen.h>
36#include <osmocom/core/endian.h>
37
38#include <osmocom/gsm/protocol/gsm_04_08.h>
39#include "gsm0503.h"
40#include <osmocom/codec/codec.h>
41
42#include "gsm0503_interleaving.h"
43#include "gsm0503_mapping.h"
44#include "gsm0503_tables.h"
45#include "gsm0503_coding.h"
46#include "gsm0503_parity.h"
47
48#ifdef __cplusplus
49}
50#endif
51
52
53/*
54 * EGPRS coding limits
55 */
56
57/* Max header size with parity bits */
58#define EGPRS_HDR_UPP_MAX 54
59
60/* Max encoded header size */
61#define EGPRS_HDR_C_MAX 162
62
63/* Max punctured header size */
64#define EGPRS_HDR_HC_MAX 160
65
66/* Max data block size with parity bits */
67#define EGPRS_DATA_U_MAX 612
68
69/* Max encoded data block size */
70#define EGPRS_DATA_C_MAX 1836
71
72/* Max single block punctured data size */
73#define EGPRS_DATA_DC_MAX 1248
74
75/* Dual block punctured data size */
76#define EGPRS_DATA_C1 612
77#define EGPRS_DATA_C2 EGPRS_DATA_C1
78
79/* TS 101318 Chapter 5.1: 260 bits + 4bit sig */
80#define GSM_FR_BYTES 33
81/* TS 101318 Chapter 5.2: 112 bits, no sig */
82#define GSM_HR_BYTES 14
83/* TS 101318 Chapter 5.3: 244 bits + 4bit sig */
84#define GSM_EFR_BYTES 31
85
86struct gsm0503_mcs_code {
87 uint8_t mcs;
88 uint8_t usf_len;
89
90 /* Header coding */
91 uint8_t hdr_len;
92 uint8_t hdr_code_len;
93 uint8_t hdr_punc_len;
94 const struct osmo_conv_code *hdr_conv;
95 const uint8_t *hdr_punc;
96
97 /* Data coding */
98 uint16_t data_len;
99 uint16_t data_code_len;
100 uint16_t data_punc_len;
101 const struct osmo_conv_code *data_conv;
102 const uint8_t *data_punc[3];
103};
104
105static int osmo_conv_decode_ber(const struct osmo_conv_code *code,
106 const sbit_t *input, ubit_t *output,
107 int *n_errors, int *n_bits_total)
108{
109 int res, i, coded_len;
110 ubit_t recoded[EGPRS_DATA_C_MAX];
111
112 res = osmo_conv_decode(code, input, output);
113
114 if (n_bits_total || n_errors) {
115 coded_len = osmo_conv_encode(code, output, recoded);
116 OSMO_ASSERT(sizeof(recoded) / sizeof(recoded[0]) >= coded_len);
117 }
118
119 /* Count bit errors */
120 if (n_errors) {
121 *n_errors = 0;
122 for (i = 0; i < coded_len; i++) {
123 if (!((recoded[i] && input[i] < 0) ||
124 (!recoded[i] && input[i] > 0)) )
125 *n_errors += 1;
126 }
127 }
128
129 if (n_bits_total)
130 *n_bits_total = coded_len;
131
132 return res;
133}
134
135static int _xcch_decode_cB(uint8_t *l2_data, sbit_t *cB,
136 int *n_errors, int *n_bits_total)
137{
138 ubit_t conv[224];
139 int rv;
140
141 osmo_conv_decode_ber(&gsm0503_xcch, cB,
142 conv, n_errors, n_bits_total);
143
144 rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40,
145 conv, 184, conv + 184);
146 if (rv)
147 return -1;
148
149 osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1);
150
151 return 0;
152}
153
154static int _xcch_encode_cB(ubit_t *cB, uint8_t *l2_data)
155{
156 ubit_t conv[224];
157
158 osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1);
159
160 osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184);
161
162 osmo_conv_encode(&gsm0503_xcch, conv, cB);
163
164 return 0;
165}
166
167/*
168 * GSM xCCH block transcoding
169 */
170int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts,
171 int *n_errors, int *n_bits_total)
172{
173 sbit_t iB[456], cB[456];
174 int i;
175
176 for (i = 0; i < 4; i++)
177 gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], NULL, NULL);
178
179 gsm0503_xcch_deinterleave(cB, iB);
180
181 return _xcch_decode_cB(l2_data, cB, n_errors, n_bits_total);
182}
183
184int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data)
185{
186 ubit_t iB[456], cB[456], hl = 1, hn = 1;
187 int i;
188
189 _xcch_encode_cB(cB, l2_data);
190
191 gsm0503_xcch_interleave(cB, iB);
192
193 for (i = 0; i < 4; i++)
194 gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], &hl, &hn);
195
196 return 0;
197}
198
199
200
201/*
202 * GSM PDTCH block transcoding
203 */
204
205int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p,
206 int *n_errors, int *n_bits_total)
207{
208 sbit_t iB[456], cB[676], hl_hn[8];
209 ubit_t conv[456];
210 int i, j, k, rv, best = 0, cs = 0, usf = 0; /* make GCC happy */
211
212 for (i = 0; i < 4; i++)
213 gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116],
214 hl_hn + i * 2, hl_hn + i * 2 + 1);
215
216 for (i = 0; i < 4; i++) {
217 for (j = 0, k = 0; j < 8; j++)
218 k += abs(((int)gsm0503_pdtch_hl_hn_sbit[i][j]) - ((int)hl_hn[j]));
219
220 if (i == 0 || k < best) {
221 best = k;
222 cs = i+1;
223 }
224 }
225
226 gsm0503_xcch_deinterleave(cB, iB);
227
228 switch (cs) {
229 case 1:
230 osmo_conv_decode_ber(&gsm0503_xcch, cB,
231 conv, n_errors, n_bits_total);
232
233 rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40,
234 conv, 184, conv + 184);
235 if (rv)
236 return -1;
237
238 osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1);
239
240 return 23;
241 case 2:
242 for (i = 587, j = 455; i >= 0; i--) {
243 if (!gsm0503_puncture_cs2[i])
244 cB[i] = cB[j--];
245 else
246 cB[i] = 0;
247 }
248
249 osmo_conv_decode_ber(&gsm0503_cs2, cB,
250 conv, n_errors, n_bits_total);
251
252 for (i = 0; i < 8; i++) {
253 for (j = 0, k = 0; j < 6; j++)
254 k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j]));
255
256 if (i == 0 || k < best) {
257 best = k;
258 usf = i;
259 }
260 }
261
262 conv[3] = usf & 1;
263 conv[4] = (usf >> 1) & 1;
264 conv[5] = (usf >> 2) & 1;
265 if (usf_p)
266 *usf_p = usf;
267
268 rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16,
269 conv + 3, 271, conv + 3 + 271);
270 if (rv)
271 return -1;
272
273 osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 271, 1);
274
275 return 34;
276 case 3:
277 for (i = 675, j = 455; i >= 0; i--) {
278 if (!gsm0503_puncture_cs3[i])
279 cB[i] = cB[j--];
280 else
281 cB[i] = 0;
282 }
283
284 osmo_conv_decode_ber(&gsm0503_cs3, cB,
285 conv, n_errors, n_bits_total);
286
287 for (i = 0; i < 8; i++) {
288 for (j = 0, k = 0; j < 6; j++)
289 k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j]));
290
291 if (i == 0 || k < best) {
292 best = k;
293 usf = i;
294 }
295 }
296
297 conv[3] = usf & 1;
298 conv[4] = (usf >> 1) & 1;
299 conv[5] = (usf >> 2) & 1;
300 if (usf_p)
301 *usf_p = usf;
302
303 rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16,
304 conv + 3, 315, conv + 3 + 315);
305 if (rv)
306 return -1;
307
308 osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 315, 1);
309
310 return 40;
311 case 4:
312 for (i = 12; i < 456; i++)
313 conv[i] = (cB[i] < 0) ? 1 : 0;
314
315 for (i = 0; i < 8; i++) {
316 for (j = 0, k = 0; j < 12; j++)
317 k += abs(((int)gsm0503_usf2twelve_sbit[i][j]) - ((int)cB[j]));
318
319 if (i == 0 || k < best) {
320 best = k;
321 usf = i;
322 }
323 }
324
325 conv[9] = usf & 1;
326 conv[10] = (usf >> 1) & 1;
327 conv[11] = (usf >> 2) & 1;
328 if (usf_p)
329 *usf_p = usf;
330
331 rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16,
332 conv + 9, 431, conv + 9 + 431);
333 if (rv) {
334 *n_bits_total = 456 - 12;
335 *n_errors = *n_bits_total;
336 return -1;
337 }
338
339 *n_bits_total = 456 - 12;
340 *n_errors = 0;
341
342 osmo_ubit2pbit_ext(l2_data, 0, conv, 9, 431, 1);
343
344 return 54;
345 default:
346 *n_bits_total = 0;
347 *n_errors = 0;
348 break;
349 }
350
351 return -1;
352}
353
354int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len)
355{
356 ubit_t iB[456], cB[676];
357 const ubit_t *hl_hn;
358 ubit_t conv[334];
359 int i, j, usf;
360
361 switch (l2_len) {
362 case 23:
363 osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1);
364
365 osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184);
366
367 osmo_conv_encode(&gsm0503_xcch, conv, cB);
368
369 hl_hn = gsm0503_pdtch_hl_hn_ubit[0];
370
371 break;
372 case 34:
373 osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 271, 1);
374 usf = l2_data[0] & 0x7;
375
376 osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3,
377 271, conv + 3 + 271);
378
379 memcpy(conv, gsm0503_usf2six[usf], 6);
380
381 osmo_conv_encode(&gsm0503_cs2, conv, cB);
382
383 for (i = 0, j = 0; i < 588; i++)
384 if (!gsm0503_puncture_cs2[i])
385 cB[j++] = cB[i];
386
387 hl_hn = gsm0503_pdtch_hl_hn_ubit[1];
388
389 break;
390 case 40:
391 osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 315, 1);
392 usf = l2_data[0] & 0x7;
393
394 osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3,
395 315, conv + 3 + 315);
396
397 memcpy(conv, gsm0503_usf2six[usf], 6);
398
399 osmo_conv_encode(&gsm0503_cs3, conv, cB);
400
401 for (i = 0, j = 0; i < 676; i++)
402 if (!gsm0503_puncture_cs3[i])
403 cB[j++] = cB[i];
404
405 hl_hn = gsm0503_pdtch_hl_hn_ubit[2];
406
407 break;
408 case 54:
409 osmo_pbit2ubit_ext(cB, 9, l2_data, 0, 431, 1);
410 usf = l2_data[0] & 0x7;
411
412 osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, cB + 9,
413 431, cB + 9 + 431);
414
415 memcpy(cB, gsm0503_usf2twelve_ubit[usf], 12);
416
417 hl_hn = gsm0503_pdtch_hl_hn_ubit[3];
418
419 break;
420 default:
421 return -1;
422 }
423
424 gsm0503_xcch_interleave(cB, iB);
425
426 for (i = 0; i < 4; i++) {
427 gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116],
428 hl_hn + i * 2, hl_hn + i * 2 + 1);
429 }
430
431 return GSM0503_GPRS_BURSTS_NBITS;
432}
433
434/*
435 * GSM TCH/F FR/EFR transcoding
436 */
437
438static void tch_fr_reassemble(uint8_t *tch_data,
439 ubit_t *b_bits, int net_order)
440{
441 int i, j, k, l, o;
442
443 tch_data[0] = 0xd << 4;
444 memset(tch_data + 1, 0, 32);
445
446 if (net_order) {
447 for (i = 0, j = 4; i < 260; i++, j++)
448 tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7)));
449
450 return;
451 }
452
453 /* reassemble d-bits */
454 i = 0; /* counts bits */
455 j = 4; /* counts output bits */
456 k = gsm0503_gsm_fr_map[0]-1; /* current number bit in element */
457 l = 0; /* counts element bits */
458 o = 0; /* offset input bits */
459 while (i < 260) {
460 tch_data[j >> 3] |= (b_bits[k + o] << (7 - (j & 7)));
461 if (--k < 0) {
462 o += gsm0503_gsm_fr_map[l];
463 k = gsm0503_gsm_fr_map[++l]-1;
464 }
465 i++;
466 j++;
467 }
468}
469
470static void tch_fr_disassemble(ubit_t *b_bits,
471 uint8_t *tch_data, int net_order)
472{
473 int i, j, k, l, o;
474
475 if (net_order) {
476 for (i = 0, j = 4; i < 260; i++, j++)
477 b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
478
479 return;
480 }
481
482 i = 0; /* counts bits */
483 j = 4; /* counts input bits */
484 k = gsm0503_gsm_fr_map[0] - 1; /* current number bit in element */
485 l = 0; /* counts element bits */
486 o = 0; /* offset output bits */
487 while (i < 260) {
488 b_bits[k + o] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
489 if (--k < 0) {
490 o += gsm0503_gsm_fr_map[l];
491 k = gsm0503_gsm_fr_map[++l] - 1;
492 }
493 i++;
494 j++;
495 }
496}
497
498static void tch_hr_reassemble(uint8_t *tch_data, ubit_t *b_bits)
499{
500 int i, j;
501
502 tch_data[0] = 0x00; /* F = 0, FT = 000 */
503 memset(tch_data + 1, 0, 14);
504
505 for (i = 0, j = 8; i < 112; i++, j++)
506 tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7)));
507}
508
509static void tch_hr_disassemble(ubit_t *b_bits, uint8_t *tch_data)
510{
511 int i, j;
512
513 for (i = 0, j = 8; i < 112; i++, j++)
514 b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
515}
516
517static void tch_efr_reassemble(uint8_t *tch_data, ubit_t *b_bits)
518{
519 int i, j;
520
521 tch_data[0] = 0xc << 4;
522 memset(tch_data + 1, 0, 30);
523
524 for (i = 0, j = 4; i < 244; i++, j++)
525 tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7)));
526}
527
528static void tch_efr_disassemble(ubit_t *b_bits, uint8_t *tch_data)
529{
530 int i, j;
531
532 for (i = 0, j = 4; i < 244; i++, j++)
533 b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
534}
535
536static void tch_amr_reassemble(uint8_t *tch_data, ubit_t *d_bits, int len)
537{
538 int i, j;
539
540 memset(tch_data, 0, (len + 7) >> 3);
541
542 for (i = 0, j = 0; i < len; i++, j++)
543 tch_data[j >> 3] |= (d_bits[i] << (7 - (j & 7)));
544}
545
546static void tch_amr_disassemble(ubit_t *d_bits, uint8_t *tch_data, int len)
547{
548 int i, j;
549
550 for (i = 0, j = 0; i < len; i++, j++)
551 d_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
552}
553
554static void tch_fr_d_to_b(ubit_t *b_bits, ubit_t *d_bits)
555{
556 int i;
557
558 for (i = 0; i < 260; i++)
559 b_bits[gsm610_bitorder[i]] = d_bits[i];
560}
561
562static void tch_fr_b_to_d(ubit_t *d_bits, ubit_t *b_bits)
563{
564 int i;
565
566 for (i = 0; i < 260; i++)
567 d_bits[i] = b_bits[gsm610_bitorder[i]];
568}
569
570static void tch_hr_d_to_b(ubit_t *b_bits, ubit_t *d_bits)
571{
572 int i;
573
574 const uint16_t *map;
575
576 if (!d_bits[93] && !d_bits[94])
577 map = gsm620_unvoiced_bitorder;
578 else
579 map = gsm620_voiced_bitorder;
580
581 for (i = 0; i < 112; i++)
582 b_bits[map[i]] = d_bits[i];
583}
584
585static void tch_hr_b_to_d(ubit_t *d_bits, ubit_t *b_bits)
586{
587 int i;
588 const uint16_t *map;
589
590 if (!b_bits[34] && !b_bits[35])
591 map = gsm620_unvoiced_bitorder;
592 else
593 map = gsm620_voiced_bitorder;
594
595 for (i = 0; i < 112; i++)
596 d_bits[i] = b_bits[map[i]];
597}
598
599static void tch_efr_d_to_w(ubit_t *b_bits, ubit_t *d_bits)
600{
601 int i;
602
603 for (i = 0; i < 260; i++)
604 b_bits[gsm660_bitorder[i]] = d_bits[i];
605}
606
607static void tch_efr_w_to_d(ubit_t *d_bits, ubit_t *b_bits)
608{
609 int i;
610
611 for (i = 0; i < 260; i++)
612 d_bits[i] = b_bits[gsm660_bitorder[i]];
613}
614
615static void tch_efr_protected(ubit_t *s_bits, ubit_t *b_bits)
616{
617 int i;
618
619 for (i = 0; i < 65; i++)
620 b_bits[i] = s_bits[gsm0503_gsm_efr_protected_bits[i] - 1];
621}
622
623static void tch_fr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u)
624{
625 int i;
626
627 for (i = 0; i < 91; i++) {
628 d[i << 1] = u[i];
629 d[(i << 1) + 1] = u[184 - i];
630 }
631
632 for (i = 0; i < 3; i++)
633 p[i] = u[91 + i];
634}
635
636static void tch_fr_reorder(ubit_t *u, ubit_t *d, ubit_t *p)
637{
638 int i;
639
640 for (i = 0; i < 91; i++) {
641 u[i] = d[i << 1];
642 u[184 - i] = d[(i << 1) + 1];
643 }
644
645 for (i = 0; i < 3; i++)
646 u[91 + i] = p[i];
647}
648
649static void tch_hr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u)
650{
651 memcpy(d, u, 95);
652 memcpy(p, u + 95, 3);
653}
654
655static void tch_hr_reorder(ubit_t *u, ubit_t *d, ubit_t *p)
656{
657 memcpy(u, d, 95);
658 memcpy(u + 95, p, 3);
659}
660
661static void tch_efr_reorder(ubit_t *w, ubit_t *s, ubit_t *p)
662{
663 memcpy(w, s, 71);
664 w[71] = w[72] = s[69];
665 memcpy(w + 73, s + 71, 50);
666 w[123] = w[124] = s[119];
667 memcpy(w + 125, s + 121, 53);
668 w[178] = w[179] = s[172];
669 memcpy(w + 180, s + 174, 50);
670 w[230] = w[231] = s[222];
671 memcpy(w + 232, s + 224, 20);
672 memcpy(w + 252, p, 8);
673}
674
675static void tch_efr_unreorder(ubit_t *s, ubit_t *p, ubit_t *w)
676{
677 int sum;
678
679 memcpy(s, w, 71);
680 sum = s[69] + w[71] + w[72];
681 s[69] = (sum > 2);
682 memcpy(s + 71, w + 73, 50);
683 sum = s[119] + w[123] + w[124];
684 s[119] = (sum > 2);
685 memcpy(s + 121, w + 125, 53);
686 sum = s[172] + w[178] + w[179];
687 s[172] = (sum > 2);
688 memcpy(s + 174, w + 180, 50);
689 sum = s[220] + w[230] + w[231];
690 s[222] = (sum > 2);
691 memcpy(s + 224, w + 232, 20);
692 memcpy(p, w + 252, 8);
693}
694
695static void tch_amr_merge(ubit_t *u, ubit_t *d, ubit_t *p, int len, int prot)
696{
697 memcpy(u, d, prot);
698 memcpy(u + prot, p, 6);
699 memcpy(u + prot + 6, d + prot, len - prot);
700}
701
702static void tch_amr_unmerge(ubit_t *d, ubit_t *p,
703 ubit_t *u, int len, int prot)
704{
705 memcpy(d, u, prot);
706 memcpy(p, u+prot, 6);
707 memcpy(d + prot, u + prot + 6, len - prot);
708}
709
710int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts,
711 int net_order, int efr, int *n_errors, int *n_bits_total)
712{
713 sbit_t iB[912], cB[456], h;
714 ubit_t conv[185], s[244], w[260], b[65], d[260], p[8];
715 int i, rv, len, steal = 0;
716
717 for (i=0; i<8; i++) {
718 gsm0503_tch_burst_unmap(&iB[i * 114],
719 &bursts[i * 116], &h, i >> 2);
720 steal -= h;
721 }
722
723 gsm0503_tch_fr_deinterleave(cB, iB);
724
725 if (steal > 0) {
726 rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
727 if (rv) {
728 /* Error decoding FACCH frame */
729 return -1;
730 }
731
732 return 23;
733 }
734
735 osmo_conv_decode_ber(&gsm0503_tch_fr, cB, conv, n_errors, n_bits_total);
736
737 tch_fr_unreorder(d, p, conv);
738
739 for (i = 0; i < 78; i++)
740 d[i + 182] = (cB[i + 378] < 0) ? 1 : 0;
741
742 rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d, 50, p);
743 if (rv) {
744 /* Error checking CRC8 for the FR part of an EFR/FR frame */
745 return -1;
746 }
747
748 if (efr) {
749 tch_efr_d_to_w(w, d);
750
751 tch_efr_unreorder(s, p, w);
752
753 tch_efr_protected(s, b);
754
755 rv = osmo_crc8gen_check_bits(&gsm0503_tch_efr_crc8, b, 65, p);
756 if (rv) {
757 /* Error checking CRC8 for the EFR part of an EFR frame */
758 return -1;
759 }
760
761 tch_efr_reassemble(tch_data, s);
762
763 len = GSM_EFR_BYTES;
764 } else {
765 tch_fr_d_to_b(w, d);
766
767 tch_fr_reassemble(tch_data, w, net_order);
768
769 len = GSM_FR_BYTES;
770 }
771
772 return len;
773}
774
775int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data,
776 int len, int net_order)
777{
778 ubit_t iB[912], cB[456], h;
779 ubit_t conv[185], w[260], b[65], s[244], d[260], p[8];
780 int i;
781
782 switch (len) {
783 case GSM_EFR_BYTES: /* TCH EFR */
784
785 tch_efr_disassemble(s, tch_data);
786
787 tch_efr_protected(s, b);
788
789 osmo_crc8gen_set_bits(&gsm0503_tch_efr_crc8, b, 65, p);
790
791 tch_efr_reorder(w, s, p);
792
793 tch_efr_w_to_d(d, w);
794
795 goto coding_efr_fr;
796 case GSM_FR_BYTES: /* TCH FR */
797 tch_fr_disassemble(w, tch_data, net_order);
798
799 tch_fr_b_to_d(d, w);
800
801coding_efr_fr:
802 osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d, 50, p);
803
804 tch_fr_reorder(conv, d, p);
805
806 memcpy(cB + 378, d + 182, 78);
807
808 osmo_conv_encode(&gsm0503_tch_fr, conv, cB);
809
810 h = 0;
811
812 break;
813 case GSM_MACBLOCK_LEN: /* FACCH */
814 _xcch_encode_cB(cB, tch_data);
815
816 h = 1;
817
818 break;
819 default:
820 return -1;
821 }
822
823 gsm0503_tch_fr_interleave(cB, iB);
824
825 for (i = 0; i < 8; i++) {
826 gsm0503_tch_burst_map(&iB[i * 114],
827 &bursts[i * 116], &h, i >> 2);
828 }
829
830 return 0;
831}
832
833int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd,
834 int *n_errors, int *n_bits_total)
835{
836 sbit_t iB[912], cB[456], h;
837 ubit_t conv[98], b[112], d[112], p[3];
838 int i, rv, steal = 0;
839
840 /* Only unmap the stealing bits */
841 if (!odd) {
842 for (i = 0; i < 4; i++) {
843 gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0);
844 steal -= h;
845 }
846
847 for (i = 2; i < 5; i++) {
848 gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1);
849 steal -= h;
850 }
851 }
852
853 /* If we found a stole FACCH, but only at correct alignment */
854 if (steal > 0) {
855 for (i = 0; i < 6; i++) {
856 gsm0503_tch_burst_unmap(&iB[i * 114],
857 &bursts[i * 116], NULL, i >> 2);
858 }
859
860 for (i = 2; i < 4; i++) {
861 gsm0503_tch_burst_unmap(&iB[i * 114 + 456],
862 &bursts[i * 116], NULL, 1);
863 }
864
865 gsm0503_tch_fr_deinterleave(cB, iB);
866
867 rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
868 if (rv) {
869 /* Error decoding FACCH frame */
870 return -1;
871 }
872
873 return GSM_MACBLOCK_LEN;
874 }
875
876 for (i = 0; i < 4; i++) {
877 gsm0503_tch_burst_unmap(&iB[i * 114],
878 &bursts[i * 116], NULL, i >> 1);
879 }
880
881 gsm0503_tch_hr_deinterleave(cB, iB);
882
883 osmo_conv_decode_ber(&gsm0503_tch_hr, cB, conv, n_errors, n_bits_total);
884
885 tch_hr_unreorder(d, p, conv);
886
887 for (i = 0; i < 17; i++)
888 d[i + 95] = (cB[i + 211] < 0) ? 1 : 0;
889
890 rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p);
891 if (rv) {
892 /* Error checking CRC8 for an HR frame */
893 return -1;
894 }
895
896 tch_hr_d_to_b(b, d);
897
898 tch_hr_reassemble(tch_data, b);
899
900 return 15;
901}
902
903int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len)
904{
905 ubit_t iB[912], cB[456], h;
906 ubit_t conv[98], b[112], d[112], p[3];
907 int i;
908
909 switch (len) {
910 case 15: /* TCH HR */
911 tch_hr_disassemble(b, tch_data);
912
913 tch_hr_b_to_d(d, b);
914
915 osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p);
916
917 tch_hr_reorder(conv, d, p);
918
919 osmo_conv_encode(&gsm0503_tch_hr, conv, cB);
920
921 memcpy(cB + 211, d + 95, 17);
922
923 h = 0;
924
925 gsm0503_tch_hr_interleave(cB, iB);
926
927 for (i = 0; i < 4; i++) {
928 gsm0503_tch_burst_map(&iB[i * 114],
929 &bursts[i * 116], &h, i >> 1);
930 }
931
932 break;
933 case GSM_MACBLOCK_LEN: /* FACCH */
934 _xcch_encode_cB(cB, tch_data);
935
936 h = 1;
937
938 gsm0503_tch_fr_interleave(cB, iB);
939
940 for (i=0; i<6; i++) {
941 gsm0503_tch_burst_map(&iB[i * 114],
942 &bursts[i * 116], &h, i >> 2);
943 }
944
945 for (i=2; i<4; i++) {
946 gsm0503_tch_burst_map(&iB[i * 114 + 456],
947 &bursts[i * 116], &h, 1);
948 }
949
950 break;
951 default:
952 return -1;
953 }
954
955 return 0;
956}
957
958int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts,
959 int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
960 uint8_t *cmr, int *n_errors, int *n_bits_total)
961{
962 sbit_t iB[912], cB[456], h;
963 ubit_t d[244], p[6], conv[250];
964 int i, j, k, best = 0, rv, len, steal = 0, id = 0;
965 *n_errors = 0; *n_bits_total = 0;
966
967 for (i=0; i<8; i++) {
968 gsm0503_tch_burst_unmap(&iB[i * 114], &bursts[i * 116], &h, i >> 2);
969 steal -= h;
970 }
971
972 gsm0503_tch_fr_deinterleave(cB, iB);
973
974 if (steal > 0) {
975 rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
976 if (rv) {
977 /* Error decoding FACCH frame */
978 return -1;
979 }
980
981 return GSM_MACBLOCK_LEN;
982 }
983
984 for (i = 0; i < 4; i++) {
985 for (j = 0, k = 0; j < 8; j++)
986 k += abs(((int)gsm0503_afs_ic_sbit[i][j]) - ((int)cB[j]));
987
988 if (i == 0 || k < best) {
989 best = k;
990 id = i;
991 }
992 }
993
994 /* Check if indicated codec fits into range of codecs */
995 if (id >= codecs) {
996 /* Codec mode out of range, return id */
997 return id;
998 }
999
1000 switch ((codec_mode_req) ? codec[*ft] : codec[id]) {
1001 case 7: /* TCH/AFS12.2 */
1002 osmo_conv_decode_ber(&gsm0503_tch_afs_12_2, cB + 8,
1003 conv, n_errors, n_bits_total);
1004
1005 tch_amr_unmerge(d, p, conv, 244, 81);
1006
1007 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 81, p);
1008 if (rv) {
1009 /* Error checking CRC8 for an AMR 12.2 frame */
1010 return -1;
1011 }
1012
1013 tch_amr_reassemble(tch_data, d, 244);
1014
1015 len = 31;
1016
1017 break;
1018 case 6: /* TCH/AFS10.2 */
1019 osmo_conv_decode_ber(&gsm0503_tch_afs_10_2, cB + 8,
1020 conv, n_errors, n_bits_total);
1021
1022 tch_amr_unmerge(d, p, conv, 204, 65);
1023
1024 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 65, p);
1025 if (rv) {
1026 /* Error checking CRC8 for an AMR 10.2 frame */
1027 return -1;
1028 }
1029
1030 tch_amr_reassemble(tch_data, d, 204);
1031
1032 len = 26;
1033
1034 break;
1035 case 5: /* TCH/AFS7.95 */
1036 osmo_conv_decode_ber(&gsm0503_tch_afs_7_95, cB + 8,
1037 conv, n_errors, n_bits_total);
1038
1039 tch_amr_unmerge(d, p, conv, 159, 75);
1040
1041 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 75, p);
1042 if (rv) {
1043 /* Error checking CRC8 for an AMR 7.95 frame */
1044 return -1;
1045 }
1046
1047 tch_amr_reassemble(tch_data, d, 159);
1048
1049 len = 20;
1050
1051 break;
1052 case 4: /* TCH/AFS7.4 */
1053 osmo_conv_decode_ber(&gsm0503_tch_afs_7_4, cB + 8,
1054 conv, n_errors, n_bits_total);
1055
1056 tch_amr_unmerge(d, p, conv, 148, 61);
1057
1058 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p);
1059 if (rv) {
1060 /* Error checking CRC8 for an AMR 7.4 frame */
1061 return -1;
1062 }
1063
1064 tch_amr_reassemble(tch_data, d, 148);
1065
1066 len = 19;
1067
1068 break;
1069 case 3: /* TCH/AFS6.7 */
1070 osmo_conv_decode_ber(&gsm0503_tch_afs_6_7, cB + 8,
1071 conv, n_errors, n_bits_total);
1072
1073 tch_amr_unmerge(d, p, conv, 134, 55);
1074
1075 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
1076 if (rv) {
1077 /* Error checking CRC8 for an AMR 6.7 frame */
1078 return -1;
1079 }
1080
1081 tch_amr_reassemble(tch_data, d, 134);
1082
1083 len = 17;
1084
1085 break;
1086 case 2: /* TCH/AFS5.9 */
1087 osmo_conv_decode_ber(&gsm0503_tch_afs_5_9, cB + 8,
1088 conv, n_errors, n_bits_total);
1089
1090 tch_amr_unmerge(d, p, conv, 118, 55);
1091
1092 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
1093 if (rv) {
1094 /* Error checking CRC8 for an AMR 5.9 frame */
1095 return -1;
1096 }
1097
1098 tch_amr_reassemble(tch_data, d, 118);
1099
1100 len = 15;
1101
1102 break;
1103 case 1: /* TCH/AFS5.15 */
1104 osmo_conv_decode_ber(&gsm0503_tch_afs_5_15, cB + 8,
1105 conv, n_errors, n_bits_total);
1106
1107 tch_amr_unmerge(d, p, conv, 103, 49);
1108
1109 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p);
1110 if (rv) {
1111 /* Error checking CRC8 for an AMR 5.15 frame */
1112 return -1;
1113 }
1114
1115 tch_amr_reassemble(tch_data, d, 103);
1116
1117 len = 13;
1118
1119 break;
1120 case 0: /* TCH/AFS4.75 */
1121 osmo_conv_decode_ber(&gsm0503_tch_afs_4_75, cB + 8,
1122 conv, n_errors, n_bits_total);
1123
1124 tch_amr_unmerge(d, p, conv, 95, 39);
1125
1126 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p);
1127 if (rv) {
1128 /* Error checking CRC8 for an AMR 4.75 frame */
1129 return -1;
1130 }
1131
1132 tch_amr_reassemble(tch_data, d, 95);
1133
1134 len = 12;
1135
1136 break;
1137 default:
1138 /* Unknown frame type */
1139 *n_bits_total = 448;
1140 *n_errors = *n_bits_total;
1141 return -1;
1142 }
1143
1144 /* Change codec request / indication, if frame is valid */
1145 if (codec_mode_req)
1146 *cmr = id;
1147 else
1148 *ft = id;
1149
1150 return len;
1151}
1152
1153int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len,
1154 int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft,
1155 uint8_t cmr)
1156{
1157 ubit_t iB[912], cB[456], h;
1158 ubit_t d[244], p[6], conv[250];
1159 int i;
1160 uint8_t id;
1161
1162 if (len == GSM_MACBLOCK_LEN) { /* FACCH */
1163 _xcch_encode_cB(cB, tch_data);
1164
1165 h = 1;
1166
1167 goto facch;
1168 }
1169
1170 h = 0;
1171
1172 if (codec_mode_req) {
1173 if (cmr >= codecs) {
1174 /* FIXME: CMR ID is not in codec list! */
1175 return -1;
1176 }
1177 id = cmr;
1178 } else {
1179 if (ft >= codecs) {
1180 /* FIXME: FT ID is not in codec list! */
1181 return -1;
1182 }
1183 id = ft;
1184 }
1185
1186 switch (codec[ft]) {
1187 case 7: /* TCH/AFS12.2 */
1188 if (len != 31)
1189 goto invalid_length;
1190
1191 tch_amr_disassemble(d, tch_data, 244);
1192
1193 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 81, p);
1194
1195 tch_amr_merge(conv, d, p, 244, 81);
1196
1197 osmo_conv_encode(&gsm0503_tch_afs_12_2, conv, cB + 8);
1198
1199 break;
1200 case 6: /* TCH/AFS10.2 */
1201 if (len != 26)
1202 goto invalid_length;
1203
1204 tch_amr_disassemble(d, tch_data, 204);
1205
1206 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 65, p);
1207
1208 tch_amr_merge(conv, d, p, 204, 65);
1209
1210 osmo_conv_encode(&gsm0503_tch_afs_10_2, conv, cB + 8);
1211
1212 break;
1213 case 5: /* TCH/AFS7.95 */
1214 if (len != 20)
1215 goto invalid_length;
1216
1217 tch_amr_disassemble(d, tch_data, 159);
1218
1219 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 75, p);
1220
1221 tch_amr_merge(conv, d, p, 159, 75);
1222
1223 osmo_conv_encode(&gsm0503_tch_afs_7_95, conv, cB + 8);
1224
1225 break;
1226 case 4: /* TCH/AFS7.4 */
1227 if (len != 19)
1228 goto invalid_length;
1229
1230 tch_amr_disassemble(d, tch_data, 148);
1231
1232 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p);
1233
1234 tch_amr_merge(conv, d, p, 148, 61);
1235
1236 osmo_conv_encode(&gsm0503_tch_afs_7_4, conv, cB + 8);
1237
1238 break;
1239 case 3: /* TCH/AFS6.7 */
1240 if (len != 17)
1241 goto invalid_length;
1242
1243 tch_amr_disassemble(d, tch_data, 134);
1244
1245 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
1246
1247 tch_amr_merge(conv, d, p, 134, 55);
1248
1249 osmo_conv_encode(&gsm0503_tch_afs_6_7, conv, cB + 8);
1250
1251 break;
1252 case 2: /* TCH/AFS5.9 */
1253 if (len != 15)
1254 goto invalid_length;
1255
1256 tch_amr_disassemble(d, tch_data, 118);
1257
1258 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
1259
1260 tch_amr_merge(conv, d, p, 118, 55);
1261
1262 osmo_conv_encode(&gsm0503_tch_afs_5_9, conv, cB + 8);
1263
1264 break;
1265 case 1: /* TCH/AFS5.15 */
1266 if (len != 13)
1267 goto invalid_length;
1268
1269 tch_amr_disassemble(d, tch_data, 103);
1270
1271 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p);
1272
1273 tch_amr_merge(conv, d, p, 103, 49);
1274
1275 osmo_conv_encode(&gsm0503_tch_afs_5_15, conv, cB + 8);
1276
1277 break;
1278 case 0: /* TCH/AFS4.75 */
1279 if (len != 12)
1280 goto invalid_length;
1281
1282 tch_amr_disassemble(d, tch_data, 95);
1283
1284 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p);
1285
1286 tch_amr_merge(conv, d, p, 95, 39);
1287
1288 osmo_conv_encode(&gsm0503_tch_afs_4_75, conv, cB + 8);
1289
1290 break;
1291 default:
1292 /* FIXME: FT %ft is not supported */
1293 return -1;
1294 }
1295
1296 memcpy(cB, gsm0503_afs_ic_ubit[id], 8);
1297
1298facch:
1299 gsm0503_tch_fr_interleave(cB, iB);
1300
1301 for (i = 0; i < 8; i++) {
1302 gsm0503_tch_burst_map(&iB[i * 114],
1303 &bursts[i * 116], &h, i >> 2);
1304 }
1305
1306 return 0;
1307
1308invalid_length:
1309 /* FIXME: payload length %len does not comply with codec type %ft */
1310 return -1;
1311}
1312
1313int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd,
1314 int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
1315 uint8_t *cmr, int *n_errors, int *n_bits_total)
1316{
1317 sbit_t iB[912], cB[456], h;
1318 ubit_t d[244], p[6], conv[135];
1319 int i, j, k, best = 0, rv, len, steal = 0, id = 0;
1320
1321 /* only unmap the stealing bits */
1322 if (!odd) {
1323 for (i = 0; i < 4; i++) {
1324 gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0);
1325 steal -= h;
1326 }
1327 for (i = 2; i < 5; i++) {
1328 gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1);
1329 steal -= h;
1330 }
1331 }
1332
1333 /* if we found a stole FACCH, but only at correct alignment */
1334 if (steal > 0) {
1335 for (i = 0; i < 6; i++) {
1336 gsm0503_tch_burst_unmap(&iB[i * 114],
1337 &bursts[i * 116], NULL, i >> 2);
1338 }
1339
1340 for (i = 2; i < 4; i++) {
1341 gsm0503_tch_burst_unmap(&iB[i * 114 + 456],
1342 &bursts[i * 116], NULL, 1);
1343 }
1344
1345 gsm0503_tch_fr_deinterleave(cB, iB);
1346
1347 rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
1348 if (rv) {
1349 /* Error decoding FACCH frame */
1350 return -1;
1351 }
1352
1353 return GSM_MACBLOCK_LEN;
1354 }
1355
1356 for (i = 0; i < 4; i++) {
1357 gsm0503_tch_burst_unmap(&iB[i * 114],
1358 &bursts[i * 116], NULL, i >> 1);
1359 }
1360
1361 gsm0503_tch_hr_deinterleave(cB, iB);
1362
1363 for (i = 0; i < 4; i++) {
1364 for (j = 0, k = 0; j < 4; j++)
1365 k += abs(((int)gsm0503_ahs_ic_sbit[i][j]) - ((int)cB[j]));
1366
1367 if (i == 0 || k < best) {
1368 best = k;
1369 id = i;
1370 }
1371 }
1372
1373 /* Check if indicated codec fits into range of codecs */
1374 if (id >= codecs) {
1375 /* Codec mode out of range, return id */
1376 return id;
1377 }
1378
1379 switch ((codec_mode_req) ? codec[*ft] : codec[id]) {
1380 case 5: /* TCH/AHS7.95 */
1381 osmo_conv_decode_ber(&gsm0503_tch_ahs_7_95, cB + 4,
1382 conv, n_errors, n_bits_total);
1383
1384 tch_amr_unmerge(d, p, conv, 123, 67);
1385
1386 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 67, p);
1387 if (rv) {
1388 /* Error checking CRC8 for an AMR 7.95 frame */
1389 return -1;
1390 }
1391
1392 for (i = 0; i < 36; i++)
1393 d[i + 123] = (cB[i + 192] < 0) ? 1 : 0;
1394
1395 tch_amr_reassemble(tch_data, d, 159);
1396
1397 len = 20;
1398
1399 break;
1400 case 4: /* TCH/AHS7.4 */
1401 osmo_conv_decode_ber(&gsm0503_tch_ahs_7_4, cB + 4,
1402 conv, n_errors, n_bits_total);
1403
1404 tch_amr_unmerge(d, p, conv, 120, 61);
1405
1406 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p);
1407 if (rv) {
1408 /* Error checking CRC8 for an AMR 7.4 frame */
1409 return -1;
1410 }
1411
1412 for (i = 0; i < 28; i++)
1413 d[i + 120] = (cB[i + 200] < 0) ? 1 : 0;
1414
1415 tch_amr_reassemble(tch_data, d, 148);
1416
1417 len = 19;
1418
1419 break;
1420 case 3: /* TCH/AHS6.7 */
1421 osmo_conv_decode_ber(&gsm0503_tch_ahs_6_7, cB + 4,
1422 conv, n_errors, n_bits_total);
1423
1424 tch_amr_unmerge(d, p, conv, 110, 55);
1425
1426 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
1427 if (rv) {
1428 /* Error checking CRC8 for an AMR 6.7 frame */
1429 return -1;
1430 }
1431
1432 for (i = 0; i < 24; i++)
1433 d[i + 110] = (cB[i + 204] < 0) ? 1 : 0;
1434
1435 tch_amr_reassemble(tch_data, d, 134);
1436
1437 len = 17;
1438
1439 break;
1440 case 2: /* TCH/AHS5.9 */
1441 osmo_conv_decode_ber(&gsm0503_tch_ahs_5_9, cB + 4,
1442 conv, n_errors, n_bits_total);
1443
1444 tch_amr_unmerge(d, p, conv, 102, 55);
1445
1446 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
1447 if (rv) {
1448 /* Error checking CRC8 for an AMR 5.9 frame */
1449 return -1;
1450 }
1451
1452 for (i = 0; i < 16; i++)
1453 d[i + 102] = (cB[i + 212] < 0) ? 1 : 0;
1454
1455 tch_amr_reassemble(tch_data, d, 118);
1456
1457 len = 15;
1458
1459 break;
1460 case 1: /* TCH/AHS5.15 */
1461 osmo_conv_decode_ber(&gsm0503_tch_ahs_5_15, cB + 4,
1462 conv, n_errors, n_bits_total);
1463
1464 tch_amr_unmerge(d, p, conv, 91, 49);
1465
1466 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p);
1467 if (rv) {
1468 /* Error checking CRC8 for an AMR 5.15 frame */
1469 return -1;
1470 }
1471
1472 for (i = 0; i < 12; i++)
1473 d[i + 91] = (cB[i + 216] < 0) ? 1 : 0;
1474
1475 tch_amr_reassemble(tch_data, d, 103);
1476
1477 len = 13;
1478
1479 break;
1480 case 0: /* TCH/AHS4.75 */
1481 osmo_conv_decode_ber(&gsm0503_tch_ahs_4_75, cB + 4,
1482 conv, n_errors, n_bits_total);
1483
1484 tch_amr_unmerge(d, p, conv, 83, 39);
1485
1486 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p);
1487 if (rv) {
1488 /* Error checking CRC8 for an AMR 4.75 frame */
1489 return -1;
1490 }
1491
1492 for (i = 0; i < 12; i++)
1493 d[i + 83] = (cB[i + 216] < 0) ? 1 : 0;
1494
1495 tch_amr_reassemble(tch_data, d, 95);
1496
1497 len = 12;
1498
1499 break;
1500 default:
1501 /* Unknown frame type */
1502 *n_bits_total = 159;
1503 *n_errors = *n_bits_total;
1504 return -1;
1505 }
1506
1507 /* Change codec request / indication, if frame is valid */
1508 if (codec_mode_req)
1509 *cmr = id;
1510 else
1511 *ft = id;
1512
1513 return len;
1514}
1515
1516int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len,
1517 int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft,
1518 uint8_t cmr)
1519{
1520 ubit_t iB[912], cB[456], h;
1521 ubit_t d[244], p[6], conv[135];
1522 int i;
1523 uint8_t id;
1524
1525 if (len == GSM_MACBLOCK_LEN) { /* FACCH */
1526 _xcch_encode_cB(cB, tch_data);
1527
1528 h = 1;
1529
1530 gsm0503_tch_fr_interleave(cB, iB);
1531
1532 for (i = 0; i < 6; i++)
1533 gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116],
1534 &h, i >> 2);
1535 for (i = 2; i < 4; i++)
1536 gsm0503_tch_burst_map(&iB[i * 114 + 456],
1537 &bursts[i * 116], &h, 1);
1538
1539 return 0;
1540 }
1541
1542 h = 0;
1543
1544 if (codec_mode_req) {
1545 if (cmr >= codecs) {
1546 /* FIXME: CMR ID %d not in codec list */
1547 return -1;
1548 }
1549 id = cmr;
1550 } else {
1551 if (ft >= codecs) {
1552 /* FIXME: FT ID %d not in codec list */
1553 return -1;
1554 }
1555 id = ft;
1556 }
1557
1558 switch (codec[ft]) {
1559 case 5: /* TCH/AHS7.95 */
1560 if (len != 20)
1561 goto invalid_length;
1562
1563 tch_amr_disassemble(d, tch_data, 159);
1564
1565 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 67, p);
1566
1567 tch_amr_merge(conv, d, p, 123, 67);
1568
1569 osmo_conv_encode(&gsm0503_tch_ahs_7_95, conv, cB + 4);
1570
1571 memcpy(cB + 192, d + 123, 36);
1572
1573 break;
1574 case 4: /* TCH/AHS7.4 */
1575 if (len != 19)
1576 goto invalid_length;
1577
1578 tch_amr_disassemble(d, tch_data, 148);
1579
1580 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p);
1581
1582 tch_amr_merge(conv, d, p, 120, 61);
1583
1584 osmo_conv_encode(&gsm0503_tch_ahs_7_4, conv, cB + 4);
1585
1586 memcpy(cB + 200, d + 120, 28);
1587
1588 break;
1589 case 3: /* TCH/AHS6.7 */
1590 if (len != 17)
1591 goto invalid_length;
1592
1593 tch_amr_disassemble(d, tch_data, 134);
1594
1595 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
1596
1597 tch_amr_merge(conv, d, p, 110, 55);
1598
1599 osmo_conv_encode(&gsm0503_tch_ahs_6_7, conv, cB + 4);
1600
1601 memcpy(cB + 204, d + 110, 24);
1602
1603 break;
1604 case 2: /* TCH/AHS5.9 */
1605 if (len != 15)
1606 goto invalid_length;
1607
1608 tch_amr_disassemble(d, tch_data, 118);
1609
1610 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
1611
1612 tch_amr_merge(conv, d, p, 102, 55);
1613
1614 osmo_conv_encode(&gsm0503_tch_ahs_5_9, conv, cB + 4);
1615
1616 memcpy(cB + 212, d + 102, 16);
1617
1618 break;
1619 case 1: /* TCH/AHS5.15 */
1620 if (len != 13)
1621 goto invalid_length;
1622
1623 tch_amr_disassemble(d, tch_data, 103);
1624
1625 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p);
1626
1627 tch_amr_merge(conv, d, p, 91, 49);
1628
1629 osmo_conv_encode(&gsm0503_tch_ahs_5_15, conv, cB + 4);
1630
1631 memcpy(cB + 216, d + 91, 12);
1632
1633 break;
1634 case 0: /* TCH/AHS4.75 */
1635 if (len != 12)
1636 goto invalid_length;
1637
1638 tch_amr_disassemble(d, tch_data, 95);
1639
1640 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p);
1641
1642 tch_amr_merge(conv, d, p, 83, 39);
1643
1644 osmo_conv_encode(&gsm0503_tch_ahs_4_75, conv, cB + 4);
1645
1646 memcpy(cB + 216, d + 83, 12);
1647
1648 break;
1649 default:
1650 /* FIXME: FT %ft is not supported */
1651 return -1;
1652 }
1653
1654 memcpy(cB, gsm0503_afs_ic_ubit[id], 4);
1655
1656 gsm0503_tch_hr_interleave(cB, iB);
1657
1658 for (i = 0; i < 4; i++)
1659 gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], &h, i >> 1);
1660
1661 return 0;
1662
1663invalid_length:
1664 /* FIXME: payload length %len does not comply with codec type %ft */
1665 return -1;
1666}
1667
1668/*
1669 * GSM RACH transcoding
1670 */
1671
1672/*
1673 * GSM RACH apply BSIC to parity
1674 *
1675 * p(j) = p(j) xor b(j) j = 0, ..., 5
1676 * b(0) = MSB of PLMN colour code
1677 * b(5) = LSB of BS colour code
1678 */
1679static int rach_apply_bsic(ubit_t *d, uint8_t bsic)
1680{
1681 int i;
1682
1683 /* Apply it */
1684 for (i = 0; i < 6; i++)
1685 d[8 + i] ^= ((bsic >> (5 - i)) & 1);
1686
1687 return 0;
1688}
1689
1690int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic)
1691{
1692 ubit_t conv[14];
1693 int rv;
1694
1695 osmo_conv_decode(&gsm0503_rach, burst, conv);
1696
1697 rach_apply_bsic(conv, bsic);
1698
1699 rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 8, conv + 8);
1700 if (rv)
1701 return -1;
1702
1703 osmo_ubit2pbit_ext(ra, 0, conv, 0, 8, 1);
1704
1705 return 0;
1706}
1707
1708int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic)
1709{
1710 ubit_t conv[14];
1711
1712 osmo_pbit2ubit_ext(conv, 0, ra, 0, 8, 1);
1713
1714 osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 8, conv + 8);
1715
1716 rach_apply_bsic(conv, bsic);
1717
1718 osmo_conv_encode(&gsm0503_rach, conv, burst);
1719
1720 return 0;
1721}
1722
1723/*
1724 * GSM SCH transcoding
1725 */
1726int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst)
1727{
1728 ubit_t conv[35];
1729 int rv;
1730
1731 osmo_conv_decode(&gsm0503_sch, burst, conv);
1732
1733 rv = osmo_crc16gen_check_bits(&gsm0503_sch_crc10, conv, 25, conv + 25);
1734 if (rv)
1735 return -1;
1736
1737 osmo_ubit2pbit_ext(sb_info, 0, conv, 0, 25, 1);
1738
1739 return 0;
1740}
1741
1742int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info)
1743{
1744 ubit_t conv[35];
1745
1746 osmo_pbit2ubit_ext(conv, 0, sb_info, 0, 25, 1);
1747
1748 osmo_crc16gen_set_bits(&gsm0503_sch_crc10, conv, 25, conv + 25);
1749
1750 osmo_conv_encode(&gsm0503_sch, conv, burst);
1751
1752 return 0;
1753}