diff --git a/include/osmocom/coding/gsm0503_coding.h b/include/osmocom/coding/gsm0503_coding.h index 75e12e6da..13d53447e 100644 --- a/include/osmocom/coding/gsm0503_coding.h +++ b/include/osmocom/coding/gsm0503_coding.h @@ -101,6 +101,10 @@ int gsm0503_tch_hr48_encode(ubit_t *bursts, const ubit_t *data); int gsm0503_tch_hr48_decode(ubit_t *data, const sbit_t *bursts, int *n_errors, int *n_bits_total); +int gsm0503_tch_fr24_encode(ubit_t *bursts, const ubit_t *data); +int gsm0503_tch_fr24_decode(ubit_t *data, const sbit_t *bursts, + int *n_errors, int *n_bits_total); + int gsm0503_tch_hr24_encode(ubit_t *bursts, const ubit_t *data); int gsm0503_tch_hr24_decode(ubit_t *data, const sbit_t *bursts, int *n_errors, int *n_bits_total); diff --git a/src/coding/gsm0503_coding.c b/src/coding/gsm0503_coding.c index 3faa512ef..0e7f68927 100644 --- a/src/coding/gsm0503_coding.c +++ b/src/coding/gsm0503_coding.c @@ -3472,6 +3472,54 @@ int gsm0503_tch_hr48_decode(ubit_t *data, const sbit_t *bursts, return gsm0503_tch_fr96_decode(data, bursts, n_errors, n_bits_total); } +/*! Perform channel encoding of a TCH/F2.4 channel as per section 3.6. + * \param[out] bursts Caller-allocated buffer for symbols of 8 bursts, + * 8 * 2 * 58 == 928 bits total. + * \param[in] data Data to be encoded (72 unpacked bits). + * \returns 0 in case of success; negative on error */ +int gsm0503_tch_fr24_encode(ubit_t *bursts, const ubit_t *data) +{ + ubit_t iB[8 * 114], cB[4 * 114]; + const ubit_t h = 0; + + /* 3.6.{1-3} Block code and Convolutional encoder */ + osmo_conv_encode(&gsm0503_tch_f24, &data[0], &cB[0]); + + /* 3.6.4 Interleaving: as specified for the TCH/FS in subclause 3.1.3 */ + gsm0503_tch_fr_interleave(&cB[0], &iB[0]); + + /* 3.6.5 Mapping on a burst: as specified for TCH/FS in subclause 3.1.4 */ + for (unsigned int i = 0; i < 8; i++) + gsm0503_tch_burst_map(&iB[i * 114], &bursts[i * 116], &h, i >> 2); + + return 0; +} + +/*! Perform channel decoding of a TCH/F2.4 channel as per section 3.6. + * \param[out] data Caller-allocated buffer for decoded data (72 unpacked bits). + * \param[in] bursts Buffer containing the symbols of 8 bursts, + * 8 * 2 * 58 == 928 bits total. + * \param[out] n_errors Number of detected bit errors. + * \param[out] n_bits_total Total number of bits. + * \returns Number of unpacked bits used in the output buffer; negative on error. */ +int gsm0503_tch_fr24_decode(ubit_t *data, const sbit_t *bursts, + int *n_errors, int *n_bits_total) +{ + sbit_t iB[8 * 114], cB[4 * 114]; + + /* 3.6.5 Mapping on a burst: as specified for TCH/FS in subclause 3.1.4 */ + for (unsigned int i = 0; i < 8; i++) + gsm0503_tch_burst_unmap(&iB[i * 114], &bursts[i * 116], NULL, i >> 2); + + /* 3.6.4 Interleaving: as specified for the TCH/FS in subclause 3.1.3 */ + gsm0503_tch_fr_deinterleave(&cB[0], &iB[0]); + + /* 3.6.{1-3} Block code and Convolutional encoder */ + osmo_conv_decode_ber(&gsm0503_tch_f24, &cB[0], &data[0], n_errors, n_bits_total); + + return 72; +} + /*! Perform channel encoding of a TCH/H2.4 channel as per section 3.7. * \param[out] bursts Caller-allocated buffer for symbols of 22 bursts, * 22 * 2 * 58 == 2552 bits total. diff --git a/src/coding/libosmocoding.map b/src/coding/libosmocoding.map index b1087e32e..0444690ec 100644 --- a/src/coding/libosmocoding.map +++ b/src/coding/libosmocoding.map @@ -135,6 +135,8 @@ gsm0503_tch_fr48_encode; gsm0503_tch_fr48_decode; gsm0503_tch_hr48_encode; gsm0503_tch_hr48_decode; +gsm0503_tch_fr24_encode; +gsm0503_tch_fr24_decode; gsm0503_tch_hr24_encode; gsm0503_tch_hr24_decode; gsm0503_tch_fr144_encode; diff --git a/tests/coding/coding_test.c b/tests/coding/coding_test.c index 7cef7b3a0..c9508f7dd 100644 --- a/tests/coding/coding_test.c +++ b/tests/coding/coding_test.c @@ -563,9 +563,15 @@ static const struct csd_test_case csd_tests[] = { .dec_fn = &gsm0503_tch_hr48_decode, .half_rate = true, }, + { + .name = "TCH/F2.4", + .num_bits = 2 * 36, + .enc_fn = &gsm0503_tch_fr24_encode, + .dec_fn = &gsm0503_tch_fr24_decode, + }, { .name = "TCH/H2.4", - .num_bits = 2 * 72, + .num_bits = 4 * 36, .enc_fn = &gsm0503_tch_hr24_encode, .dec_fn = &gsm0503_tch_hr24_decode, .half_rate = true, diff --git a/tests/coding/coding_test.ok b/tests/coding/coding_test.ok index c5c145dfd..1fc2f1d8d 100644 --- a/tests/coding/coding_test.ok +++ b/tests/coding/coding_test.ok @@ -445,6 +445,16 @@ test_csd(TCH/H4.8): block #2 (pattern 0xff): n_errors=0 / n_bits_total=456 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 +test_csd(TCH/F2.4): block #0 (pattern 0x00): n_errors=0 / n_bits_total=456 +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +00000000 +test_csd(TCH/F2.4): block #1 (pattern 0xaa): n_errors=0 / n_bits_total=456 +01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 +01010101 +test_csd(TCH/F2.4): block #2 (pattern 0xff): n_errors=0 / n_bits_total=456 +11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 +11111111 + test_csd(TCH/H2.4): block #0 (pattern 0x00): n_errors=0 / n_bits_total=456 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 @@ -527,6 +537,18 @@ test_csd(TCH/H4.8): block #2 (pattern 0xff): n_errors=3 / n_bits_total=456 test_csd(TCH/H4.8): FACCH/H (pattern 0x2b): n_errors=0 / n_bits_total=456 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +test_csd(TCH/F2.4): block #0 (pattern 0x00): n_errors=0 / n_bits_total=456 +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +00000000 +test_csd(TCH/F2.4): block #1 (pattern 0xaa): n_errors=138 / n_bits_total=456 +11000010 10010010 10010010 10010010 10010010 10010010 10010101 00011000 +01001010 +test_csd(TCH/F2.4): block #2 (pattern 0xff): n_errors=0 / n_bits_total=456 +11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 +11111111 +test_csd(TCH/F2.4): FACCH/F (pattern 0x2b): n_errors=0 / n_bits_total=456 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b + test_csd(TCH/H2.4): block #0 (pattern 0x00): n_errors=38 / n_bits_total=456 00000000 00000000 00000101 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000