fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/34219 )
Change subject: csd_v110: handle empty/incomplete Uplink frames gracefully ......................................................................
csd_v110: handle empty/incomplete Uplink frames gracefully
Change-Id: I7cbf868df3ba5d390cea3d529eef26d18dbe55ab Related: OS#1572 --- M src/common/csd_v110.c M tests/csd/csd_test.c M tests/csd/csd_test.err 3 files changed, 90 insertions(+), 3 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve osmith: Looks good to me, approved
diff --git a/src/common/csd_v110.c b/src/common/csd_v110.c index 230a6a7..5046d6e 100644 --- a/src/common/csd_v110.c +++ b/src/common/csd_v110.c @@ -87,9 +87,14 @@ 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 @@ 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 f24331d..466ff88 100644 --- a/tests/csd/csd_test.c +++ b/tests/csd/csd_test.c @@ -135,6 +135,17 @@ 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 94505dc..b862324 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