falconia has uploaded this change for review.

View Change

E1: change dummy fill frame generation method

In the absence of a proper TFO transform (TS 28.062 section
C3.2.1.1), OsmoMGW-E1 inserts constant fill frames when there is
no RTP input, or when RTP input fails conversion to TRAU-DL and
thus does not enqueue anything to the I.460 mux. (We accept
TW-TS-001 and TW-TS-002 from RTP side, but bad frames cannot be
converted to TRAU-DL without a TFO transform.)

Prior to the present change, this idle fill of the DL was done
using fully hard-coded frames, i.e., the operation of converting
the desired fill to TRAU-DL bit format was done once externally
and the raw bit frames were hard-coded. Change this approach:
use fill frames in RTP format provided by libosmocodec, and
execute osmo_rtp2trau() followed by osmo_trau_frame_encode() in
the fill frame output path just like we do for regular RTP to DL.

Depends: libosmocore.git I2c510ac62a0786c137115c45eee7a48b9736265f
Change-Id: I123f77295c56d61ff9aac5f5d64b25eca01e0d63
---
M TODO-RELEASE
M src/libosmo-mgcp/mgcp_e1.c
2 files changed, 35 insertions(+), 157 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/50/39750/1
diff --git a/TODO-RELEASE b/TODO-RELEASE
index bdb3915..73a6cd6 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -9,3 +9,4 @@
#library what description / commit summary line
libosmocore bump_dep; workaround Bump libosmocore version dependency after I68328adb952ca8833ba047cb3b49ccc6f8a1f1b5
has been merged to libosmocore.git; then remove my_msgb_copy_c wrapper function.
+libosmocodec bump_dep We depend on the additions of I2c510ac62a0786c137115c45eee7a48b9736265f
diff --git a/src/libosmo-mgcp/mgcp_e1.c b/src/libosmo-mgcp/mgcp_e1.c
index f056d75..e3d72e0 100644
--- a/src/libosmo-mgcp/mgcp_e1.c
+++ b/src/libosmo-mgcp/mgcp_e1.c
@@ -57,149 +57,6 @@
.sign_link = NULL,
};

-/* The following EFR TRAU-DL frame is a dummy to be transmitted in the absence
- * of RTP-derived TRAU-DL frames. The payload bit content here is the decoder
- * homing frame (DHF) of TS 46.060 section 8.2 Table 7 - the best we can do
- * in the absence of a proper TFO transform for EFR - while the full TRAU-DL
- * frame was generated by passing said EFR DHF through osmo_rtp2trau().
- */
-static const ubit_t idle_tf_efr[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0, 1, 1, 1,
- 1, 1, 0, 1, 0, 1, 1, 0,
- 1, 0, 0, 1, 0, 0, 1, 0,
- 1, 0, 0, 0, 1, 1, 1, 1,
- 1, 0, 0, 1, 0, 1, 0, 1,
- 1, 0, 1, 0, 1, 1, 0, 1,
- 0, 1, 1, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 1, 1, 1, 0, 1,
- 1, 0, 0, 0, 0, 1, 1, 0,
- 0, 0, 0, 1, 1, 0, 0, 0,
- 1, 0, 0, 0, 1, 1, 1, 1,
- 0, 1, 1, 0, 1, 1, 0, 0,
- 1, 0, 0, 1, 1, 0, 0, 0,
- 1, 0, 0, 0, 0, 1, 0, 1,
- 1, 1, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 1, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 1, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 0,
- 1, 1, 1, 0, 1, 0, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
-};
-
-/* The following FRv1 TRAU-DL frame is a dummy to be transmitted in the absence
- * of RTP-derived TRAU-DL frames. The payload bit content here is the silence
- * frame of TS 46.011 Table 1 - the best we can do without integrating the
- * TFO transform for FRv1 from Themyscira libgsmfr2 - while the full TRAU-DL
- * frame was generated by passing said FRv1 silence frame through
- * osmo_rtp2trau().
- */
-static const ubit_t idle_tf_fr[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 0, 1, 0, 1, 0, 1, 1,
- 1, 1, 0, 0, 1, 1, 0, 1,
- 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 0, 1, 0, 0, 1, 0,
- 1, 1, 1, 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 1, 0, 0, 0,
- 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 0, 0, 0, 1, 1,
- 1, 1, 0, 0, 0, 1, 0, 0,
- 1, 1, 1, 0, 1, 1, 0, 1,
- 1, 1, 0, 1, 1, 0, 0, 0,
- 1, 0, 0, 1, 1, 1, 0, 1,
- 1, 1, 0, 0, 0, 0, 1, 0,
- 1, 0, 0, 0, 1, 0, 0, 0,
- 1, 0, 0, 0, 0, 1, 1, 0,
- 0, 0, 1, 1, 1, 0, 0, 0,
- 1, 1, 0, 0, 1, 1, 1, 0,
- 1, 1, 0, 1, 1, 0, 1, 1,
- 1, 0, 0, 0, 1, 0, 0, 1,
- 1, 1, 0, 1, 1, 0, 0, 0,
- 1, 0, 1, 0, 1, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 0, 0, 0, 1, 1,
- 1, 0, 0, 0, 1, 0, 0, 1,
- 1, 1, 1, 0, 1, 1, 0, 1,
- 1, 0, 1, 1, 0, 0, 0, 1,
- 1, 0, 0, 1, 1, 1, 0, 1,
- 1, 0, 0, 0, 0, 1, 0, 1,
- 1, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 0, 0,
- 1, 0, 1, 1, 1, 0, 0, 0,
- 1, 0, 0, 1, 1, 1, 0, 1,
- 1, 1, 0, 1, 1, 0, 1, 1,
- 0, 0, 0, 1, 0, 0, 1, 1,
- 1, 1, 0, 1, 1, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
-};
-
-/* Idle speech frame, see also GSM 08.60, chapter 3.4 */
-static const ubit_t idle_tf_spch[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 1, 1, 1, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 0,
- 1, 1, 1, 1, 1, 1, 1, 1,
-};
-
/* If the RTP transmission has dropouts for some reason the I.460 TX-Queue may
* run empty. In order to make sure that the TRAU frame transmission continues
* we generate idle TRAU frames here. */
@@ -208,33 +65,53 @@
struct mgcp_endpoint *endp = user_data;
struct rate_ctr_group *rate_ctrs = endp->trunk->ratectr.e1_stats;
struct msgb *msg = msgb_alloc_c(endp->trunk, E1_TRAU_BITS_MSGB, "E1-I.460-IDLE-TX-TRAU-frame");
- uint8_t *ptr;
- const uint8_t *ptr_ft;
- enum osmo_trau_frame_type ft;
+ const uint8_t *dummy_fill_pl;
+ unsigned dummy_fill_pl_len;
+ struct osmo_trau_frame tf;
+ int rc;

rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, E1_I460_TRAU_MUX_EMPTY_CTR));

- /* Choose an appropiate idle frame type */
- ft = endp->e1.trau_rtp_st->type;
- switch (ft) {
+ /* choose dummy fill frame payload based on current codec */
+ switch (endp->e1.trau_rtp_st->type) {
case OSMO_TRAU16_FT_FR:
- ptr_ft = idle_tf_fr;
+ dummy_fill_pl = osmo_gsm611_silence_frame;
+ dummy_fill_pl_len = GSM_FR_BYTES;
break;
case OSMO_TRAU16_FT_EFR:
- ptr_ft = idle_tf_efr;
+ dummy_fill_pl = osmo_gsm660_homing_frame;
+ dummy_fill_pl_len = GSM_EFR_BYTES;
break;
default:
- /* FIXME: What about 8k subslots and AMR frames? */
- ptr_ft = idle_tf_spch;
+ LOGPENDP(endp, DE1, LOGL_ERROR, "E1-I.460-IDLE-TX: unsupported frame type\n");
+ goto skip;
}

- /* Put the replacement into a message buffer and enqueue it into the
- * I.460 multiplexer */
- ptr = msgb_put(msg, E1_TRAU_BITS);
- memcpy(ptr, ptr_ft, E1_TRAU_BITS);
+ /* turn it into a TRAU-DL frame */
+ memset(&tf, 0, sizeof(tf));
+ tf.dir = OSMO_TRAU_DIR_DL;
+ rc = osmo_rtp2trau(&tf, dummy_fill_pl, dummy_fill_pl_len, endp->e1.trau_rtp_st);
+ if (rc < 0) {
+ LOGPENDP(endp, DE1, LOGL_ERROR,
+ "E1-I.460-IDLE-TX: error converting dummy fill frame!\n");
+ goto skip;
+ }
+ rc = osmo_trau_frame_encode(msgb_data(msg), msg->data_len, &tf);
+ if (rc < 0) {
+ LOGPENDP(endp, DE1, LOGL_ERROR,
+ "E1-I.460-IDLE-TX: error encoding dummy fill frame!\n");
+ goto skip;
+ }
+ msgb_put(msg, rc);
+
+ /* enqueue it into the I.460 multiplexer */
LOGPENDP(endp, DE1, LOGL_DEBUG, "E1-I.460-IDLE-TX: enquing %u trau frame bits: %s...\n", msgb_length(msg),
osmo_ubit_dump(msgb_data(msg), msgb_length(msg) > DEBUG_BITS_MAX ? DEBUG_BITS_MAX : msgb_length(msg)));
osmo_i460_mux_enqueue(endp->e1.schan, msg);
+
+skip:
+ rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, E1_I460_TRAU_TX_FAIL_CTR));
+ msgb_free(msg);
}

/* called by I.460 de-multiplexer; feed output of I.460 demux into TRAU frame sync */

To view, visit change 39750. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-mgw
Gerrit-Branch: master
Gerrit-Change-Id: I123f77295c56d61ff9aac5f5d64b25eca01e0d63
Gerrit-Change-Number: 39750
Gerrit-PatchSet: 1
Gerrit-Owner: falconia <falcon@freecalypso.org>