aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPiotr Krysik <ptrkrysik@gmail.com>2017-01-03 08:01:23 +0100
committerPiotr Krysik <ptrkrysik@gmail.com>2017-01-03 08:01:23 +0100
commit70c25a112a3a8637dccafb278ca27a96ba950117 (patch)
tree087a08f8fcd582fa4950325ebf8823ea33652f65 /lib
parent25ae3e2066e589f7faf2ddf9b1811697583233ac (diff)
Changes in decoding:
-copied decoding routines from libosmocore to gr-gsm, -made cmake files entries for new source files and added linking with libosmocodec, -moved sch.c file to decoding folder.
Diffstat (limited to 'lib')
-rw-r--r--lib/CMakeLists.txt11
-rw-r--r--lib/decoding/control_channels_decoder_impl.h2
-rw-r--r--lib/decoding/osmocom/coding/gsm0503.h183
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_coding.c1753
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_coding.h46
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_conv.c1919
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_interleaving.c573
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_interleaving.h51
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_mapping.c291
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_mapping.h33
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_parity.c132
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_parity.h13
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_tables.c1732
-rw-r--r--lib/decoding/osmocom/coding/gsm0503_tables.h50
-rw-r--r--lib/decoding/sch.c (renamed from lib/receiver/sch.c)2
-rw-r--r--lib/decoding/tch_f_decoder_impl.cc2
16 files changed, 6788 insertions, 5 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 4c18c18..4b4a993 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -28,7 +28,7 @@ list(APPEND grgsm_sources
receiver/receiver_impl.cc
receiver/receiver_config.cc
receiver/viterbi_detector.cc
- receiver/sch.c
+ decoding/sch.c
receiver/clock_offset_control_impl.cc
receiver/cx_channel_hopper_impl.cc
demapping/universal_ctrl_chans_demapper_impl.cc
@@ -41,6 +41,12 @@ list(APPEND grgsm_sources
decoding/GSM660Tables.cpp
decoding/GSM503Tables.cpp
decoding/ViterbiR204.cpp
+ decoding/osmocom/coding/gsm0503_conv.c
+ decoding/osmocom/coding/gsm0503_coding.c
+ decoding/osmocom/coding/gsm0503_interleaving.c
+ decoding/osmocom/coding/gsm0503_mapping.c
+ decoding/osmocom/coding/gsm0503_parity.c
+ decoding/osmocom/coding/gsm0503_tables.c
flow_control/burst_timeslot_splitter_impl.cc
flow_control/burst_sdcch_subslot_splitter_impl.cc
flow_control/burst_timeslot_filter_impl.cc
@@ -69,7 +75,8 @@ list(APPEND grgsm_sources
add_library(grgsm SHARED ${grgsm_sources})
-target_link_libraries(grgsm ${Boost_LIBRARIES} ${GNURADIO_ALL_LIBRARIES} ${VOLK_LIBRARIES} ${LIBOSMOCORE_LIBRARIES} ${LIBOSMOCODING_LIBRARIES}
+target_link_libraries(grgsm ${Boost_LIBRARIES} ${GNURADIO_ALL_LIBRARIES} ${VOLK_LIBRARIES} ${LIBOSMOCODEC_LIBRARIES} ${LIBOSMOCORE_LIBRARIES}
+# ${LIBOSMOCODING_LIBRARIES}
# libraries required by plotting.h - have troubles to be installed by pybombs
# boost_iostreams
# boost_system
diff --git a/lib/decoding/control_channels_decoder_impl.h b/lib/decoding/control_channels_decoder_impl.h
index f2261a2..1117940 100644
--- a/lib/decoding/control_channels_decoder_impl.h
+++ b/lib/decoding/control_channels_decoder_impl.h
@@ -25,7 +25,7 @@
#include <grgsm/decoding/control_channels_decoder.h>
extern "C" {
- #include <osmocom/coding/gsm0503_coding.h>
+ #include "osmocom/coding/gsm0503_coding.h"
}
namespace gr {
diff --git a/lib/decoding/osmocom/coding/gsm0503.h b/lib/decoding/osmocom/coding/gsm0503.h
new file mode 100644
index 0000000..e1c62a6
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503.h
@@ -0,0 +1,183 @@
+/*
+ * gsm0503.h
+ *
+ * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <stdint.h>
+
+#include <osmocom/core/conv.h>
+
+/*! \file gsm0503.h
+ * Osmocom convolutional encoder/decoder for xCCH channels, see 3GPP TS 05.03
+ */
+
+/*! \brief structure describing convolutional code xCCH
+ *
+ * Non-recursive code, flushed, not punctured code.
+ */
+extern const struct osmo_conv_code gsm0503_xcch;
+
+/*! \brief structure describing convolutional code RACH
+ */
+extern const struct osmo_conv_code gsm0503_rach;
+
+/*! \brief structure describing convolutional code SCH
+ */
+extern const struct osmo_conv_code gsm0503_sch;
+
+/*! \brief structures describing convolutional codes CS2/3
+ */
+extern const struct osmo_conv_code gsm0503_cs2;
+extern const struct osmo_conv_code gsm0503_cs3;
+
+/*! \brief structure describing convolutional code TCH/FR
+ */
+extern const struct osmo_conv_code gsm0503_tch_fr;
+
+/*! \brief structure describing convolutional code TCH/HR
+ */
+extern const struct osmo_conv_code gsm0503_tch_hr;
+
+/*! \brief structure describing convolutional code TCH/AFS 12.2
+ */
+extern const struct osmo_conv_code gsm0503_tch_afs_12_2;
+
+/*! \brief structure describing convolutional code TCH/AFS 10.2
+ */
+extern const struct osmo_conv_code gsm0503_tch_afs_10_2;
+
+/*! \brief structure describing convolutional code TCH/AFS 7.95
+ */
+extern const struct osmo_conv_code gsm0503_tch_afs_7_95;
+
+/*! \brief structure describing convolutional code TCH/AFS 7.4
+ */
+extern const struct osmo_conv_code gsm0503_tch_afs_7_4;
+
+/*! \brief structure describing convolutional code TCH/AFS 6.7
+ */
+extern const struct osmo_conv_code gsm0503_tch_afs_6_7;
+
+/*! \brief structure describing convolutional code TCH/AFS 5.9
+ */
+extern const struct osmo_conv_code gsm0503_tch_afs_5_9;
+
+/*! \brief structure describing convolutional code TCH/AFS 5.15
+ */
+extern const struct osmo_conv_code gsm0503_tch_afs_5_15;
+
+/*! \brief structure describing convolutional code TCH/AFS 4.75
+ */
+extern const struct osmo_conv_code gsm0503_tch_afs_4_75;
+
+/*! \brief structure describing convolutional code TCH/AHS 7.95
+ */
+extern const struct osmo_conv_code gsm0503_tch_ahs_7_95;
+
+/*! \brief structure describing convolutional code TCH/AHS 7.4
+ */
+extern const struct osmo_conv_code gsm0503_tch_ahs_7_4;
+
+/*! \brief structure describing convolutional code TCH/AHS 6.7
+ */
+extern const struct osmo_conv_code gsm0503_tch_ahs_6_7;
+
+/*! \brief structure describing convolutional code TCH/AHS 5.9
+ */
+extern const struct osmo_conv_code gsm0503_tch_ahs_5_9;
+
+/*! \brief structure describing convolutional code TCH/AHS 5.15
+ */
+extern const struct osmo_conv_code gsm0503_tch_ahs_5_15;
+
+/*! \brief structure describing convolutional code TCH/AHS 4.75
+ */
+extern const struct osmo_conv_code gsm0503_tch_ahs_4_75;
+
+/*! \brief structure describing convolutional code EDGE MCS-1 DL HDR
+ */
+extern const struct osmo_conv_code gsm0503_mcs1_dl_hdr;
+
+/*! \brief structure describing convolutional code EDGE MCS-1 UL HDR
+ */
+extern const struct osmo_conv_code gsm0503_mcs1_ul_hdr;
+
+/*! \brief structure describing convolutional code EDGE MCS-1
+ */
+extern const struct osmo_conv_code gsm0503_mcs1;
+
+/*! \brief structure describing convolutional code EDGE MCS-2
+ */
+extern const struct osmo_conv_code gsm0503_mcs2;
+
+/*! \brief structure describing convolutional code EDGE MCS-3
+ */
+extern const struct osmo_conv_code gsm0503_mcs3;
+
+/*! \brief structure describing convolutional code EDGE MCS-4
+ */
+extern const struct osmo_conv_code gsm0503_mcs4;
+
+/*! \brief structure describing convolutional code EDGE MCS-5 DL HDR
+ */
+extern const struct osmo_conv_code gsm0503_mcs5_dl_hdr;
+
+/*! \brief structure describing convolutional code EDGE MCS-5 UL HDR
+ */
+extern const struct osmo_conv_code gsm0503_mcs5_ul_hdr;
+
+/*! \brief structure describing convolutional code EDGE MCS-5
+ */
+extern const struct osmo_conv_code gsm0503_mcs5;
+
+/*! \brief structure describing convolutional code EDGE MCS-6
+ */
+extern const struct osmo_conv_code gsm0503_mcs6;
+
+/*! \brief structure describing convolutional code EDGE MCS-7 DL HDR
+ */
+extern const struct osmo_conv_code gsm0503_mcs7_dl_hdr;
+
+/*! \brief structure describing convolutional code EDGE MCS-7 UL HDR
+ */
+extern const struct osmo_conv_code gsm0503_mcs7_ul_hdr;
+
+/*! \brief structure describing convolutional code EDGE MCS-7
+ */
+extern const struct osmo_conv_code gsm0503_mcs7;
+
+/*! \brief structure describing convolutional code EDGE MCS-8
+ */
+extern const struct osmo_conv_code gsm0503_mcs8;
+
+/*! \brief structure describing convolutional code EDGE MCS-9
+ */
+extern const struct osmo_conv_code gsm0503_mcs9;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/lib/decoding/osmocom/coding/gsm0503_coding.c b/lib/decoding/osmocom/coding/gsm0503_coding.c
new file mode 100644
index 0000000..afbba88
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_coding.c
@@ -0,0 +1,1753 @@
+/*
+ * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
+ * (C) 2015 by Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
+ * (C) 2016 by Tom Tsou <tom.tsou@ettus.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/conv.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/crcgen.h>
+#include <osmocom/core/endian.h>
+
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include "gsm0503.h"
+#include <osmocom/codec/codec.h>
+
+#include "gsm0503_interleaving.h"
+#include "gsm0503_mapping.h"
+#include "gsm0503_tables.h"
+#include "gsm0503_coding.h"
+#include "gsm0503_parity.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*
+ * EGPRS coding limits
+ */
+
+/* Max header size with parity bits */
+#define EGPRS_HDR_UPP_MAX 54
+
+/* Max encoded header size */
+#define EGPRS_HDR_C_MAX 162
+
+/* Max punctured header size */
+#define EGPRS_HDR_HC_MAX 160
+
+/* Max data block size with parity bits */
+#define EGPRS_DATA_U_MAX 612
+
+/* Max encoded data block size */
+#define EGPRS_DATA_C_MAX 1836
+
+/* Max single block punctured data size */
+#define EGPRS_DATA_DC_MAX 1248
+
+/* Dual block punctured data size */
+#define EGPRS_DATA_C1 612
+#define EGPRS_DATA_C2 EGPRS_DATA_C1
+
+/* TS 101318 Chapter 5.1: 260 bits + 4bit sig */
+#define GSM_FR_BYTES 33
+/* TS 101318 Chapter 5.2: 112 bits, no sig */
+#define GSM_HR_BYTES 14
+/* TS 101318 Chapter 5.3: 244 bits + 4bit sig */
+#define GSM_EFR_BYTES 31
+
+struct gsm0503_mcs_code {
+ uint8_t mcs;
+ uint8_t usf_len;
+
+ /* Header coding */
+ uint8_t hdr_len;
+ uint8_t hdr_code_len;
+ uint8_t hdr_punc_len;
+ const struct osmo_conv_code *hdr_conv;
+ const uint8_t *hdr_punc;
+
+ /* Data coding */
+ uint16_t data_len;
+ uint16_t data_code_len;
+ uint16_t data_punc_len;
+ const struct osmo_conv_code *data_conv;
+ const uint8_t *data_punc[3];
+};
+
+static int osmo_conv_decode_ber(const struct osmo_conv_code *code,
+ const sbit_t *input, ubit_t *output,
+ int *n_errors, int *n_bits_total)
+{
+ int res, i, coded_len;
+ ubit_t recoded[EGPRS_DATA_C_MAX];
+
+ res = osmo_conv_decode(code, input, output);
+
+ if (n_bits_total || n_errors) {
+ coded_len = osmo_conv_encode(code, output, recoded);
+ OSMO_ASSERT(sizeof(recoded) / sizeof(recoded[0]) >= coded_len);
+ }
+
+ /* Count bit errors */
+ if (n_errors) {
+ *n_errors = 0;
+ for (i = 0; i < coded_len; i++) {
+ if (!((recoded[i] && input[i] < 0) ||
+ (!recoded[i] && input[i] > 0)) )
+ *n_errors += 1;
+ }
+ }
+
+ if (n_bits_total)
+ *n_bits_total = coded_len;
+
+ return res;
+}
+
+static int _xcch_decode_cB(uint8_t *l2_data, sbit_t *cB,
+ int *n_errors, int *n_bits_total)
+{
+ ubit_t conv[224];
+ int rv;
+
+ osmo_conv_decode_ber(&gsm0503_xcch, cB,
+ conv, n_errors, n_bits_total);
+
+ rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40,
+ conv, 184, conv + 184);
+ if (rv)
+ return -1;
+
+ osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1);
+
+ return 0;
+}
+
+static int _xcch_encode_cB(ubit_t *cB, uint8_t *l2_data)
+{
+ ubit_t conv[224];
+
+ osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1);
+
+ osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184);
+
+ osmo_conv_encode(&gsm0503_xcch, conv, cB);
+
+ return 0;
+}
+
+/*
+ * GSM xCCH block transcoding
+ */
+int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts,
+ int *n_errors, int *n_bits_total)
+{
+ sbit_t iB[456], cB[456];
+ int i;
+
+ for (i = 0; i < 4; i++)
+ gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116], NULL, NULL);
+
+ gsm0503_xcch_deinterleave(cB, iB);
+
+ return _xcch_decode_cB(l2_data, cB, n_errors, n_bits_total);
+}
+
+int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data)
+{
+ ubit_t iB[456], cB[456], hl = 1, hn = 1;
+ int i;
+
+ _xcch_encode_cB(cB, l2_data);
+
+ gsm0503_xcch_interleave(cB, iB);
+
+ for (i = 0; i < 4; i++)
+ gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], &hl, &hn);
+
+ return 0;
+}
+
+
+
+/*
+ * GSM PDTCH block transcoding
+ */
+
+int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p,
+ int *n_errors, int *n_bits_total)
+{
+ sbit_t iB[456], cB[676], hl_hn[8];
+ ubit_t conv[456];
+ int i, j, k, rv, best = 0, cs = 0, usf = 0; /* make GCC happy */
+
+ for (i = 0; i < 4; i++)
+ gsm0503_xcch_burst_unmap(&iB[i * 114], &bursts[i * 116],
+ hl_hn + i * 2, hl_hn + i * 2 + 1);
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0, k = 0; j < 8; j++)
+ k += abs(((int)gsm0503_pdtch_hl_hn_sbit[i][j]) - ((int)hl_hn[j]));
+
+ if (i == 0 || k < best) {
+ best = k;
+ cs = i+1;
+ }
+ }
+
+ gsm0503_xcch_deinterleave(cB, iB);
+
+ switch (cs) {
+ case 1:
+ osmo_conv_decode_ber(&gsm0503_xcch, cB,
+ conv, n_errors, n_bits_total);
+
+ rv = osmo_crc64gen_check_bits(&gsm0503_fire_crc40,
+ conv, 184, conv + 184);
+ if (rv)
+ return -1;
+
+ osmo_ubit2pbit_ext(l2_data, 0, conv, 0, 184, 1);
+
+ return 23;
+ case 2:
+ for (i = 587, j = 455; i >= 0; i--) {
+ if (!gsm0503_puncture_cs2[i])
+ cB[i] = cB[j--];
+ else
+ cB[i] = 0;
+ }
+
+ osmo_conv_decode_ber(&gsm0503_cs2, cB,
+ conv, n_errors, n_bits_total);
+
+ for (i = 0; i < 8; i++) {
+ for (j = 0, k = 0; j < 6; j++)
+ k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j]));
+
+ if (i == 0 || k < best) {
+ best = k;
+ usf = i;
+ }
+ }
+
+ conv[3] = usf & 1;
+ conv[4] = (usf >> 1) & 1;
+ conv[5] = (usf >> 2) & 1;
+ if (usf_p)
+ *usf_p = usf;
+
+ rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16,
+ conv + 3, 271, conv + 3 + 271);
+ if (rv)
+ return -1;
+
+ osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 271, 1);
+
+ return 34;
+ case 3:
+ for (i = 675, j = 455; i >= 0; i--) {
+ if (!gsm0503_puncture_cs3[i])
+ cB[i] = cB[j--];
+ else
+ cB[i] = 0;
+ }
+
+ osmo_conv_decode_ber(&gsm0503_cs3, cB,
+ conv, n_errors, n_bits_total);
+
+ for (i = 0; i < 8; i++) {
+ for (j = 0, k = 0; j < 6; j++)
+ k += abs(((int)gsm0503_usf2six[i][j]) - ((int)conv[j]));
+
+ if (i == 0 || k < best) {
+ best = k;
+ usf = i;
+ }
+ }
+
+ conv[3] = usf & 1;
+ conv[4] = (usf >> 1) & 1;
+ conv[5] = (usf >> 2) & 1;
+ if (usf_p)
+ *usf_p = usf;
+
+ rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16,
+ conv + 3, 315, conv + 3 + 315);
+ if (rv)
+ return -1;
+
+ osmo_ubit2pbit_ext(l2_data, 0, conv, 3, 315, 1);
+
+ return 40;
+ case 4:
+ for (i = 12; i < 456; i++)
+ conv[i] = (cB[i] < 0) ? 1 : 0;
+
+ for (i = 0; i < 8; i++) {
+ for (j = 0, k = 0; j < 12; j++)
+ k += abs(((int)gsm0503_usf2twelve_sbit[i][j]) - ((int)cB[j]));
+
+ if (i == 0 || k < best) {
+ best = k;
+ usf = i;
+ }
+ }
+
+ conv[9] = usf & 1;
+ conv[10] = (usf >> 1) & 1;
+ conv[11] = (usf >> 2) & 1;
+ if (usf_p)
+ *usf_p = usf;
+
+ rv = osmo_crc16gen_check_bits(&gsm0503_cs234_crc16,
+ conv + 9, 431, conv + 9 + 431);
+ if (rv) {
+ *n_bits_total = 456 - 12;
+ *n_errors = *n_bits_total;
+ return -1;
+ }
+
+ *n_bits_total = 456 - 12;
+ *n_errors = 0;
+
+ osmo_ubit2pbit_ext(l2_data, 0, conv, 9, 431, 1);
+
+ return 54;
+ default:
+ *n_bits_total = 0;
+ *n_errors = 0;
+ break;
+ }
+
+ return -1;
+}
+
+int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len)
+{
+ ubit_t iB[456], cB[676];
+ const ubit_t *hl_hn;
+ ubit_t conv[334];
+ int i, j, usf;
+
+ switch (l2_len) {
+ case 23:
+ osmo_pbit2ubit_ext(conv, 0, l2_data, 0, 184, 1);
+
+ osmo_crc64gen_set_bits(&gsm0503_fire_crc40, conv, 184, conv + 184);
+
+ osmo_conv_encode(&gsm0503_xcch, conv, cB);
+
+ hl_hn = gsm0503_pdtch_hl_hn_ubit[0];
+
+ break;
+ case 34:
+ osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 271, 1);
+ usf = l2_data[0] & 0x7;
+
+ osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3,
+ 271, conv + 3 + 271);
+
+ memcpy(conv, gsm0503_usf2six[usf], 6);
+
+ osmo_conv_encode(&gsm0503_cs2, conv, cB);
+
+ for (i = 0, j = 0; i < 588; i++)
+ if (!gsm0503_puncture_cs2[i])
+ cB[j++] = cB[i];
+
+ hl_hn = gsm0503_pdtch_hl_hn_ubit[1];
+
+ break;
+ case 40:
+ osmo_pbit2ubit_ext(conv, 3, l2_data, 0, 315, 1);
+ usf = l2_data[0] & 0x7;
+
+ osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, conv + 3,
+ 315, conv + 3 + 315);
+
+ memcpy(conv, gsm0503_usf2six[usf], 6);
+
+ osmo_conv_encode(&gsm0503_cs3, conv, cB);
+
+ for (i = 0, j = 0; i < 676; i++)
+ if (!gsm0503_puncture_cs3[i])
+ cB[j++] = cB[i];
+
+ hl_hn = gsm0503_pdtch_hl_hn_ubit[2];
+
+ break;
+ case 54:
+ osmo_pbit2ubit_ext(cB, 9, l2_data, 0, 431, 1);
+ usf = l2_data[0] & 0x7;
+
+ osmo_crc16gen_set_bits(&gsm0503_cs234_crc16, cB + 9,
+ 431, cB + 9 + 431);
+
+ memcpy(cB, gsm0503_usf2twelve_ubit[usf], 12);
+
+ hl_hn = gsm0503_pdtch_hl_hn_ubit[3];
+
+ break;
+ default:
+ return -1;
+ }
+
+ gsm0503_xcch_interleave(cB, iB);
+
+ for (i = 0; i < 4; i++) {
+ gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116],
+ hl_hn + i * 2, hl_hn + i * 2 + 1);
+ }
+
+ return GSM0503_GPRS_BURSTS_NBITS;
+}
+
+/*
+ * GSM TCH/F FR/EFR transcoding
+ */
+
+static void tch_fr_reassemble(uint8_t *tch_data,
+ ubit_t *b_bits, int net_order)
+{
+ int i, j, k, l, o;
+
+ tch_data[0] = 0xd << 4;
+ memset(tch_data + 1, 0, 32);
+
+ if (net_order) {
+ for (i = 0, j = 4; i < 260; i++, j++)
+ tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7)));
+
+ return;
+ }
+
+ /* reassemble d-bits */
+ i = 0; /* counts bits */
+ j = 4; /* counts output bits */
+ k = gsm0503_gsm_fr_map[0]-1; /* current number bit in element */
+ l = 0; /* counts element bits */
+ o = 0; /* offset input bits */
+ while (i < 260) {
+ tch_data[j >> 3] |= (b_bits[k + o] << (7 - (j & 7)));
+ if (--k < 0) {
+ o += gsm0503_gsm_fr_map[l];
+ k = gsm0503_gsm_fr_map[++l]-1;
+ }
+ i++;
+ j++;
+ }
+}
+
+static void tch_fr_disassemble(ubit_t *b_bits,
+ uint8_t *tch_data, int net_order)
+{
+ int i, j, k, l, o;
+
+ if (net_order) {
+ for (i = 0, j = 4; i < 260; i++, j++)
+ b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
+
+ return;
+ }
+
+ i = 0; /* counts bits */
+ j = 4; /* counts input bits */
+ k = gsm0503_gsm_fr_map[0] - 1; /* current number bit in element */
+ l = 0; /* counts element bits */
+ o = 0; /* offset output bits */
+ while (i < 260) {
+ b_bits[k + o] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
+ if (--k < 0) {
+ o += gsm0503_gsm_fr_map[l];
+ k = gsm0503_gsm_fr_map[++l] - 1;
+ }
+ i++;
+ j++;
+ }
+}
+
+static void tch_hr_reassemble(uint8_t *tch_data, ubit_t *b_bits)
+{
+ int i, j;
+
+ tch_data[0] = 0x00; /* F = 0, FT = 000 */
+ memset(tch_data + 1, 0, 14);
+
+ for (i = 0, j = 8; i < 112; i++, j++)
+ tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7)));
+}
+
+static void tch_hr_disassemble(ubit_t *b_bits, uint8_t *tch_data)
+{
+ int i, j;
+
+ for (i = 0, j = 8; i < 112; i++, j++)
+ b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
+}
+
+static void tch_efr_reassemble(uint8_t *tch_data, ubit_t *b_bits)
+{
+ int i, j;
+
+ tch_data[0] = 0xc << 4;
+ memset(tch_data + 1, 0, 30);
+
+ for (i = 0, j = 4; i < 244; i++, j++)
+ tch_data[j >> 3] |= (b_bits[i] << (7 - (j & 7)));
+}
+
+static void tch_efr_disassemble(ubit_t *b_bits, uint8_t *tch_data)
+{
+ int i, j;
+
+ for (i = 0, j = 4; i < 244; i++, j++)
+ b_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
+}
+
+static void tch_amr_reassemble(uint8_t *tch_data, ubit_t *d_bits, int len)
+{
+ int i, j;
+
+ memset(tch_data, 0, (len + 7) >> 3);
+
+ for (i = 0, j = 0; i < len; i++, j++)
+ tch_data[j >> 3] |= (d_bits[i] << (7 - (j & 7)));
+}
+
+static void tch_amr_disassemble(ubit_t *d_bits, uint8_t *tch_data, int len)
+{
+ int i, j;
+
+ for (i = 0, j = 0; i < len; i++, j++)
+ d_bits[i] = (tch_data[j >> 3] >> (7 - (j & 7))) & 1;
+}
+
+static void tch_fr_d_to_b(ubit_t *b_bits, ubit_t *d_bits)
+{
+ int i;
+
+ for (i = 0; i < 260; i++)
+ b_bits[gsm610_bitorder[i]] = d_bits[i];
+}
+
+static void tch_fr_b_to_d(ubit_t *d_bits, ubit_t *b_bits)
+{
+ int i;
+
+ for (i = 0; i < 260; i++)
+ d_bits[i] = b_bits[gsm610_bitorder[i]];
+}
+
+static void tch_hr_d_to_b(ubit_t *b_bits, ubit_t *d_bits)
+{
+ int i;
+
+ const uint16_t *map;
+
+ if (!d_bits[93] && !d_bits[94])
+ map = gsm620_unvoiced_bitorder;
+ else
+ map = gsm620_voiced_bitorder;
+
+ for (i = 0; i < 112; i++)
+ b_bits[map[i]] = d_bits[i];
+}
+
+static void tch_hr_b_to_d(ubit_t *d_bits, ubit_t *b_bits)
+{
+ int i;
+ const uint16_t *map;
+
+ if (!b_bits[34] && !b_bits[35])
+ map = gsm620_unvoiced_bitorder;
+ else
+ map = gsm620_voiced_bitorder;
+
+ for (i = 0; i < 112; i++)
+ d_bits[i] = b_bits[map[i]];
+}
+
+static void tch_efr_d_to_w(ubit_t *b_bits, ubit_t *d_bits)
+{
+ int i;
+
+ for (i = 0; i < 260; i++)
+ b_bits[gsm660_bitorder[i]] = d_bits[i];
+}
+
+static void tch_efr_w_to_d(ubit_t *d_bits, ubit_t *b_bits)
+{
+ int i;
+
+ for (i = 0; i < 260; i++)
+ d_bits[i] = b_bits[gsm660_bitorder[i]];
+}
+
+static void tch_efr_protected(ubit_t *s_bits, ubit_t *b_bits)
+{
+ int i;
+
+ for (i = 0; i < 65; i++)
+ b_bits[i] = s_bits[gsm0503_gsm_efr_protected_bits[i] - 1];
+}
+
+static void tch_fr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u)
+{
+ int i;
+
+ for (i = 0; i < 91; i++) {
+ d[i << 1] = u[i];
+ d[(i << 1) + 1] = u[184 - i];
+ }
+
+ for (i = 0; i < 3; i++)
+ p[i] = u[91 + i];
+}
+
+static void tch_fr_reorder(ubit_t *u, ubit_t *d, ubit_t *p)
+{
+ int i;
+
+ for (i = 0; i < 91; i++) {
+ u[i] = d[i << 1];
+ u[184 - i] = d[(i << 1) + 1];
+ }
+
+ for (i = 0; i < 3; i++)
+ u[91 + i] = p[i];
+}
+
+static void tch_hr_unreorder(ubit_t *d, ubit_t *p, ubit_t *u)
+{
+ memcpy(d, u, 95);
+ memcpy(p, u + 95, 3);
+}
+
+static void tch_hr_reorder(ubit_t *u, ubit_t *d, ubit_t *p)
+{
+ memcpy(u, d, 95);
+ memcpy(u + 95, p, 3);
+}
+
+static void tch_efr_reorder(ubit_t *w, ubit_t *s, ubit_t *p)
+{
+ memcpy(w, s, 71);
+ w[71] = w[72] = s[69];
+ memcpy(w + 73, s + 71, 50);
+ w[123] = w[124] = s[119];
+ memcpy(w + 125, s + 121, 53);
+ w[178] = w[179] = s[172];
+ memcpy(w + 180, s + 174, 50);
+ w[230] = w[231] = s[222];
+ memcpy(w + 232, s + 224, 20);
+ memcpy(w + 252, p, 8);
+}
+
+static void tch_efr_unreorder(ubit_t *s, ubit_t *p, ubit_t *w)
+{
+ int sum;
+
+ memcpy(s, w, 71);
+ sum = s[69] + w[71] + w[72];
+ s[69] = (sum > 2);
+ memcpy(s + 71, w + 73, 50);
+ sum = s[119] + w[123] + w[124];
+ s[119] = (sum > 2);
+ memcpy(s + 121, w + 125, 53);
+ sum = s[172] + w[178] + w[179];
+ s[172] = (sum > 2);
+ memcpy(s + 174, w + 180, 50);
+ sum = s[220] + w[230] + w[231];
+ s[222] = (sum > 2);
+ memcpy(s + 224, w + 232, 20);
+ memcpy(p, w + 252, 8);
+}
+
+static void tch_amr_merge(ubit_t *u, ubit_t *d, ubit_t *p, int len, int prot)
+{
+ memcpy(u, d, prot);
+ memcpy(u + prot, p, 6);
+ memcpy(u + prot + 6, d + prot, len - prot);
+}
+
+static void tch_amr_unmerge(ubit_t *d, ubit_t *p,
+ ubit_t *u, int len, int prot)
+{
+ memcpy(d, u, prot);
+ memcpy(p, u+prot, 6);
+ memcpy(d + prot, u + prot + 6, len - prot);
+}
+
+int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts,
+ int net_order, int efr, int *n_errors, int *n_bits_total)
+{
+ sbit_t iB[912], cB[456], h;
+ ubit_t conv[185], s[244], w[260], b[65], d[260], p[8];
+ int i, rv, len, steal = 0;
+
+ for (i=0; i<8; i++) {
+ gsm0503_tch_burst_unmap(&iB[i * 114],
+ &bursts[i * 116], &h, i >> 2);
+ steal -= h;
+ }
+
+ gsm0503_tch_fr_deinterleave(cB, iB);
+
+ if (steal > 0) {
+ rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
+ if (rv) {
+ /* Error decoding FACCH frame */
+ return -1;
+ }
+
+ return 23;
+ }
+
+ osmo_conv_decode_ber(&gsm0503_tch_fr, cB, conv, n_errors, n_bits_total);
+
+ tch_fr_unreorder(d, p, conv);
+
+ for (i = 0; i < 78; i++)
+ d[i + 182] = (cB[i + 378] < 0) ? 1 : 0;
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d, 50, p);
+ if (rv) {
+ /* Error checking CRC8 for the FR part of an EFR/FR frame */
+ return -1;
+ }
+
+ if (efr) {
+ tch_efr_d_to_w(w, d);
+
+ tch_efr_unreorder(s, p, w);
+
+ tch_efr_protected(s, b);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_tch_efr_crc8, b, 65, p);
+ if (rv) {
+ /* Error checking CRC8 for the EFR part of an EFR frame */
+ return -1;
+ }
+
+ tch_efr_reassemble(tch_data, s);
+
+ len = GSM_EFR_BYTES;
+ } else {
+ tch_fr_d_to_b(w, d);
+
+ tch_fr_reassemble(tch_data, w, net_order);
+
+ len = GSM_FR_BYTES;
+ }
+
+ return len;
+}
+
+int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data,
+ int len, int net_order)
+{
+ ubit_t iB[912], cB[456], h;
+ ubit_t conv[185], w[260], b[65], s[244], d[260], p[8];
+ int i;
+
+ switch (len) {
+ case GSM_EFR_BYTES: /* TCH EFR */
+
+ tch_efr_disassemble(s, tch_data);
+
+ tch_efr_protected(s, b);
+
+ osmo_crc8gen_set_bits(&gsm0503_tch_efr_crc8, b, 65, p);
+
+ tch_efr_reorder(w, s, p);
+
+ tch_efr_w_to_d(d, w);
+
+ goto coding_efr_fr;
+ case GSM_FR_BYTES: /* TCH FR */
+ tch_fr_disassemble(w, tch_data, net_order);
+
+ tch_fr_b_to_d(d, w);
+
+coding_efr_fr:
+ osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d, 50, p);
+
+ tch_fr_reorder(conv, d, p);
+
+ memcpy(cB + 378, d + 182, 78);
+
+ osmo_conv_encode(&gsm0503_tch_fr, conv, cB);
+
+ h = 0;
+
+ break;
+ case GSM_MACBLOCK_LEN: /* FACCH */
+ _xcch_encode_cB(cB, tch_data);
+
+ h = 1;
+
+ break;
+ default:
+ return -1;
+ }
+
+ gsm0503_tch_fr_interleave(cB, iB);
+
+ for (i = 0; i < 8; i++) {
+ gsm0503_tch_burst_map(&iB[i * 114],
+ &bursts[i * 116], &h, i >> 2);
+ }
+
+ return 0;
+}
+
+int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd,
+ int *n_errors, int *n_bits_total)
+{
+ sbit_t iB[912], cB[456], h;
+ ubit_t conv[98], b[112], d[112], p[3];
+ int i, rv, steal = 0;
+
+ /* Only unmap the stealing bits */
+ if (!odd) {
+ for (i = 0; i < 4; i++) {
+ gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0);
+ steal -= h;
+ }
+
+ for (i = 2; i < 5; i++) {
+ gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1);
+ steal -= h;
+ }
+ }
+
+ /* If we found a stole FACCH, but only at correct alignment */
+ if (steal > 0) {
+ for (i = 0; i < 6; i++) {
+ gsm0503_tch_burst_unmap(&iB[i * 114],
+ &bursts[i * 116], NULL, i >> 2);
+ }
+
+ for (i = 2; i < 4; i++) {
+ gsm0503_tch_burst_unmap(&iB[i * 114 + 456],
+ &bursts[i * 116], NULL, 1);
+ }
+
+ gsm0503_tch_fr_deinterleave(cB, iB);
+
+ rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
+ if (rv) {
+ /* Error decoding FACCH frame */
+ return -1;
+ }
+
+ return GSM_MACBLOCK_LEN;
+ }
+
+ for (i = 0; i < 4; i++) {
+ gsm0503_tch_burst_unmap(&iB[i * 114],
+ &bursts[i * 116], NULL, i >> 1);
+ }
+
+ gsm0503_tch_hr_deinterleave(cB, iB);
+
+ osmo_conv_decode_ber(&gsm0503_tch_hr, cB, conv, n_errors, n_bits_total);
+
+ tch_hr_unreorder(d, p, conv);
+
+ for (i = 0; i < 17; i++)
+ d[i + 95] = (cB[i + 211] < 0) ? 1 : 0;
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p);
+ if (rv) {
+ /* Error checking CRC8 for an HR frame */
+ return -1;
+ }
+
+ tch_hr_d_to_b(b, d);
+
+ tch_hr_reassemble(tch_data, b);
+
+ return 15;
+}
+
+int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len)
+{
+ ubit_t iB[912], cB[456], h;
+ ubit_t conv[98], b[112], d[112], p[3];
+ int i;
+
+ switch (len) {
+ case 15: /* TCH HR */
+ tch_hr_disassemble(b, tch_data);
+
+ tch_hr_b_to_d(d, b);
+
+ osmo_crc8gen_set_bits(&gsm0503_tch_fr_crc3, d + 73, 22, p);
+
+ tch_hr_reorder(conv, d, p);
+
+ osmo_conv_encode(&gsm0503_tch_hr, conv, cB);
+
+ memcpy(cB + 211, d + 95, 17);
+
+ h = 0;
+
+ gsm0503_tch_hr_interleave(cB, iB);
+
+ for (i = 0; i < 4; i++) {
+ gsm0503_tch_burst_map(&iB[i * 114],
+ &bursts[i * 116], &h, i >> 1);
+ }
+
+ break;
+ case GSM_MACBLOCK_LEN: /* FACCH */
+ _xcch_encode_cB(cB, tch_data);
+
+ h = 1;
+
+ gsm0503_tch_fr_interleave(cB, iB);
+
+ for (i=0; i<6; i++) {
+ gsm0503_tch_burst_map(&iB[i * 114],
+ &bursts[i * 116], &h, i >> 2);
+ }
+
+ for (i=2; i<4; i++) {
+ gsm0503_tch_burst_map(&iB[i * 114 + 456],
+ &bursts[i * 116], &h, 1);
+ }
+
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts,
+ int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+ uint8_t *cmr, int *n_errors, int *n_bits_total)
+{
+ sbit_t iB[912], cB[456], h;
+ ubit_t d[244], p[6], conv[250];
+ int i, j, k, best = 0, rv, len, steal = 0, id = 0;
+ *n_errors = 0; *n_bits_total = 0;
+
+ for (i=0; i<8; i++) {
+ gsm0503_tch_burst_unmap(&iB[i * 114], &bursts[i * 116], &h, i >> 2);
+ steal -= h;
+ }
+
+ gsm0503_tch_fr_deinterleave(cB, iB);
+
+ if (steal > 0) {
+ rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
+ if (rv) {
+ /* Error decoding FACCH frame */
+ return -1;
+ }
+
+ return GSM_MACBLOCK_LEN;
+ }
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0, k = 0; j < 8; j++)
+ k += abs(((int)gsm0503_afs_ic_sbit[i][j]) - ((int)cB[j]));
+
+ if (i == 0 || k < best) {
+ best = k;
+ id = i;
+ }
+ }
+
+ /* Check if indicated codec fits into range of codecs */
+ if (id >= codecs) {
+ /* Codec mode out of range, return id */
+ return id;
+ }
+
+ switch ((codec_mode_req) ? codec[*ft] : codec[id]) {
+ case 7: /* TCH/AFS12.2 */
+ osmo_conv_decode_ber(&gsm0503_tch_afs_12_2, cB + 8,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 244, 81);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 81, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 12.2 frame */
+ return -1;
+ }
+
+ tch_amr_reassemble(tch_data, d, 244);
+
+ len = 31;
+
+ break;
+ case 6: /* TCH/AFS10.2 */
+ osmo_conv_decode_ber(&gsm0503_tch_afs_10_2, cB + 8,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 204, 65);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 65, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 10.2 frame */
+ return -1;
+ }
+
+ tch_amr_reassemble(tch_data, d, 204);
+
+ len = 26;
+
+ break;
+ case 5: /* TCH/AFS7.95 */
+ osmo_conv_decode_ber(&gsm0503_tch_afs_7_95, cB + 8,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 159, 75);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 75, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 7.95 frame */
+ return -1;
+ }
+
+ tch_amr_reassemble(tch_data, d, 159);
+
+ len = 20;
+
+ break;
+ case 4: /* TCH/AFS7.4 */
+ osmo_conv_decode_ber(&gsm0503_tch_afs_7_4, cB + 8,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 148, 61);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 7.4 frame */
+ return -1;
+ }
+
+ tch_amr_reassemble(tch_data, d, 148);
+
+ len = 19;
+
+ break;
+ case 3: /* TCH/AFS6.7 */
+ osmo_conv_decode_ber(&gsm0503_tch_afs_6_7, cB + 8,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 134, 55);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 6.7 frame */
+ return -1;
+ }
+
+ tch_amr_reassemble(tch_data, d, 134);
+
+ len = 17;
+
+ break;
+ case 2: /* TCH/AFS5.9 */
+ osmo_conv_decode_ber(&gsm0503_tch_afs_5_9, cB + 8,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 118, 55);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 5.9 frame */
+ return -1;
+ }
+
+ tch_amr_reassemble(tch_data, d, 118);
+
+ len = 15;
+
+ break;
+ case 1: /* TCH/AFS5.15 */
+ osmo_conv_decode_ber(&gsm0503_tch_afs_5_15, cB + 8,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 103, 49);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 5.15 frame */
+ return -1;
+ }
+
+ tch_amr_reassemble(tch_data, d, 103);
+
+ len = 13;
+
+ break;
+ case 0: /* TCH/AFS4.75 */
+ osmo_conv_decode_ber(&gsm0503_tch_afs_4_75, cB + 8,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 95, 39);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 4.75 frame */
+ return -1;
+ }
+
+ tch_amr_reassemble(tch_data, d, 95);
+
+ len = 12;
+
+ break;
+ default:
+ /* Unknown frame type */
+ *n_bits_total = 448;
+ *n_errors = *n_bits_total;
+ return -1;
+ }
+
+ /* Change codec request / indication, if frame is valid */
+ if (codec_mode_req)
+ *cmr = id;
+ else
+ *ft = id;
+
+ return len;
+}
+
+int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len,
+ int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft,
+ uint8_t cmr)
+{
+ ubit_t iB[912], cB[456], h;
+ ubit_t d[244], p[6], conv[250];
+ int i;
+ uint8_t id;
+
+ if (len == GSM_MACBLOCK_LEN) { /* FACCH */
+ _xcch_encode_cB(cB, tch_data);
+
+ h = 1;
+
+ goto facch;
+ }
+
+ h = 0;
+
+ if (codec_mode_req) {
+ if (cmr >= codecs) {
+ /* FIXME: CMR ID is not in codec list! */
+ return -1;
+ }
+ id = cmr;
+ } else {
+ if (ft >= codecs) {
+ /* FIXME: FT ID is not in codec list! */
+ return -1;
+ }
+ id = ft;
+ }
+
+ switch (codec[ft]) {
+ case 7: /* TCH/AFS12.2 */
+ if (len != 31)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 244);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 81, p);
+
+ tch_amr_merge(conv, d, p, 244, 81);
+
+ osmo_conv_encode(&gsm0503_tch_afs_12_2, conv, cB + 8);
+
+ break;
+ case 6: /* TCH/AFS10.2 */
+ if (len != 26)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 204);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 65, p);
+
+ tch_amr_merge(conv, d, p, 204, 65);
+
+ osmo_conv_encode(&gsm0503_tch_afs_10_2, conv, cB + 8);
+
+ break;
+ case 5: /* TCH/AFS7.95 */
+ if (len != 20)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 159);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 75, p);
+
+ tch_amr_merge(conv, d, p, 159, 75);
+
+ osmo_conv_encode(&gsm0503_tch_afs_7_95, conv, cB + 8);
+
+ break;
+ case 4: /* TCH/AFS7.4 */
+ if (len != 19)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 148);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p);
+
+ tch_amr_merge(conv, d, p, 148, 61);
+
+ osmo_conv_encode(&gsm0503_tch_afs_7_4, conv, cB + 8);
+
+ break;
+ case 3: /* TCH/AFS6.7 */
+ if (len != 17)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 134);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
+
+ tch_amr_merge(conv, d, p, 134, 55);
+
+ osmo_conv_encode(&gsm0503_tch_afs_6_7, conv, cB + 8);
+
+ break;
+ case 2: /* TCH/AFS5.9 */
+ if (len != 15)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 118);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
+
+ tch_amr_merge(conv, d, p, 118, 55);
+
+ osmo_conv_encode(&gsm0503_tch_afs_5_9, conv, cB + 8);
+
+ break;
+ case 1: /* TCH/AFS5.15 */
+ if (len != 13)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 103);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p);
+
+ tch_amr_merge(conv, d, p, 103, 49);
+
+ osmo_conv_encode(&gsm0503_tch_afs_5_15, conv, cB + 8);
+
+ break;
+ case 0: /* TCH/AFS4.75 */
+ if (len != 12)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 95);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p);
+
+ tch_amr_merge(conv, d, p, 95, 39);
+
+ osmo_conv_encode(&gsm0503_tch_afs_4_75, conv, cB + 8);
+
+ break;
+ default:
+ /* FIXME: FT %ft is not supported */
+ return -1;
+ }
+
+ memcpy(cB, gsm0503_afs_ic_ubit[id], 8);
+
+facch:
+ gsm0503_tch_fr_interleave(cB, iB);
+
+ for (i = 0; i < 8; i++) {
+ gsm0503_tch_burst_map(&iB[i * 114],
+ &bursts[i * 116], &h, i >> 2);
+ }
+
+ return 0;
+
+invalid_length:
+ /* FIXME: payload length %len does not comply with codec type %ft */
+ return -1;
+}
+
+int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd,
+ int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+ uint8_t *cmr, int *n_errors, int *n_bits_total)
+{
+ sbit_t iB[912], cB[456], h;
+ ubit_t d[244], p[6], conv[135];
+ int i, j, k, best = 0, rv, len, steal = 0, id = 0;
+
+ /* only unmap the stealing bits */
+ if (!odd) {
+ for (i = 0; i < 4; i++) {
+ gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 0);
+ steal -= h;
+ }
+ for (i = 2; i < 5; i++) {
+ gsm0503_tch_burst_unmap(NULL, &bursts[i * 116], &h, 1);
+ steal -= h;
+ }
+ }
+
+ /* if we found a stole FACCH, but only at correct alignment */
+ if (steal > 0) {
+ for (i = 0; i < 6; i++) {
+ gsm0503_tch_burst_unmap(&iB[i * 114],
+ &bursts[i * 116], NULL, i >> 2);
+ }
+
+ for (i = 2; i < 4; i++) {
+ gsm0503_tch_burst_unmap(&iB[i * 114 + 456],
+ &bursts[i * 116], NULL, 1);
+ }
+
+ gsm0503_tch_fr_deinterleave(cB, iB);
+
+ rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
+ if (rv) {
+ /* Error decoding FACCH frame */
+ return -1;
+ }
+
+ return GSM_MACBLOCK_LEN;
+ }
+
+ for (i = 0; i < 4; i++) {
+ gsm0503_tch_burst_unmap(&iB[i * 114],
+ &bursts[i * 116], NULL, i >> 1);
+ }
+
+ gsm0503_tch_hr_deinterleave(cB, iB);
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0, k = 0; j < 4; j++)
+ k += abs(((int)gsm0503_ahs_ic_sbit[i][j]) - ((int)cB[j]));
+
+ if (i == 0 || k < best) {
+ best = k;
+ id = i;
+ }
+ }
+
+ /* Check if indicated codec fits into range of codecs */
+ if (id >= codecs) {
+ /* Codec mode out of range, return id */
+ return id;
+ }
+
+ switch ((codec_mode_req) ? codec[*ft] : codec[id]) {
+ case 5: /* TCH/AHS7.95 */
+ osmo_conv_decode_ber(&gsm0503_tch_ahs_7_95, cB + 4,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 123, 67);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 67, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 7.95 frame */
+ return -1;
+ }
+
+ for (i = 0; i < 36; i++)
+ d[i + 123] = (cB[i + 192] < 0) ? 1 : 0;
+
+ tch_amr_reassemble(tch_data, d, 159);
+
+ len = 20;
+
+ break;
+ case 4: /* TCH/AHS7.4 */
+ osmo_conv_decode_ber(&gsm0503_tch_ahs_7_4, cB + 4,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 120, 61);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 61, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 7.4 frame */
+ return -1;
+ }
+
+ for (i = 0; i < 28; i++)
+ d[i + 120] = (cB[i + 200] < 0) ? 1 : 0;
+
+ tch_amr_reassemble(tch_data, d, 148);
+
+ len = 19;
+
+ break;
+ case 3: /* TCH/AHS6.7 */
+ osmo_conv_decode_ber(&gsm0503_tch_ahs_6_7, cB + 4,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 110, 55);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 6.7 frame */
+ return -1;
+ }
+
+ for (i = 0; i < 24; i++)
+ d[i + 110] = (cB[i + 204] < 0) ? 1 : 0;
+
+ tch_amr_reassemble(tch_data, d, 134);
+
+ len = 17;
+
+ break;
+ case 2: /* TCH/AHS5.9 */
+ osmo_conv_decode_ber(&gsm0503_tch_ahs_5_9, cB + 4,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 102, 55);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 55, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 5.9 frame */
+ return -1;
+ }
+
+ for (i = 0; i < 16; i++)
+ d[i + 102] = (cB[i + 212] < 0) ? 1 : 0;
+
+ tch_amr_reassemble(tch_data, d, 118);
+
+ len = 15;
+
+ break;
+ case 1: /* TCH/AHS5.15 */
+ osmo_conv_decode_ber(&gsm0503_tch_ahs_5_15, cB + 4,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 91, 49);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 49, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 5.15 frame */
+ return -1;
+ }
+
+ for (i = 0; i < 12; i++)
+ d[i + 91] = (cB[i + 216] < 0) ? 1 : 0;
+
+ tch_amr_reassemble(tch_data, d, 103);
+
+ len = 13;
+
+ break;
+ case 0: /* TCH/AHS4.75 */
+ osmo_conv_decode_ber(&gsm0503_tch_ahs_4_75, cB + 4,
+ conv, n_errors, n_bits_total);
+
+ tch_amr_unmerge(d, p, conv, 83, 39);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_amr_crc6, d, 39, p);
+ if (rv) {
+ /* Error checking CRC8 for an AMR 4.75 frame */
+ return -1;
+ }
+
+ for (i = 0; i < 12; i++)
+ d[i + 83] = (cB[i + 216] < 0) ? 1 : 0;
+
+ tch_amr_reassemble(tch_data, d, 95);
+
+ len = 12;
+
+ break;
+ default:
+ /* Unknown frame type */
+ *n_bits_total = 159;
+ *n_errors = *n_bits_total;
+ return -1;
+ }
+
+ /* Change codec request / indication, if frame is valid */
+ if (codec_mode_req)
+ *cmr = id;
+ else
+ *ft = id;
+
+ return len;
+}
+
+int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len,
+ int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft,
+ uint8_t cmr)
+{
+ ubit_t iB[912], cB[456], h;
+ ubit_t d[244], p[6], conv[135];
+ int i;
+ uint8_t id;
+
+ if (len == GSM_MACBLOCK_LEN) { /* FACCH */
+ _xcch_encode_cB(cB, tch_data);
+
+ h = 1;
+
+ gsm0503_tch_fr_interleave(cB, iB);
+
+ for (i = 0; i < 6; i++)
+ gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116],
+ &h, i >> 2);
+ for (i = 2; i < 4; i++)
+ gsm0503_tch_burst_map(&iB[i * 114 + 456],
+ &bursts[i * 116], &h, 1);
+
+ return 0;
+ }
+
+ h = 0;
+
+ if (codec_mode_req) {
+ if (cmr >= codecs) {
+ /* FIXME: CMR ID %d not in codec list */
+ return -1;
+ }
+ id = cmr;
+ } else {
+ if (ft >= codecs) {
+ /* FIXME: FT ID %d not in codec list */
+ return -1;
+ }
+ id = ft;
+ }
+
+ switch (codec[ft]) {
+ case 5: /* TCH/AHS7.95 */
+ if (len != 20)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 159);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 67, p);
+
+ tch_amr_merge(conv, d, p, 123, 67);
+
+ osmo_conv_encode(&gsm0503_tch_ahs_7_95, conv, cB + 4);
+
+ memcpy(cB + 192, d + 123, 36);
+
+ break;
+ case 4: /* TCH/AHS7.4 */
+ if (len != 19)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 148);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 61, p);
+
+ tch_amr_merge(conv, d, p, 120, 61);
+
+ osmo_conv_encode(&gsm0503_tch_ahs_7_4, conv, cB + 4);
+
+ memcpy(cB + 200, d + 120, 28);
+
+ break;
+ case 3: /* TCH/AHS6.7 */
+ if (len != 17)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 134);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
+
+ tch_amr_merge(conv, d, p, 110, 55);
+
+ osmo_conv_encode(&gsm0503_tch_ahs_6_7, conv, cB + 4);
+
+ memcpy(cB + 204, d + 110, 24);
+
+ break;
+ case 2: /* TCH/AHS5.9 */
+ if (len != 15)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 118);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 55, p);
+
+ tch_amr_merge(conv, d, p, 102, 55);
+
+ osmo_conv_encode(&gsm0503_tch_ahs_5_9, conv, cB + 4);
+
+ memcpy(cB + 212, d + 102, 16);
+
+ break;
+ case 1: /* TCH/AHS5.15 */
+ if (len != 13)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 103);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 49, p);
+
+ tch_amr_merge(conv, d, p, 91, 49);
+
+ osmo_conv_encode(&gsm0503_tch_ahs_5_15, conv, cB + 4);
+
+ memcpy(cB + 216, d + 91, 12);
+
+ break;
+ case 0: /* TCH/AHS4.75 */
+ if (len != 12)
+ goto invalid_length;
+
+ tch_amr_disassemble(d, tch_data, 95);
+
+ osmo_crc8gen_set_bits(&gsm0503_amr_crc6, d, 39, p);
+
+ tch_amr_merge(conv, d, p, 83, 39);
+
+ osmo_conv_encode(&gsm0503_tch_ahs_4_75, conv, cB + 4);
+
+ memcpy(cB + 216, d + 83, 12);
+
+ break;
+ default:
+ /* FIXME: FT %ft is not supported */
+ return -1;
+ }
+
+ memcpy(cB, gsm0503_afs_ic_ubit[id], 4);
+
+ gsm0503_tch_hr_interleave(cB, iB);
+
+ for (i = 0; i < 4; i++)
+ gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], &h, i >> 1);
+
+ return 0;
+
+invalid_length:
+ /* FIXME: payload length %len does not comply with codec type %ft */
+ return -1;
+}
+
+/*
+ * GSM RACH transcoding
+ */
+
+/*
+ * GSM RACH apply BSIC to parity
+ *
+ * p(j) = p(j) xor b(j) j = 0, ..., 5
+ * b(0) = MSB of PLMN colour code
+ * b(5) = LSB of BS colour code
+ */
+static int rach_apply_bsic(ubit_t *d, uint8_t bsic)
+{
+ int i;
+
+ /* Apply it */
+ for (i = 0; i < 6; i++)
+ d[8 + i] ^= ((bsic >> (5 - i)) & 1);
+
+ return 0;
+}
+
+int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic)
+{
+ ubit_t conv[14];
+ int rv;
+
+ osmo_conv_decode(&gsm0503_rach, burst, conv);
+
+ rach_apply_bsic(conv, bsic);
+
+ rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 8, conv + 8);
+ if (rv)
+ return -1;
+
+ osmo_ubit2pbit_ext(ra, 0, conv, 0, 8, 1);
+
+ return 0;
+}
+
+int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic)
+{
+ ubit_t conv[14];
+
+ osmo_pbit2ubit_ext(conv, 0, ra, 0, 8, 1);
+
+ osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 8, conv + 8);
+
+ rach_apply_bsic(conv, bsic);
+
+ osmo_conv_encode(&gsm0503_rach, conv, burst);
+
+ return 0;
+}
+
+/*
+ * GSM SCH transcoding
+ */
+int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst)
+{
+ ubit_t conv[35];
+ int rv;
+
+ osmo_conv_decode(&gsm0503_sch, burst, conv);
+
+ rv = osmo_crc16gen_check_bits(&gsm0503_sch_crc10, conv, 25, conv + 25);
+ if (rv)
+ return -1;
+
+ osmo_ubit2pbit_ext(sb_info, 0, conv, 0, 25, 1);
+
+ return 0;
+}
+
+int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info)
+{
+ ubit_t conv[35];
+
+ osmo_pbit2ubit_ext(conv, 0, sb_info, 0, 25, 1);
+
+ osmo_crc16gen_set_bits(&gsm0503_sch_crc10, conv, 25, conv + 25);
+
+ osmo_conv_encode(&gsm0503_sch, conv, burst);
+
+ return 0;
+}
diff --git a/lib/decoding/osmocom/coding/gsm0503_coding.h b/lib/decoding/osmocom/coding/gsm0503_coding.h
new file mode 100644
index 0000000..83cdbd5
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_coding.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+#define GSM0503_GPRS_BURSTS_NBITS (116 * 4)
+#define GSM0503_EGPRS_BURSTS_NBITS (348 * 4)
+#define NUM_BYTES(N) ((N + 8 - 1) / 8)
+
+
+
+int gsm0503_xcch_encode(ubit_t *bursts, uint8_t *l2_data);
+int gsm0503_xcch_decode(uint8_t *l2_data, sbit_t *bursts,
+ int *n_errors, int *n_bits_total);
+
+int gsm0503_pdtch_encode(ubit_t *bursts, uint8_t *l2_data, uint8_t l2_len);
+int gsm0503_pdtch_decode(uint8_t *l2_data, sbit_t *bursts, uint8_t *usf_p,
+ int *n_errors, int *n_bits_total);
+
+int gsm0503_tch_fr_encode(ubit_t *bursts, uint8_t *tch_data, int len,
+ int net_order);
+int gsm0503_tch_fr_decode(uint8_t *tch_data, sbit_t *bursts, int net_order,
+ int efr, int *n_errors, int *n_bits_total);
+
+int gsm0503_tch_hr_encode(ubit_t *bursts, uint8_t *tch_data, int len);
+int gsm0503_tch_hr_decode(uint8_t *tch_data, sbit_t *bursts, int odd,
+ int *n_errors, int *n_bits_total);
+
+int gsm0503_tch_afs_encode(ubit_t *bursts, uint8_t *tch_data, int len,
+ int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft,
+ uint8_t cmr);
+int gsm0503_tch_afs_decode(uint8_t *tch_data, sbit_t *bursts,
+ int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+ uint8_t *cmr, int *n_errors, int *n_bits_total);
+
+int gsm0503_tch_ahs_encode(ubit_t *bursts, uint8_t *tch_data, int len,
+ int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, uint8_t cmr);
+int gsm0503_tch_ahs_decode(uint8_t *tch_data, sbit_t *bursts, int odd,
+ int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+ uint8_t *cmr, int *n_errors, int *n_bits_total);
+
+int gsm0503_rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic);
+int gsm0503_rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic);
+
+int gsm0503_sch_encode(ubit_t *burst, uint8_t *sb_info);
+int gsm0503_sch_decode(uint8_t *sb_info, sbit_t *burst);
diff --git a/lib/decoding/osmocom/coding/gsm0503_conv.c b/lib/decoding/osmocom/coding/gsm0503_conv.c
new file mode 100644
index 0000000..f275ea4
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_conv.c
@@ -0,0 +1,1919 @@
+
+/*
+ * Copyright (C) 2011-2016 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdint.h>
+#include <osmocom/core/conv.h>
+
+static const uint8_t xcch_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t xcch_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+/**
+ * xCCH convolutional code:
+ * 228 bits blocks, rate 1/2, k = 5
+ * G0 = 1 + D3 + D4
+ * G1 = 1 + D + D3 + D4
+ */
+const struct osmo_conv_code gsm0503_xcch = {
+ .N = 2,
+ .K = 5,
+ .len = 224,
+ .next_output = xcch_output,
+ .next_state = xcch_state,
+};
+
+static const uint8_t rach_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t rach_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+/**
+ * RACH convolutional code
+ */
+const struct osmo_conv_code gsm0503_rach = {
+ .N = 2,
+ .K = 5,
+ .len = 14,
+ .next_output = rach_output,
+ .next_state = rach_state,
+};
+
+static const uint8_t sch_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t sch_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+/**
+ * SCH convolutional code
+ */
+const struct osmo_conv_code gsm0503_sch = {
+ .N = 2,
+ .K = 5,
+ .len = 35,
+ .next_output = sch_output,
+ .next_state = sch_state,
+};
+
+static const uint8_t cs2_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t cs2_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+static const int cs2_puncture[] = {
+ 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63,
+ 67, 71, 75, 79, 83, 91, 95, 99, 103, 107, 111, 115,
+ 119, 123, 127, 131, 139, 143, 147, 151, 155, 159, 163, 167,
+ 171, 175, 179, 187, 191, 195, 199, 203, 207, 211, 215, 219,
+ 223, 227, 235, 239, 243, 247, 251, 255, 259, 263, 267, 271,
+ 275, 283, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323,
+ 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379,
+ 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431,
+ 435, 439, 443, 447, 451, 455, 459, 463, 467, 475, 479, 483,
+ 487, 491, 495, 499, 503, 507, 511, 515, 523, 527, 531, 535,
+ 539, 543, 547, 551, 555, 559, 563, 571, 575, 579, 583, 587,
+ -1,
+};
+
+/**
+ * CS2 convolutional code:
+ * G0 = 1 + D3 + D4
+ * G1 = 1 + D + D3 + D4
+ */
+const struct osmo_conv_code gsm0503_cs2 = {
+ .N = 2,
+ .K = 5,
+ .len = 290,
+ .next_output = cs2_output,
+ .next_state = cs2_state,
+ .puncture = cs2_puncture,
+};
+
+static const uint8_t cs3_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t cs3_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+static const int cs3_puncture[] = {
+ 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47,
+ 51, 53, 57, 59, 63, 65, 69, 71, 75, 77, 81, 83,
+ 87, 89, 93, 95, 99, 101, 105, 107, 111, 113, 117, 119,
+ 123, 125, 129, 131, 135, 137, 141, 143, 147, 149, 153, 155,
+ 159, 161, 165, 167, 171, 173, 177, 179, 183, 185, 189, 191,
+ 195, 197, 201, 203, 207, 209, 213, 215, 219, 221, 225, 227,
+ 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263,
+ 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299,
+ 303, 305, 309, 311, 315, 317, 321, 323, 327, 329, 333, 335,
+ 339, 341, 345, 347, 351, 353, 357, 359, 363, 365, 369, 371,
+ 375, 377, 381, 383, 387, 389, 393, 395, 399, 401, 405, 407,
+ 411, 413, 417, 419, 423, 425, 429, 431, 435, 437, 441, 443,
+ 447, 449, 453, 455, 459, 461, 465, 467, 471, 473, 477, 479,
+ 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515,
+ 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551,
+ 555, 557, 561, 563, 567, 569, 573, 575, 579, 581, 585, 587,
+ 591, 593, 597, 599, 603, 605, 609, 611, 615, 617, 621, 623,
+ 627, 629, 633, 635, 639, 641, 645, 647, 651, 653, 657, 659,
+ 663, 665, 669, 671, -1,
+};
+
+/**
+ * CS3 convolutional code:
+ * G0 = 1 + D3 + D4
+ * G1 = 1 + D + D3 + D4
+ */
+const struct osmo_conv_code gsm0503_cs3 = {
+ .N = 2,
+ .K = 5,
+ .len = 334,
+ .next_output = cs3_output,
+ .next_state = cs3_state,
+ .puncture = cs3_puncture,
+};
+
+static const uint8_t tch_afs_12_2_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 9, 8 }, { 11, 10 }, { 13, 12 }, { 15, 14 },
+ { 1, 0 }, { 3, 2 }, { 5, 4 }, { 7, 6 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t tch_afs_12_2_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+static const uint8_t tch_afs_12_2_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_afs_12_2_term_output[] = {
+ 0, 1, 0, 1, 3, 2, 3, 2, 3, 2, 3, 2,
+ 0, 1, 0, 1,
+};
+
+static const int tch_afs_12_2_puncture[] = {
+ 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363,
+ 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401,
+ 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441,
+ 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477,
+ 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507,
+ -1,
+};
+
+/**
+ * TCH/AFS 12.2 kbits convolutional code:
+ * 250 bits block, rate 1/2, punctured
+ * G0/G0 = 1
+ * G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4
+ */
+const struct osmo_conv_code gsm0503_tch_afs_12_2 = {
+ .N = 2,
+ .K = 5,
+ .len = 250,
+ .next_output = tch_afs_12_2_output,
+ .next_state = tch_afs_12_2_state,
+ .next_term_output = tch_afs_12_2_term_output,
+ .next_term_state = tch_afs_12_2_term_state,
+ .puncture = tch_afs_12_2_puncture,
+};
+
+static const uint8_t tch_afs_10_2_state[][2] = {
+ { 0, 1 }, { 3, 2 }, { 5, 4 }, { 6, 7 },
+ { 9, 8 }, { 10, 11 }, { 12, 13 }, { 15, 14 },
+ { 1, 0 }, { 2, 3 }, { 4, 5 }, { 7, 6 },
+ { 8, 9 }, { 11, 10 }, { 13, 12 }, { 14, 15 },
+};
+
+static const uint8_t tch_afs_10_2_output[][2] = {
+ { 0, 7 }, { 2, 5 }, { 4, 3 }, { 6, 1 },
+ { 2, 5 }, { 0, 7 }, { 6, 1 }, { 4, 3 },
+ { 0, 7 }, { 2, 5 }, { 4, 3 }, { 6, 1 },
+ { 2, 5 }, { 0, 7 }, { 6, 1 }, { 4, 3 },
+};
+
+static const uint8_t tch_afs_10_2_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_afs_10_2_term_output[] = {
+ 0, 5, 3, 6, 5, 0, 6, 3, 7, 2, 4, 1,
+ 2, 7, 1, 4,
+};
+
+static const int tch_afs_10_2_puncture[] = {
+ 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43,
+ 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91,
+ 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139,
+ 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187,
+ 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235,
+ 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283,
+ 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328,
+ 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364,
+ 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
+ 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436,
+ 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472,
+ 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508,
+ 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544,
+ 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580,
+ 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613,
+ 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637,
+ 639, 640, -1,
+};
+
+/**
+ * TCH/AFS 10.2 kbits convolutional code:
+ * G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4
+ * G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4
+ * G3/G3 = 1
+ */
+const struct osmo_conv_code gsm0503_tch_afs_10_2 = {
+ .N = 3,
+ .K = 5,
+ .len = 210,
+ .next_output = tch_afs_10_2_output,
+ .next_state = tch_afs_10_2_state,
+ .next_term_output = tch_afs_10_2_term_output,
+ .next_term_state = tch_afs_10_2_term_state,
+ .puncture = tch_afs_10_2_puncture,
+};
+
+static const uint8_t tch_afs_7_95_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 5, 4 }, { 7, 6 },
+ { 9, 8 }, { 11, 10 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 21, 20 }, { 23, 22 },
+ { 25, 24 }, { 27, 26 }, { 28, 29 }, { 30, 31 },
+ { 33, 32 }, { 35, 34 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 45, 44 }, { 47, 46 },
+ { 49, 48 }, { 51, 50 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 61, 60 }, { 63, 62 },
+ { 1, 0 }, { 3, 2 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 13, 12 }, { 15, 14 },
+ { 17, 16 }, { 19, 18 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 29, 28 }, { 31, 30 },
+ { 32, 33 }, { 34, 35 }, { 37, 36 }, { 39, 38 },
+ { 41, 40 }, { 43, 42 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 53, 52 }, { 55, 54 },
+ { 57, 56 }, { 59, 58 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t tch_afs_7_95_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+};
+
+static const uint8_t tch_afs_7_95_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22,
+ 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46,
+ 48, 50, 52, 54, 56, 58, 60, 62, 0, 2, 4, 6,
+ 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
+ 56, 58, 60, 62,
+};
+
+static const uint8_t tch_afs_7_95_term_output[] = {
+ 0, 3, 5, 6, 5, 6, 0, 3, 3, 0, 6, 5,
+ 6, 5, 3, 0, 4, 7, 1, 2, 1, 2, 4, 7,
+ 7, 4, 2, 1, 2, 1, 7, 4, 7, 4, 2, 1,
+ 2, 1, 7, 4, 4, 7, 1, 2, 1, 2, 4, 7,
+ 3, 0, 6, 5, 6, 5, 3, 0, 0, 3, 5, 6,
+ 5, 6, 0, 3,
+};
+
+static const int tch_afs_7_95_puncture[] = {
+ 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310,
+ 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367,
+ 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415,
+ 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463,
+ 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505,
+ 506, 508, 509, 511, 512, -1,
+};
+
+/**
+ * TCH/AFS 7.95 kbits convolutional code:
+ * G4/G4 = 1
+ * G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6
+ * G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6
+ */
+const struct osmo_conv_code gsm0503_tch_afs_7_95 = {
+ .N = 3,
+ .K = 7,
+ .len = 165,
+ .next_output = tch_afs_7_95_output,
+ .next_state = tch_afs_7_95_state,
+ .next_term_output = tch_afs_7_95_term_output,
+ .next_term_state = tch_afs_7_95_term_state,
+ .puncture = tch_afs_7_95_puncture,
+};
+
+static const uint8_t tch_afs_7_4_state[][2] = {
+ { 0, 1 }, { 3, 2 }, { 5, 4 }, { 6, 7 },
+ { 9, 8 }, { 10, 11 }, { 12, 13 }, { 15, 14 },
+ { 1, 0 }, { 2, 3 }, { 4, 5 }, { 7, 6 },
+ { 8, 9 }, { 11, 10 }, { 13, 12 }, { 14, 15 },
+};
+
+static const uint8_t tch_afs_7_4_output[][2] = {
+ { 0, 7 }, { 2, 5 }, { 4, 3 }, { 6, 1 },
+ { 2, 5 }, { 0, 7 }, { 6, 1 }, { 4, 3 },
+ { 0, 7 }, { 2, 5 }, { 4, 3 }, { 6, 1 },
+ { 2, 5 }, { 0, 7 }, { 6, 1 }, { 4, 3 },
+};
+
+static const uint8_t tch_afs_7_4_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_afs_7_4_term_output[] = {
+ 0, 5, 3, 6, 5, 0, 6, 3, 7, 2, 4, 1,
+ 2, 7, 1, 4,
+};
+
+static const int tch_afs_7_4_puncture[] = {
+ 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415,
+ 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469,
+ 471, 472, -1,
+};
+
+/**
+ * TCH/AFS 7.4 kbits convolutional code:
+ * G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4
+ * G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4
+ * G3/G3 = 1
+ */
+const struct osmo_conv_code gsm0503_tch_afs_7_4 = {
+ .N = 3,
+ .K = 5,
+ .len = 154,
+ .next_output = tch_afs_7_4_output,
+ .next_state = tch_afs_7_4_state,
+ .next_term_output = tch_afs_7_4_term_output,
+ .next_term_state = tch_afs_7_4_term_state,
+ .puncture = tch_afs_7_4_puncture,
+};
+
+static const uint8_t tch_afs_6_7_state[][2] = {
+ { 0, 1 }, { 3, 2 }, { 5, 4 }, { 6, 7 },
+ { 9, 8 }, { 10, 11 }, { 12, 13 }, { 15, 14 },
+ { 1, 0 }, { 2, 3 }, { 4, 5 }, { 7, 6 },
+ { 8, 9 }, { 11, 10 }, { 13, 12 }, { 14, 15 },
+};
+
+static const uint8_t tch_afs_6_7_output[][2] = {
+ { 0, 15 }, { 4, 11 }, { 8, 7 }, { 12, 3 },
+ { 4, 11 }, { 0, 15 }, { 12, 3 }, { 8, 7 },
+ { 0, 15 }, { 4, 11 }, { 8, 7 }, { 12, 3 },
+ { 4, 11 }, { 0, 15 }, { 12, 3 }, { 8, 7 },
+};
+
+static const uint8_t tch_afs_6_7_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_afs_6_7_term_output[] = {
+ 0, 11, 7, 12, 11, 0, 12, 7, 15, 4, 8, 3,
+ 4, 15, 3, 8,
+};
+
+static const int tch_afs_6_7_puncture[] = {
+ 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107,
+ 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267,
+ 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327,
+ 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371,
+ 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403,
+ 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435,
+ 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467,
+ 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499,
+ 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531,
+ 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559,
+ 561, 563, 565, 567, 569, 571, 573, 575, -1,
+};
+
+/**
+ * TCH/AFS 6.7 kbits convolutional code:
+ * G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4
+ * G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4
+ * G3/G3 = 1
+ * G3/G3 = 1
+ */
+const struct osmo_conv_code gsm0503_tch_afs_6_7 = {
+ .N = 4,
+ .K = 5,
+ .len = 140,
+ .next_output = tch_afs_6_7_output,
+ .next_state = tch_afs_6_7_state,
+ .next_term_output = tch_afs_6_7_term_output,
+ .next_term_state = tch_afs_6_7_term_state,
+ .puncture = tch_afs_6_7_puncture,
+};
+
+static const uint8_t tch_afs_5_9_state[][2] = {
+ { 0, 1 }, { 3, 2 }, { 5, 4 }, { 6, 7 },
+ { 9, 8 }, { 10, 11 }, { 12, 13 }, { 15, 14 },
+ { 17, 16 }, { 18, 19 }, { 20, 21 }, { 23, 22 },
+ { 24, 25 }, { 27, 26 }, { 29, 28 }, { 30, 31 },
+ { 32, 33 }, { 35, 34 }, { 37, 36 }, { 38, 39 },
+ { 41, 40 }, { 42, 43 }, { 44, 45 }, { 47, 46 },
+ { 49, 48 }, { 50, 51 }, { 52, 53 }, { 55, 54 },
+ { 56, 57 }, { 59, 58 }, { 61, 60 }, { 62, 63 },
+ { 1, 0 }, { 2, 3 }, { 4, 5 }, { 7, 6 },
+ { 8, 9 }, { 11, 10 }, { 13, 12 }, { 14, 15 },
+ { 16, 17 }, { 19, 18 }, { 21, 20 }, { 22, 23 },
+ { 25, 24 }, { 26, 27 }, { 28, 29 }, { 31, 30 },
+ { 33, 32 }, { 34, 35 }, { 36, 37 }, { 39, 38 },
+ { 40, 41 }, { 43, 42 }, { 45, 44 }, { 46, 47 },
+ { 48, 49 }, { 51, 50 }, { 53, 52 }, { 54, 55 },
+ { 57, 56 }, { 58, 59 }, { 60, 61 }, { 63, 62 },
+};
+
+static const uint8_t tch_afs_5_9_output[][2] = {
+ { 0, 15 }, { 8, 7 }, { 4, 11 }, { 12, 3 },
+ { 4, 11 }, { 12, 3 }, { 0, 15 }, { 8, 7 },
+ { 8, 7 }, { 0, 15 }, { 12, 3 }, { 4, 11 },
+ { 12, 3 }, { 4, 11 }, { 8, 7 }, { 0, 15 },
+ { 8, 7 }, { 0, 15 }, { 12, 3 }, { 4, 11 },
+ { 12, 3 }, { 4, 11 }, { 8, 7 }, { 0, 15 },
+ { 0, 15 }, { 8, 7 }, { 4, 11 }, { 12, 3 },
+ { 4, 11 }, { 12, 3 }, { 0, 15 }, { 8, 7 },
+ { 0, 15 }, { 8, 7 }, { 4, 11 }, { 12, 3 },
+ { 4, 11 }, { 12, 3 }, { 0, 15 }, { 8, 7 },
+ { 8, 7 }, { 0, 15 }, { 12, 3 }, { 4, 11 },
+ { 12, 3 }, { 4, 11 }, { 8, 7 }, { 0, 15 },
+ { 8, 7 }, { 0, 15 }, { 12, 3 }, { 4, 11 },
+ { 12, 3 }, { 4, 11 }, { 8, 7 }, { 0, 15 },
+ { 0, 15 }, { 8, 7 }, { 4, 11 }, { 12, 3 },
+ { 4, 11 }, { 12, 3 }, { 0, 15 }, { 8, 7 },
+};
+
+static const uint8_t tch_afs_5_9_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22,
+ 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46,
+ 48, 50, 52, 54, 56, 58, 60, 62, 0, 2, 4, 6,
+ 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
+ 56, 58, 60, 62,
+};
+
+static const uint8_t tch_afs_5_9_term_output[] = {
+ 0, 7, 11, 12, 11, 12, 0, 7, 7, 0, 12, 11,
+ 12, 11, 7, 0, 8, 15, 3, 4, 3, 4, 8, 15,
+ 15, 8, 4, 3, 4, 3, 15, 8, 15, 8, 4, 3,
+ 4, 3, 15, 8, 8, 15, 3, 4, 3, 4, 8, 15,
+ 7, 0, 12, 11, 12, 11, 7, 0, 0, 7, 11, 12,
+ 11, 12, 0, 7,
+};
+
+static const int tch_afs_5_9_puncture[] = {
+ 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95,
+ 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287,
+ 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375,
+ 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439,
+ 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491,
+ 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519,
+ -1,
+};
+
+/**
+ * TCH/AFS 5.9 kbits convolutional code:
+ * 124 bits
+ * G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6
+ * G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6
+ * G6/G6 = 1
+ * G6/G6 = 1
+ */
+const struct osmo_conv_code gsm0503_tch_afs_5_9 = {
+ .N = 4,
+ .K = 7,
+ .len = 124,
+ .next_output = tch_afs_5_9_output,
+ .next_state = tch_afs_5_9_state,
+ .next_term_output = tch_afs_5_9_term_output,
+ .next_term_state = tch_afs_5_9_term_state,
+ .puncture = tch_afs_5_9_puncture,
+};
+
+static const uint8_t tch_afs_5_15_state[][2] = {
+ { 0, 1 }, { 3, 2 }, { 5, 4 }, { 6, 7 },
+ { 9, 8 }, { 10, 11 }, { 12, 13 }, { 15, 14 },
+ { 1, 0 }, { 2, 3 }, { 4, 5 }, { 7, 6 },
+ { 8, 9 }, { 11, 10 }, { 13, 12 }, { 14, 15 },
+};
+
+static const uint8_t tch_afs_5_15_output[][2] = {
+ { 0, 31 }, { 4, 27 }, { 24, 7 }, { 28, 3 },
+ { 4, 27 }, { 0, 31 }, { 28, 3 }, { 24, 7 },
+ { 0, 31 }, { 4, 27 }, { 24, 7 }, { 28, 3 },
+ { 4, 27 }, { 0, 31 }, { 28, 3 }, { 24, 7 },
+};
+
+static const uint8_t tch_afs_5_15_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_afs_5_15_term_output[] = {
+ 0, 27, 7, 28, 27, 0, 28, 7, 31, 4, 24, 3,
+ 4, 31, 3, 24,
+};
+
+static const int tch_afs_5_15_puncture[] = {
+ 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40,
+ 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,
+ 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280,
+ 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345,
+ 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385,
+ 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425,
+ 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465,
+ 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505,
+ 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540,
+ 544, 545, 549, 550, 554, 555, 559, 560, 564, -1,
+};
+
+/**
+ * TCH/AFS 5.15 kbits convolutional code:
+ * G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4
+ * G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4
+ * G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4
+ * G3/G3 = 1
+ * G3/G3 = 1
+ */
+const struct osmo_conv_code gsm0503_tch_afs_5_15 = {
+ .N = 5,
+ .K = 5,
+ .len = 109,
+ .next_output = tch_afs_5_15_output,
+ .next_state = tch_afs_5_15_state,
+ .next_term_output = tch_afs_5_15_term_output,
+ .next_term_state = tch_afs_5_15_term_state,
+ .puncture = tch_afs_5_15_puncture,
+};
+
+static const uint8_t tch_afs_4_75_state[][2] = {
+ { 0, 1 }, { 3, 2 }, { 5, 4 }, { 6, 7 },
+ { 9, 8 }, { 10, 11 }, { 12, 13 }, { 15, 14 },
+ { 17, 16 }, { 18, 19 }, { 20, 21 }, { 23, 22 },
+ { 24, 25 }, { 27, 26 }, { 29, 28 }, { 30, 31 },
+ { 32, 33 }, { 35, 34 }, { 37, 36 }, { 38, 39 },
+ { 41, 40 }, { 42, 43 }, { 44, 45 }, { 47, 46 },
+ { 49, 48 }, { 50, 51 }, { 52, 53 }, { 55, 54 },
+ { 56, 57 }, { 59, 58 }, { 61, 60 }, { 62, 63 },
+ { 1, 0 }, { 2, 3 }, { 4, 5 }, { 7, 6 },
+ { 8, 9 }, { 11, 10 }, { 13, 12 }, { 14, 15 },
+ { 16, 17 }, { 19, 18 }, { 21, 20 }, { 22, 23 },
+ { 25, 24 }, { 26, 27 }, { 28, 29 }, { 31, 30 },
+ { 33, 32 }, { 34, 35 }, { 36, 37 }, { 39, 38 },
+ { 40, 41 }, { 43, 42 }, { 45, 44 }, { 46, 47 },
+ { 48, 49 }, { 51, 50 }, { 53, 52 }, { 54, 55 },
+ { 57, 56 }, { 58, 59 }, { 60, 61 }, { 63, 62 },
+};
+
+static const uint8_t tch_afs_4_75_output[][2] = {
+ { 0, 31 }, { 24, 7 }, { 4, 27 }, { 28, 3 },
+ { 4, 27 }, { 28, 3 }, { 0, 31 }, { 24, 7 },
+ { 24, 7 }, { 0, 31 }, { 28, 3 }, { 4, 27 },
+ { 28, 3 }, { 4, 27 }, { 24, 7 }, { 0, 31 },
+ { 24, 7 }, { 0, 31 }, { 28, 3 }, { 4, 27 },
+ { 28, 3 }, { 4, 27 }, { 24, 7 }, { 0, 31 },
+ { 0, 31 }, { 24, 7 }, { 4, 27 }, { 28, 3 },
+ { 4, 27 }, { 28, 3 }, { 0, 31 }, { 24, 7 },
+ { 0, 31 }, { 24, 7 }, { 4, 27 }, { 28, 3 },
+ { 4, 27 }, { 28, 3 }, { 0, 31 }, { 24, 7 },
+ { 24, 7 }, { 0, 31 }, { 28, 3 }, { 4, 27 },
+ { 28, 3 }, { 4, 27 }, { 24, 7 }, { 0, 31 },
+ { 24, 7 }, { 0, 31 }, { 28, 3 }, { 4, 27 },
+ { 28, 3 }, { 4, 27 }, { 24, 7 }, { 0, 31 },
+ { 0, 31 }, { 24, 7 }, { 4, 27 }, { 28, 3 },
+ { 4, 27 }, { 28, 3 }, { 0, 31 }, { 24, 7 },
+};
+
+static const uint8_t tch_afs_4_75_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22,
+ 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46,
+ 48, 50, 52, 54, 56, 58, 60, 62, 0, 2, 4, 6,
+ 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
+ 56, 58, 60, 62,
+};
+
+static const uint8_t tch_afs_4_75_term_output[] = {
+ 0, 7, 27, 28, 27, 28, 0, 7, 7, 0, 28, 27,
+ 28, 27, 7, 0, 24, 31, 3, 4, 3, 4, 24, 31,
+ 31, 24, 4, 3, 4, 3, 31, 24, 31, 24, 4, 3,
+ 4, 3, 31, 24, 24, 31, 3, 4, 3, 4, 24, 31,
+ 7, 0, 28, 27, 28, 27, 7, 0, 0, 7, 27, 28,
+ 27, 28, 0, 7,
+};
+
+static const int tch_afs_4_75_puncture[] = {
+ 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55,
+ 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175,
+ 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295,
+ 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405,
+ 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460,
+ 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509,
+ 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530,
+ 531, 532, 534, -1,
+};
+
+/**
+ * TCH/AFS 4.75 kbits convolutional code:
+ * G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6
+ * G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6
+ * G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6
+ * G6/G6 = 1
+ * G6/G6 = 1
+ */
+const struct osmo_conv_code gsm0503_tch_afs_4_75 = {
+ .N = 5,
+ .K = 7,
+ .len = 101,
+ .next_output = tch_afs_4_75_output,
+ .next_state = tch_afs_4_75_state,
+ .next_term_output = tch_afs_4_75_term_output,
+ .next_term_state = tch_afs_4_75_term_state,
+ .puncture = tch_afs_4_75_puncture,
+};
+
+static const uint8_t tch_fr_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t tch_fr_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+/**
+ * TCH/F convolutional code
+ */
+const struct osmo_conv_code gsm0503_tch_fr = {
+ .N = 2,
+ .K = 5,
+ .len = 185,
+ .next_output = tch_fr_output,
+ .next_state = tch_fr_state,
+};
+
+static const uint8_t tch_hr_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t tch_hr_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 },
+ { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 },
+ { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 },
+ { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 },
+ { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 },
+ { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 },
+ { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 },
+};
+
+static const int tch_hr_puncture[] = {
+ 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34,
+ 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70,
+ 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106,
+ 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142,
+ 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178,
+ 181, 184, 187, 190, 193, 196, 199, 202, 205, 208, 211, 214,
+ 217, 220, 223, 226, 229, 232, 235, 238, 241, 244, 247, 250,
+ 253, 256, 259, 262, 265, 268, 271, 274, 277, 280, 283, 295,
+ 298, 301, 304, 307, 310, -1,
+};
+
+/**
+ * TCH/H convolutional code
+ */
+const struct osmo_conv_code gsm0503_tch_hr = {
+ .N = 3,
+ .K = 7,
+ .len = 98,
+ .next_output = tch_hr_output,
+ .next_state = tch_hr_state,
+ .puncture = tch_hr_puncture,
+};
+
+static const uint8_t tch_ahs_7_95_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 9, 8 }, { 11, 10 }, { 13, 12 }, { 15, 14 },
+ { 1, 0 }, { 3, 2 }, { 5, 4 }, { 7, 6 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t tch_ahs_7_95_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+static const uint8_t tch_ahs_7_95_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_ahs_7_95_term_output[] = {
+ 0, 1, 0, 1, 3, 2, 3, 2, 3, 2, 3, 2,
+ 0, 1, 0, 1,
+};
+
+static const int tch_ahs_7_95_puncture[] = {
+ 1, 3, 5, 7, 11, 15, 19, 23, 27, 31, 35, 43,
+ 47, 51, 55, 59, 63, 67, 71, 79, 83, 87, 91, 95,
+ 99, 103, 107, 115, 119, 123, 127, 131, 135, 139, 143, 151,
+ 155, 159, 163, 167, 171, 175, 177, 179, 183, 185, 187, 191,
+ 193, 195, 197, 199, 203, 205, 207, 211, 213, 215, 219, 221,
+ 223, 227, 229, 231, 233, 235, 239, 241, 243, 247, 249, 251,
+ 255, 257, 259, 261, 263, 265, -1,
+};
+
+/**
+ * TCH/AHS 7.95 kbits convolutional code
+ */
+const struct osmo_conv_code gsm0503_tch_ahs_7_95 = {
+ .N = 2,
+ .K = 5,
+ .len = 129,
+ .next_output = tch_ahs_7_95_output,
+ .next_state = tch_ahs_7_95_state,
+ .next_term_output = tch_ahs_7_95_term_output,
+ .next_term_state = tch_ahs_7_95_term_state,
+ .puncture = tch_ahs_7_95_puncture,
+};
+
+static const uint8_t tch_ahs_7_4_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 9, 8 }, { 11, 10 }, { 13, 12 }, { 15, 14 },
+ { 1, 0 }, { 3, 2 }, { 5, 4 }, { 7, 6 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t tch_ahs_7_4_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+static const uint8_t tch_ahs_7_4_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_ahs_7_4_term_output[] = {
+ 0, 1, 0, 1, 3, 2, 3, 2, 3, 2, 3, 2,
+ 0, 1, 0, 1,
+};
+
+static const int tch_ahs_7_4_puncture[] = {
+ 1, 3, 7, 11, 19, 23, 27, 35, 39, 43, 51, 55,
+ 59, 67, 71, 75, 83, 87, 91, 99, 103, 107, 115, 119,
+ 123, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171,
+ 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219,
+ 221, 223, 227, 229, 231, 235, 237, 239, 243, 245, 247, 251,
+ 253, 255, 257, 259, -1,
+};
+
+/**
+ * TCH/AHS 7.4 kbits convolutional code
+ */
+const struct osmo_conv_code gsm0503_tch_ahs_7_4 = {
+ .N = 2,
+ .K = 5,
+ .len = 126,
+ .next_output = tch_ahs_7_4_output,
+ .next_state = tch_ahs_7_4_state,
+ .next_term_output = tch_ahs_7_4_term_output,
+ .next_term_state = tch_ahs_7_4_term_state,
+ .puncture = tch_ahs_7_4_puncture,
+};
+
+static const uint8_t tch_ahs_6_7_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 9, 8 }, { 11, 10 }, { 13, 12 }, { 15, 14 },
+ { 1, 0 }, { 3, 2 }, { 5, 4 }, { 7, 6 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t tch_ahs_6_7_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+static const uint8_t tch_ahs_6_7_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_ahs_6_7_term_output[] = {
+ 0, 1, 0, 1, 3, 2, 3, 2, 3, 2, 3, 2,
+ 0, 1, 0, 1,
+};
+
+static const int tch_ahs_6_7_puncture[] = {
+ 1, 3, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99,
+ 109, 119, 129, 139, 149, 159, 167, 169, 177, 179, 187, 189,
+ 197, 199, 203, 207, 209, 213, 217, 219, 223, 227, 229, 231,
+ 233, 235, 237, 239, -1,
+};
+
+/**
+ * TCH/AHS 6.7 kbits convolutional code
+ */
+const struct osmo_conv_code gsm0503_tch_ahs_6_7 = {
+ .N = 2,
+ .K = 5,
+ .len = 116,
+ .next_output = tch_ahs_6_7_output,
+ .next_state = tch_ahs_6_7_state,
+ .next_term_output = tch_ahs_6_7_term_output,
+ .next_term_state = tch_ahs_6_7_term_state,
+ .puncture = tch_ahs_6_7_puncture,
+};
+
+static const uint8_t tch_ahs_5_9_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 9, 8 }, { 11, 10 }, { 13, 12 }, { 15, 14 },
+ { 1, 0 }, { 3, 2 }, { 5, 4 }, { 7, 6 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const uint8_t tch_ahs_5_9_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+static const uint8_t tch_ahs_5_9_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_ahs_5_9_term_output[] = {
+ 0, 1, 0, 1, 3, 2, 3, 2, 3, 2, 3, 2,
+ 0, 1, 0, 1,
+};
+
+static const int tch_ahs_5_9_puncture[] = {
+ 1, 15, 71, 127, 139, 151, 163, 175, 187, 195, 203, 211,
+ 215, 219, 221, 223, -1,
+};
+
+/**
+ * TCH/AHS 5.9 kbits convolutional code
+ */
+const struct osmo_conv_code gsm0503_tch_ahs_5_9 = {
+ .N = 2,
+ .K = 5,
+ .len = 108,
+ .next_output = tch_ahs_5_9_output,
+ .next_state = tch_ahs_5_9_state,
+ .next_term_output = tch_ahs_5_9_term_output,
+ .next_term_state = tch_ahs_5_9_term_state,
+ .puncture = tch_ahs_5_9_puncture,
+};
+
+static const uint8_t tch_ahs_5_15_state[][2] = {
+ { 0, 1 }, { 3, 2 }, { 5, 4 }, { 6, 7 },
+ { 9, 8 }, { 10, 11 }, { 12, 13 }, { 15, 14 },
+ { 1, 0 }, { 2, 3 }, { 4, 5 }, { 7, 6 },
+ { 8, 9 }, { 11, 10 }, { 13, 12 }, { 14, 15 },
+};
+
+static const uint8_t tch_ahs_5_15_output[][2] = {
+ { 0, 7 }, { 2, 5 }, { 4, 3 }, { 6, 1 },
+ { 2, 5 }, { 0, 7 }, { 6, 1 }, { 4, 3 },
+ { 0, 7 }, { 2, 5 }, { 4, 3 }, { 6, 1 },
+ { 2, 5 }, { 0, 7 }, { 6, 1 }, { 4, 3 },
+};
+
+static const uint8_t tch_ahs_5_15_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6,
+ 8, 10, 12, 14,
+};
+
+static const uint8_t tch_ahs_5_15_term_output[] = {
+ 0, 5, 3, 6, 5, 0, 6, 3, 7, 2, 4, 1,
+ 2, 7, 1, 4,
+};
+
+static const int tch_ahs_5_15_puncture[] = {
+ 0, 1, 3, 4, 6, 9, 12, 15, 18, 21, 27, 33,
+ 39, 45, 51, 54, 57, 63, 69, 75, 81, 87, 90, 93,
+ 99, 105, 111, 117, 123, 126, 129, 135, 141, 147, 153, 159,
+ 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195,
+ 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231,
+ 234, 237, 240, 243, 244, 246, 249, 252, 255, 256, 258, 261,
+ 264, 267, 268, 270, 273, 276, 279, 280, 282, 285, 288, 289,
+ 291, 294, 295, 297, 298, 300, 301, -1,
+};
+
+/**
+ * TCH/AHS 5.15 kbits convolutional code
+ */
+const struct osmo_conv_code gsm0503_tch_ahs_5_15 = {
+ .N = 3,
+ .K = 5,
+ .len = 97,
+ .next_output = tch_ahs_5_15_output,
+ .next_state = tch_ahs_5_15_state,
+ .next_term_output = tch_ahs_5_15_term_output,
+ .next_term_state = tch_ahs_5_15_term_state,
+ .puncture = tch_ahs_5_15_puncture,
+};
+
+static const uint8_t tch_ahs_4_75_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 5, 4 }, { 7, 6 },
+ { 9, 8 }, { 11, 10 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 21, 20 }, { 23, 22 },
+ { 25, 24 }, { 27, 26 }, { 28, 29 }, { 30, 31 },
+ { 33, 32 }, { 35, 34 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 45, 44 }, { 47, 46 },
+ { 49, 48 }, { 51, 50 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 61, 60 }, { 63, 62 },
+ { 1, 0 }, { 3, 2 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 13, 12 }, { 15, 14 },
+ { 17, 16 }, { 19, 18 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 29, 28 }, { 31, 30 },
+ { 32, 33 }, { 34, 35 }, { 37, 36 }, { 39, 38 },
+ { 41, 40 }, { 43, 42 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 53, 52 }, { 55, 54 },
+ { 57, 56 }, { 59, 58 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t tch_ahs_4_75_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+};
+
+static const uint8_t tch_ahs_4_75_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22,
+ 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46,
+ 48, 50, 52, 54, 56, 58, 60, 62, 0, 2, 4, 6,
+ 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
+ 56, 58, 60, 62,
+};
+
+static const uint8_t tch_ahs_4_75_term_output[] = {
+ 0, 3, 5, 6, 5, 6, 0, 3, 3, 0, 6, 5,
+ 6, 5, 3, 0, 4, 7, 1, 2, 1, 2, 4, 7,
+ 7, 4, 2, 1, 2, 1, 7, 4, 7, 4, 2, 1,
+ 2, 1, 7, 4, 4, 7, 1, 2, 1, 2, 4, 7,
+ 3, 0, 6, 5, 6, 5, 3, 0, 0, 3, 5, 6,
+ 5, 6, 0, 3,
+};
+
+static const int tch_ahs_4_75_puncture[] = {
+ 1, 2, 4, 5, 7, 8, 10, 13, 16, 22, 28, 34,
+ 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106,
+ 112, 118, 124, 130, 136, 142, 148, 151, 154, 160, 163, 166,
+ 172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214,
+ 220, 223, 226, 232, 235, 238, 241, 244, 247, 250, 253, 256,
+ 259, 262, 265, 268, 271, 274, 275, 277, 278, 280, 281, 283,
+ 284, -1,
+};
+
+/**
+ * TCH/AHS 4.75 kbits convolutional code
+ */
+const struct osmo_conv_code gsm0503_tch_ahs_4_75 = {
+ .N = 3,
+ .K = 7,
+ .len = 89,
+ .next_output = tch_ahs_4_75_output,
+ .next_state = tch_ahs_4_75_state,
+ .next_term_output = tch_ahs_4_75_term_output,
+ .next_term_state = tch_ahs_4_75_term_state,
+ .puncture = tch_ahs_4_75_puncture,
+};
+
+static const uint8_t mcs1_dl_hdr_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs1_dl_hdr_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-1 DL header convolutional code:
+ * 42 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs1_dl_hdr = {
+ .N = 3,
+ .K = 7,
+ .len = 36,
+ .next_output = mcs1_dl_hdr_output,
+ .next_state = mcs1_dl_hdr_state,
+ .term = CONV_TERM_TAIL_BITING,
+};
+
+static const uint8_t mcs1_ul_hdr_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs1_ul_hdr_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-1 UL header convolutional code:
+ * 45 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs1_ul_hdr = {
+ .N = 3,
+ .K = 7,
+ .len = 39,
+ .next_output = mcs1_ul_hdr_output,
+ .next_state = mcs1_ul_hdr_state,
+ .term = CONV_TERM_TAIL_BITING,
+};
+
+static const uint8_t mcs1_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs1_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-1 data convolutional code:
+ * 196 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs1 = {
+ .N = 3,
+ .K = 7,
+ .len = 190,
+ .next_output = mcs1_output,
+ .next_state = mcs1_state,
+};
+
+static const uint8_t mcs2_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs2_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-2 data convolutional code:
+ * 244 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs2 = {
+ .N = 3,
+ .K = 7,
+ .len = 238,
+ .next_output = mcs2_output,
+ .next_state = mcs2_state,
+};
+
+static const uint8_t mcs3_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs3_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-3 data convolutional code:
+ * 316 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs3 = {
+ .N = 3,
+ .K = 7,
+ .len = 310,
+ .next_output = mcs3_output,
+ .next_state = mcs3_state,
+};
+
+static const uint8_t mcs4_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs4_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-4 data convolutional code:
+ * 372 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs4 = {
+ .N = 3,
+ .K = 7,
+ .len = 366,
+ .next_output = mcs4_output,
+ .next_state = mcs4_state,
+};
+
+static const uint8_t mcs5_dl_hdr_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs5_dl_hdr_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-5 DL header convolutional code:
+ * 39 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs5_dl_hdr = {
+ .N = 3,
+ .K = 7,
+ .len = 33,
+ .next_output = mcs5_dl_hdr_output,
+ .next_state = mcs5_dl_hdr_state,
+ .term = CONV_TERM_TAIL_BITING,
+};
+
+static const uint8_t mcs5_ul_hdr_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs5_ul_hdr_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-5 UL header convolutional code:
+ * 51 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs5_ul_hdr = {
+ .N = 3,
+ .K = 7,
+ .len = 45,
+ .next_output = mcs5_ul_hdr_output,
+ .next_state = mcs5_ul_hdr_state,
+ .term = CONV_TERM_TAIL_BITING,
+};
+
+static const uint8_t mcs5_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs5_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-5 data convolutional code:
+ * 468 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs5 = {
+ .N = 3,
+ .K = 7,
+ .len = 462,
+ .next_output = mcs5_output,
+ .next_state = mcs5_state,
+};
+
+static const uint8_t mcs6_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs6_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-6 data convolutional code:
+ * 612 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs6 = {
+ .N = 3,
+ .K = 7,
+ .len = 606,
+ .next_output = mcs6_output,
+ .next_state = mcs6_state,
+};
+
+static const uint8_t mcs7_dl_hdr_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs7_dl_hdr_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-7 DL header convolutional code:
+ * 51 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs7_dl_hdr = {
+ .N = 3,
+ .K = 7,
+ .len = 45,
+ .next_output = mcs7_dl_hdr_output,
+ .next_state = mcs7_dl_hdr_state,
+ .term = CONV_TERM_TAIL_BITING,
+};
+
+static const uint8_t mcs7_ul_hdr_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs7_ul_hdr_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-7 UL header convolutional code:
+ * 60 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs7_ul_hdr = {
+ .N = 3,
+ .K = 7,
+ .len = 54,
+ .next_output = mcs7_ul_hdr_output,
+ .next_state = mcs7_ul_hdr_state,
+ .term = CONV_TERM_TAIL_BITING,
+};
+
+static const uint8_t mcs7_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs7_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-7 data convolutional code:
+ * 468 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs7 = {
+ .N = 3,
+ .K = 7,
+ .len = 462,
+ .next_output = mcs7_output,
+ .next_state = mcs7_state,
+};
+
+static const uint8_t mcs8_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs8_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-8 data convolutional code:
+ * 564 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs8 = {
+ .N = 3,
+ .K = 7,
+ .len = 558,
+ .next_output = mcs8_output,
+ .next_state = mcs8_state,
+};
+
+static const uint8_t mcs9_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t mcs9_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 7, 0 }, { 4, 3 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 7, 0 }, { 4, 3 },
+ { 6, 1 }, { 5, 2 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 6, 1 }, { 5, 2 },
+ { 3, 4 }, { 0, 7 }, { 5, 2 }, { 6, 1 },
+ { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 },
+ { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 },
+ { 4, 3 }, { 7, 0 }, { 2, 5 }, { 1, 6 },
+};
+
+/**
+ * EDGE MCS-9 data convolutional code:
+ * 612 bits blocks, rate 1/3, k = 7
+ * G4 = 1 + D2 + D3 + D5 + D6
+ * G7 = 1 + D + D2 + D3 + D6
+ * G5 = 1 + D + D4 + D6
+ */
+const struct osmo_conv_code gsm0503_mcs9 = {
+ .N = 3,
+ .K = 7,
+ .len = 606,
+ .next_output = mcs9_output,
+ .next_state = mcs9_state,
+};
+
diff --git a/lib/decoding/osmocom/coding/gsm0503_interleaving.c b/lib/decoding/osmocom/coding/gsm0503_interleaving.c
new file mode 100644
index 0000000..333e105
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_interleaving.c
@@ -0,0 +1,573 @@
+/*
+ * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
+ * (C) 2016 by Tom Tsou <tom.tsou@ettus.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <osmocom/core/bits.h>
+#include "gsm0503_tables.h"
+#include "gsm0503_interleaving.h"
+
+/*
+ * GSM xCCH interleaving and burst mapping
+ *
+ * Interleaving:
+ *
+ * Given 456 coded input bits, form 4 blocks of 114 bits:
+ *
+ * i(B, j) = c(n, k) k = 0, ..., 455
+ * n = 0, ..., N, N + 1, ...
+ * B = B_0 + 4n + (k mod 4)
+ * j = 2(49k mod 57) + ((k mod 8) div 4)
+ *
+ * Mapping on Burst:
+ *
+ * e(B, j) = i(B, j)
+ * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56
+ * e(B, 57) = h_l(B)
+ * e(B, 58) = h_n(B)
+ *
+ * Where hl(B) and hn(B) are bits in burst B indicating flags.
+ */
+
+void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB)
+{
+ int j, k, B;
+
+ for (k = 0; k < 456; k++) {
+ B = k & 3;
+ j = 2 * ((49 * k) % 57) + ((k & 7) >> 2);
+ cB[k] = iB[B * 114 + j];
+ }
+}
+
+void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB)
+{
+ int j, k, B;
+
+ for (k = 0; k < 456; k++) {
+ B = k & 3;
+ j = 2 * ((49 * k) % 57) + ((k & 7) >> 2);
+ iB[B * 114 + j] = cB[k];
+ }
+}
+
+void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc,
+ sbit_t *dc, const sbit_t *iB)
+{
+ int k;
+ sbit_t c[452];
+ sbit_t cp[456];
+
+ gsm0503_xcch_deinterleave(cp, iB);
+
+ for (k = 0; k < 25; k++)
+ c[k] = cp[k];
+ for (k = 26; k < 82; k++)
+ c[k - 1] = cp[k];
+ for (k = 83; k < 139; k++)
+ c[k - 2] = cp[k];
+ for (k = 140; k < 424; k++)
+ c[k - 3] = cp[k];
+ for (k = 425; k < 456; k++)
+ c[k - 4] = cp[k];
+
+ if (u) {
+ for (k = 0; k < 12; k++)
+ u[k] = c[k];
+ }
+
+ if (hc) {
+ for (k = 12; k < 80; k++)
+ hc[k - 12] = c[k];
+ }
+
+ if (dc) {
+ for (k = 80; k < 452; k++)
+ dc[k - 80] = c[k];
+ }
+}
+
+void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc,
+ const ubit_t *dc, ubit_t *iB)
+{
+ int k;
+ ubit_t c[452];
+ ubit_t cp[456];
+
+ for (k = 0; k < 12; k++)
+ c[k] = up[k];
+ for (k = 12; k < 80; k++)
+ c[k] = hc[k - 12];
+ for (k = 80; k < 452; k++)
+ c[k] = dc[k - 80];
+
+ for (k = 0; k < 25; k++)
+ cp[k] = c[k];
+ for (k = 26; k < 82; k++)
+ cp[k] = c[k - 1];
+ for (k = 83; k < 139; k++)
+ cp[k] = c[k - 2];
+ for (k = 140; k < 424; k++)
+ cp[k] = c[k - 3];
+ for (k = 425; k < 456; k++)
+ cp[k] = c[k - 4];
+
+ cp[25] = 0;
+ cp[82] = 0;
+ cp[139] = 0;
+ cp[424] = 0;
+
+ gsm0503_xcch_interleave(cp, iB);
+}
+
+void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB)
+{
+ int k;
+ sbit_t c[452];
+ sbit_t cp[456];
+
+ gsm0503_xcch_deinterleave(cp, iB);
+
+ for (k = 0; k < 25; k++)
+ c[k] = cp[k];
+ for (k = 26; k < 82; k++)
+ c[k - 1] = cp[k];
+ for (k = 83; k < 139; k++)
+ c[k - 2] = cp[k];
+ for (k = 140; k < 424; k++)
+ c[k - 3] = cp[k];
+ for (k = 425; k < 456; k++)
+ c[k - 4] = cp[k];
+
+ if (hc) {
+ for (k = 0; k < 80; k++)
+ hc[k] = c[k];
+ }
+
+ if (dc) {
+ for (k = 80; k < 452; k++)
+ dc[k - 80] = c[k];
+ }
+}
+
+void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB)
+{
+ int k;
+ ubit_t c[452];
+ ubit_t cp[456];
+
+ for (k = 0; k < 80; k++)
+ c[k] = hc[k];
+ for (k = 80; k < 452; k++)
+ c[k] = dc[k - 80];
+
+ for (k = 0; k < 25; k++)
+ cp[k] = c[k];
+ for (k = 26; k < 82; k++)
+ cp[k] = c[k - 1];
+ for (k = 83; k < 139; k++)
+ cp[k] = c[k - 2];
+ for (k = 140; k < 424; k++)
+ cp[k] = c[k - 3];
+ for (k = 425; k < 456; k++)
+ cp[k] = c[k - 4];
+
+ cp[25] = 0;
+ cp[82] = 0;
+ cp[139] = 0;
+ cp[424] = 0;
+
+ gsm0503_xcch_interleave(cp, iB);
+}
+
+void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc,
+ ubit_t *hi, ubit_t *di)
+{
+ int j, k;
+
+ /* Header */
+ for (k = 0; k < 136; k++) {
+ j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4;
+ hi[j] = hc[k];
+ }
+
+ /* Data */
+ for (k = 0; k < 1248; k++) {
+ j = gsm0503_interleave_mcs5[k];
+ di[j] = dc[k];
+ }
+}
+
+void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc,
+ const sbit_t *hi, const sbit_t *di)
+{
+ int j, k;
+
+ /* Header */
+ if (hc) {
+ for (k = 0; k < 136; k++) {
+ j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4;
+ hc[k] = hi[j];
+ }
+ }
+
+ /* Data */
+ if (dc) {
+ for (k = 0; k < 1248; k++) {
+ j = gsm0503_interleave_mcs5[k];
+ dc[k] = di[j];
+ }
+ }
+}
+
+void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc,
+ ubit_t *hi, ubit_t *di)
+{
+ int j, k;
+
+ /* Header */
+ for (k = 0; k < 100; k++) {
+ j = 25 * (k % 4) + ((17 * k) % 25);
+ hi[j] = hc[k];
+ }
+
+ /* Data */
+ for (k = 0; k < 1248; k++) {
+ j = gsm0503_interleave_mcs5[k];
+ di[j] = dc[k];
+ }
+}
+
+void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc,
+ const sbit_t *hi, const sbit_t *di)
+{
+ int j, k;
+
+ /* Header */
+ if (hc) {
+ for (k = 0; k < 100; k++) {
+ j = 25 * (k % 4) + ((17 * k) % 25);
+ hc[k] = hi[j];
+ }
+ }
+
+ /* Data */
+ if (dc) {
+ for (k = 0; k < 1248; k++) {
+ j = gsm0503_interleave_mcs5[k];
+ dc[k] = di[j];
+ }
+ }
+}
+
+void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1,
+ const ubit_t *c2, ubit_t *hi, ubit_t *di)
+{
+ int j, k;
+ ubit_t dc[1224];
+
+ /* Header */
+ for (k = 0; k < 124; k++) {
+ j = 31 * (k % 4) + ((17 * k) % 31);
+ hi[j] = hc[k];
+ }
+
+ memcpy(&dc[0], c1, 612);
+ memcpy(&dc[612], c2, 612);
+
+ /* Data */
+ for (k = 0; k < 1224; k++) {
+ j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) +
+ (k + 2 - k / 408) % 3;
+ di[j] = dc[k];
+ }
+}
+
+
+void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+ const sbit_t *hi, const sbit_t *di)
+{
+ int j, k;
+ ubit_t dc[1224];
+
+ /* Header */
+ if (hc) {
+ for (k = 0; k < 124; k++) {
+ j = 31 * (k % 4) + ((17 * k) % 31);
+ hc[k] = hi[j];
+ }
+ }
+
+ /* Data */
+ if (c1 && c2) {
+ for (k = 0; k < 1224; k++) {
+ j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) +
+ (k + 2 - k / 408) % 3;
+ dc[k] = di[j];
+ }
+
+ memcpy(c1, &dc[0], 612);
+ memcpy(c2, &dc[612], 612);
+ }
+}
+
+void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1,
+ const ubit_t *c2, ubit_t *hi, ubit_t *di)
+{
+ int j, k;
+ ubit_t dc[1224];
+
+ /* Header */
+ for (k = 0; k < 160; k++) {
+ j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+ hi[j] = hc[k];
+ }
+
+ memcpy(&dc[0], c1, 612);
+ memcpy(&dc[612], c2, 612);
+
+ /* Data */
+ for (k = 0; k < 1224; k++) {
+ j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) +
+ (k + 2 - k / 408) % 3;
+ di[j] = dc[k];
+ }
+}
+
+void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+ const sbit_t *hi, const sbit_t *di)
+{
+ int j, k;
+ ubit_t dc[1224];
+
+ /* Header */
+ if (hc) {
+ for (k = 0; k < 160; k++) {
+ j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+ hc[k] = hi[j];
+ }
+ }
+
+ /* Data */
+ if (c1 && c2) {
+ for (k = 0; k < 1224; k++) {
+ j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) +
+ (k + 2 - k / 408) % 3;
+ dc[k] = di[j];
+ }
+
+ memcpy(c1, &dc[0], 612);
+ memcpy(c2, &dc[612], 612);
+ }
+}
+
+void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1,
+ const ubit_t *c2, ubit_t *hi, ubit_t *di)
+{
+ int j, k;
+ ubit_t dc[1224];
+
+ /* Header */
+ for (k = 0; k < 160; k++) {
+ j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+ hi[j] = hc[k];
+ }
+
+ memcpy(&dc[0], c1, 612);
+ memcpy(&dc[612], c2, 612);
+
+ /* Data */
+ for (k = 0; k < 1224; k++) {
+ j = 306 * (2 * (k / 612) + (k % 2)) +
+ 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3;
+ di[j] = dc[k];
+ }
+}
+
+void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+ const sbit_t *hi, const sbit_t *di)
+{
+ int j, k;
+ ubit_t dc[1224];
+
+ /* Header */
+ if (hc) {
+ for (k = 0; k < 160; k++) {
+ j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+ hc[k] = hi[j];
+ }
+ }
+
+ /* Data */
+ if (c1 && c2) {
+ for (k = 0; k < 1224; k++) {
+ j = 306 * (2 * (k / 612) + (k % 2)) +
+ 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3;
+ dc[k] = di[j];
+ }
+
+ memcpy(c1, &dc[0], 612);
+ memcpy(c2, &dc[612], 612);
+ }
+}
+
+void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1,
+ const ubit_t *c2, ubit_t *hi, ubit_t *di)
+{
+ int j, k;
+ ubit_t dc[1224];
+
+ /* Header */
+ for (k = 0; k < 124; k++) {
+ j = 31 * (k % 4) + ((17 * k) % 31);
+ hi[j] = hc[k];
+ }
+
+ memcpy(&dc[0], c1, 612);
+ memcpy(&dc[612], c2, 612);
+
+ /* Data */
+ for (k = 0; k < 1224; k++) {
+ j = 306 * (2 * (k / 612) + (k % 2)) +
+ 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3;
+ di[j] = dc[k];
+ }
+}
+
+void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+ const sbit_t *hi, const sbit_t *di)
+{
+ int j, k;
+ ubit_t dc[1224];
+
+ /* Header */
+ if (hc) {
+ for (k = 0; k < 124; k++) {
+ j = 31 * (k % 4) + ((17 * k) % 31);
+ hc[k] = hi[j];
+ }
+ }
+
+ /* Data */
+ if (c1 && c2) {
+ for (k = 0; k < 1224; k++) {
+ j = 306 * (2 * (k / 612) + (k % 2)) +
+ 3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3;
+ dc[k] = di[j];
+ }
+
+ memcpy(c1, &dc[0], 612);
+ memcpy(c2, &dc[612], 612);
+ }
+}
+
+/*
+ * GSM TCH FR/EFR/AFS interleaving and burst mapping
+ *
+ * Interleaving:
+ *
+ * Given 456 coded input bits, form 8 blocks of 114 bits,
+ * where even bits of the first 4 blocks and odd bits of the last 4 blocks
+ * are used:
+ *
+ * i(B, j) = c(n, k) k = 0, ..., 455
+ * n = 0, ..., N, N + 1, ...
+ * B = B_0 + 4n + (k mod 8)
+ * j = 2(49k mod 57) + ((k mod 8) div 4)
+ *
+ * Mapping on Burst:
+ *
+ * e(B, j) = i(B, j)
+ * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56
+ * e(B, 57) = h_l(B)
+ * e(B, 58) = h_n(B)
+ *
+ * Where hl(B) and hn(B) are bits in burst B indicating flags.
+ */
+
+void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB)
+{
+ int j, k, B;
+
+ for (k = 0; k < 456; k++) {
+ B = k & 7;
+ j = 2 * ((49 * k) % 57) + ((k & 7) >> 2);
+ cB[k] = iB[B * 114 + j];
+ }
+}
+
+void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB)
+{
+ int j, k, B;
+
+ for (k = 0; k < 456; k++) {
+ B = k & 7;
+ j = 2 * ((49 * k) % 57) + ((k & 7) >> 2);
+ iB[B * 114 + j] = cB[k];
+ }
+}
+
+/*
+ * GSM TCH HR/AHS interleaving and burst mapping
+ *
+ * Interleaving:
+ *
+ * Given 288 coded input bits, form 4 blocks of 114 bits,
+ * where even bits of the first 2 blocks and odd bits of the last 2 blocks
+ * are used:
+ *
+ * i(B, j) = c(n, k) k = 0, ..., 227
+ * n = 0, ..., N, N + 1, ...
+ * B = B_0 + 2n + b
+ * j, b = table[k];
+ *
+ * Mapping on Burst:
+ *
+ * e(B, j) = i(B, j)
+ * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56
+ * e(B, 57) = h_l(B)
+ * e(B, 58) = h_n(B)
+ *
+ * Where hl(B) and hn(B) are bits in burst B indicating flags.
+ */
+
+void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB)
+{
+ int j, k, B;
+
+ for (k = 0; k < 228; k++) {
+ B = gsm0503_tch_hr_interleaving[k][1];
+ j = gsm0503_tch_hr_interleaving[k][0];
+ cB[k] = iB[B * 114 + j];
+ }
+}
+
+void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB)
+{
+ int j, k, B;
+
+ for (k = 0; k < 228; k++) {
+ B = gsm0503_tch_hr_interleaving[k][1];
+ j = gsm0503_tch_hr_interleaving[k][0];
+ iB[B * 114 + j] = cB[k];
+ }
+}
diff --git a/lib/decoding/osmocom/coding/gsm0503_interleaving.h b/lib/decoding/osmocom/coding/gsm0503_interleaving.h
new file mode 100644
index 0000000..f97dff4
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_interleaving.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <osmocom/core/bits.h>
+
+void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB);
+void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB);
+
+void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB);
+void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB);
+
+void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB);
+void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB);
+
+void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB);
+void gsm0503_mcs1_ul_interleave(const ubit_t *hc,
+ const ubit_t *dc, ubit_t *iB);
+
+void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc,
+ sbit_t *dc, const sbit_t *iB);
+void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc,
+ const ubit_t *dc, ubit_t *iB);
+
+void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc,
+ const sbit_t *hi, const sbit_t *di);
+void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc,
+ ubit_t *hi, ubit_t *di);
+
+void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc,
+ const sbit_t *hi, const sbit_t *di);
+void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc,
+ ubit_t *hi, ubit_t *di);
+
+void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+ const sbit_t *hi, const sbit_t *di);
+void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1,
+ const ubit_t *c2, ubit_t *hi, ubit_t *di);
+
+void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+ const sbit_t *hi, const sbit_t *di);
+void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1,
+ const ubit_t *c2, ubit_t *hi, ubit_t *di);
+
+void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+ const sbit_t *hi, const sbit_t *di);
+void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1,
+ const ubit_t *c2, ubit_t *hi, ubit_t *di);
+
+void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+ const sbit_t *hi, const sbit_t *di);
+void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1,
+ const ubit_t *c2, ubit_t *hi, ubit_t *di);
diff --git a/lib/decoding/osmocom/coding/gsm0503_mapping.c b/lib/decoding/osmocom/coding/gsm0503_mapping.c
new file mode 100644
index 0000000..45275bf
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_mapping.c
@@ -0,0 +1,291 @@
+/*
+ * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
+ * (C) 2016 by Tom Tsou <tom.tsou@ettus.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <osmocom/core/bits.h>
+#include "gsm0503_mapping.h"
+
+void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB,
+ sbit_t *hl, sbit_t *hn)
+{
+ memcpy(iB, eB, 57);
+ memcpy(iB + 57, eB + 59, 57);
+
+ if (hl)
+ *hl = eB[57];
+
+ if (hn)
+ *hn = eB[58];
+}
+
+void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl,
+ const ubit_t *hn)
+{
+ memcpy(eB, iB, 57);
+ memcpy(eB + 59, iB + 57, 57);
+
+ if (hl)
+ eB[57] = *hl;
+ if (hn)
+ eB[58] = *hn;
+}
+
+void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd)
+{
+ int i;
+
+ /* brainfuck: only copy even or odd bits */
+ if (iB) {
+ for (i = odd; i < 57; i += 2)
+ iB[i] = eB[i];
+ for (i = 58 - odd; i < 114; i += 2)
+ iB[i] = eB[i + 2];
+ }
+
+ if (h) {
+ if (!odd)
+ *h = eB[58];
+ else
+ *h = eB[57];
+ }
+}
+
+void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd)
+{
+ int i;
+
+ /* brainfuck: only copy even or odd bits */
+ if (eB) {
+ for (i = odd; i < 57; i += 2)
+ eB[i] = iB[i];
+ for (i = 58 - odd; i < 114; i += 2)
+ eB[i + 2] = iB[i];
+ }
+
+ if (h) {
+ if (!odd)
+ eB[58] = *h;
+ else
+ eB[57] = *h;
+ }
+}
+
+void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB,
+ const ubit_t *hi, const ubit_t *up, int B)
+{
+ int j;
+ int q[8] = { 0, 0, 0, 0, 0, 0, 0, 0, };
+
+ for (j = 0; j < 156; j++)
+ eB[j] = di[312 * B + j];
+ for (j = 156; j < 168; j++)
+ eB[j] = hi[25 * B + j - 156];
+ for (j = 168; j < 174; j++)
+ eB[j] = up[9 * B + j - 168];
+ for (j = 174; j < 176; j++)
+ eB[j] = q[2 * B + j - 174];
+ for (j = 176; j < 179; j++)
+ eB[j] = up[9 * B + j - 170];
+ for (j = 179; j < 192; j++)
+ eB[j] = hi[25 * B + j - 167];
+ for (j = 192; j < 348; j++)
+ eB[j] = di[312 * B + j - 36];
+}
+
+void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB,
+ sbit_t *hi, sbit_t *up, int B)
+{
+ int j;
+
+ for (j = 0; j < 156; j++)
+ di[312 * B + j] = eB[j];
+ for (j = 156; j < 168; j++)
+ hi[25 * B + j - 156] = eB[j];
+ for (j = 168; j < 174; j++)
+ up[9 * B + j - 168] = eB[j];
+
+ for (j = 176; j < 179; j++)
+ up[9 * B + j - 170] = eB[j];
+ for (j = 179; j < 192; j++)
+ hi[25 * B + j - 167] = eB[j];
+ for (j = 192; j < 348; j++)
+ di[312 * B + j - 36] = eB[j];
+}
+
+void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB,
+ const ubit_t *hi, int B)
+{
+ int j;
+
+ for (j = 0; j < 156; j++)
+ eB[j] = di[312 * B + j];
+ for (j = 156; j < 174; j++)
+ eB[j] = hi[34 * B + j - 156];
+ for (j = 174; j < 176; j++)
+ eB[j] = 0;
+ for (j = 176; j < 192; j++)
+ eB[j] = hi[34 * B + j - 158];
+ for (j = 192; j < 348; j++)
+ eB[j] = di[312 * B + j - 36];
+}
+
+void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB,
+ sbit_t *hi, int B)
+{
+ int j;
+
+ for (j = 0; j < 156; j++)
+ di[312 * B + j] = eB[j];
+ for (j = 156; j < 174; j++)
+ hi[34 * B + j - 156] = eB[j];
+ for (j = 176; j < 192; j++)
+ hi[34 * B + j - 158] = eB[j];
+ for (j = 192; j < 348; j++)
+ di[312 * B + j - 36] = eB[j];
+}
+
+void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB,
+ const ubit_t *hi, const ubit_t *up, int B)
+{
+ int j;
+ int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, };
+
+ for (j = 0; j < 153; j++)
+ eB[j] = di[306 * B + j];
+ for (j = 153; j < 168; j++)
+ eB[j] = hi[31 * B + j - 153];
+ for (j = 168; j < 174; j++)
+ eB[j] = up[9 * B + j - 168];
+ for (j = 174; j < 176; j++)
+ eB[j] = q[2 * B + j - 174];
+ for (j = 176; j < 179; j++)
+ eB[j] = up[9 * B + j - 170];
+ for (j = 179; j < 195; j++)
+ eB[j] = hi[31 * B + j - 164];
+ for (j = 195; j < 348; j++)
+ eB[j] = di[306 * B + j - 42];
+}
+
+void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB,
+ sbit_t *hi, sbit_t *up, int B)
+{
+ int j;
+
+ for (j = 0; j < 153; j++)
+ di[306 * B + j] = eB[j];
+ for (j = 153; j < 168; j++)
+ hi[31 * B + j - 153] = eB[j];
+ for (j = 168; j < 174; j++)
+ up[9 * B + j - 168] = eB[j];
+
+ for (j = 176; j < 179; j++)
+ up[9 * B + j - 170] = eB[j];
+ for (j = 179; j < 195; j++)
+ hi[31 * B + j - 164] = eB[j];
+ for (j = 195; j < 348; j++)
+ di[306 * B + j - 42] = eB[j];
+}
+
+void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB,
+ const ubit_t *hi, int B)
+{
+ int j;
+ int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, };
+
+ for (j = 0; j < 153; j++)
+ eB[j] = di[306 * B + j];
+ for (j = 153; j < 174; j++)
+ eB[j] = hi[40 * B + j - 153];
+ for (j = 174; j < 176; j++)
+ eB[j] = q[2 * B + j - 174];
+ for (j = 176; j < 195; j++)
+ eB[j] = hi[40 * B + j - 155];
+ for (j = 195; j < 348; j++)
+ eB[j] = di[306 * B + j - 42];
+}
+
+void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB,
+ sbit_t *hi, int B)
+{
+ int j;
+
+ for (j = 0; j < 153; j++)
+ di[306 * B + j] = eB[j];
+ for (j = 153; j < 174; j++)
+ hi[40 * B + j - 153] = eB[j];
+
+ for (j = 176; j < 195; j++)
+ hi[40 * B + j - 155] = eB[j];
+ for (j = 195; j < 348; j++)
+ di[306 * B + j - 42] = eB[j];
+}
+
+void gsm0503_mcs5_burst_swap(sbit_t *eB)
+{
+ sbit_t t[14];
+
+ t[0] = eB[155];
+ t[1] = eB[158];
+ t[2] = eB[161];
+ t[3] = eB[164];
+ t[4] = eB[167];
+ t[5] = eB[170];
+ t[6] = eB[173];
+ t[7] = eB[195];
+ t[8] = eB[196];
+ t[9] = eB[198];
+ t[10] = eB[199];
+ t[11] = eB[201];
+ t[12] = eB[202];
+ t[13] = eB[204];
+
+ eB[155] = eB[142];
+ eB[158] = eB[144];
+ eB[161] = eB[145];
+ eB[164] = eB[147];
+ eB[167] = eB[148];
+ eB[170] = eB[150];
+ eB[173] = eB[151];
+ eB[195] = eB[176];
+ eB[196] = eB[179];
+ eB[198] = eB[182];
+ eB[199] = eB[185];
+ eB[201] = eB[188];
+ eB[202] = eB[191];
+ eB[204] = eB[194];
+
+ eB[142] = t[0];
+ eB[144] = t[1];
+ eB[145] = t[2];
+ eB[147] = t[3];
+ eB[148] = t[4];
+ eB[150] = t[5];
+ eB[151] = t[6];
+ eB[176] = t[7];
+ eB[179] = t[8];
+ eB[182] = t[9];
+ eB[185] = t[10];
+ eB[188] = t[11];
+ eB[191] = t[12];
+ eB[194] = t[13];
+}
diff --git a/lib/decoding/osmocom/coding/gsm0503_mapping.h b/lib/decoding/osmocom/coding/gsm0503_mapping.h
new file mode 100644
index 0000000..4c6550a
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_mapping.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <osmocom/core/bits.h>
+
+void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB,
+ sbit_t *hl, sbit_t *hn);
+void gsm0503_xcch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *hl,
+ const ubit_t *hn);
+
+void gsm0503_tch_burst_unmap(sbit_t *iB, sbit_t *eB, sbit_t *h, int odd);
+void gsm0503_tch_burst_map(ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd);
+
+void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB,
+ const ubit_t *hi, int B);
+void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB,
+ sbit_t *hi, int B);
+
+void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB,
+ const ubit_t *hi, int B);
+void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB,
+ sbit_t *hi, int B);
+
+void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB,
+ const ubit_t *hi, const ubit_t *up, int B);
+void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB,
+ sbit_t *hi, sbit_t *up, int B);
+
+void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB,
+ const ubit_t *hi, const ubit_t *up, int B);
+void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB,
+ sbit_t *hi, sbit_t *up, int B);
+
+void gsm0503_mcs5_burst_swap(sbit_t *eB);
diff --git a/lib/decoding/osmocom/coding/gsm0503_parity.c b/lib/decoding/osmocom/coding/gsm0503_parity.c
new file mode 100644
index 0000000..50977f7
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_parity.c
@@ -0,0 +1,132 @@
+/*
+ * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
+ * (C) 2016 by Tom Tsou <tom.tsou@ettus.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/crcgen.h>
+#include "gsm0503_parity.h"
+
+/*
+ * GSM (SACCH) parity (FIRE code)
+ *
+ * g(x) = (x^23 + 1)(x^17 + x^3 + 1)
+ * = x^40 + x^26 + x^23 + x^17 + x^3 + a1
+ */
+const struct osmo_crc64gen_code gsm0503_fire_crc40 = {
+ .bits = 40,
+ .poly = 0x0004820009ULL,
+ .init = 0x0000000000ULL,
+ .remainder = 0xffffffffffULL,
+};
+
+/*
+ * GSM PDTCH CS-2, CS-3, CS-4 parity
+ *
+ * g(x) = x^16 + x^12 + x^5 + 1
+ */
+const struct osmo_crc16gen_code gsm0503_cs234_crc16 = {
+ .bits = 16,
+ .poly = 0x1021,
+ .init = 0x0000,
+ .remainder = 0xffff,
+};
+
+/*
+ * EDGE MCS header parity
+ *
+ */
+const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr = {
+ .bits = 8,
+ .poly = 0x49,
+ .init = 0x00,
+ .remainder = 0xff,
+};
+
+/*
+ * EDGE MCS data parity
+ *
+ */
+const struct osmo_crc16gen_code gsm0503_mcs_crc12 = {
+ .bits = 12,
+ .poly = 0x0d31,
+ .init = 0x0000,
+ .remainder = 0x0fff,
+};
+
+/*
+ * GSM RACH parity
+ *
+ * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1
+ */
+const struct osmo_crc8gen_code gsm0503_rach_crc6 = {
+ .bits = 6,
+ .poly = 0x2f,
+ .init = 0x00,
+ .remainder = 0x3f,
+};
+
+/*
+ * GSM SCH parity
+ *
+ * g(x) = x^10 + x^8 + x^6 + x^5 + x^4 + x^2 + 1
+ */
+const struct osmo_crc16gen_code gsm0503_sch_crc10 = {
+ .bits = 10,
+ .poly = 0x175,
+ .init = 0x000,
+ .remainder = 0x3ff,
+};
+
+/*
+ * GSM TCH FR/HR/EFR parity
+ *
+ * g(x) = x^3 + x + 1
+ */
+const struct osmo_crc8gen_code gsm0503_tch_fr_crc3 = {
+ .bits = 3,
+ .poly = 0x3,
+ .init = 0x0,
+ .remainder = 0x7,
+};
+
+/*
+ * GSM TCH EFR parity
+ *
+ * g(x) = x^8 + x^4 + x^3 + x^2 + 1
+ */
+const struct osmo_crc8gen_code gsm0503_tch_efr_crc8 = {
+ .bits = 8,
+ .poly = 0x1d,
+ .init = 0x00,
+ .remainder = 0x00,
+};
+
+/*
+ * GSM AMR parity
+ *
+ * g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1
+ */
+const struct osmo_crc8gen_code gsm0503_amr_crc6 = {
+ .bits = 6,
+ .poly = 0x2f,
+ .init = 0x00,
+ .remainder = 0x3f,
+};
diff --git a/lib/decoding/osmocom/coding/gsm0503_parity.h b/lib/decoding/osmocom/coding/gsm0503_parity.h
new file mode 100644
index 0000000..540124a
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_parity.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <osmocom/core/crcgen.h>
+
+const struct osmo_crc64gen_code gsm0503_fire_crc40;
+const struct osmo_crc16gen_code gsm0503_cs234_crc16;
+const struct osmo_crc8gen_code gsm0503_mcs_crc8_hdr;
+const struct osmo_crc16gen_code gsm0503_mcs_crc12;
+const struct osmo_crc8gen_code gsm0503_rach_crc6;
+const struct osmo_crc16gen_code gsm0503_sch_crc10;
+const struct osmo_crc8gen_code gsm0503_tch_fr_crc3;
+const struct osmo_crc8gen_code gsm0503_tch_efr_crc8;
+const struct osmo_crc8gen_code gsm0503_amr_crc6;
diff --git a/lib/decoding/osmocom/coding/gsm0503_tables.c b/lib/decoding/osmocom/coding/gsm0503_tables.c
new file mode 100644
index 0000000..d4cabcc
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_tables.c
@@ -0,0 +1,1732 @@
+/*
+ * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
+ * (C) 2016 by Tom Tsou <tom.tsou@ettus.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include "gsm0503_tables.h"
+
+const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8] = {
+ { 1,1, 1,1, 1,1, 1,1 },
+ { 1,1, 0,0, 1,0, 0,0 },
+ { 0,0, 1,0, 0,0, 0,1 },
+ { 0,0, 0,1, 0,1, 1,0 },
+};
+
+const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8] = {
+ { 0,0, 0,1, 0,1, 1,0 },
+ { 0,0, 0,0, 0,0, 0,0 },
+ { 1,1, 1,0, 0,1, 1,1 },
+};
+
+const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8] = {
+ { -127,-127, -127,-127, -127,-127, -127,-127 },
+ { -127,-127, 127, 127, -127, 127, 127, 127 },
+ { 127, 127, -127, 127, 127, 127, 127,-127 },
+ { 127, 127, 127,-127, 127,-127, -127, 127 },
+};
+
+const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8] = {
+ { 127, 127, 127,-127, 127,-127, -127, 127 },
+ { 127, 127, 127, 127, 127, 127, 127, 127 },
+ { -127,-127, -127, 127, 127,-127, -127,-127 },
+};
+
+const ubit_t gsm0503_usf2six[8][6] = {
+ { 0,0,0, 0,0,0 },
+ { 1,0,0, 1,0,1 },
+ { 0,1,0, 1,1,0 },
+ { 1,1,0, 0,1,1 },
+ { 0,0,1, 0,1,1 },
+ { 1,0,1, 1,1,0 },
+ { 0,1,1, 1,0,1 },
+ { 1,1,1, 0,0,0 },
+};
+
+const ubit_t gsm0503_usf2twelve_ubit[8][12] = {
+ { 0,0,0, 0,0,0, 0,0,0, 0,0,0 },
+ { 1,1,0, 1,0,0, 0,0,1, 0,1,1 },
+ { 0,0,1, 1,0,1, 1,1,0, 1,1,0 },
+ { 1,1,1, 0,0,1, 1,1,1, 1,0,1 },
+ { 0,0,0, 0,1,1, 0,1,1, 1,0,1 },
+ { 1,1,0, 1,1,1, 0,1,0, 1,1,0 },
+ { 0,0,1, 1,1,0, 1,0,1, 0,1,1 },
+ { 1,1,1, 0,1,0, 1,0,0, 0,0,0 },
+};
+
+const sbit_t gsm0503_usf2twelve_sbit[8][12] = {
+ { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127 },
+ { -127,-127, 127, -127, 127, 127, 127, 127,-127, 127,-127,-127 },
+ { 127, 127,-127, -127, 127,-127, -127,-127, 127, -127,-127, 127 },
+ { -127,-127,-127, 127, 127,-127, -127,-127,-127, -127, 127,-127 },
+ { 127, 127, 127, 127,-127,-127, 127,-127,-127, -127, 127,-127 },
+ { -127,-127, 127, -127,-127,-127, 127,-127, 127, -127,-127, 127 },
+ { 127, 127,-127, -127,-127, 127, -127, 127,-127, 127,-127,-127 },
+ { -127,-127,-127, 127,-127, 127, -127, 127, 127, 127, 127, 127 },
+};
+
+const uint8_t gsm0503_puncture_cs2[588] = {
+ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,1, 0,0,0,1,
+ 0,0,0,1, 0,0,0,1, 0,0,0,1
+};
+
+const uint8_t gsm0503_puncture_cs3[676] = {
+ 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,1,0,1,
+ 0,0,0,1,0,1, 0,0,0,1,0,1, 0,0,0,0
+};
+
+const uint8_t gsm0503_puncture_mcs1_dl_hdr[108] = {
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,1,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,1,1,
+};
+
+const uint8_t gsm0503_puncture_mcs1_ul_hdr[117] = {
+ 0,0,0,0,0,1,0,0,1,0,0,1,
+ 0,0,0,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs1_p1[588] = {
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,0,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+ 0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs1_p2[588] = {
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+ 0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,0,0,1,0,
+};
+
+const uint8_t gsm0503_puncture_mcs2_p1[732] = {
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,0,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,0,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0, 0,0,1,1,1,0,
+ 0,0,1,1,1,0, 0,0,1,1,1,0,
+};
+
+const uint8_t gsm0503_puncture_mcs2_p2[732] = {
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 0,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 0,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1, 1,1,0,0,0,1,
+ 1,1,0,0,0,1, 1,1,0,0,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs3_p1[948] = {
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,
+ 0,0,1,0,1,1,0,1,1,1,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs3_p2[948] = {
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,
+};
+
+const uint8_t gsm0503_puncture_mcs3_p3[948] = {
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,
+};
+
+const uint8_t gsm0503_puncture_mcs4_p1[1116] = {
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1,
+};
+
+const uint8_t gsm0503_puncture_mcs4_p2[1116] = {
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs4_p3[1116] = {
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0,
+};
+
+const uint8_t gsm0503_puncture_mcs5_p1[1404] = {
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0, 0,0,1,0,0,1,0,0,1, 0,0,1,0,0,1,0,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs5_p2[1404] = {
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0, 0,1,0,0,1,0,0,1,0, 0,1,0,0,1,0,0,1,0,
+};
+
+const uint8_t gsm0503_puncture_mcs6_p1[1836] = {
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,
+ 0,0,1, 0,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs6_p2[1836] = {
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,0,0,
+ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,
+ 0,1,0, 0,1,0,
+};
+
+const uint8_t gsm0503_puncture_mcs7_dl_hdr[135] = {
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,1,0,0,0,0,0,
+ 0,0,0,1,0,0,0,0,0,0,
+ 0,0,0,1,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 1,0,0,0,0,0,0,0,0,1,
+ 0,0,0,0,0,0,0,0,0,1,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,1,0,0,0,
+ 0,0,0,0,0,1,0,0,0,0,
+ 0,0,0,0,0,1,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,0,0,0,
+ 0,1,0,0,0,
+};
+
+const uint8_t gsm0503_puncture_mcs7_ul_hdr[162] = {
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,1,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,1,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,
+};
+
+const uint8_t gsm0503_puncture_mcs7_p1[1404] = {
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+ 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,1,
+};
+
+const uint8_t gsm0503_puncture_mcs7_p2[1404] = {
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+ 1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,
+};
+
+const uint8_t gsm0503_puncture_mcs7_p3[1404] = {
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,0,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+ 1,1,0,1,1,0,0,0,1,0,1,1,0,1,1,1,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs8_p1[1692] = {
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+ 0,1,0,1,1,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,
+};
+
+const uint8_t gsm0503_puncture_mcs8_p2[1692] = {
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,
+};
+
+const uint8_t gsm0503_puncture_mcs8_p3[1692] = {
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,0,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+ 1,1,0,0,1,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,1,0,1,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs9_p1[1836] = {
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+ 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1,
+};
+
+const uint8_t gsm0503_puncture_mcs9_p2[1836] = {
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+ 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1,
+};
+
+const uint8_t gsm0503_puncture_mcs9_p3[1836] = {
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+ 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,
+};
+
+const uint16_t gsm0503_interleave_mcs5[1248] = {
+ 0, 463, 890, 1038, 220, 371, 795, 946, 582, 733, 1160, 63, 490, 641, 277, 428,
+ 852, 1003, 185, 333, 1223, 120, 547, 698, 1122, 28, 915, 1066, 242, 390, 817, 968,
+ 610, 761, 1185, 85, 512, 660, 305, 453, 880, 1031, 204, 355, 782, 1242, 148, 575,
+ 723, 1150, 50, 474, 625, 1088, 267, 418, 845, 993, 169, 320, 1207, 113, 537, 688,
+ 1115, 12, 902, 1050, 232, 383, 807, 958, 594, 745, 1172, 75, 502, 653, 289, 440,
+ 864, 1015, 197, 345, 1235, 132, 559, 710, 1134, 40, 927, 1078, 254, 402, 829, 980,
+ 159, 622, 773, 1197, 97, 524, 672, 1099, 5, 465, 892, 1043, 216, 367, 794, 942,
+ 587, 735, 1162, 62, 486, 637, 279, 430, 857, 1005, 181, 332, 1219, 125, 549, 700,
+ 1127, 24, 914, 1062, 244, 395, 819, 970, 606, 757, 1184, 87, 514, 665, 301, 452,
+ 876, 1027, 209, 357, 784, 1247, 144, 571, 722, 1146, 52, 479, 627, 1090, 266, 414,
+ 841, 992, 171, 322, 1209, 109, 536, 684, 1111, 17, 904, 1055, 228, 379, 806, 954,
+ 599, 747, 1174, 74, 498, 649, 291, 442, 869, 1017, 193, 344, 1231, 137, 561, 712,
+ 1139, 36, 926, 1074, 256, 407, 831, 982, 158, 618, 769, 1196, 99, 526, 677, 1101,
+ 7, 458, 894, 1033, 227, 363, 802, 941, 577, 740, 1152, 70, 485, 645, 284, 420,
+ 859, 998, 189, 328, 1215, 127, 542, 702, 1117, 35, 922, 1061, 246, 385, 824, 960,
+ 605, 765, 1180, 92, 504, 667, 309, 448, 887, 1023, 211, 350, 786, 1237, 155, 567,
+ 730, 1145, 54, 469, 632, 1080, 274, 413, 849, 988, 176, 312, 1202, 117, 532, 695,
+ 1107, 19, 906, 1045, 239, 375, 814, 953, 589, 752, 1164, 82, 497, 657, 296, 432,
+ 871, 1010, 201, 340, 1227, 139, 554, 714, 1129, 47, 934, 1073, 258, 397, 836, 972,
+ 166, 617, 777, 1192, 104, 516, 679, 1094, 9, 460, 899, 1035, 223, 362, 798, 937,
+ 579, 742, 1157, 66, 481, 644, 286, 425, 861, 1000, 188, 324, 1214, 129, 544, 707,
+ 1119, 31, 918, 1057, 251, 387, 826, 965, 601, 764, 1176, 94, 509, 669, 308, 444,
+ 883, 1022, 213, 352, 791, 1239, 151, 566, 726, 1141, 59, 471, 634, 1085, 270, 409,
+ 848, 984, 178, 317, 1204, 116, 528, 691, 1106, 21, 911, 1047, 235, 374, 810, 949,
+ 591, 754, 1169, 78, 493, 656, 298, 437, 873, 1012, 200, 336, 1226, 141, 556, 719,
+ 1131, 43, 930, 1069, 263, 399, 838, 977, 162, 613, 776, 1188, 106, 521, 681, 1096,
+ 2, 462, 889, 1040, 219, 370, 797, 945, 584, 732, 1159, 65, 489, 640, 276, 427,
+ 854, 1002, 184, 335, 1222, 122, 546, 697, 1124, 27, 917, 1065, 241, 392, 816, 967,
+ 609, 760, 1187, 84, 511, 662, 304, 455, 879, 1030, 206, 354, 781, 1244, 147, 574,
+ 725, 1149, 49, 476, 624, 1087, 269, 417, 844, 995, 168, 319, 1206, 112, 539, 687,
+ 1114, 14, 901, 1052, 231, 382, 809, 957, 596, 744, 1171, 77, 501, 652, 288, 439,
+ 866, 1014, 196, 347, 1234, 134, 558, 709, 1136, 39, 929, 1077, 253, 404, 828, 979,
+ 161, 621, 772, 1199, 96, 523, 674, 1098, 4, 467, 891, 1042, 218, 366, 793, 944,
+ 586, 737, 1161, 61, 488, 636, 281, 429, 856, 1007, 180, 331, 1218, 124, 551, 699,
+ 1126, 26, 913, 1064, 243, 394, 821, 969, 608, 756, 1183, 89, 513, 664, 300, 451,
+ 878, 1026, 208, 359, 783, 1246, 146, 570, 721, 1148, 51, 478, 629, 1089, 265, 416,
+ 840, 991, 173, 321, 1211, 108, 535, 686, 1110, 16, 903, 1054, 230, 378, 805, 956,
+ 598, 749, 1173, 73, 500, 648, 293, 441, 868, 1019, 192, 343, 1230, 136, 563, 711,
+ 1138, 38, 925, 1076, 255, 406, 833, 981, 157, 620, 768, 1195, 101, 525, 676, 1103,
+ 6, 457, 896, 1032, 226, 365, 801, 940, 576, 739, 1154, 69, 484, 647, 283, 422,
+ 858, 997, 191, 327, 1217, 126, 541, 704, 1116, 34, 921, 1060, 248, 384, 823, 962,
+ 604, 767, 1179, 91, 506, 666, 311, 447, 886, 1025, 210, 349, 788, 1236, 154, 569,
+ 729, 1144, 56, 468, 631, 1082, 273, 412, 851, 987, 175, 314, 1201, 119, 531, 694,
+ 1109, 18, 908, 1044, 238, 377, 813, 952, 588, 751, 1166, 81, 496, 659, 295, 434,
+ 870, 1009, 203, 339, 1229, 138, 553, 716, 1128, 46, 933, 1072, 260, 396, 835, 974,
+ 165, 616, 779, 1191, 103, 518, 678, 1093, 11, 459, 898, 1037, 222, 361, 800, 936,
+ 581, 741, 1156, 68, 480, 643, 285, 424, 863, 999, 187, 326, 1213, 131, 543, 706,
+ 1121, 30, 920, 1056, 250, 389, 825, 964, 600, 763, 1178, 93, 508, 671, 307, 446,
+ 882, 1021, 215, 351, 790, 1241, 150, 565, 728, 1140, 58, 473, 633, 1084, 272, 408,
+ 847, 986, 177, 316, 1203, 115, 530, 690, 1105, 23, 910, 1049, 234, 373, 812, 948,
+ 593, 753, 1168, 80, 492, 655, 297, 436, 875, 1011, 199, 338, 1225, 143, 555, 718,
+ 1133, 42, 932, 1068, 262, 401, 837, 976, 164, 612, 775, 1190, 105, 520, 683, 1095,
+ 1, 464, 888, 1039, 221, 369, 796, 947, 583, 734, 1158, 64, 491, 639, 278, 426,
+ 853, 1004, 183, 334, 1221, 121, 548, 696, 1123, 29, 916, 1067, 240, 391, 818, 966,
+ 611, 759, 1186, 86, 510, 661, 303, 454, 881, 1029, 205, 356, 780, 1243, 149, 573,
+ 724, 1151, 48, 475, 626, 1086, 268, 419, 843, 994, 170, 318, 1208, 111, 538, 689,
+ 1113, 13, 900, 1051, 233, 381, 808, 959, 595, 746, 1170, 76, 503, 651, 290, 438,
+ 865, 1016, 195, 346, 1233, 133, 560, 708, 1135, 41, 928, 1079, 252, 403, 830, 978,
+ 160, 623, 771, 1198, 98, 522, 673, 1100, 3, 466, 893, 1041, 217, 368, 792, 943,
+ 585, 736, 1163, 60, 487, 638, 280, 431, 855, 1006, 182, 330, 1220, 123, 550, 701,
+ 1125, 25, 912, 1063, 245, 393, 820, 971, 607, 758, 1182, 88, 515, 663, 302, 450,
+ 877, 1028, 207, 358, 785, 1245, 145, 572, 720, 1147, 53, 477, 628, 1091, 264, 415,
+ 842, 990, 172, 323, 1210, 110, 534, 685, 1112, 15, 905, 1053, 229, 380, 804, 955,
+ 597, 748, 1175, 72, 499, 650, 292, 443, 867, 1018, 194, 342, 1232, 135, 562, 713,
+ 1137, 37, 924, 1075, 257, 405, 832, 983, 156, 619, 770, 1194, 100, 527, 675, 1102,
+ 8, 456, 895, 1034, 225, 364, 803, 939, 578, 738, 1153, 71, 483, 646, 282, 421,
+ 860, 996, 190, 329, 1216, 128, 540, 703, 1118, 33, 923, 1059, 247, 386, 822, 961,
+ 603, 766, 1181, 90, 505, 668, 310, 449, 885, 1024, 212, 348, 787, 1238, 153, 568,
+ 731, 1143, 55, 470, 630, 1081, 275, 411, 850, 989, 174, 313, 1200, 118, 533, 693,
+ 1108, 20, 907, 1046, 237, 376, 815, 951, 590, 750, 1165, 83, 495, 658, 294, 433,
+ 872, 1008, 202, 341, 1228, 140, 552, 715, 1130, 45, 935, 1071, 259, 398, 834, 973,
+ 167, 615, 778, 1193, 102, 517, 680, 1092, 10, 461, 897, 1036, 224, 360, 799, 938,
+ 580, 743, 1155, 67, 482, 642, 287, 423, 862, 1001, 186, 325, 1212, 130, 545, 705,
+ 1120, 32, 919, 1058, 249, 388, 827, 963, 602, 762, 1177, 95, 507, 670, 306, 445,
+ 884, 1020, 214, 353, 789, 1240, 152, 564, 727, 1142, 57, 472, 635, 1083, 271, 410,
+ 846, 985, 179, 315, 1205, 114, 529, 692, 1104, 22, 909, 1048, 236, 372, 811, 950,
+ 592, 755, 1167, 79, 494, 654, 299, 435, 874, 1013, 198, 337, 1224, 142, 557, 717,
+ 1132, 44, 931, 1070, 261, 400, 839, 975, 163, 614, 774, 1189, 107, 519, 682, 1097,
+};
+
+/* this corresponds to the bit-lengths of the individual codec
+ * parameters as indicated in Table 1.1 of TS 06.10 */
+const uint8_t gsm0503_gsm_fr_map[76] = {
+ 6, 6, 5, 5, 4, 4, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3
+};
+
+/* this table describes the 65 most importaint bits from EFR coded
+ * bits as indicated in TS 05.03 (3.1.1.1) */
+const uint8_t gsm0503_gsm_efr_protected_bits[65] = {
+ 39, 40, 41, 42, 43, 44, 48, 87, 45, 2,
+ 3, 8, 10, 18, 19, 24, 46, 47,142,143,
+ 144,145,146,147, 92, 93,195,196, 98,137,
+ 148, 94,197,149,150, 95,198, 4, 5, 11,
+ 12, 16, 9, 6, 7, 13, 17, 20, 96,199,
+ 1, 14, 15, 21, 25, 26, 28,151,201,190,
+ 240, 88,138,191,241
+};
+
+/* Encoded in-band data for speech frames */
+const ubit_t gsm0503_afs_ic_ubit[4][8] = {
+ { 0,0,0,0,0,0,0,0 },
+ { 0,1,0,1,1,1,0,1 },
+ { 1,0,1,1,1,0,1,0 },
+ { 1,1,1,0,0,1,1,1 },
+};
+
+const sbit_t gsm0503_afs_ic_sbit[4][8] = {
+ { 127, 127, 127, 127, 127, 127, 127, 127 },
+ { 127,-127, 127,-127,-127,-127, 127,-127 },
+ { -127, 127,-127,-127,-127, 127,-127, 127 },
+ { -127,-127,-127, 127, 127,-127,-127,-127 },
+};
+
+const ubit_t gsm0503_ahs_ic_ubit[4][4] = {
+ { 0,0,0,0 },
+ { 1,0,0,1 },
+ { 1,1,1,0 },
+ { 0,1,1,1 },
+};
+
+const sbit_t gsm0503_ahs_ic_sbit[4][4] = {
+ { 127, 127, 127, 127 },
+ { -127, 127, 127,-127 },
+ { -127,-127,-127, 127 },
+ { 127,-127,-127,-127 },
+};
+
+const uint8_t gsm0503_tch_hr_interleaving[228][2] = {
+ { 0 ,0 }, { 1 ,2 }, { 78 ,1 }, { 79 ,3 }, { 48 ,0 }, { 49 ,2 },
+ { 54 ,1 }, { 55 ,3 }, { 24 ,0 }, { 25 ,2 }, { 30 ,1 }, { 31 ,3 },
+ { 72 ,0 }, { 73 ,2 }, { 6 ,1 }, { 7 ,3 }, { 96 ,0 }, { 97 ,2 },
+ { 12 ,0 }, { 13 ,2 }, { 102,1 }, { 103,3 }, { 60 ,0 }, { 61 ,2 },
+ { 66 ,1 }, { 67 ,3 }, { 90 ,1 }, { 91 ,3 }, { 36 ,0 }, { 37 ,2 },
+ { 42 ,1 }, { 43 ,3 }, { 18 ,1 }, { 19 ,3 }, { 84 ,0 }, { 85 ,2 },
+ { 108,0 }, { 109,2 }, { 2 ,0 }, { 3 ,2 }, { 80 ,1 }, { 81 ,3 },
+ { 50 ,0 }, { 51 ,2 }, { 56 ,1 }, { 57 ,3 }, { 26 ,0 }, { 27 ,2 },
+ { 32 ,1 }, { 33 ,3 }, { 74 ,0 }, { 75 ,2 }, { 8 ,1 }, { 9 ,3 },
+ { 98 ,0 }, { 99 ,2 }, { 14 ,0 }, { 15 ,2 }, { 104,1 }, { 105,3 },
+ { 62 ,0 }, { 63 ,2 }, { 68 ,1 }, { 69 ,3 }, { 92 ,1 }, { 93 ,3 },
+ { 38 ,0 }, { 39 ,2 }, { 44 ,1 }, { 45 ,3 }, { 20 ,1 }, { 21 ,3 },
+ { 86 ,0 }, { 87 ,2 }, { 110,0 }, { 111,2 }, { 4 ,0 }, { 5 ,2 },
+ { 82 ,1 }, { 83 ,3 }, { 52 ,0 }, { 53 ,2 }, { 58 ,1 }, { 59 ,3 },
+ { 28 ,0 }, { 29 ,2 }, { 34 ,1 }, { 35 ,3 }, { 76 ,0 }, { 77 ,2 },
+ { 10 ,1 }, { 12 ,3 }, { 100,0 }, { 101,2 }, { 16 ,0 }, { 17 ,2 },
+ { 106,1 }, { 107,3 }, { 64 ,0 }, { 65 ,2 }, { 70 ,1 }, { 71 ,3 },
+ { 94 ,1 }, { 95 ,3 }, { 40 ,0 }, { 41 ,2 }, { 46 ,1 }, { 47 ,3 },
+ { 22 ,1 }, { 23 ,3 }, { 88 ,0 }, { 89 ,2 }, { 112,0 }, { 113,2 },
+ { 6 ,0 }, { 7 ,2 }, { 84 ,1 }, { 85 ,3 }, { 54 ,0 }, { 55 ,2 },
+ { 60 ,1 }, { 61 ,3 }, { 30 ,0 }, { 31 ,2 }, { 36 ,1 }, { 37 ,3 },
+ { 78 ,0 }, { 79 ,2 }, { 12 ,1 }, { 13 ,3 }, { 102,0 }, { 103,2 },
+ { 18 ,0 }, { 19 ,2 }, { 108,1 }, { 109,3 }, { 66 ,0 }, { 67 ,2 },
+ { 72 ,1 }, { 73 ,3 }, { 96 ,1 }, { 97 ,3 }, { 42 ,0 }, { 43 ,2 },
+ { 48 ,1 }, { 49 ,3 }, { 24 ,1 }, { 25 ,3 }, { 90 ,0 }, { 91 ,2 },
+ { 0 ,1 }, { 1 ,3 }, { 8 ,0 }, { 9 ,2 }, { 86 ,1 }, { 87 ,3 },
+ { 56 ,0 }, { 57 ,2 }, { 62 ,1 }, { 63 ,3 }, { 32 ,0 }, { 33 ,2 },
+ { 38 ,1 }, { 39 ,3 }, { 80 ,0 }, { 81 ,2 }, { 14 ,1 }, { 15 ,3 },
+ { 104,0 }, { 105,2 }, { 20 ,0 }, { 21 ,2 }, { 110,1 }, { 111,3 },
+ { 68 ,0 }, { 69 ,2 }, { 74 ,1 }, { 75 ,3 }, { 98 ,1 }, { 99 ,3 },
+ { 44 ,0 }, { 45 ,2 }, { 50 ,1 }, { 51 ,3 }, { 26 ,1 }, { 27 ,3 },
+ { 92 ,0 }, { 93 ,2 }, { 2 ,1 }, { 3 ,3 }, { 10 ,0 }, { 11 ,2 },
+ { 88 ,1 }, { 89 ,3 }, { 58 ,0 }, { 59 ,2 }, { 64 ,1 }, { 65 ,3 },
+ { 34 ,0 }, { 35 ,2 }, { 40 ,1 }, { 41 ,3 }, { 82 ,0 }, { 83 ,2 },
+ { 16 ,1 }, { 17 ,3 }, { 106,0 }, { 107,2 }, { 22 ,0 }, { 23 ,2 },
+ { 112,1 }, { 113,3 }, { 70 ,0 }, { 71 ,2 }, { 76 ,1 }, { 77 ,3 },
+ { 100,1 }, { 101,3 }, { 46 ,0 }, { 47 ,2 }, { 52 ,1 }, { 53 ,3 },
+ { 28 ,1 }, { 29 ,3 }, { 94 ,0 }, { 95 ,2 }, { 4 ,1 }, { 5 ,3 },
+};
+
+/*
+ * 3GPP TS 05.03 5.1.9.1.2 "USF precoding"
+ */
+const ubit_t gsm0503_mcs5_usf_precode_table[8][36] = {
+ { 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, },
+ { 1,1,1,1,1,0,0,0,0, 1,1,1,1,0,0,0,0,0, 1,1,1,1,1,1,0,0,0, 1,1,1,1,1,0,0,0,1, },
+ { 1,1,1,0,0,1,1,1,0, 1,1,1,0,1,1,1,0,0, 1,1,0,0,0,0,1,1,0, 1,1,0,0,0,1,1,0,0, },
+ { 1,0,0,1,1,1,1,0,0, 1,1,0,0,0,0,0,1,1, 1,0,1,1,1,0,1,1,1, 0,0,1,0,0,1,1,1,1, },
+ { 0,0,0,1,1,0,0,1,1, 0,0,1,0,1,1,0,1,0, 1,0,0,0,0,1,1,0,1, 1,1,1,1,1,1,1,1,0, },
+ { 1,1,0,1,0,1,0,1,1, 0,0,0,1,1,0,1,0,1, 0,1,1,1,0,1,0,1,1, 1,0,0,1,0,1,0,1,1, },
+ { 0,0,1,0,0,1,1,0,1, 1,0,1,1,1,1,1,1,1, 0,1,1,0,1,0,0,0,1, 0,0,1,1,1,0,1,0,0, },
+ { 0,1,1,0,1,0,1,1,1, 0,1,0,1,0,1,1,1,1, 0,0,0,1,1,1,1,1,0, 0,1,0,0,1,0,0,1,1, },
+};
diff --git a/lib/decoding/osmocom/coding/gsm0503_tables.h b/lib/decoding/osmocom/coding/gsm0503_tables.h
new file mode 100644
index 0000000..e6761ca
--- /dev/null
+++ b/lib/decoding/osmocom/coding/gsm0503_tables.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+extern const ubit_t gsm0503_pdtch_hl_hn_ubit[4][8];
+extern const ubit_t gsm0503_pdtch_edge_hl_hn_ubit[3][8];
+extern const sbit_t gsm0503_pdtch_hl_hn_sbit[4][8];
+extern const sbit_t gsm0503_pdtch_edge_hl_hn_sbit[3][8];
+extern const ubit_t gsm0503_usf2six[8][6];
+extern const ubit_t gsm0503_usf2twelve_ubit[8][12];
+extern const sbit_t gsm0503_usf2twelve_sbit[8][12];
+extern const uint8_t gsm0503_puncture_cs2[588];
+extern const uint8_t gsm0503_puncture_cs3[676];
+extern const uint8_t gsm0503_puncture_mcs1_dl_hdr[108];
+extern const uint8_t gsm0503_puncture_mcs1_ul_hdr[117];
+extern const uint8_t gsm0503_puncture_mcs1_p1[588];
+extern const uint8_t gsm0503_puncture_mcs1_p2[588];
+extern const uint8_t gsm0503_puncture_mcs2_p1[732];
+extern const uint8_t gsm0503_puncture_mcs2_p2[732];
+extern const uint8_t gsm0503_puncture_mcs3_p1[948];
+extern const uint8_t gsm0503_puncture_mcs3_p2[948];
+extern const uint8_t gsm0503_puncture_mcs3_p3[948];
+extern const uint8_t gsm0503_puncture_mcs4_p1[1116];
+extern const uint8_t gsm0503_puncture_mcs4_p2[1116];
+extern const uint8_t gsm0503_puncture_mcs4_p3[1116];
+extern const uint8_t gsm0503_puncture_mcs5_p1[1404];
+extern const uint8_t gsm0503_puncture_mcs5_p2[1404];
+extern const uint8_t gsm0503_puncture_mcs6_p1[1836];
+extern const uint8_t gsm0503_puncture_mcs6_p2[1836];
+extern const uint8_t gsm0503_puncture_mcs7_dl_hdr[135];
+extern const uint8_t gsm0503_puncture_mcs7_ul_hdr[162];
+extern const uint8_t gsm0503_puncture_mcs7_p1[1404];
+extern const uint8_t gsm0503_puncture_mcs7_p2[1404];
+extern const uint8_t gsm0503_puncture_mcs7_p3[1404];
+extern const uint8_t gsm0503_puncture_mcs8_p1[1692];
+extern const uint8_t gsm0503_puncture_mcs8_p2[1692];
+extern const uint8_t gsm0503_puncture_mcs8_p3[1692];
+extern const uint8_t gsm0503_puncture_mcs9_p1[1836];
+extern const uint8_t gsm0503_puncture_mcs9_p2[1836];
+extern const uint8_t gsm0503_puncture_mcs9_p3[1836];
+extern const uint16_t gsm0503_interleave_mcs5[1248];
+extern const uint8_t gsm0503_gsm_fr_map[76];
+extern const uint8_t gsm0503_gsm_efr_protected_bits[65];
+extern const ubit_t gsm0503_afs_ic_ubit[4][8];
+extern const sbit_t gsm0503_afs_ic_sbit[4][8];
+extern const ubit_t gsm0503_ahs_ic_ubit[4][4];
+extern const sbit_t gsm0503_ahs_ic_sbit[4][4];
+extern const uint8_t gsm0503_tch_hr_interleaving[228][2];
+extern const ubit_t gsm0503_mcs5_usf_precode_table[8][36];
diff --git a/lib/receiver/sch.c b/lib/decoding/sch.c
index a75673f..24cee30 100644
--- a/lib/receiver/sch.c
+++ b/lib/decoding/sch.c
@@ -23,7 +23,7 @@
#include <string.h>
#include "gsm_constants.h"
-#include <osmocom/coding/gsm0503_coding.h>
+#include "osmocom/coding/gsm0503_coding.h"
#include <osmocom/core/utils.h>
static int ubits2sbits(ubit_t *ubits, sbit_t *sbits, int count)
diff --git a/lib/decoding/tch_f_decoder_impl.cc b/lib/decoding/tch_f_decoder_impl.cc
index a84c47c..5b77be2 100644
--- a/lib/decoding/tch_f_decoder_impl.cc
+++ b/lib/decoding/tch_f_decoder_impl.cc
@@ -30,7 +30,7 @@
#include "tch_f_decoder_impl.h"
extern "C" {
- #include <osmocom/coding/gsm0503_coding.h>
+ #include "osmocom/coding/gsm0503_coding.h"
}
#define DATA_BYTES 23