aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-08-26 04:11:25 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-08-26 04:11:33 +0700
commitb33502a39b98c0015385253e5713e21970e3c32e (patch)
tree1c1f732c4229580037a0715dbfa9b53cdf34606c
parent183c0888648a8406ea962b3b7f0532456e0fdb2f (diff)
csd_v110: handle empty/incomplete Uplink frames gracefully
-rw-r--r--src/common/csd_v110.c12
-rw-r--r--tests/csd/csd_test.c11
-rw-r--r--tests/csd/csd_test.err60
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