csd_v110_rtp_encode(): properly set E1/E2/E3 bits

The E1/E2/E3 bits are set based on out-of-band knowledge of the
current user data rate.  The actual bit values are defined in
3GPP TS 44.021, Figure 4 "Coding of data rates".

TODO: this is only valid for transparent services,
      for non-transparent services see 3GPP TS 48.020.
TODO: lchan->csd_mode is never set to the actual CSD mode...

Change-Id: I1a14597dff746cf975140b294400a2cc05badccd
Related: OS#1572
This commit is contained in:
Vadim Yanitskiy
2023-07-25 05:35:02 +07:00
parent d1f8f3429c
commit ca418643b3
4 changed files with 46 additions and 19 deletions

View File

@@ -75,15 +75,17 @@ struct amr_multirate_conf {
};
enum lchan_csd_mode {
LCHAN_CSD_M_NT,
LCHAN_CSD_M_NT = 0,
LCHAN_CSD_M_T_1200_75,
LCHAN_CSD_M_T_600,
LCHAN_CSD_M_T_1200,
LCHAN_CSD_M_T_2400,
LCHAN_CSD_M_T_4800,
LCHAN_CSD_M_T_9600,
LCHAN_CSD_M_T_14400,
LCHAN_CSD_M_T_29000,
LCHAN_CSD_M_T_32000,
_LCHAN_CSD_M_NUM,
};
/* State of the SAPIs in the lchan */

View File

@@ -58,6 +58,21 @@ const struct csd_v110_lchan_desc csd_v110_lchan_desc[256] = {
},
};
/* 3GPP TS 44.021, Figure 4: Coding of data rates (E1/E2/E3 bits) */
static const uint8_t e1e2e3_map[_LCHAN_CSD_M_NUM][3] = {
[LCHAN_CSD_M_T_600] = { 1, 0, 0 },
[LCHAN_CSD_M_T_1200] = { 0, 1, 0 },
[LCHAN_CSD_M_T_2400] = { 1, 1, 0 },
[LCHAN_CSD_M_T_4800] = { 0, 1, 1 },
[LCHAN_CSD_M_T_9600] = { 0, 1, 1 },
#if 0
[LCHAN_CSD_M_T_19200] = { 0, 1, 1 },
[LCHAN_CSD_M_T_38400] = { 0, 1, 1 },
[LCHAN_CSD_M_T_14400] = { 1, 0, 1 },
[LCHAN_CSD_M_T_28800] = { 1, 0, 1 },
#endif
};
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
const uint8_t *data, size_t data_len)
{
@@ -86,8 +101,10 @@ int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
else /* desc->num_bits == 36 */
osmo_csd_3k6_decode_frame(&df, &data[i * 36], 36);
/* FIXME: E1 .. E3 must be set by out-of-band knowledge! */
memset(&df.e_bits[0], 0, 3);
/* E1 .. E3 must set by out-of-band knowledge */
df.e_bits[0] = e1e2e3_map[lchan->csd_mode][0];
df.e_bits[1] = e1e2e3_map[lchan->csd_mode][1];
df.e_bits[2] = e1e2e3_map[lchan->csd_mode][2];
osmo_v110_encode_frame(&ra_bits[i * 80], 80, &df);
}

View File

@@ -37,6 +37,7 @@ struct test_case {
const char *name;
enum gsm_chan_t lchan_type;
enum gsm48_chan_mode tch_mode;
enum lchan_csd_mode csd_mode;
};
static const struct test_case tests[] = {
@@ -44,31 +45,37 @@ static const struct test_case tests[] = {
.name = "TCH/F14.4",
.lchan_type = GSM_LCHAN_TCH_F,
.tch_mode = GSM48_CMODE_DATA_14k5,
.csd_mode = LCHAN_CSD_M_T_14400,
},
{
.name = "TCH/F9.6",
.lchan_type = GSM_LCHAN_TCH_F,
.tch_mode = GSM48_CMODE_DATA_12k0,
.csd_mode = LCHAN_CSD_M_T_9600,
},
{
.name = "TCH/F4.8",
.lchan_type = GSM_LCHAN_TCH_F,
.tch_mode = GSM48_CMODE_DATA_6k0,
.csd_mode = LCHAN_CSD_M_T_4800,
},
{
.name = "TCH/H4.8",
.lchan_type = GSM_LCHAN_TCH_H,
.tch_mode = GSM48_CMODE_DATA_6k0,
.csd_mode = LCHAN_CSD_M_T_4800,
},
{
.name = "TCH/F2.4",
.lchan_type = GSM_LCHAN_TCH_F,
.tch_mode = GSM48_CMODE_DATA_3k6,
.csd_mode = LCHAN_CSD_M_T_2400,
},
{
.name = "TCH/H2.4",
.lchan_type = GSM_LCHAN_TCH_H,
.tch_mode = GSM48_CMODE_DATA_3k6,
.csd_mode = LCHAN_CSD_M_T_600,
},
};
@@ -99,6 +106,7 @@ static void exec_test_case(const struct test_case *tc)
struct gsm_lchan lchan = {
.type = tc->lchan_type,
.tch_mode = tc->tch_mode,
.csd_mode = tc->csd_mode,
};
/* populate the data_enc[] buffer with some bits */

