falconia has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-abis/+/32078 )
Change subject: osmo_rtp2trau() for FR & EFR: correctly handle the no-data case ......................................................................
osmo_rtp2trau() for FR & EFR: correctly handle the no-data case
3GPP TS 48.060 sections 6.5.2 and 6.5.3 prescribe the behavior of TRAU frame emitters under conditions of not having any speech or SID frame to send. In the case of osmo_rtp2trau() this no-data condition is indicated with a zero rtp_len argument to the function, but this case was not handled correctly: a garbage speech frame (previous buffer content for the D bits in struct osmo_trau_frame) was being generated. The present change implements the rules of TS 48.060 sections 6.5.2 and 6.5.3: standard FR/EFR speech frame with BFI=1 for UL, special idle speech frame pattern for DL.
Change-Id: I7f21e2210bba9ef87f1af515a001a0cfc1c0a1d8 --- M src/trau/trau_rtp_conv.c 1 file changed, 60 insertions(+), 16 deletions(-)
Approvals: Jenkins Builder: Verified falconia: Looks good to me, approved
diff --git a/src/trau/trau_rtp_conv.c b/src/trau/trau_rtp_conv.c index ebbdbef..a434c2a 100644 --- a/src/trau/trau_rtp_conv.c +++ b/src/trau/trau_rtp_conv.c @@ -273,19 +273,28 @@
/* set c-bits and t-bits */ if (tf->dir == OSMO_TRAU_DIR_UL) { - /* C1 .. C5 */ + /* C1 .. C5: FR UL */ tf->c_bits[0] = 0; tf->c_bits[1] = 0; tf->c_bits[2] = 0; tf->c_bits[3] = 1; tf->c_bits[4] = 0; - } else { - /* C1 .. C5 */ - tf->c_bits[0] = 1; - tf->c_bits[1] = 1; - tf->c_bits[2] = 1; - tf->c_bits[3] = 0; - tf->c_bits[4] = 0; + } else { /* DL */ + if (data_len == 0) { + /* C1 .. C5: idle speech */ + tf->c_bits[0] = 0; + tf->c_bits[1] = 1; + tf->c_bits[2] = 1; + tf->c_bits[3] = 1; + tf->c_bits[4] = 0; + } else { + /* C1 .. C5: FR DL */ + tf->c_bits[0] = 1; + tf->c_bits[1] = 1; + tf->c_bits[2] = 1; + tf->c_bits[3] = 0; + tf->c_bits[4] = 0; + } } memset(&tf->c_bits[5], 0, 6); /* C6 .. C11: Time Alignment */ if (tf->dir == OSMO_TRAU_DIR_UL) { @@ -302,11 +311,14 @@ memset(&tf->c_bits[11], 1, 10); /* C12 .. C15: spare */ tf->c_bits[15] = 1; /* C16: SP=1 */ } - memset(&tf->c_bits[17], 1, 4); /* C18 .. C12: spare */ + memset(&tf->c_bits[17], 1, 4); /* C18 .. C21: spare */ memset(&tf->t_bits[0], 1, 4);
- if (!data_len) + if (!data_len) { + /* idle speech frame if DL, BFI speech frame if UL */ + memset(&tf->d_bits[0], 1, 260); return 0; + }
/* reassemble d-bits */ i = 0; /* counts bits */ @@ -428,11 +440,21 @@ /* FR Data Bits according to TS 48.060 Section 5.5.1.1.2 */
/* set c-bits and t-bits */ - tf->c_bits[0] = 1; - tf->c_bits[1] = 1; - tf->c_bits[2] = 0; - tf->c_bits[3] = 1; - tf->c_bits[4] = 0; + if (data_len == 0 && tf->dir == OSMO_TRAU_DIR_DL) { + /* C1 .. C5: idle speech */ + tf->c_bits[0] = 0; + tf->c_bits[1] = 1; + tf->c_bits[2] = 1; + tf->c_bits[3] = 1; + tf->c_bits[4] = 0; + } else { + /* C1 .. C5: EFR */ + tf->c_bits[0] = 1; + tf->c_bits[1] = 1; + tf->c_bits[2] = 0; + tf->c_bits[3] = 1; + tf->c_bits[4] = 0; + }
memset(&tf->c_bits[5], 0, 6); /* C6 .. C11: Time Alignment */ if (tf->dir == OSMO_TRAU_DIR_UL) { @@ -455,8 +477,11 @@ memset(&tf->c_bits[17], 1, 4); /* C18 .. C21: spare */ memset(&tf->t_bits[0], 1, 4);
- if (data_len == 0) + if (data_len == 0) { + /* idle speech frame if DL, BFI speech frame if UL */ + memset(&tf->d_bits[0], 1, 260); return 0; + }
/* reassemble d-bits */ tf->d_bits[0] = 1;