From b33502a39b98c0015385253e5713e21970e3c32e Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Sat, 26 Aug 2023 04:11:25 +0700 Subject: csd_v110: handle empty/incomplete Uplink frames gracefully Change-Id: I7cbf868df3ba5d390cea3d529eef26d18dbe55ab Related: OS#1572 --- src/common/csd_v110.c | 12 +++++++--- tests/csd/csd_test.c | 11 +++++++++ tests/csd/csd_test.err | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/common/csd_v110.c b/src/common/csd_v110.c index 230a6a7d..5046d6e9 100644 --- a/src/common/csd_v110.c +++ b/src/common/csd_v110.c @@ -87,9 +87,14 @@ int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp, if (OSMO_UNLIKELY(desc->num_blocks == 0)) return -ENOTSUP; - /* handle empty/incomplete frames gracefully */ - if (OSMO_UNLIKELY(data_len < (desc->num_blocks * desc->num_bits))) - return -ENODATA; + /* handle empty/incomplete Uplink frames gracefully */ + if (OSMO_UNLIKELY(data_len < (desc->num_blocks * desc->num_bits))) { + /* encode N idle frames as per 3GPP TS 44.021, section 8.1.6 */ + memset(&ra_bits[0], 0x01, sizeof(ra_bits)); + for (unsigned int i = 0; i < desc->num_blocks; i++) + memset(&ra_bits[i * 80], 0x00, 8); /* alignment pattern */ + goto ra1_ra2; + } /* RA1'/RA1: convert from radio rate to an intermediate data rate */ for (unsigned int i = 0; i < desc->num_blocks; i++) { @@ -117,6 +122,7 @@ int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp, osmo_v110_encode_frame(&ra_bits[i * 80], 80, &df); } +ra1_ra2: /* RA1/RA2: convert from an intermediate rate to 64 kbit/s */ if (desc->num_blocks == 4) { /* 4 * 80 bits (16 kbit/s) => 2 bits per octet */ diff --git a/tests/csd/csd_test.c b/tests/csd/csd_test.c index f24331d3..466ff880 100644 --- a/tests/csd/csd_test.c +++ b/tests/csd/csd_test.c @@ -135,6 +135,17 @@ static void exec_test_case(const struct test_case *tc) fprintf(stderr, "[!] Data mismatch @ %03u: D%u vs E%u\n", i, data_dec[i], data_enc[i]); } + + fprintf(stderr, "[i] Testing '%s' (IDLE)\n", tc->name); + + /* encode an idle RTP frame and print it */ + rc = csd_v110_rtp_encode(&lchan, &rtp[0], &data_enc[0], 0); + fprintf(stderr, "[i] csd_v110_rtp_encode() returns %d\n", rc); + if (rc != RFC4040_RTP_PLEN) + return; + /* print the encoded RTP frame (16 bytes per row) */ + for (unsigned int i = 0; i < sizeof(rtp) / 16; i++) + fprintf(stderr, " %s\n", osmo_hexdump(&rtp[i * 16], 16)); } int main(int argc, char **argv) diff --git a/tests/csd/csd_test.err b/tests/csd/csd_test.err index 94505dc3..b8623247 100644 --- a/tests/csd/csd_test.err +++ b/tests/csd/csd_test.err @@ -12,6 +12,18 @@ 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/F9.6' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff [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 @@ -25,6 +37,18 @@ 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/F4.8' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff [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 @@ -38,6 +62,18 @@ 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/H4.8' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff [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 @@ -51,6 +87,18 @@ 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/F2.4' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff [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 @@ -64,3 +112,15 @@ 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 +[i] Testing 'TCH/H2.4' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff -- cgit v1.2.3