View File

@@ -2,65 +2,65 @@
[i] Testing 'TCH/F9.6' (bitnum=240)
[i] csd_v110_rtp_encode() returns 160
3f 3f 3f 3f bf bf bf bf ff 7f 7f 7f bf bf bf bf
ff 7f 7f 7f bf 3f 7f 7f bf bf bf bf ff 7f 7f 7f
ff 7f 7f 7f bf ff 7f 7f bf bf bf bf ff 7f 7f 7f
bf bf bf bf ff 7f 7f 7f 3f 3f 3f 3f bf bf bf bf
ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf 3f 7f 7f
ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf ff 7f 7f
bf bf bf bf ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f
3f 3f 3f 3f bf bf bf bf ff 7f 7f 7f bf bf bf bf
ff 7f 7f 7f bf 3f 7f 7f bf bf bf bf ff 7f 7f 7f
ff 7f 7f 7f bf ff 7f 7f bf bf bf bf ff 7f 7f 7f
bf bf bf bf ff 7f 7f 7f 3f 3f 3f 3f bf bf bf bf
ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf 3f 7f 7f
ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf ff 7f 7f
bf bf bf bf ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f
[i] csd_v110_rtp_decode() returns 240
[i] Testing 'TCH/F4.8' (bitnum=120)
[i] csd_v110_rtp_encode() returns 160
7f 7f 7f 7f 7f 7f 7f 7f ff 7f ff 7f ff 7f ff 7f
ff ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff 7f
ff ff 7f ff 7f ff 7f ff ff 7f 7f 7f 7f ff 7f ff
ff ff 7f ff 7f ff 7f ff ff 7f ff ff 7f ff 7f ff
ff 7f ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff
ff 7f ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff
7f 7f 7f 7f 7f 7f 7f 7f ff 7f ff 7f ff 7f ff 7f
ff ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff 7f
ff ff 7f ff 7f ff 7f ff ff 7f 7f 7f 7f ff 7f ff
ff ff 7f ff 7f ff 7f ff ff 7f ff ff 7f ff 7f ff
ff 7f ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff
ff 7f ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff
[i] csd_v110_rtp_decode() returns 120
[i] Testing 'TCH/H4.8' (bitnum=240)
[i] csd_v110_rtp_encode() returns 160
3f 3f 3f 3f bf bf bf bf ff 7f 7f 7f bf bf bf bf
ff 7f 7f 7f bf 3f 7f 7f bf bf bf bf ff 7f 7f 7f
ff 7f 7f 7f bf ff 7f 7f bf bf bf bf ff 7f 7f 7f
bf bf bf bf ff 7f 7f 7f 3f 3f 3f 3f bf bf bf bf
ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf 3f 7f 7f
ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf ff 7f 7f
bf bf bf bf ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f
3f 3f 3f 3f bf bf bf bf ff 7f 7f 7f bf bf bf bf
ff 7f 7f 7f bf 3f 7f 7f bf bf bf bf ff 7f 7f 7f
ff 7f 7f 7f bf ff 7f 7f bf bf bf bf ff 7f 7f 7f
bf bf bf bf ff 7f 7f 7f 3f 3f 3f 3f bf bf bf bf
ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf 3f 7f 7f
ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf ff 7f 7f
bf bf bf bf ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f
[i] csd_v110_rtp_decode() returns 240
[i] Testing 'TCH/F2.4' (bitnum=72)
[i] csd_v110_rtp_encode() returns 160
7f 7f 7f 7f 7f 7f 7f 7f ff 7f 7f ff ff 7f 7f ff
ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff
ff 7f 7f ff ff 7f 7f ff ff 7f 7f 7f 7f ff 7f ff
ff 7f 7f ff ff 7f 7f ff ff ff ff 7f 7f ff 7f ff
ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff
ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff
7f 7f 7f 7f 7f 7f 7f 7f ff 7f 7f ff ff 7f 7f ff
ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff
ff 7f 7f ff ff 7f 7f ff ff 7f 7f 7f 7f ff 7f ff
ff 7f 7f ff ff 7f 7f ff ff ff ff 7f 7f ff 7f ff
ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff
ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff
[i] csd_v110_rtp_decode() returns 72
[i] Testing 'TCH/H2.4' (bitnum=144)
[i] csd_v110_rtp_encode() returns 160
3f 3f 3f 3f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f
bf 7f bf 7f bf 3f 7f 7f bf 7f bf 7f bf 7f bf 7f
bf 7f bf 7f ff 3f 7f 7f bf 7f bf 7f bf 7f bf 7f
bf 7f bf 7f bf 7f bf 7f 3f 3f 3f 3f bf 7f bf 7f
bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 3f 7f 7f
bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f ff 3f 7f 7f
bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f
3f 3f 3f 3f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f
bf 7f bf 7f bf 3f 7f 7f bf 7f bf 7f bf 7f bf 7f
bf 7f bf 7f ff 3f 7f 7f bf 7f bf 7f bf 7f bf 7f
bf 7f bf 7f bf 7f bf 7f 3f 3f 3f 3f bf 7f bf 7f
bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 3f 7f 7f
bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f ff 3f 7f 7f
bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f
[i] csd_v110_rtp_decode() returns 144