From f588b5f91d78d7cf1fc01d657b8483d3908c8841 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Fri, 30 Jun 2017 15:19:00 +0200 Subject: Allow passing low link quality buffers to upper layers We want to always call l1if_tch_rx and l1sap_up in order to avoid losing triggering events on the upper layer. With this change, the upper layer will increase correctly seq + ts for RTP. It will then send an RTP packet with only the header and no payload, which is not correct but at least we avoid drifting the RTP clock. Upcoming patch in the series solves this issue. This patch assumes that we are not lossing data events from the physical layer and that we receive an event every 20ms, even if the MS is not transmitting due to DTX. Depends on libosmocore If4ae20c22b881e94585dad710f17b9e37f77bf82 Change-Id: If5df8940fab833eb4e3ed851880b66987d356031 --- include/osmo-bts/l1sap.h | 3 ++- src/common/l1sap.c | 7 +++++-- src/common/pcu_sock.c | 8 ++++++++ src/osmo-bts-litecell15/l1_if.c | 7 ------- src/osmo-bts-litecell15/tch.c | 14 +++++++++----- src/osmo-bts-octphy/l1_if.c | 2 -- src/osmo-bts-octphy/l1_tch.c | 18 ++++++++++++++---- src/osmo-bts-sysmo/l1_if.c | 9 +-------- src/osmo-bts-sysmo/tch.c | 15 ++++++++++----- 9 files changed, 49 insertions(+), 34 deletions(-) diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 6373ba84..4e9c9e20 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -85,7 +85,8 @@ extern uint32_t gsmtap_sapi_mask; extern uint8_t gsmtap_sapi_acch; int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg, - struct gsm_lchan *lchan, uint8_t chan_nr, uint32_t fn); + struct gsm_lchan *lchan, uint8_t chan_nr, uint32_t fn, + uint16_t ber10k, int16_t lqual_cb); #define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h) diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 71690cd2..b05ed721 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -135,11 +135,12 @@ struct msgb *l1sap_msgb_alloc(unsigned int l2_len) } int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg, - struct gsm_lchan *lchan, uint8_t chan_nr, uint32_t fn) + struct gsm_lchan *lchan, uint8_t chan_nr, uint32_t fn, + uint16_t ber10k, int16_t lqual_cb) { struct osmo_phsap_prim *l1sap; - LOGP(DL1C, LOGL_DEBUG, "%s Rx -> RTP: %s\n", + LOGP(DL1P, LOGL_DEBUG, "%s Rx -> RTP: %s\n", gsm_lchan_name(lchan), osmo_hexdump(rmsg->data, rmsg->len)); rmsg->l2h = rmsg->data; @@ -150,6 +151,8 @@ int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg, rmsg); l1sap->u.tch.chan_nr = chan_nr; l1sap->u.tch.fn = fn; + l1sap->u.tch.ber10k = ber10k; + l1sap->u.tch.lqual_cb = lqual_cb; return l1sap_up(trx, l1sap); } diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 27550480..a4ddc052 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -329,11 +330,18 @@ int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, struct gsm_pcu_if *pcu_prim; struct gsm_pcu_if_data *data_ind; struct gsm_bts *bts = ts->trx->bts; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); LOGP(DPCU, LOGL_DEBUG, "Sending data indication: is_ptcch=%d arfcn=%d " "block=%d data=%s\n", is_ptcch, arfcn, block_nr, osmo_hexdump(data, len)); + if (lqual / 10 < btsb->min_qual_norm) { + LOGP(DPCU, LOGL_DEBUG, "Link quality %"PRId16" is below threshold %f, dropping packet\n", + lqual, btsb->min_qual_norm); + return 0; + } + msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_IND, bts->nr); if (!msg) return -ENOMEM; diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index bd9e0030..66aa21ab 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -923,7 +923,6 @@ static int handle_ph_data_ind(struct lc15l1_hdl *fl1, GsmL1_PhDataInd_t *data_in struct msgb *l1p_msg) { struct gsm_bts_trx *trx = lc15l1_hdl_trx(fl1); - struct gsm_bts_role_bts *btsb = bts_role_bts(trx->bts); uint8_t chan_nr, link_id; struct osmo_phsap_prim *l1sap; uint32_t fn; @@ -944,12 +943,6 @@ static int handle_ph_data_ind(struct lc15l1_hdl *fl1, GsmL1_PhDataInd_t *data_in process_meas_res(trx, chan_nr, &data_ind->measParam, fn); - if (data_ind->measParam.fLinkQuality < btsb->min_qual_norm - && data_ind->msgUnitParam.u8Size != 0) { - msgb_free(l1p_msg); - return 0; - } - DEBUGP(DL1C, "Rx PH-DATA.ind %s (hL2 %08x): %s", get_value_string(lc15bts_l1sapi_names, data_ind->sapi), (uint32_t)data_ind->hLayer2, diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index a29733f1..c61712f1 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -369,9 +369,12 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) return -EAGAIN; if (data_ind->msgUnitParam.u8Size < 1) { - LOGP(DL1C, LOGL_ERROR, "chan_nr %d Rx Payload size 0\n", - chan_nr); - return -EINVAL; + LOGP(DL1P, LOGL_DEBUG, "chan_nr %d Rx Payload size 0\n", chan_nr); + /* Push empty payload to upper layers */ + rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP"); + return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn, + data_ind->measParam.fBer * 10000, + data_ind->measParam.fLinkQuality * 10); } payload_type = data_ind->msgUnitParam.u8Buffer[0]; @@ -459,8 +462,9 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) } if (rmsg) - return add_l1sap_header(trx, rmsg, lchan, chan_nr, - data_ind->u32Fn); + return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn, + data_ind->measParam.fBer * 10000, + data_ind->measParam.fLinkQuality * 10); return 0; diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index 427acdff..5785b9a0 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -1050,8 +1050,6 @@ static int handle_ph_data_ind(struct octphy_hdl *fl1, process_meas_res(trx, chan_nr, fn, data_ind->Data.ulDataLength, &data_ind->MeasurementInfo); - /* FIXME: check min_qual_norm! */ - DEBUGP(DL1C, "Rx PH-DATA.ind %s: %s data_len:%d \n", get_value_string(octphy_l1sapi_names, sapi), osmo_hexdump(data_ind->Data.abyDataContent, diff --git a/src/osmo-bts-octphy/l1_tch.c b/src/osmo-bts-octphy/l1_tch.c index 79bf245b..38fb9fb6 100644 --- a/src/osmo-bts-octphy/l1_tch.c +++ b/src/osmo-bts-octphy/l1_tch.c @@ -188,16 +188,25 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, uint32_t payload_type = data_ind->Data.ulPayloadType; uint8_t *payload = data_ind->Data.abyDataContent; + uint16_t b_total = data_ind->MeasurementInfo.usBERTotalBitCnt; + uint16_t b_error = data_ind->MeasurementInfo.usBERCnt; + uint16_t ber10k = b_total ? BER_10K * b_error / b_total : 0; + int16_t lqual_cb = 0; /* FIXME: check min_qual_norm! */ + uint8_t payload_len; struct msgb *rmsg = NULL; struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)]; if (data_ind->Data.ulDataLength < 1) { - LOGP(DL1C, LOGL_DEBUG, "chan_nr %d Rx Payload size 0\n", - chan_nr); - return -EINVAL; + LOGP(DL1P, LOGL_DEBUG, "chan_nr %d Rx Payload size 0\n", chan_nr); + /* Push empty payload to upper layers */ + rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP"); + return add_l1sap_header(trx, rmsg, lchan, chan_nr, + data_ind->Data.ulFrameNumber, + ber10k, lqual_cb); } + payload_len = data_ind->Data.ulDataLength; switch (payload_type) { @@ -255,7 +264,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, if (rmsg) return add_l1sap_header(trx, rmsg, lchan, chan_nr, - data_ind->Data.ulFrameNumber); + data_ind->Data.ulFrameNumber, + ber10k, lqual_cb); return 0; diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 05805b89..72d64ead 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -918,7 +918,6 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i struct msgb *l1p_msg) { struct gsm_bts_trx *trx = femtol1_hdl_trx(fl1); - struct gsm_bts_role_bts *btsb = bts_role_bts(trx->bts); uint8_t chan_nr, link_id; struct msgb *sap_msg; struct osmo_phsap_prim *l1sap; @@ -938,12 +937,6 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i process_meas_res(trx, chan_nr, &data_ind->measParam); - if (data_ind->measParam.fLinkQuality < btsb->min_qual_norm - && data_ind->msgUnitParam.u8Size != 0) { - msgb_free(l1p_msg); - return 0; - } - DEBUGP(DL1P, "Rx PH-DATA.ind %s (hL2 %08x): %s", get_value_string(femtobts_l1sapi_names, data_ind->sapi), data_ind->hLayer2, @@ -969,7 +962,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i l1sap->u.data.chan_nr = chan_nr; l1sap->u.data.fn = fn; l1sap->u.data.rssi = (int8_t) (data_ind->measParam.fRssi); - if (!pcu_direct) { + if (!pcu_direct) { /* FIXME: if pcu_direct=1, then this is not set, what to do in pcu_tx_data_ind() in this case ?*/ l1sap->u.data.ber10k = data_ind->measParam.fBer * 10000; l1sap->u.data.ta_offs_qbits = data_ind->measParam.i16BurstTiming; l1sap->u.data.lqual_cb = data_ind->measParam.fLinkQuality * 10; diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 6333d195..b65628f0 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -514,9 +514,12 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) return -EAGAIN; if (data_ind->msgUnitParam.u8Size < 1) { - LOGP(DL1C, LOGL_ERROR, "chan_nr %d Rx Payload size 0\n", - chan_nr); - return -EINVAL; + LOGP(DL1P, LOGL_DEBUG, "chan_nr %d Rx Payload size 0\n", chan_nr); + /* Push empty payload to upper layers */ + rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP"); + return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn, + data_ind->measParam.fBer * 10000, + data_ind->measParam.fLinkQuality * 10); } payload_type = data_ind->msgUnitParam.u8Buffer[0]; @@ -605,11 +608,13 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) return 0; rmsg = l1_to_rtppayload_amr(sid_first, len, lchan); break; + /* FIXME: what about GsmL1_TchPlType_Amr_SidBad? not well documented. */ } if (rmsg) - return add_l1sap_header(trx, rmsg, lchan, chan_nr, - data_ind->u32Fn); + return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn, + data_ind->measParam.fBer * 10000, + data_ind->measParam.fLinkQuality * 10); return 0; -- cgit v1.2.3