Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/5753

to look at the new patch set (#5).

LC15: Fix missing fill frame and GSM 05.08 mandatory frame

It was discovered that the LC15 BTS does not send L2 fill frame
in case there is nothing to transmit. This leads to bad RXQUAL
reported by MS during signaling in TCH channel.

BTS needs to send L2 fill frame in case there is nothing to
transmit as indicated in GSM TS 05.08, section 8.3.

Related: OS#1950
Change-Id: I40e9bf9438c0b400e4d29eb39ffae37207e34db6
---
M src/common/msg_utils.c
M src/osmo-bts-litecell15/l1_if.c
2 files changed, 127 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/53/5753/5

diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c
index f936c98..55874cf 100644
--- a/src/common/msg_utils.c
+++ b/src/common/msg_utils.c
@@ -379,15 +379,18 @@
        static const uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 },
                                h0[] = { 0, 2, 4, 6, 52, 54, 56, 58 },
                                h1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };
-       if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1) {
+
+       switch (lchan->tch_mode) {
+       case GSM48_CMODE_SPEECH_V1:
+       case GSM48_CMODE_SPEECH_AMR:
                if (lchan->type == GSM_LCHAN_TCH_F)
                        return fn_chk(f, fn, ARRAY_SIZE(f));
                else
                        return fn_chk(lchan->nr ? h1 : h0, fn,
-                                     lchan->nr ? ARRAY_SIZE(h1) :
-                                     ARRAY_SIZE(h0));
+                               lchan->nr ? ARRAY_SIZE(h1) : ARRAY_SIZE(h0));
+       default:
+               return false;
        }
-       return false;
 }
 
 /*! \brief Check if DTX DL AMR is enabled for a given lchan (it have proper 
type,
@@ -465,16 +468,72 @@
  */
 uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn)
 {
-       /* FIXME: add EFR support */
-       if (lchan->tch_mode == GSM48_CMODE_SPEECH_EFR)
+       uint8_t payload_len;
+
+       static const uint8_t amr_sid_first_zero[] = {
+               0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+
+       switch (lchan->tch_mode) {
+       case GSM48_CMODE_SPEECH_EFR:
+               /* FIXME: add EFR support */
                return 0;
 
-       if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
-               if (dtx_sched_optional(lchan, fn))
-                       return 0;
-       } else
+       case GSM48_CMODE_SPEECH_AMR:
                if (dtx_amr_sid_optional(lchan, fn))
                        return 0;
+
+               if (lchan->rsl_cmode != RSL_CMOD_SPD_SPEECH)
+                       break;
+
+               if (!!lchan->tch.dtx.len)
+                       break;
+
+               /* Send zero SID FIRST frame */
+               payload_len = sizeof(amr_sid_first_zero);
+               memcpy(dst, amr_sid_first_zero, payload_len);
+
+               /* Debug print */
+               LOGP(DL1C, LOGL_DEBUG, "%s %s %s: Sending zero speech frame "
+                       "for tch_mode=%s\n", gsm_fn_as_gsmtime_str(fn),
+                       gsm_ts_name(lchan->ts), 
get_value_string(gsm_chan_t_names, lchan->type),
+                       get_value_string(gsm48_chan_mode_names, 
lchan->tch_mode));
+
+               return payload_len + 1;
+
+       default:
+               if (dtx_sched_optional(lchan, fn))
+                       return 0;
+
+               if (!lchan->ts->trx->bts->dtxd)
+                       break;
+
+               /* Determine the payload length */
+               switch (lchan->type) {
+               case GSM_LCHAN_TCH_F:
+                       payload_len = GSM_FR_BYTES;
+                       break;
+               case GSM_LCHAN_TCH_H:
+                       payload_len = GSM_HR_BYTES;
+                       break;
+               default:
+                       return 0;
+               }
+
+               /**
+                * Need to send zeroed TCH frame on mandatory fn,
+                * defined in GSM TS 05.08, section 8.3
+                */
+               memset(dst, 0x00, payload_len);
+
+               /* Debug print */
+               LOGP(DL1C, LOGL_DEBUG, "%s %s %s: Sending zero speech frame "
+                       "for tch_mode=%s\n", gsm_fn_as_gsmtime_str(fn),
+                       gsm_ts_name(lchan->ts), 
get_value_string(gsm_chan_t_names, lchan->type),
+                       get_value_string(gsm48_chan_mode_names, 
lchan->tch_mode));
+
+               return payload_len + 1;
+       }
 
        if (lchan->tch.dtx.len) {
                if (dtx_dl_amr_enabled(lchan)) {
@@ -502,6 +561,13 @@
                }
                memcpy(dst, lchan->tch.dtx.cache, lchan->tch.dtx.len);
                lchan->tch.dtx.fn = fn;
+
+               /* Debug print */
+               LOGP(DL1C, LOGL_DEBUG, "%s %s %s: Sending SID buffer "
+                       "for tch_mode=%s\n", gsm_fn_as_gsmtime_str(fn),
+                       gsm_ts_name(lchan->ts), 
get_value_string(gsm_chan_t_names, lchan->type),
+                       get_value_string(gsm48_chan_mode_names, 
lchan->tch_mode));
+
                return lchan->tch.dtx.len + 1;
        }
 
diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
index 9e122cd..73890f0 100644
--- a/src/osmo-bts-litecell15/l1_if.c
+++ b/src/osmo-bts-litecell15/l1_if.c
@@ -331,6 +331,45 @@
        return empty_req;
 }
 
