blob: 3812c9fb28496520cd753374f6533cf022ca9ba6 [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>
Piotr Krysik9e2e8352018-02-27 12:16:25 +01005 * (C) 2017 by Harald Welte <laforge@gnumonks.org>
Piotr Krysik70c25a12017-01-03 08:01:23 +01006 *
7 * All Rights Reserved
8 *
Piotr Krysik9e2e8352018-02-27 12:16:25 +01009 * SPDX-License-Identifier: GPL-2.0+
10 *
Piotr Krysik70c25a12017-01-03 08:01:23 +010011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#include <stdio.h>
27#include <stdint.h>
28#include <string.h>
29#include <stdlib.h>
Piotr Krysik9e2e8352018-02-27 12:16:25 +010030#include <errno.h>
Piotr Krysik70c25a12017-01-03 08:01:23 +010031
32#include <osmocom/core/bits.h>
33#include <osmocom/core/conv.h>
Piotr Krysik9e2e8352018-02-27 12:16:25 +010034//#include <osmocom/core/utils.h>
Piotr Krysik70c25a12017-01-03 08:01:23 +010035#include <osmocom/core/crcgen.h>
36#include <osmocom/core/endian.h>
37
Piotr Krysik9e2e8352018-02-27 12:16:25 +010038//#include <osmocom/gsm/protocol/gsm_04_08.h>
39#include <osmocom/gprs/protocol/gsm_04_60.h>
40#include <osmocom/gprs/gprs_rlc.h>
41
42#include <osmocom/gsm/gsm0503.h>
Piotr Krysik70c25a12017-01-03 08:01:23 +010043#include <osmocom/codec/codec.h>
44
Piotr Krysik9e2e8352018-02-27 12:16:25 +010045#include <osmocom/coding/gsm0503_interleaving.h>
46#include <osmocom/coding/gsm0503_mapping.h>
47#include <osmocom/coding/gsm0503_tables.h>
48#include <osmocom/coding/gsm0503_coding.h>
49#include <osmocom/coding/gsm0503_parity.h>
Piotr Krysik70c25a12017-01-03 08:01:23 +010050
Piotr Krysik9e2e8352018-02-27 12:16:25 +010051/*! \mainpage libosmocoding Documentation
52 *
53 * \section sec_intro Introduction
54 * This library is a collection of definitions, tables and functions
55 * implementing the GSM/GPRS/EGPRS channel coding (and decoding) as
56 * specified in 3GPP TS 05.03 / 45.003.
57 *
58 * libosmocoding is developed as part of the Osmocom (Open Source Mobile
59 * Communications) project, a community-based, collaborative development
60 * project to create Free and Open Source implementations of mobile
61 * communications systems. For more information about Osmocom, please
62 * see https://osmocom.org/
63 *
64 * \section sec_copyright Copyright and License
65 * Copyright © 2013 by Andreas Eversberg\n
66 * Copyright © 2015 by Alexander Chemeris\n
67 * Copyright © 2016 by Tom Tsou\n
68 * Documentation Copyright © 2017 by Harald Welte\n
69 * All rights reserved. \n\n
70 * The source code of libosmocoding is licensed under the terms of the GNU
71 * General Public License as published by the Free Software Foundation;
72 * either version 2 of the License, or (at your option) any later
73 * version.\n
74 * See <http://www.gnu.org/licenses/> or COPYING included in the source
75 * code package istelf.\n
76 * The information detailed here is provided AS IS with NO WARRANTY OF
77 * ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND
78 * FITNESS FOR A PARTICULAR PURPOSE.
79 * \n\n
80 *
81 * \section sec_tracker Homepage + Issue Tracker
82 * libosmocoding is distributed as part of libosmocore and shares its
83 * project page at http://osmocom.org/projects/libosmocore
84 *
85 * An Issue Tracker can be found at
86 * https://osmocom.org/projects/libosmocore/issues
87 *
88 * \section sec_contact Contact and Support
89 * Community-based support is available at the OpenBSC mailing list
90 * <http://lists.osmocom.org/mailman/listinfo/openbsc>\n
91 * Commercial support options available upon request from
92 * <http://sysmocom.de/>
93 */
Piotr Krysik70c25a12017-01-03 08:01:23 +010094
95
Piotr Krysik9e2e8352018-02-27 12:16:25 +010096/*! \addtogroup coding
97 * @{
98 *
99 * GSM TS 05.03 coding
100 *
101 * This module is the "master module" of libosmocoding. It uses the
102 * various other modules (mapping, parity, interleaving) in order to
103 * implement the complete channel coding (and decoding) chain for the
104 * various channel types as defined in TS 05.03 / 45.003.
105 *
106 * \file gsm0503_coding.c */
107
Piotr Krysik70c25a12017-01-03 08:01:23 +0100108/*
109 * EGPRS coding limits
110 */
111
112/* Max header size with parity bits */
113#define EGPRS_HDR_UPP_MAX 54
114
115/* Max encoded header size */
116#define EGPRS_HDR_C_MAX 162
117
118/* Max punctured header size */
119#define EGPRS_HDR_HC_MAX 160
120
121/* Max data block size with parity bits */
122#define EGPRS_DATA_U_MAX 612
123
124/* Max encoded data block size */
125#define EGPRS_DATA_C_MAX 1836
126
127/* Max single block punctured data size */
128#define EGPRS_DATA_DC_MAX 1248
129
130/* Dual block punctured data size */
131#define EGPRS_DATA_C1 612
132#define EGPRS_DATA_C2 EGPRS_DATA_C1
133
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100134/*! union across the three different EGPRS Uplink header types */
135union gprs_rlc_ul_hdr_egprs {
136 struct gprs_rlc_ul_header_egprs_1 type1;
137 struct gprs_rlc_ul_header_egprs_2 type2;
138 struct gprs_rlc_ul_header_egprs_3 type3;
139};
Piotr Krysik70c25a12017-01-03 08:01:23 +0100140
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100141/*! union across the three different EGPRS Downlink header types */
142union gprs_rlc_dl_hdr_egprs {
143 struct gprs_rlc_dl_header_egprs_1 type1;
144 struct gprs_rlc_dl_header_egprs_2 type2;
145 struct gprs_rlc_dl_header_egprs_3 type3;
146};
147
148/*! Structure describing a Modulation and Coding Scheme */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100149struct gsm0503_mcs_code {
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100150 /*! Modulation and Coding Scheme (MSC) number */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100151 uint8_t mcs;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100152 /*! Length of Uplink Stealing Flag (USF) in bits */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100153 uint8_t usf_len;
154
155 /* Header coding */
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100156 /*! Length of header (bits) */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100157 uint8_t hdr_len;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100158 /*! Length of header convolutional code */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100159 uint8_t hdr_code_len;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100160 /*! Length of header code puncturing sequence */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100161 uint8_t hdr_punc_len;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100162 /*! header convolutional code */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100163 const struct osmo_conv_code *hdr_conv;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100164 /*! header puncturing sequence */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100165 const uint8_t *hdr_punc;
166
167 /* Data coding */
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100168 /*! length of data (bits) */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100169 uint16_t data_len;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100170 /*! length of data convolutional code */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100171 uint16_t data_code_len;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100172 /*! length of data code puncturing sequence */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100173 uint16_t data_punc_len;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100174 /*! data convolutional code */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100175 const struct osmo_conv_code *data_conv;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100176 /*! data puncturing sequences */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100177 const uint8_t *data_punc[3];
178};
179
180static int osmo_conv_decode_ber(const struct osmo_conv_code *code,
181 const sbit_t *input, ubit_t *output,
182 int *n_errors, int *n_bits_total)
183{
184 int res, i, coded_len;
185 ubit_t recoded[EGPRS_DATA_C_MAX];
186
187 res = osmo_conv_decode(code, input, output);
188
189 if (n_bits_total || n_errors) {
190 coded_len = osmo_conv_encode(code, output, recoded);
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100191 //OSMO_ASSERT(sizeof(recoded) / sizeof(recoded[0]) >= coded_len);
Piotr Krysik70c25a12017-01-03 08:01:23 +0100192 }
193
194 /* Count bit errors */
195 if (n_errors) {
196 *n_errors = 0;
197 for (i = 0; i < coded_len; i++) {
198 if (!((recoded[i] && input[i] < 0) ||
199 (!recoded[i] && input[i] > 0)) )
200 *n_errors += 1;
201 }
202 }
203
204 if (n_bits_total)
205 *n_bits_total = coded_len;
206
207 return res;
208}
209
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100210/*! convenience wrapper for decoding coded bits
211 * \param[out] l2_data caller-allocated buffer for L2 Frame
212 * \param[in] cB 456 coded (soft) bits as per TS 05.03 4.1.3
213 * \param[out] n_errors Number of detected errors
214 * \param[out] n_bits_total Number of total coded bits
215 * \returns 0 on success; -1 on CRC error */
216static int _xcch_decode_cB(uint8_t *l2_data, const sbit_t *cB,
Piotr Krysik70c25a12017-01-03 08:01:23 +0100217 int *n_errors, int *n_bits_total)
218{
219 ubit_t conv[224];
220 int rv;
221
222 osmo_conv_decode_ber(&gsm0503_xcch, cB,
223 conv, n_errors, n_bits_total);
224
225 rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40,
226 conv, 184, conv + 184);
227 if (rv)
228 return -1;
229
230 osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1);
231
232 return 0;
233}
234
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100235/*! convenience wrapper for encoding to coded bits
236 * \param[out] cB caller-allocated buffer for 456 coded bits as per TS 05.03 4.1.3
237 * \param[out] l2_data to-be-encoded L2 Frame
238 * \returns 0 */
239static int _xcch_encode_cB(ubit_t *cB, const uint8_t *l2_data)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100240{
241 ubit_t conv[224];
242
243 osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1);
244
245 osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184);
246
247 osmo_conv_encode(&gsm0503_xcch, conv, cB);
248
249 return 0;
250}
251
252/*
253 * GSM xCCH block transcoding
254 */
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100255
256/*! Decoding of xCCH data from bursts to L2 frame
257 * \param[out] l2_data caller-allocated output data buffer
258 * \param[in] bursts four GSM bursts in soft-bits
259 * \param[out] n_errors Number of detected errors
260 * \param[out] n_bits_total Number of total coded bits
261 */
262int gsm0503_xcch_decode(uint8_t *l2_data, const sbit_t *bursts,
Piotr Krysik70c25a12017-01-03 08:01:23 +0100263 int *n_errors, int *n_bits_total)
264{
265 sbit_t iB[456], cB[456];
266 int i;
267
268 for (i = 0; i < 4; i++)
269 gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], NULL, NULL);
270
271 gsm0503_xcch_deinterleave(cB, iB);
272
273 return _xcch_decode_cB(l2_data, cB, n_errors, n_bits_total);
274}
275
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100276/*! Encoding of xCCH data from L2 frame to bursts
277 * \param[out] bursts caller-allocated burst data (unpacked bits)
278 * \param[in] l2_data L2 input data (MAC block)
279 * \returns 0
280 */
281int gsm0503_xcch_encode(ubit_t *bursts, const uint8_t *l2_data)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100282{
283 ubit_t iB[456], cB[456], hl = 1, hn = 1;
284 int i;
285
286 _xcch_encode_cB(cB, l2_data);
287
288 gsm0503_xcch_interleave(cB, iB);
289
290 for (i = 0; i < 4; i++)
291 gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], &hl, &hn);
292
293 return 0;
294}
295
296
297
298/*
299 * GSM PDTCH block transcoding
300 */
301
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100302/*! Decode GPRS PDTCH
303 * \param[out] l2_data caller-allocated buffer for L2 Frame
304 * \param[in] bursts burst input data as soft unpacked bits
305 * \param[out] usf_p uplink stealing flag
306 * \param[out] n_errors number of detected bit-errors
307 * \param[out] n_bits_total total number of dcoded bits
308 * \returns 0 on success; negative on error */
309int gsm0503_pdtch_decode(uint8_t *l2_data, const sbit_t *bursts, uint8_t *usf_p,
Piotr Krysik70c25a12017-01-03 08:01:23 +0100310 int *n_errors, int *n_bits_total)
311{
312 sbit_t iB[456], cB[676], hl_hn[8];
313 ubit_t conv[456];
314 int i, j, k, rv, best = 0, cs = 0, usf = 0; /* make GCC happy */
315
316 for (i = 0; i < 4; i++)
317 gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116],
318 hl_hn + i * 2, hl_hn + i * 2 + 1);
319
320 for (i = 0; i < 4; i++) {
321 for (j = 0, k = 0; j < 8; j++)
322 k += abs(((int)gsm0503_pdtch_hl_hn_sbit[i][j]) - ((int)hl_hn[j]));
323
324 if (i == 0 || k < best) {
325 best = k;
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100326 cs = i + 1;
Piotr Krysik70c25a12017-01-03 08:01:23 +0100327 }
328 }
329
330 gsm0503_xcch_deinterleave(cB, iB);
331
332 switch (cs) {
333 case 1:
334 osmo_conv_decode_ber(&gsm0503_xcch, cB,
335 conv, n_errors, n_bits_total);
336
337 rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40,
338 conv, 184, conv + 184);
339 if (rv)
340 return -1;
341
342 osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1);
343
344 return 23;
345 case 2:
346 for (i = 587, j = 455; i >= 0; i--) {
347 if (!gsm0503_puncture_cs2[i])
348 cB[i] = cB[j--];
349 else
350 cB[i] = 0;
351 }
352
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100353 osmo_conv_decode_ber(&gsm0503_cs2_np, cB,
Piotr Krysik70c25a12017-01-03 08:01:23 +0100354 conv, n_errors, n_bits_total);
355
356 for (i = 0; i < 8; i++) {
357 for (j = 0, k = 0; j < 6; j++)
358 k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j]));
359
360 if (i == 0 || k < best) {
361 best = k;
362 usf = i;
363 }
364 }
365
366 conv[3] = usf & 1;
367 conv[4] = (usf >> 1) & 1;
368 conv[5] = (usf >> 2) & 1;
369 if (usf_p)
370 *usf_p = usf;
371
372 rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16,
373 conv + 3, 271, conv + 3 + 271);
374 if (rv)
375 return -1;
376
377 osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 271, 1);
378
379 return 34;
380 case 3:
381 for (i = 675, j = 455; i >= 0; i--) {
382 if (!gsm0503_puncture_cs3[i])
383 cB[i] = cB[j--];
384 else
385 cB[i] = 0;
386 }
387
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100388 osmo_conv_decode_ber(&gsm0503_cs3_np, cB,
Piotr Krysik70c25a12017-01-03 08:01:23 +0100389 conv, n_errors, n_bits_total);
390
391 for (i = 0; i < 8; i++) {
392 for (j = 0, k = 0; j < 6; j++)
393 k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j]));
394
395 if (i == 0 || k < best) {
396 best = k;
397 usf = i;
398 }
399 }
400
401 conv[3] = usf & 1;
402 conv[4] = (usf >> 1) & 1;
403 conv[5] = (usf >> 2) & 1;
404 if (usf_p)
405 *usf_p = usf;
406
407 rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16,
408 conv + 3, 315, conv + 3 + 315);
409 if (rv)
410 return -1;
411
412 osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 315, 1);
413
414 return 40;
415 case 4:
416 for (i = 12; i < 456; i++)
417 conv[i] = (cB[i] < 0) ? 1 : 0;
418
419 for (i = 0; i < 8; i++) {
420 for (j = 0, k = 0; j < 12; j++)
421 k += abs(((int)gsm0503_usf2twelve_sbit[i][j]) - ((int)cB[j]));
422
423 if (i == 0 || k < best) {
424 best = k;
425 usf = i;
426 }
427 }
428
429 conv[9] = usf & 1;
430 conv[10] = (usf >> 1) & 1;
431 conv[11] = (usf >> 2) & 1;
432 if (usf_p)
433 *usf_p = usf;
434
435 rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16,
436 conv + 9, 431, conv + 9 + 431);
437 if (rv) {
438 *n_bits_total = 456 - 12;
439 *n_errors = *n_bits_total;
440 return -1;
441 }
442
443 *n_bits_total = 456 - 12;
444 *n_errors = 0;
445
446 osmo_ubit2pbit_ext(l2_data, 0, conv, 9, 431, 1);
447
448 return 54;
449 default:
450 *n_bits_total = 0;
451 *n_errors = 0;
452 break;
453 }
454
455 return -1;
456}
457
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100458
459/*! GPRS DL message encoding
460 * \param[out] bursts caller-allocated buffer for unpacked burst bits
461 * \param[in] l2_data L2 (MAC) block to be encoded
462 * \param[in] l2_len length of l2_data in bytes, used to determine CS
463 * \returns 0 on success; negative on error */
464int gsm0503_pdtch_encode(ubit_t *bursts, const uint8_t *l2_data, uint8_t l2_len)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100465{
466 ubit_t iB[456], cB[676];
467 const ubit_t *hl_hn;
468 ubit_t conv[334];
469 int i, j, usf;
470
471 switch (l2_len) {
472 case 23:
473 osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1);
474
475 osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184);
476
477 osmo_conv_encode(&gsm0503_xcch, conv, cB);
478
479 hl_hn = gsm0503_pdtch_hl_hn_ubit[0];
480
481 break;
482 case 34:
483 osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 271, 1);
484 usf = l2_data[0] & 0x7;
485
486 osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3,
487 271, conv + 3 + 271);
488
489 memcpy(conv, gsm0503_usf2six[usf], 6);
490
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100491 osmo_conv_encode(&gsm0503_cs2_np, conv, cB);
Piotr Krysik70c25a12017-01-03 08:01:23 +0100492
493 for (i = 0, j = 0; i < 588; i++)
494 if (!gsm0503_puncture_cs2[i])
495 cB[j++] = cB[i];
496
497 hl_hn = gsm0503_pdtch_hl_hn_ubit[1];
498
499 break;
500 case 40:
501 osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 315, 1);
502 usf = l2_data[0] & 0x7;
503
504 osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3,
505 315, conv + 3 + 315);
506
507 memcpy(conv, gsm0503_usf2six[usf], 6);
508
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100509 osmo_conv_encode(&gsm0503_cs3_np, conv, cB);
Piotr Krysik70c25a12017-01-03 08:01:23 +0100510
511 for (i = 0, j = 0; i < 676; i++)
512 if (!gsm0503_puncture_cs3[i])
513 cB[j++] = cB[i];
514
515 hl_hn = gsm0503_pdtch_hl_hn_ubit[2];
516
517 break;
518 case 54:
519 osmo_pbit2ubit_ext(cB, 9, l2_data, 0, 431, 1);
520 usf = l2_data[0] & 0x7;
521
522 osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, cB + 9,
523 431, cB + 9 + 431);
524
525 memcpy(cB, gsm0503_usf2twelve_ubit[usf], 12);
526
527 hl_hn = gsm0503_pdtch_hl_hn_ubit[3];
528
529 break;
530 default:
531 return -1;
532 }
533
534 gsm0503_xcch_interleave(cB, iB);
535
536 for (i = 0; i < 4; i++) {
537 gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116],
538 hl_hn + i * 2, hl_hn + i * 2 + 1);
539 }
540
541 return GSM0503_GPRS_BURSTS_NBITS;
542}
543
544/*
545 * GSM TCH/F FR/EFR transcoding
546 */
547
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100548/*! assemble a FR codec frame in format as used inside RTP
549 * \param[out] tch_data Codec frame in RTP format
550 * \param[in] b_bits Codec frame in 'native' format
551 * \param[in] net_order FIXME */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100552static void tch_fr_reassemble(uint8_t *tch_data,
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100553 const ubit_t *b_bits, int net_order)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100554{
555 int i, j, k, l, o;
556
557 tch_data[0] = 0xd << 4;
558 memset(tch_data + 1, 0, 32);
559
560 if (net_order) {
561 for (i = 0, j = 4; i < 260; i++, j++)
562 tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7)));
563
564 return;
565 }
566
567 /* reassemble d-bits */
568 i = 0; /* counts bits */
569 j = 4; /* counts output bits */
570 k = gsm0503_gsm_fr_map[0]-1; /* current number bit in element */
571 l = 0; /* counts element bits */
572 o = 0; /* offset input bits */
573 while (i < 260) {
574 tch_data[j >> 3] |= (b_bits[k + o] << (7 - (j & 7)));
575 if (--k < 0) {
576 o += gsm0503_gsm_fr_map[l];
577 k = gsm0503_gsm_fr_map[++l]-1;
578 }
579 i++;
580 j++;
581 }
582}
583
584static void tch_fr_disassemble(ubit_t *b_bits,
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100585 const uint8_t *tch_data, int net_order)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100586{
587 int i, j, k, l, o;
588
589 if (net_order) {
590 for (i = 0, j = 4; i < 260; i++, j++)
591 b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
592
593 return;
594 }
595
596 i = 0; /* counts bits */
597 j = 4; /* counts input bits */
598 k = gsm0503_gsm_fr_map[0] - 1; /* current number bit in element */
599 l = 0; /* counts element bits */
600 o = 0; /* offset output bits */
601 while (i < 260) {
602 b_bits[k + o] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
603 if (--k < 0) {
604 o += gsm0503_gsm_fr_map[l];
605 k = gsm0503_gsm_fr_map[++l] - 1;
606 }
607 i++;
608 j++;
609 }
610}
611
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100612/* assemble a HR codec frame in format as used inside RTP */
613static void tch_hr_reassemble(uint8_t *tch_data, const ubit_t *b_bits)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100614{
615 int i, j;
616
617 tch_data[0] = 0x00; /* F = 0, FT = 000 */
618 memset(tch_data + 1, 0, 14);
619
620 for (i = 0, j = 8; i < 112; i++, j++)
621 tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7)));
622}
623
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100624static void tch_hr_disassemble(ubit_t *b_bits, const uint8_t *tch_data)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100625{
626 int i, j;
627
628 for (i = 0, j = 8; i < 112; i++, j++)
629 b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
630}
631
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100632/* assemble a EFR codec frame in format as used inside RTP */
633static void tch_efr_reassemble(uint8_t *tch_data, const ubit_t *b_bits)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100634{
635 int i, j;
636
637 tch_data[0] = 0xc << 4;
638 memset(tch_data + 1, 0, 30);
639
640 for (i = 0, j = 4; i < 244; i++, j++)
641 tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7)));
642}
643
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100644static void tch_efr_disassemble(ubit_t *b_bits, const uint8_t *tch_data)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100645{
646 int i, j;
647
648 for (i = 0, j = 4; i < 244; i++, j++)
649 b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
650}
651
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100652/* assemble a AMR codec frame in format as used inside RTP */
653static void tch_amr_reassemble(uint8_t *tch_data, const ubit_t *d_bits, int len)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100654{
655 int i, j;
656
657 memset(tch_data, 0, (len + 7) >> 3);
658
659 for (i = 0, j = 0; i < len; i++, j++)
660 tch_data[j >> 3] |= (d_bits[i] << (7 - (j & 7)));
661}
662
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100663static void tch_amr_disassemble(ubit_t *d_bits, const uint8_t *tch_data, int len)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100664{
665 int i, j;
666
667 for (i = 0, j = 0; i < len; i++, j++)
668 d_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
669}
670
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100671/* re-arrange according to TS 05.03 Table 2 (receiver) */
672static void tch_fr_d_to_b(ubit_t *b_bits, const ubit_t *d_bits)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100673{
674 int i;
675
676 for (i = 0; i < 260; i++)
677 b_bits[gsm610_bitorder[i]] = d_bits[i];
678}
679
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100680/* re-arrange according to TS 05.03 Table 2 (transmitter) */
681static void tch_fr_b_to_d(ubit_t *d_bits, const ubit_t *b_bits)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100682{
683 int i;
684
685 for (i = 0; i < 260; i++)
686 d_bits[i] = b_bits[gsm610_bitorder[i]];
687}
688
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100689/* re-arrange according to TS 05.03 Table 3a (receiver) */
690static void tch_hr_d_to_b(ubit_t *b_bits, const ubit_t *d_bits)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100691{
692 int i;
693
694 const uint16_t *map;
695
696 if (!d_bits[93] && !d_bits[94])
697 map = gsm620_unvoiced_bitorder;
698 else
699 map = gsm620_voiced_bitorder;
700
701 for (i = 0; i < 112; i++)
702 b_bits[map[i]] = d_bits[i];
703}
704
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100705/* re-arrange according to TS 05.03 Table 3a (transmitter) */
706static void tch_hr_b_to_d(ubit_t *d_bits, const ubit_t *b_bits)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100707{
708 int i;
709 const uint16_t *map;
710
711 if (!b_bits[34] && !b_bits[35])
712 map = gsm620_unvoiced_bitorder;
713 else
714 map = gsm620_voiced_bitorder;
715
716 for (i = 0; i < 112; i++)
717 d_bits[i] = b_bits[map[i]];
718}
719
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100720/* re-arrange according to TS 05.03 Table 6 (receiver) */
721static void tch_efr_d_to_w(ubit_t *b_bits, const ubit_t *d_bits)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100722{
723 int i;
724
725 for (i = 0; i < 260; i++)
726 b_bits[gsm660_bitorder[i]] = d_bits[i];
727}
728
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100729/* re-arrange according to TS 05.03 Table 6 (transmitter) */
730static void tch_efr_w_to_d(ubit_t *d_bits, const ubit_t *b_bits)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100731{
732 int i;
733
734 for (i = 0; i < 260; i++)
735 d_bits[i] = b_bits[gsm660_bitorder[i]];
736}
737
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100738/* extract the 65 protected class1a+1b bits */
739static void tch_efr_protected(const ubit_t *s_bits, ubit_t *b_bits)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100740{
741 int i;
742
743 for (i = 0; i < 65; i++)
744 b_bits[i] = s_bits[gsm0503_gsm_efr_protected_bits[i] - 1];
745}
746
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100747static void tch_fr_unreorder(ubit_t *d, ubit_t *p, const ubit_t *u)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100748{
749 int i;
750
751 for (i = 0; i < 91; i++) {
752 d[i << 1] = u[i];
753 d[(i << 1) + 1] = u[184 - i];
754 }
755
756 for (i = 0; i < 3; i++)
757 p[i] = u[91 + i];
758}
759
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100760static void tch_fr_reorder(ubit_t *u, const ubit_t *d, const ubit_t *p)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100761{
762 int i;
763
764 for (i = 0; i < 91; i++) {
765 u[i] = d[i << 1];
766 u[184 - i] = d[(i << 1) + 1];
767 }
768
769 for (i = 0; i < 3; i++)
770 u[91 + i] = p[i];
771}
772
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100773static void tch_hr_unreorder(ubit_t *d, ubit_t *p, const ubit_t *u)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100774{
775 memcpy(d, u, 95);
776 memcpy(p, u + 95, 3);
777}
778
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100779static void tch_hr_reorder(ubit_t *u, const ubit_t *d, const ubit_t *p)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100780{
781 memcpy(u, d, 95);
782 memcpy(u + 95, p, 3);
783}
784
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100785static void tch_efr_reorder(ubit_t *w, const ubit_t *s, const ubit_t *p)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100786{
787 memcpy(w, s, 71);
788 w[71] = w[72] = s[69];
789 memcpy(w + 73, s + 71, 50);
790 w[123] = w[124] = s[119];
791 memcpy(w + 125, s + 121, 53);
792 w[178] = w[179] = s[172];
793 memcpy(w + 180, s + 174, 50);
794 w[230] = w[231] = s[222];
795 memcpy(w + 232, s + 224, 20);
796 memcpy(w + 252, p, 8);
797}
798
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100799static void tch_efr_unreorder(ubit_t *s, ubit_t *p, const ubit_t *w)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100800{
801 int sum;
802
803 memcpy(s, w, 71);
804 sum = s[69] + w[71] + w[72];
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100805 s[69] = (sum >= 2);
Piotr Krysik70c25a12017-01-03 08:01:23 +0100806 memcpy(s + 71, w + 73, 50);
807 sum = s[119] + w[123] + w[124];
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100808 s[119] = (sum >= 2);
Piotr Krysik70c25a12017-01-03 08:01:23 +0100809 memcpy(s + 121, w + 125, 53);
810 sum = s[172] + w[178] + w[179];
811 s[172] = (sum > 2);
812 memcpy(s + 174, w + 180, 50);
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100813 sum = s[222] + w[230] + w[231];
814 s[222] = (sum >= 2);
Piotr Krysik70c25a12017-01-03 08:01:23 +0100815 memcpy(s + 224, w + 232, 20);
816 memcpy(p, w + 252, 8);
817}
818
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100819static void tch_amr_merge(ubit_t *u, const ubit_t *d, const ubit_t *p, int len, int prot)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100820{
821 memcpy(u, d, prot);
822 memcpy(u + prot, p, 6);
823 memcpy(u + prot + 6, d + prot, len - prot);
824}
825
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100826static void tch_amr_unmerge(ubit_t *d, ubit_t *p, const ubit_t *u, int len, int prot)
Piotr Krysik70c25a12017-01-03 08:01:23 +0100827{
828 memcpy(d, u, prot);
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100829 memcpy(p, u + prot, 6);
Piotr Krysik70c25a12017-01-03 08:01:23 +0100830 memcpy(d + prot, u + prot + 6, len - prot);
831}
832
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100833/*! Perform channel decoding of a FR/EFR channel according TS 05.03
834 * \param[out] tch_data Codec frame in RTP payload format
835 * \param[in] bursts buffer containing the symbols of 8 bursts
836 * \param[in] net_order FIXME
837 * \param[in] efr Is this channel using EFR (1) or FR (0)
838 * \param[out] n_errors Number of detected bit errors
839 * \param[out] n_bits_total Total number of bits
840 * \returns length of bytes used in \a tch_data output buffer */
841int gsm0503_tch_fr_decode(uint8_t *tch_data, const sbit_t *bursts,
Piotr Krysik70c25a12017-01-03 08:01:23 +0100842 int net_order, int efr, int *n_errors, int *n_bits_total)
843{
844 sbit_t iB[912], cB[456], h;
845 ubit_t conv[185], s[244], w[260], b[65], d[260], p[8];
846 int i, rv, len, steal = 0;
847
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100848 /* map from 8 bursts to interleaved data bits (iB) */
849 for (i = 0; i < 8; i++) {
Piotr Krysik70c25a12017-01-03 08:01:23 +0100850 gsm0503_tch_burst_unmap(&iB[i * 114],
851 &bursts[i * 116], &h, i >> 2);
852 steal -= h;
853 }
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100854 /* we now have the bits of the four bursts (interface 4 in
855 * Figure 1a of TS 05.03 */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100856
857 gsm0503_tch_fr_deinterleave(cB, iB);
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100858 /* we now have the coded bits c(B): interface 3 in Fig. 1a */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100859
860 if (steal > 0) {
861 rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
862 if (rv) {
863 /* Error decoding FACCH frame */
864 return -1;
865 }
866
867 return 23;
868 }
869
870 osmo_conv_decode_ber(&gsm0503_tch_fr, cB, conv, n_errors, n_bits_total);
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100871 /* we now have the data bits 'u': interface 2 in Fig. 1a */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100872
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100873 /* input: 'conv', output: d[ata] + p[arity] */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100874 tch_fr_unreorder(d, p, conv);
875
876 for (i = 0; i < 78; i++)
877 d[i + 182] = (cB[i + 378] < 0) ? 1 : 0;
878
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100879 /* check if parity of first 50 (class 1) 'd'-bits match 'p' */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100880 rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d, 50, p);
881 if (rv) {
882 /* Error checking CRC8 for the FR part of an EFR/FR frame */
883 return -1;
884 }
885
886 if (efr) {
887 tch_efr_d_to_w(w, d);
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100888 /* we now have the preliminary-coded bits w(k) */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100889
890 tch_efr_unreorder(s, p, w);
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100891 /* we now have the data delivered to the preliminary
892 * channel encoding unit s(k) */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100893
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100894 /* extract the 65 most important bits according TS 05.03 3.1.1.1 */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100895 tch_efr_protected(s, b);
896
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100897 /* perform CRC-8 on 65 most important bits (50 bits of
898 * class 1a + 15 bits of class 1b) */
Piotr Krysik70c25a12017-01-03 08:01:23 +0100899 rv = osmo_crc8gen_check_bits(&gsm0503_tch_efr_crc8, b, 65, p);
900 if (rv) {
901 /* Error checking CRC8 for the EFR part of an EFR frame */
902 return -1;
903 }
904
905 tch_efr_reassemble(tch_data, s);
906
907 len = GSM_EFR_BYTES;
908 } else {
909 tch_fr_d_to_b(w, d);
910
911 tch_fr_reassemble(tch_data, w, net_order);
912
913 len = GSM_FR_BYTES;
914 }
915
916 return len;
917}
918
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100919/*! Perform channel encoding on a TCH/FS channel according to TS 05.03
920 * \param[out] bursts caller-allocated output buffer for bursts bits
921 * \param[in] tch_data Codec input data in RTP payload format
922 * \param[in] len Length of \a tch_data in bytes
923 * \param[in] net_order FIXME
924 * \returns 0 in case of success; negative on error */
925int gsm0503_tch_fr_encode(ubit_t *bursts, const uint8_t *tch_data,
Piotr Krysik70c25a12017-01-03 08:01:23 +0100926 int len, int net_order)
927{
928 ubit_t iB[912], cB[456], h;
929 ubit_t conv[185], w[260], b[65], s[244], d[260], p[8];
930 int i;
931
932 switch (len) {
933 case GSM_EFR_BYTES: /* TCH EFR */
934
935 tch_efr_disassemble(s, tch_data);
936
937 tch_efr_protected(s, b);
938
939 osmo_crc8gen_set_bits(&gsm0503_tch_efr_crc8, b, 65, p);
940
941 tch_efr_reorder(w, s, p);
942
943 tch_efr_w_to_d(d, w);
944
945 goto coding_efr_fr;
946 case GSM_FR_BYTES: /* TCH FR */
947 tch_fr_disassemble(w, tch_data, net_order);
948
949 tch_fr_b_to_d(d, w);
950
951coding_efr_fr:
952 osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d, 50, p);
953
954 tch_fr_reorder(conv, d, p);
955
956 memcpy(cB + 378, d + 182, 78);
957
958 osmo_conv_encode(&gsm0503_tch_fr, conv, cB);
959
960 h = 0;
961
962 break;
963 case GSM_MACBLOCK_LEN: /* FACCH */
964 _xcch_encode_cB(cB, tch_data);
965
966 h = 1;
967
968 break;
969 default:
970 return -1;
971 }
972
973 gsm0503_tch_fr_interleave(cB, iB);
974
975 for (i = 0; i < 8; i++) {
976 gsm0503_tch_burst_map(&iB[i * 114],
977 &bursts[i * 116], &h, i >> 2);
978 }
979
980 return 0;
981}
982
Piotr Krysik9e2e8352018-02-27 12:16:25 +0100983/*! Perform channel decoding of a HR(v1) channel according TS 05.03
984 * \param[out] tch_data Codec frame in RTP payload format
985 * \param[in] bursts buffer containing the symbols of 8 bursts
986 * \param[in] odd Odd (1) or even (0) frame number
987 * \param[out] n_errors Number of detected bit errors
988 * \param[out] n_bits_total Total number of bits
989 * \returns length of bytes used in \a tch_data output buffer */
990int gsm0503_tch_hr_decode(uint8_t *tch_data, const sbit_t *bursts, int odd,
Piotr Krysik70c25a12017-01-03 08:01:23 +0100991 int *n_errors, int *n_bits_total)
992{
993 sbit_t iB[912], cB[456], h;
994 ubit_t conv[98], b[112], d[112], p[3];
995 int i, rv, steal = 0;
996
997 /* Only unmap the stealing bits */
998 if (!odd) {
999 for (i = 0; i < 4; i++) {
1000 gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0);
1001 steal -= h;
1002 }
1003
1004 for (i = 2; i < 5; i++) {
1005 gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1);
1006 steal -= h;
1007 }
1008 }
1009
1010 /* If we found a stole FACCH, but only at correct alignment */
1011 if (steal > 0) {
1012 for (i = 0; i < 6; i++) {
1013 gsm0503_tch_burst_unmap(&iB[i * 114],
1014 &bursts[i * 116], NULL, i >> 2);
1015 }
1016
1017 for (i = 2; i < 4; i++) {
1018 gsm0503_tch_burst_unmap(&iB[i * 114 + 456],
1019 &bursts[i * 116], NULL, 1);
1020 }
1021
1022 gsm0503_tch_fr_deinterleave(cB, iB);
1023
1024 rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
1025 if (rv) {
1026 /* Error decoding FACCH frame */
1027 return -1;
1028 }
1029
1030 return GSM_MACBLOCK_LEN;
1031 }
1032
1033 for (i = 0; i < 4; i++) {
1034 gsm0503_tch_burst_unmap(&iB[i * 114],
1035 &bursts[i * 116], NULL, i >> 1);
1036 }
1037
1038 gsm0503_tch_hr_deinterleave(cB, iB);
1039
1040 osmo_conv_decode_ber(&gsm0503_tch_hr, cB, conv, n_errors, n_bits_total);
1041
1042 tch_hr_unreorder(d, p, conv);
1043
1044 for (i = 0; i < 17; i++)
1045 d[i + 95] = (cB[i + 211] < 0) ? 1 : 0;
1046
1047 rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p);
1048 if (rv) {
1049 /* Error checking CRC8 for an HR frame */
1050 return -1;
1051 }
1052
1053 tch_hr_d_to_b(b, d);
1054
1055 tch_hr_reassemble(tch_data, b);
1056
1057 return 15;
1058}
1059
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001060/*! Perform channel encoding on a TCH/HS channel according to TS 05.03
1061 * \param[out] bursts caller-allocated output buffer for bursts bits
1062 * \param[in] tch_data Codec input data in RTP payload format
1063 * \param[in] len Length of \a tch_data in bytes
1064 * \returns 0 in case of success; negative on error */
1065int gsm0503_tch_hr_encode(ubit_t *bursts, const uint8_t *tch_data, int len)
Piotr Krysik70c25a12017-01-03 08:01:23 +01001066{
1067 ubit_t iB[912], cB[456], h;
1068 ubit_t conv[98], b[112], d[112], p[3];
1069 int i;
1070
1071 switch (len) {
1072 case 15: /* TCH HR */
1073 tch_hr_disassemble(b, tch_data);
1074
1075 tch_hr_b_to_d(d, b);
1076
1077 osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p);
1078
1079 tch_hr_reorder(conv, d, p);
1080
1081 osmo_conv_encode(&gsm0503_tch_hr, conv, cB);
1082
1083 memcpy(cB + 211, d + 95, 17);
1084
1085 h = 0;
1086
1087 gsm0503_tch_hr_interleave(cB, iB);
1088
1089 for (i = 0; i < 4; i++) {
1090 gsm0503_tch_burst_map(&iB[i * 114],
1091 &bursts[i * 116], &h, i >> 1);
1092 }
1093
1094 break;
1095 case GSM_MACBLOCK_LEN: /* FACCH */
1096 _xcch_encode_cB(cB, tch_data);
1097
1098 h = 1;
1099
1100 gsm0503_tch_fr_interleave(cB, iB);
1101
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001102 for (i = 0; i < 6; i++) {
Piotr Krysik70c25a12017-01-03 08:01:23 +01001103 gsm0503_tch_burst_map(&iB[i * 114],
1104 &bursts[i * 116], &h, i >> 2);
1105 }
1106
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001107 for (i = 2; i < 4; i++) {
Piotr Krysik70c25a12017-01-03 08:01:23 +01001108 gsm0503_tch_burst_map(&iB[i * 114 + 456],
1109 &bursts[i * 116], &h, 1);
1110 }
1111
1112 break;
1113 default:
1114 return -1;
1115 }
1116
1117 return 0;
1118}
1119
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001120/*! Perform channel decoding of a TCH/AFS channel according TS 05.03
1121 * \param[out] tch_data Codec frame in RTP payload format
1122 * \param[in] bursts buffer containing the symbols of 8 bursts
1123 * \param[in] codec_mode_req is this CMR (1) or CMC (0)
1124 * \param[in] codec array of active codecs (active codec set)
1125 * \param[in] codecs number of codecs in \a codec
1126 * \param ft Frame Type; Input if \a codec_mode_req = 1, Output * otherwise
1127 * \param[out] cmr Output in \a codec_mode_req = 1
1128 * \param[out] n_errors Number of detected bit errors
1129 * \param[out] n_bits_total Total number of bits
1130 * \returns length of bytes used in \a tch_data output buffer */
1131int gsm0503_tch_afs_decode(uint8_t *tch_data, const sbit_t *bursts,
Piotr Krysik70c25a12017-01-03 08:01:23 +01001132 int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
1133 uint8_t *cmr, int *n_errors, int *n_bits_total)
1134{
1135 sbit_t iB[912], cB[456], h;
1136 ubit_t d[244], p[6], conv[250];
1137 int i, j, k, best = 0, rv, len, steal = 0, id = 0;
1138 *n_errors = 0; *n_bits_total = 0;
1139
1140 for (i=0; i<8; i++) {
1141 gsm0503_tch_burst_unmap(&iB[i * 114], &bursts[i * 116], &h, i >> 2);
1142 steal -= h;
1143 }
1144
1145 gsm0503_tch_fr_deinterleave(cB, iB);
1146
1147 if (steal > 0) {
1148 rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
1149 if (rv) {
1150 /* Error decoding FACCH frame */
1151 return -1;
1152 }
1153
1154 return GSM_MACBLOCK_LEN;
1155 }
1156
1157 for (i = 0; i < 4; i++) {
1158 for (j = 0, k = 0; j < 8; j++)
1159 k += abs(((int)gsm0503_afs_ic_sbit[i][j]) - ((int)cB[j]));
1160
1161 if (i == 0 || k < best) {
1162 best = k;
1163 id = i;
1164 }
1165 }
1166
1167 /* Check if indicated codec fits into range of codecs */
1168 if (id >= codecs) {
1169 /* Codec mode out of range, return id */
1170 return id;
1171 }
1172
1173 switch ((codec_mode_req) ? codec[*ft] : codec[id]) {
1174 case 7: /* TCH/AFS12.2 */
1175 osmo_conv_decode_ber(&gsm0503_tch_afs_12_2, cB + 8,
1176 conv, n_errors, n_bits_total);
1177
1178 tch_amr_unmerge(d, p, conv, 244, 81);
1179
1180 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 81, p);
1181 if (rv) {
1182 /* Error checking CRC8 for an AMR 12.2 frame */
1183 return -1;
1184 }
1185
1186 tch_amr_reassemble(tch_data, d, 244);
1187
1188 len = 31;
1189
1190 break;
1191 case 6: /* TCH/AFS10.2 */
1192 osmo_conv_decode_ber(&gsm0503_tch_afs_10_2, cB + 8,
1193 conv, n_errors, n_bits_total);
1194
1195 tch_amr_unmerge(d, p, conv, 204, 65);
1196
1197 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 65, p);
1198 if (rv) {
1199 /* Error checking CRC8 for an AMR 10.2 frame */
1200 return -1;
1201 }
1202
1203 tch_amr_reassemble(tch_data, d, 204);
1204
1205 len = 26;
1206
1207 break;
1208 case 5: /* TCH/AFS7.95 */
1209 osmo_conv_decode_ber(&gsm0503_tch_afs_7_95, cB + 8,
1210 conv, n_errors, n_bits_total);
1211
1212 tch_amr_unmerge(d, p, conv, 159, 75);
1213
1214 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 75, p);
1215 if (rv) {
1216 /* Error checking CRC8 for an AMR 7.95 frame */
1217 return -1;
1218 }
1219
1220 tch_amr_reassemble(tch_data, d, 159);
1221
1222 len = 20;
1223
1224 break;
1225 case 4: /* TCH/AFS7.4 */
1226 osmo_conv_decode_ber(&gsm0503_tch_afs_7_4, cB + 8,
1227 conv, n_errors, n_bits_total);
1228
1229 tch_amr_unmerge(d, p, conv, 148, 61);
1230
1231 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p);
1232 if (rv) {
1233 /* Error checking CRC8 for an AMR 7.4 frame */
1234 return -1;
1235 }
1236
1237 tch_amr_reassemble(tch_data, d, 148);
1238
1239 len = 19;
1240
1241 break;
1242 case 3: /* TCH/AFS6.7 */
1243 osmo_conv_decode_ber(&gsm0503_tch_afs_6_7, cB + 8,
1244 conv, n_errors, n_bits_total);
1245
1246 tch_amr_unmerge(d, p, conv, 134, 55);
1247
1248 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
1249 if (rv) {
1250 /* Error checking CRC8 for an AMR 6.7 frame */
1251 return -1;
1252 }
1253
1254 tch_amr_reassemble(tch_data, d, 134);
1255
1256 len = 17;
1257
1258 break;
1259 case 2: /* TCH/AFS5.9 */
1260 osmo_conv_decode_ber(&gsm0503_tch_afs_5_9, cB + 8,
1261 conv, n_errors, n_bits_total);
1262
1263 tch_amr_unmerge(d, p, conv, 118, 55);
1264
1265 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
1266 if (rv) {
1267 /* Error checking CRC8 for an AMR 5.9 frame */
1268 return -1;
1269 }
1270
1271 tch_amr_reassemble(tch_data, d, 118);
1272
1273 len = 15;
1274
1275 break;
1276 case 1: /* TCH/AFS5.15 */
1277 osmo_conv_decode_ber(&gsm0503_tch_afs_5_15, cB + 8,
1278 conv, n_errors, n_bits_total);
1279
1280 tch_amr_unmerge(d, p, conv, 103, 49);
1281
1282 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p);
1283 if (rv) {
1284 /* Error checking CRC8 for an AMR 5.15 frame */
1285 return -1;
1286 }
1287
1288 tch_amr_reassemble(tch_data, d, 103);
1289
1290 len = 13;
1291
1292 break;
1293 case 0: /* TCH/AFS4.75 */
1294 osmo_conv_decode_ber(&gsm0503_tch_afs_4_75, cB + 8,
1295 conv, n_errors, n_bits_total);
1296
1297 tch_amr_unmerge(d, p, conv, 95, 39);
1298
1299 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p);
1300 if (rv) {
1301 /* Error checking CRC8 for an AMR 4.75 frame */
1302 return -1;
1303 }
1304
1305 tch_amr_reassemble(tch_data, d, 95);
1306
1307 len = 12;
1308
1309 break;
1310 default:
1311 /* Unknown frame type */
1312 *n_bits_total = 448;
1313 *n_errors = *n_bits_total;
1314 return -1;
1315 }
1316
1317 /* Change codec request / indication, if frame is valid */
1318 if (codec_mode_req)
1319 *cmr = id;
1320 else
1321 *ft = id;
1322
1323 return len;
1324}
1325
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001326/*! Perform channel encoding on a TCH/AFS channel according to TS 05.03
1327 * \param[out] bursts caller-allocated output buffer for bursts bits
1328 * \param[in] tch_data Codec input data in RTP payload format
1329 * \param[in] len Length of \a tch_data in bytes
1330 * \param[in] codec_mode_req Use CMR (1) or FT (0)
1331 * \param[in] codec Array of codecs (active codec set)
1332 * \param[in] codecs Number of entries in \a codec
1333 * \param[in] ft Frame Type to be used for encoding (index to \a codec)
1334 * \param[in] cmr Codec Mode Request (used in codec_mode_req = 1 only)
1335 * \returns 0 in case of success; negative on error */
1336int gsm0503_tch_afs_encode(ubit_t *bursts, const uint8_t *tch_data, int len,
Piotr Krysik70c25a12017-01-03 08:01:23 +01001337 int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft,
1338 uint8_t cmr)
1339{
1340 ubit_t iB[912], cB[456], h;
1341 ubit_t d[244], p[6], conv[250];
1342 int i;
1343 uint8_t id;
1344
1345 if (len == GSM_MACBLOCK_LEN) { /* FACCH */
1346 _xcch_encode_cB(cB, tch_data);
1347
1348 h = 1;
1349
1350 goto facch;
1351 }
1352
1353 h = 0;
1354
1355 if (codec_mode_req) {
1356 if (cmr >= codecs) {
1357 /* FIXME: CMR ID is not in codec list! */
1358 return -1;
1359 }
1360 id = cmr;
1361 } else {
1362 if (ft >= codecs) {
1363 /* FIXME: FT ID is not in codec list! */
1364 return -1;
1365 }
1366 id = ft;
1367 }
1368
1369 switch (codec[ft]) {
1370 case 7: /* TCH/AFS12.2 */
1371 if (len != 31)
1372 goto invalid_length;
1373
1374 tch_amr_disassemble(d, tch_data, 244);
1375
1376 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 81, p);
1377
1378 tch_amr_merge(conv, d, p, 244, 81);
1379
1380 osmo_conv_encode(&gsm0503_tch_afs_12_2, conv, cB + 8);
1381
1382 break;
1383 case 6: /* TCH/AFS10.2 */
1384 if (len != 26)
1385 goto invalid_length;
1386
1387 tch_amr_disassemble(d, tch_data, 204);
1388
1389 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 65, p);
1390
1391 tch_amr_merge(conv, d, p, 204, 65);
1392
1393 osmo_conv_encode(&gsm0503_tch_afs_10_2, conv, cB + 8);
1394
1395 break;
1396 case 5: /* TCH/AFS7.95 */
1397 if (len != 20)
1398 goto invalid_length;
1399
1400 tch_amr_disassemble(d, tch_data, 159);
1401
1402 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 75, p);
1403
1404 tch_amr_merge(conv, d, p, 159, 75);
1405
1406 osmo_conv_encode(&gsm0503_tch_afs_7_95, conv, cB + 8);
1407
1408 break;
1409 case 4: /* TCH/AFS7.4 */
1410 if (len != 19)
1411 goto invalid_length;
1412
1413 tch_amr_disassemble(d, tch_data, 148);
1414
1415 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p);
1416
1417 tch_amr_merge(conv, d, p, 148, 61);
1418
1419 osmo_conv_encode(&gsm0503_tch_afs_7_4, conv, cB + 8);
1420
1421 break;
1422 case 3: /* TCH/AFS6.7 */
1423 if (len != 17)
1424 goto invalid_length;
1425
1426 tch_amr_disassemble(d, tch_data, 134);
1427
1428 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
1429
1430 tch_amr_merge(conv, d, p, 134, 55);
1431
1432 osmo_conv_encode(&gsm0503_tch_afs_6_7, conv, cB + 8);
1433
1434 break;
1435 case 2: /* TCH/AFS5.9 */
1436 if (len != 15)
1437 goto invalid_length;
1438
1439 tch_amr_disassemble(d, tch_data, 118);
1440
1441 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
1442
1443 tch_amr_merge(conv, d, p, 118, 55);
1444
1445 osmo_conv_encode(&gsm0503_tch_afs_5_9, conv, cB + 8);
1446
1447 break;
1448 case 1: /* TCH/AFS5.15 */
1449 if (len != 13)
1450 goto invalid_length;
1451
1452 tch_amr_disassemble(d, tch_data, 103);
1453
1454 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p);
1455
1456 tch_amr_merge(conv, d, p, 103, 49);
1457
1458 osmo_conv_encode(&gsm0503_tch_afs_5_15, conv, cB + 8);
1459
1460 break;
1461 case 0: /* TCH/AFS4.75 */
1462 if (len != 12)
1463 goto invalid_length;
1464
1465 tch_amr_disassemble(d, tch_data, 95);
1466
1467 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p);
1468
1469 tch_amr_merge(conv, d, p, 95, 39);
1470
1471 osmo_conv_encode(&gsm0503_tch_afs_4_75, conv, cB + 8);
1472
1473 break;
1474 default:
1475 /* FIXME: FT %ft is not supported */
1476 return -1;
1477 }
1478
1479 memcpy(cB, gsm0503_afs_ic_ubit[id], 8);
1480
1481facch:
1482 gsm0503_tch_fr_interleave(cB, iB);
1483
1484 for (i = 0; i < 8; i++) {
1485 gsm0503_tch_burst_map(&iB[i * 114],
1486 &bursts[i * 116], &h, i >> 2);
1487 }
1488
1489 return 0;
1490
1491invalid_length:
1492 /* FIXME: payload length %len does not comply with codec type %ft */
1493 return -1;
1494}
1495
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001496/*! Perform channel decoding of a TCH/AFS channel according TS 05.03
1497 * \param[out] tch_data Codec frame in RTP payload format
1498 * \param[in] bursts buffer containing the symbols of 8 bursts
1499 * \param[in] odd Is this an odd (1) or even (0) frame number?
1500 * \param[in] codec_mode_req is this CMR (1) or CMC (0)
1501 * \param[in] codec array of active codecs (active codec set)
1502 * \param[in] codecs number of codecs in \a codec
1503 * \param ft Frame Type; Input if \a codec_mode_req = 1, Output * otherwise
1504 * \param[out] cmr Output in \a codec_mode_req = 1
1505 * \param[out] n_errors Number of detected bit errors
1506 * \param[out] n_bits_total Total number of bits
1507 * \returns length of bytes used in \a tch_data output buffer */
1508int gsm0503_tch_ahs_decode(uint8_t *tch_data, const sbit_t *bursts, int odd,
Piotr Krysik70c25a12017-01-03 08:01:23 +01001509 int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
1510 uint8_t *cmr, int *n_errors, int *n_bits_total)
1511{
1512 sbit_t iB[912], cB[456], h;
1513 ubit_t d[244], p[6], conv[135];
1514 int i, j, k, best = 0, rv, len, steal = 0, id = 0;
1515
1516 /* only unmap the stealing bits */
1517 if (!odd) {
1518 for (i = 0; i < 4; i++) {
1519 gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0);
1520 steal -= h;
1521 }
1522 for (i = 2; i < 5; i++) {
1523 gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1);
1524 steal -= h;
1525 }
1526 }
1527
1528 /* if we found a stole FACCH, but only at correct alignment */
1529 if (steal > 0) {
1530 for (i = 0; i < 6; i++) {
1531 gsm0503_tch_burst_unmap(&iB[i * 114],
1532 &bursts[i * 116], NULL, i >> 2);
1533 }
1534
1535 for (i = 2; i < 4; i++) {
1536 gsm0503_tch_burst_unmap(&iB[i * 114 + 456],
1537 &bursts[i * 116], NULL, 1);
1538 }
1539
1540 gsm0503_tch_fr_deinterleave(cB, iB);
1541
1542 rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
1543 if (rv) {
1544 /* Error decoding FACCH frame */
1545 return -1;
1546 }
1547
1548 return GSM_MACBLOCK_LEN;
1549 }
1550
1551 for (i = 0; i < 4; i++) {
1552 gsm0503_tch_burst_unmap(&iB[i * 114],
1553 &bursts[i * 116], NULL, i >> 1);
1554 }
1555
1556 gsm0503_tch_hr_deinterleave(cB, iB);
1557
1558 for (i = 0; i < 4; i++) {
1559 for (j = 0, k = 0; j < 4; j++)
1560 k += abs(((int)gsm0503_ahs_ic_sbit[i][j]) - ((int)cB[j]));
1561
1562 if (i == 0 || k < best) {
1563 best = k;
1564 id = i;
1565 }
1566 }
1567
1568 /* Check if indicated codec fits into range of codecs */
1569 if (id >= codecs) {
1570 /* Codec mode out of range, return id */
1571 return id;
1572 }
1573
1574 switch ((codec_mode_req) ? codec[*ft] : codec[id]) {
1575 case 5: /* TCH/AHS7.95 */
1576 osmo_conv_decode_ber(&gsm0503_tch_ahs_7_95, cB + 4,
1577 conv, n_errors, n_bits_total);
1578
1579 tch_amr_unmerge(d, p, conv, 123, 67);
1580
1581 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 67, p);
1582 if (rv) {
1583 /* Error checking CRC8 for an AMR 7.95 frame */
1584 return -1;
1585 }
1586
1587 for (i = 0; i < 36; i++)
1588 d[i + 123] = (cB[i + 192] < 0) ? 1 : 0;
1589
1590 tch_amr_reassemble(tch_data, d, 159);
1591
1592 len = 20;
1593
1594 break;
1595 case 4: /* TCH/AHS7.4 */
1596 osmo_conv_decode_ber(&gsm0503_tch_ahs_7_4, cB + 4,
1597 conv, n_errors, n_bits_total);
1598
1599 tch_amr_unmerge(d, p, conv, 120, 61);
1600
1601 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p);
1602 if (rv) {
1603 /* Error checking CRC8 for an AMR 7.4 frame */
1604 return -1;
1605 }
1606
1607 for (i = 0; i < 28; i++)
1608 d[i + 120] = (cB[i + 200] < 0) ? 1 : 0;
1609
1610 tch_amr_reassemble(tch_data, d, 148);
1611
1612 len = 19;
1613
1614 break;
1615 case 3: /* TCH/AHS6.7 */
1616 osmo_conv_decode_ber(&gsm0503_tch_ahs_6_7, cB + 4,
1617 conv, n_errors, n_bits_total);
1618
1619 tch_amr_unmerge(d, p, conv, 110, 55);
1620
1621 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
1622 if (rv) {
1623 /* Error checking CRC8 for an AMR 6.7 frame */
1624 return -1;
1625 }
1626
1627 for (i = 0; i < 24; i++)
1628 d[i + 110] = (cB[i + 204] < 0) ? 1 : 0;
1629
1630 tch_amr_reassemble(tch_data, d, 134);
1631
1632 len = 17;
1633
1634 break;
1635 case 2: /* TCH/AHS5.9 */
1636 osmo_conv_decode_ber(&gsm0503_tch_ahs_5_9, cB + 4,
1637 conv, n_errors, n_bits_total);
1638
1639 tch_amr_unmerge(d, p, conv, 102, 55);
1640
1641 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
1642 if (rv) {
1643 /* Error checking CRC8 for an AMR 5.9 frame */
1644 return -1;
1645 }
1646
1647 for (i = 0; i < 16; i++)
1648 d[i + 102] = (cB[i + 212] < 0) ? 1 : 0;
1649
1650 tch_amr_reassemble(tch_data, d, 118);
1651
1652 len = 15;
1653
1654 break;
1655 case 1: /* TCH/AHS5.15 */
1656 osmo_conv_decode_ber(&gsm0503_tch_ahs_5_15, cB + 4,
1657 conv, n_errors, n_bits_total);
1658
1659 tch_amr_unmerge(d, p, conv, 91, 49);
1660
1661 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p);
1662 if (rv) {
1663 /* Error checking CRC8 for an AMR 5.15 frame */
1664 return -1;
1665 }
1666
1667 for (i = 0; i < 12; i++)
1668 d[i + 91] = (cB[i + 216] < 0) ? 1 : 0;
1669
1670 tch_amr_reassemble(tch_data, d, 103);
1671
1672 len = 13;
1673
1674 break;
1675 case 0: /* TCH/AHS4.75 */
1676 osmo_conv_decode_ber(&gsm0503_tch_ahs_4_75, cB + 4,
1677 conv, n_errors, n_bits_total);
1678
1679 tch_amr_unmerge(d, p, conv, 83, 39);
1680
1681 rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p);
1682 if (rv) {
1683 /* Error checking CRC8 for an AMR 4.75 frame */
1684 return -1;
1685 }
1686
1687 for (i = 0; i < 12; i++)
1688 d[i + 83] = (cB[i + 216] < 0) ? 1 : 0;
1689
1690 tch_amr_reassemble(tch_data, d, 95);
1691
1692 len = 12;
1693
1694 break;
1695 default:
1696 /* Unknown frame type */
1697 *n_bits_total = 159;
1698 *n_errors = *n_bits_total;
1699 return -1;
1700 }
1701
1702 /* Change codec request / indication, if frame is valid */
1703 if (codec_mode_req)
1704 *cmr = id;
1705 else
1706 *ft = id;
1707
1708 return len;
1709}
1710
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001711/*! Perform channel encoding on a TCH/AHS channel according to TS 05.03
1712 * \param[out] bursts caller-allocated output buffer for bursts bits
1713 * \param[in] tch_data Codec input data in RTP payload format
1714 * \param[in] len Length of \a tch_data in bytes
1715 * \param[in] codec_mode_req Use CMR (1) or FT (0)
1716 * \param[in] codec Array of codecs (active codec set)
1717 * \param[in] codecs Number of entries in \a codec
1718 * \param[in] ft Frame Type to be used for encoding (index to \a codec)
1719 * \param[in] cmr Codec Mode Request (used in codec_mode_req = 1 only)
1720 * \returns 0 in case of success; negative on error */
1721int gsm0503_tch_ahs_encode(ubit_t *bursts, const uint8_t *tch_data, int len,
Piotr Krysik70c25a12017-01-03 08:01:23 +01001722 int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft,
1723 uint8_t cmr)
1724{
1725 ubit_t iB[912], cB[456], h;
1726 ubit_t d[244], p[6], conv[135];
1727 int i;
1728 uint8_t id;
1729
1730 if (len == GSM_MACBLOCK_LEN) { /* FACCH */
1731 _xcch_encode_cB(cB, tch_data);
1732
1733 h = 1;
1734
1735 gsm0503_tch_fr_interleave(cB, iB);
1736
1737 for (i = 0; i < 6; i++)
1738 gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116],
1739 &h, i >> 2);
1740 for (i = 2; i < 4; i++)
1741 gsm0503_tch_burst_map(&iB[i * 114 + 456],
1742 &bursts[i * 116], &h, 1);
1743
1744 return 0;
1745 }
1746
1747 h = 0;
1748
1749 if (codec_mode_req) {
1750 if (cmr >= codecs) {
1751 /* FIXME: CMR ID %d not in codec list */
1752 return -1;
1753 }
1754 id = cmr;
1755 } else {
1756 if (ft >= codecs) {
1757 /* FIXME: FT ID %d not in codec list */
1758 return -1;
1759 }
1760 id = ft;
1761 }
1762
1763 switch (codec[ft]) {
1764 case 5: /* TCH/AHS7.95 */
1765 if (len != 20)
1766 goto invalid_length;
1767
1768 tch_amr_disassemble(d, tch_data, 159);
1769
1770 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 67, p);
1771
1772 tch_amr_merge(conv, d, p, 123, 67);
1773
1774 osmo_conv_encode(&gsm0503_tch_ahs_7_95, conv, cB + 4);
1775
1776 memcpy(cB + 192, d + 123, 36);
1777
1778 break;
1779 case 4: /* TCH/AHS7.4 */
1780 if (len != 19)
1781 goto invalid_length;
1782
1783 tch_amr_disassemble(d, tch_data, 148);
1784
1785 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p);
1786
1787 tch_amr_merge(conv, d, p, 120, 61);
1788
1789 osmo_conv_encode(&gsm0503_tch_ahs_7_4, conv, cB + 4);
1790
1791 memcpy(cB + 200, d + 120, 28);
1792
1793 break;
1794 case 3: /* TCH/AHS6.7 */
1795 if (len != 17)
1796 goto invalid_length;
1797
1798 tch_amr_disassemble(d, tch_data, 134);
1799
1800 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
1801
1802 tch_amr_merge(conv, d, p, 110, 55);
1803
1804 osmo_conv_encode(&gsm0503_tch_ahs_6_7, conv, cB + 4);
1805
1806 memcpy(cB + 204, d + 110, 24);
1807
1808 break;
1809 case 2: /* TCH/AHS5.9 */
1810 if (len != 15)
1811 goto invalid_length;
1812
1813 tch_amr_disassemble(d, tch_data, 118);
1814
1815 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
1816
1817 tch_amr_merge(conv, d, p, 102, 55);
1818
1819 osmo_conv_encode(&gsm0503_tch_ahs_5_9, conv, cB + 4);
1820
1821 memcpy(cB + 212, d + 102, 16);
1822
1823 break;
1824 case 1: /* TCH/AHS5.15 */
1825 if (len != 13)
1826 goto invalid_length;
1827
1828 tch_amr_disassemble(d, tch_data, 103);
1829
1830 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p);
1831
1832 tch_amr_merge(conv, d, p, 91, 49);
1833
1834 osmo_conv_encode(&gsm0503_tch_ahs_5_15, conv, cB + 4);
1835
1836 memcpy(cB + 216, d + 91, 12);
1837
1838 break;
1839 case 0: /* TCH/AHS4.75 */
1840 if (len != 12)
1841 goto invalid_length;
1842
1843 tch_amr_disassemble(d, tch_data, 95);
1844
1845 osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p);
1846
1847 tch_amr_merge(conv, d, p, 83, 39);
1848
1849 osmo_conv_encode(&gsm0503_tch_ahs_4_75, conv, cB + 4);
1850
1851 memcpy(cB + 216, d + 83, 12);
1852
1853 break;
1854 default:
1855 /* FIXME: FT %ft is not supported */
1856 return -1;
1857 }
1858
1859 memcpy(cB, gsm0503_afs_ic_ubit[id], 4);
1860
1861 gsm0503_tch_hr_interleave(cB, iB);
1862
1863 for (i = 0; i < 4; i++)
1864 gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], &h, i >> 1);
1865
1866 return 0;
1867
1868invalid_length:
1869 /* FIXME: payload length %len does not comply with codec type %ft */
1870 return -1;
1871}
1872
1873/*
1874 * GSM RACH transcoding
1875 */
1876
1877/*
1878 * GSM RACH apply BSIC to parity
1879 *
1880 * p(j) = p(j) xor b(j) j = 0, ..., 5
1881 * b(0) = MSB of PLMN colour code
1882 * b(5) = LSB of BS colour code
1883 */
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001884static inline void rach_apply_bsic(ubit_t *d, uint8_t bsic, uint8_t start)
Piotr Krysik70c25a12017-01-03 08:01:23 +01001885{
1886 int i;
1887
1888 /* Apply it */
1889 for (i = 0; i < 6; i++)
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001890 d[start + i] ^= ((bsic >> (5 - i)) & 1);
Piotr Krysik70c25a12017-01-03 08:01:23 +01001891}
1892
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001893static inline int16_t rach_decode_ber(const sbit_t *burst, uint8_t bsic, bool is_11bit,
1894 int *n_errors, int *n_bits_total)
Piotr Krysik70c25a12017-01-03 08:01:23 +01001895{
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001896 ubit_t conv[17];
1897 uint8_t ra[2] = { 0 }, nbits = is_11bit ? 11 : 8;
Piotr Krysik70c25a12017-01-03 08:01:23 +01001898 int rv;
1899
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001900 osmo_conv_decode_ber(is_11bit ? &gsm0503_rach_ext : &gsm0503_rach, burst, conv,
1901 n_errors, n_bits_total);
Piotr Krysik70c25a12017-01-03 08:01:23 +01001902
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001903 rach_apply_bsic(conv, bsic, nbits);
Piotr Krysik70c25a12017-01-03 08:01:23 +01001904
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001905 rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, nbits, conv + nbits);
Piotr Krysik70c25a12017-01-03 08:01:23 +01001906 if (rv)
1907 return -1;
1908
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001909 osmo_ubit2pbit_ext(ra, 0, conv, 0, nbits, 1);
1910
1911 return is_11bit ? osmo_load16le(ra) : ra[0];
1912}
1913
1914/*! Decode the Extended (11-bit) RACH according to 3GPP TS 45.003
1915 * \param[out] ra output buffer for RACH data
1916 * \param[in] burst Input burst data
1917 * \param[in] bsic BSIC used in this cell
1918 * \returns 0 on success; negative on error (e.g. CRC error) */
1919int gsm0503_rach_ext_decode(uint16_t *ra, const sbit_t *burst, uint8_t bsic)
1920{
1921 int16_t r = rach_decode_ber(burst, bsic, true, NULL, NULL);
1922
1923 if (r < 0)
1924 return r;
1925
1926 *ra = r;
Piotr Krysik70c25a12017-01-03 08:01:23 +01001927
1928 return 0;
1929}
1930
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001931/*! Decode the (8-bit) RACH according to TS 05.03
1932 * \param[out] ra output buffer for RACH data
1933 * \param[in] burst Input burst data
1934 * \param[in] bsic BSIC used in this cell
1935 * \returns 0 on success; negative on error (e.g. CRC error) */
1936int gsm0503_rach_decode(uint8_t *ra, const sbit_t *burst, uint8_t bsic)
Piotr Krysik70c25a12017-01-03 08:01:23 +01001937{
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001938 int16_t r = rach_decode_ber(burst, bsic, false, NULL, NULL);
1939 if (r < 0)
1940 return r;
Piotr Krysik70c25a12017-01-03 08:01:23 +01001941
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001942 *ra = r;
1943 return 0;
1944}
Piotr Krysik70c25a12017-01-03 08:01:23 +01001945
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001946/*! Decode the Extended (11-bit) RACH according to 3GPP TS 45.003
1947 * \param[out] ra output buffer for RACH data
1948 * \param[in] burst Input burst data
1949 * \param[in] bsic BSIC used in this cell
1950 * \param[out] n_errors Number of detected bit errors
1951 * \param[out] n_bits_total Total number of bits
1952 * \returns 0 on success; negative on error (e.g. CRC error) */
1953int gsm0503_rach_ext_decode_ber(uint16_t *ra, const sbit_t *burst, uint8_t bsic,
1954 int *n_errors, int *n_bits_total)
1955{
1956 int16_t r = rach_decode_ber(burst, bsic, true, n_errors, n_bits_total);
1957 if (r < 0)
1958 return r;
Piotr Krysik70c25a12017-01-03 08:01:23 +01001959
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001960 *ra = r;
1961 return 0;
1962}
Piotr Krysik70c25a12017-01-03 08:01:23 +01001963
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001964/*! Decode the (8-bit) RACH according to TS 05.03
1965 * \param[out] ra output buffer for RACH data
1966 * \param[in] burst Input burst data
1967 * \param[in] bsic BSIC used in this cell
1968 * \param[out] n_errors Number of detected bit errors
1969 * \param[out] n_bits_total Total number of bits
1970 * \returns 0 on success; negative on error (e.g. CRC error) */
1971int gsm0503_rach_decode_ber(uint8_t *ra, const sbit_t *burst, uint8_t bsic,
1972 int *n_errors, int *n_bits_total)
1973{
1974 int16_t r = rach_decode_ber(burst, bsic, false, n_errors, n_bits_total);
1975
1976 if (r < 0)
1977 return r;
1978
1979 *ra = r;
1980
1981 return 0;
1982}
1983
1984/*! Encode the (8-bit) RACH according to TS 05.03
1985 * \param[out] burst Caller-allocated output burst buffer
1986 * \param[in] ra Input RACH data
1987 * \param[in] bsic BSIC used in this cell
1988 * \returns 0 on success; negative on error */
1989int gsm0503_rach_encode(ubit_t *burst, const uint8_t *ra, uint8_t bsic)
1990{
1991 return gsm0503_rach_ext_encode(burst, *ra, bsic, false);
1992}
1993
1994/*! Encode the Extended (11-bit) or regular (8-bit) RACH according to 3GPP TS 45.003
1995 * \param[out] burst Caller-allocated output burst buffer
1996 * \param[in] ra11 Input RACH data
1997 * \param[in] bsic BSIC used in this cell
1998 * \param[in] is_11bit whether given RA is 11 bit or not
1999 * \returns 0 on success; negative on error */
2000int gsm0503_rach_ext_encode(ubit_t *burst, uint16_t ra11, uint8_t bsic, bool is_11bit)
2001{
2002 ubit_t conv[17];
2003 uint8_t ra[2] = { 0 }, nbits = 8;
2004
2005 if (is_11bit) {
2006 osmo_store16le(ra11, ra);
2007 nbits = 11;
2008 } else
2009 ra[0] = (uint8_t)ra11;
2010
2011 osmo_pbit2ubit_ext(conv, 0, ra, 0, nbits, 1);
2012
2013 osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, nbits, conv + nbits);
2014
2015 rach_apply_bsic(conv, bsic, nbits);
2016
2017 osmo_conv_encode(is_11bit ? &gsm0503_rach_ext : &gsm0503_rach, conv, burst);
Piotr Krysik70c25a12017-01-03 08:01:23 +01002018
2019 return 0;
2020}
2021
2022/*
2023 * GSM SCH transcoding
2024 */
Piotr Krysik9e2e8352018-02-27 12:16:25 +01002025
2026/*! Decode the SCH according to TS 05.03
2027 * \param[out] sb_info output buffer for SCH data
2028 * \param[in] burst Input burst data
2029 * \returns 0 on success; negative on error (e.g. CRC error) */
2030int gsm0503_sch_decode(uint8_t *sb_info, const sbit_t *burst)
Piotr Krysik70c25a12017-01-03 08:01:23 +01002031{
2032 ubit_t conv[35];
2033 int rv;
2034
2035 osmo_conv_decode(&gsm0503_sch, burst, conv);
2036
2037 rv = osmo_crc16gen_check_bits(&gsm0503_sch_crc10, conv, 25, conv + 25);
2038 if (rv)
2039 return -1;
2040
2041 osmo_ubit2pbit_ext(sb_info, 0, conv, 0, 25, 1);
2042
2043 return 0;
2044}
2045
Piotr Krysik9e2e8352018-02-27 12:16:25 +01002046/*! Encode the SCH according to TS 05.03
2047 * \param[out] burst Caller-allocated output burst buffer
2048 * \param[in] sb_info Input SCH data
2049 * \returns 0 on success; negative on error */
2050int gsm0503_sch_encode(ubit_t *burst, const uint8_t *sb_info)
Piotr Krysik70c25a12017-01-03 08:01:23 +01002051{
2052 ubit_t conv[35];
2053
2054 osmo_pbit2ubit_ext(conv, 0, sb_info, 0, 25, 1);
2055
2056 osmo_crc16gen_set_bits(&gsm0503_sch_crc10, conv, 25, conv + 25);
2057
2058 osmo_conv_encode(&gsm0503_sch, conv, burst);
2059
2060 return 0;
2061}
Piotr Krysik9e2e8352018-02-27 12:16:25 +01002062
2063/*! @} */