fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/27803 )
Change subject: osmo-bts-trx: de-duplicate generation of BFI TCH frames ......................................................................
osmo-bts-trx: de-duplicate generation of BFI TCH frames
Change-Id: I3efcd4a547beb0c0be6a959dc6f140b61b448b4e Related: SYS#5919, OS#4823 --- M src/osmo-bts-trx/sched_lchan_tchf.c M src/osmo-bts-trx/sched_lchan_tchh.c M src/osmo-bts-trx/sched_tch.h 3 files changed, 49 insertions(+), 90 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/03/27803/1
diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c index e6e1eff..05cb2bf 100644 --- a/src/osmo-bts-trx/sched_lchan_tchf.c +++ b/src/osmo-bts-trx/sched_lchan_tchf.c @@ -278,35 +278,10 @@ goto compose_l1sap; }
- switch (tch_mode) { - case GSM48_CMODE_SPEECH_V1: /* FR */ - memset(tch_data, 0, GSM_FR_BYTES); - tch_data[0] = 0xd0; - rc = GSM_FR_BYTES; - break; - case GSM48_CMODE_SPEECH_EFR: /* EFR */ - memset(tch_data, 0, GSM_EFR_BYTES); - tch_data[0] = 0xc0; - rc = GSM_EFR_BYTES; - break; - case GSM48_CMODE_SPEECH_AMR: /* AMR */ - rc = osmo_amr_rtp_enc(tch_data, - chan_state->codec[chan_state->ul_cmr], - chan_state->codec[chan_state->ul_ft], - AMR_BAD); - if (rc < 2) { - LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, - "Failed to encode AMR_BAD frame (rc=%d), " - "not sending BFI\n", rc); - return -EINVAL; - } - memset(tch_data + 2, 0, rc - 2); - break; - default: - LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, - "TCH mode %u invalid, please fix!\n", tch_mode); - return -EINVAL; - } + /* populate the buffer with a BFI payload */ + rc = tch_compose_bfi(tch_data, chan_state, + true /* Uplink */, + true /* FR */); } }
diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c index bacd49b..a993100 100644 --- a/src/osmo-bts-trx/sched_lchan_tchh.c +++ b/src/osmo-bts-trx/sched_lchan_tchh.c @@ -314,30 +314,10 @@ goto compose_l1sap; }
- switch (tch_mode) { - case GSM48_CMODE_SPEECH_V1: /* HR */ - tch_data[0] = 0x70; /* F = 0, FT = 111 */ - memset(tch_data + 1, 0, 14); - rc = 15; - break; - case GSM48_CMODE_SPEECH_AMR: /* AMR */ - rc = osmo_amr_rtp_enc(tch_data, - chan_state->codec[chan_state->ul_cmr], - chan_state->codec[chan_state->ul_ft], - AMR_BAD); - if (rc < 2) { - LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, - "Failed to encode AMR_BAD frame (rc=%d), " - "not sending BFI\n", rc); - return -EINVAL; - } - memset(tch_data + 2, 0, rc - 2); - break; - default: - LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, - "TCH mode %u invalid, please fix!\n", tch_mode); - return -EINVAL; - } + /* populate the buffer with a BFI payload */ + rc = tch_compose_bfi(tch_data, chan_state, + true /* Uplink */, + false /* HR */); } }
diff --git a/src/osmo-bts-trx/sched_tch.h b/src/osmo-bts-trx/sched_tch.h index f3e9c69..3b0b1e8 100644 --- a/src/osmo-bts-trx/sched_tch.h +++ b/src/osmo-bts-trx/sched_tch.h @@ -25,6 +25,42 @@
void trx_loop_amr_set(struct l1sched_chan_state *chan_state, int loop);
+/* Populate the given buffer with a BFI payload */ +static inline int tch_compose_bfi(uint8_t *tch_data, + const struct l1sched_chan_state *chan_state, + bool uplink, bool fr) +{ + uint8_t cmr, ft; + int len; + + switch (chan_state->tch_mode) { + case GSM48_CMODE_SPEECH_V1: /* FR / HR */ + if (fr) { + memset(&tch_data[1], 0, GSM_FR_BYTES - 1); + tch_data[0] = 0xd0; /* FR magic */ + return GSM_FR_BYTES; + } else { + memset(&tch_data[1], 0, GSM_HR_BYTES); + tch_data[0] = 0x70; /* F = 0, FT = 111 */ + return GSM_HR_BYTES + 1; + } + break; + case GSM48_CMODE_SPEECH_EFR: + memset(&tch_data[1], 0, GSM_EFR_BYTES - 1); + tch_data[0] = 0xc0; /* EFR magic */ + return GSM_EFR_BYTES; + case GSM48_CMODE_SPEECH_AMR: + cmr = chan_state->codec[uplink ? chan_state->ul_cmr : chan_state->dl_cmr]; + ft = chan_state->codec[uplink ? chan_state->ul_ft : chan_state->dl_ft]; + len = osmo_amr_rtp_enc(tch_data, cmr, ft, AMR_BAD); + if (len > 2) + memset(tch_data + 2, 0, len - 2); + return len; + default: + OSMO_ASSERT(0); + } +} + /* Common section for generation of Downlink bursts (TCH/H and TCH/F) */ static inline void tx_tch_common(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br, struct msgb **_msg_tch, struct msgb **_msg_facch) @@ -43,43 +79,11 @@
LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Missing TCH bursts detected, sending BFI\n");
- /* indicate bad frame */ - switch (tch_mode) { - case GSM48_CMODE_SPEECH_V1: /* FR / HR */ - if (br->chan != TRXC_TCHF) { /* HR */ - tch_data[0] = 0x70; /* F = 0, FT = 111 */ - memset(tch_data + 1, 0, 14); - len = 15; - break; - } - memset(tch_data, 0, GSM_FR_BYTES); - len = GSM_FR_BYTES; - break; - case GSM48_CMODE_SPEECH_EFR: /* EFR */ - if (br->chan != TRXC_TCHF) - goto inval_mode1; - memset(tch_data, 0, GSM_EFR_BYTES); - len = GSM_EFR_BYTES; - break; - case GSM48_CMODE_SPEECH_AMR: /* AMR */ - len = osmo_amr_rtp_enc(tch_data, - chan_state->codec[chan_state->dl_cmr], - chan_state->codec[chan_state->dl_ft], AMR_BAD); - if (len < 2) { - LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, - "Failed to encode AMR_BAD frame (rc=%d), " - "not sending BFI\n", len); - return; - } - memset(tch_data + 2, 0, len - 2); - break; - default: -inval_mode1: - LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "TCH mode invalid, please fix!\n"); - len = 0; - } - - if (len) { + /* populate the buffer with a BFI payload */ + len = tch_compose_bfi(tch_data, chan_state, + false /* Downlink */, + br->chan == TRXC_TCHF); + if (len > 0) { /* Note: RSSI/ToA256 is set to 0 to indicate to the higher * layers that this is a faked tch_ind */ _sched_compose_tch_ind(l1ts, br->fn, br->chan,