+/* fill frame PH-DATA.req from l1sap primitive */
+static GsmL1_PhDataReq_t *
+fill_req_from_l1sap(GsmL1_Prim_t *l1p, struct lc15l1_hdl *fl1,
+       uint8_t tn, uint32_t fn, uint8_t sapi, uint8_t sub_ch, uint8_t block_nr)
+{
+       GsmL1_PhDataReq_t *data_req = &l1p->u.phDataReq;
+       GsmL1_MsgUnitParam_t *msu_param;
+       uint8_t *l1_payload;
+
+       msu_param = &data_req->msgUnitParam;
+       l1_payload = &msu_param->u8Buffer[0];
+       l1p->id = GsmL1_PrimId_PhDataReq;
+
+       memset(l1_payload, 0x2b, GSM_MACBLOCK_LEN);
+
+       /* address field */
+       l1_payload[0] = 0x03;
+       /* control field */
+       l1_payload[1] = 0x03;
+       /* length field */
+       l1_payload[2] = 0x01;
+
+       /* copy fields from PH-RTS.ind */
+       data_req->hLayer1       = (HANDLE)fl1->hLayer1;
+       data_req->u8Tn          = tn;
+       data_req->u32Fn         = fn;
+       data_req->sapi          = sapi;
+       data_req->subCh         = sub_ch;
+       data_req->u8BlockNbr    = block_nr;
+       data_req->msgUnitParam.u8Size = GSM_MACBLOCK_LEN;
+
+       /* Debug print */
+       LOGP(DL1C, LOGL_DEBUG, "%s tn=%u: Sending fill frame on in none DTX 
mode "
+               "SAPI=%d, SubCh=%d, BlockNr=%d\n", gsm_fn_as_gsmtime_str(fn),
+               tn, sapi, sub_ch, block_nr);
+
+       return data_req;
+}
+
 static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
                       struct osmo_phsap_prim *l1sap, bool use_cache)
 {
@@ -460,10 +499,19 @@
                     osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer,
                                          
l1p->u.phDataReq.msgUnitParam.u8Size));
        } else {
-               /* empty frame */
-               GsmL1_Prim_t *l1p = msgb_l1prim(l1msg);
 
-               empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, 
u8BlockNbr);
+               GsmL1_Prim_t *l1p = msgb_l1prim(l1msg);
+               if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN)
+                       /* fill frame */
+                       fill_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, 
u8BlockNbr);
+               else {
+                       if (lchan->ts->trx->bts->dtxd)
+                               /* empty frame */
+                               empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, 
sapi, subCh, u8BlockNbr);
+                       else
+                               /* fill frame */
+                               fill_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, 
sapi, subCh, u8BlockNbr);
+               }
        }
 
        /* send message to DSP's queue */

-- 
To view, visit https://gerrit.osmocom.org/5753
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I40e9bf9438c0b400e4d29eb39ffae37207e34db6
Gerrit-PatchSet: 5
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Owner: Minh-Quang Nguyen <minh-quang.ngu...@nutaq.com>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Max <msur...@sysmocom.de>
Gerrit-Reviewer: Minh-Quang Nguyen <minh-quang.ngu...@nutaq.com>
Gerrit-Reviewer: Pau Espin Pedrol <pes...@sysmocom.de>
Gerrit-Reviewer: Vadim Yanitskiy <axilira...@gmail.com>

Reply via email to