Hello Vadim Yanitskiy, Jenkins Builder,

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

    https://gerrit.osmocom.org/5753

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

LC15: Fix missing fill frame and GSM 05.08 mandatory frame

Problem:
 We have noticed that the LC15 BTS does not send L2 fill frame in case there is 
nothing to transmit.
 This leads to bad RXQUAL repored by MS during signaling in TCH channel.

 Related issue: https://osmocom.org/issues/1950

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

 "On any TCH this subset of TDMA frames is always used for transmission during 
DTX. For speech, when
 no signalling or speech is to be transmitted these TDMA frames are occupied by 
the SID (Silence
 Descriptor) speech frame, see TS GSM 06.12 and TSM GSM 06.31 for detailed 
specification of the SID
 frame and its transmission requirements. In other cases when no information is 
required to be transmitted,
 e.g. on data channels, the L2 fill frame (see GSM 04.06 section 5.4.2.3) shall 
be transmitted as a FACCH
 in the TDMA frame subset always to be transmitted.
 On the SDCCH and on the half rate speech traffic channel in signalling only 
mode DTX is not allowed. In
 these cases and during signalling on the TCH when DTX is not used, the same L2 
fill frame shall be
 transmitted in case there is nothing else to transmit."

Change-Id: I40e9bf9438c0b400e4d29eb39ffae37207e34db6
---
M src/common/msg_utils.c
M src/osmo-bts-litecell15/l1_if.c
2 files changed, 119 insertions(+), 6 deletions(-)


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

diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c
index f936c98..370dd09 100644
--- a/src/common/msg_utils.c
+++ b/src/common/msg_utils.c
@@ -36,6 +36,17 @@
 
 #define STI_BIT_MASK 16
 
+static const uint8_t gsm_speech_zero[GSM_FR_BYTES] = {
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00
+};
+
+static const uint8_t amr_sid_first_zero[9] = {
+               0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
 static int check_fom(struct abis_om_hdr *omh, size_t len)
 {
        if (omh->length != len) {
@@ -379,7 +390,7 @@
        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) {
+       if ((lchan->tch_mode == GSM48_CMODE_SPEECH_V1) || (lchan->tch_mode == 
GSM48_CMODE_SPEECH_AMR)){
                if (lchan->type == GSM_LCHAN_TCH_F)
                        return fn_chk(f, fn, ARRAY_SIZE(f));
                else
@@ -465,6 +476,7 @@
  */
 uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn)
 {
+       uint8_t pl_len;
        /* FIXME: add EFR support */
        if (lchan->tch_mode == GSM48_CMODE_SPEECH_EFR)
                return 0;
@@ -472,11 +484,54 @@
        if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
                if (dtx_sched_optional(lchan, fn))
                        return 0;
-       } else
+               else {
+                       if (lchan->ts->trx->bts->dtxd) {
+                               /* Need to send zeroed TCH frame on mandatory 
Fn defined in GSM 05.08, section 8.3 */
+                               switch (lchan->type) {
+                               case GSM_LCHAN_TCH_F:
+                                       pl_len = GSM_FR_BYTES;
+                                       break;
+                               case GSM_LCHAN_TCH_H:
+                                       pl_len = GSM_HR_BYTES;
+                                       break;
+                               default:
+                                       return 0;
+                               }
+                               memcpy(dst, gsm_speech_zero, pl_len);
+
+                               LOGP(DL1C, LOGL_DEBUG, "%s Have to send %s %s 
zero speech frame, Fn=%d, Fn mod 104=%d, dump=%s\n",
+                                                                       
gsm_lchan_name(lchan),
+                                                                       
get_value_string(gsm_chan_t_names, lchan->type),
+                                                                       
get_value_string(gsm48_chan_mode_names, lchan->tch_mode),
+                                                                       fn,
+                                                                       fn%104,
+                                                                       
osmo_hexdump(dst, pl_len));
+                               return pl_len + 1;
+                       }
+               }
+       } else {
+               if (!dtx_sched_optional(lchan, fn) && (lchan->rsl_cmode == 
RSL_CMOD_SPD_SPEECH)) {
+                       if (!(lchan->tch.dtx.len)) {
+                               pl_len = 9;
+                               /* Send zero SID FIRST frame */
+                               memcpy(dst, amr_sid_first_zero, pl_len);
+                               LOGP(DL1C, LOGL_DEBUG, "%s Have to send %s %s 
zero speech frame, Fn=%d, Fn mod 104=%d, dump=%s\n",
+                                               gsm_lchan_name(lchan),
+                                               
get_value_string(gsm_chan_t_names, lchan->type),
+                                               
get_value_string(gsm48_chan_mode_names, lchan->tch_mode),
+                                               fn,
+                                               fn%104,
+                                               osmo_hexdump(dst, pl_len));
+                               return pl_len + 1; /* plus one to take into 
account of payload type */
+                       }
+               }
+
                if (dtx_amr_sid_optional(lchan, fn))
                        return 0;
+       }
 
        if (lchan->tch.dtx.len) {
+
                if (dtx_dl_amr_enabled(lchan)) {
                        if ((lchan->type == GSM_LCHAN_TCH_H &&
                             lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F2) ||
@@ -502,11 +557,17 @@
                }
                memcpy(dst, lchan->tch.dtx.cache, lchan->tch.dtx.len);
                lchan->tch.dtx.fn = fn;
+               LOGP(DL1C, LOGL_DEBUG, "%s Have to send %s SID buffer "
+                            "%s\n",
+                                gsm_lchan_name(lchan),
+                            get_value_string(gsm48_chan_mode_names, 
lchan->tch_mode),
+                                osmo_hexdump(lchan->tch.dtx.cache, 
lchan->tch.dtx.len));
                return lchan->tch.dtx.len + 1;
        }
 
-       LOGP(DL1C, LOGL_DEBUG, "Have to send %s frame on TCH but SID buffer "
+       LOGP(DL1C, LOGL_DEBUG, "%s Have to send %s frame on TCH but SID buffer "
             "is empty - sent nothing\n",
+                gsm_lchan_name(lchan),
             get_value_string(gsm48_chan_mode_names, lchan->tch_mode));
 
        return 0;
diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
index 12c2470..6438c54 100644
--- a/src/osmo-bts-litecell15/l1_if.c
+++ b/src/osmo-bts-litecell15/l1_if.c
@@ -331,6 +331,49 @@
        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;
+
+
+       LOGP(DL1C, LOGL_DEBUG, "Send fill frame on in none DTX mode Tn=%d, 
Fn=%d, SAPI=%d, SubCh=%d, BlockNr=%d dump=%s\n",
+                       tn,
+                       fn,
+                       sapi,
+                       sub_ch,
+                       block_nr,
+                       osmo_hexdump(data_req->msgUnitParam.u8Buffer, 
data_req->msgUnitParam.u8Size));
+
+       return data_req;
+}
+
 static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
                       struct osmo_phsap_prim *l1sap, bool use_cache)
 {
@@ -461,10 +504,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: 2
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