falconia has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-bts/+/32097 )
Change subject: TCH-IND interface: move link quality check into model code
......................................................................
TCH-IND interface: move link quality check into model code
The l1sap_tch_ind() handler in the common code contains a check
to see if the link quality is >= bts->min_qual_norm; if this
condition is not met, RTP output is suppressed even if the BTS
model sent a non-empty payload. It appears that the purpose of
this check is to prevent emission of bogons during DTXu pauses
with FR1 codec: the only speech frame integrity check in GSM 05.03
coding for FR1 is a CRC-3, radio noise interpreted as frame bits
has 1/8 probability of passing that weak CRC, and if this link
quality check is removed, the resulting behavior (at least with
sysmoBTS) is that fairly frequent RTP bogons (garbage frames
pretending to be valid speech) are emitted during DTXu pauses,
and when the resulting stream is decoded per the specs,
extremely unpleasant noises are heard.
The present change does not alter behavior in any way, but
affects the code structure: the same unchanged check is moved
from the common l1sap_tch_ind() handler into model-specific code
in each BTS model that feeds TCH-IND primitives to the former.
This change allows individual BTS models more fine-grained
control as to what checks are appropriate for their PHY design,
and it paves the way for implementation of the OS#5975 feature
of emitting empty timing tick RTP packets instead of packet gaps
in the RTP stream.
Related: OS#5975
Change-Id: Id95e48a578b7a8ce576862655abbe553c5b9a7bf
---
M src/common/l1sap.c
M src/osmo-bts-lc15/tch.c
M src/osmo-bts-oc2g/tch.c
M src/osmo-bts-sysmo/tch.c
M src/osmo-bts-trx/sched_lchan_tchf.c
M src/osmo-bts-trx/sched_lchan_tchh.c
6 files changed, 67 insertions(+), 31 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/97/32097/1
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index efde406..2a1196c 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -1571,7 +1571,6 @@
static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap,
struct ph_tch_param *tch_ind)
{
- struct gsm_bts *bts = trx->bts;
struct msgb *msg = l1sap->oph.msg;
struct gsm_time g_time;
struct gsm_lchan *lchan;
@@ -1601,9 +1600,8 @@
/* Low level layers always call us when TCH content is expected, even if
* the content is not available due to decoding issues. Content not
- * available is expected as empty payload. We also check if quality is
- * good enough. */
- if (msg->len && tch_ind->lqual_cb >= bts->min_qual_norm) {
+ * available is expected as empty payload. */
+ if (msg->len) {
/* hand msg to RTP code for transmission */
if (lchan->abis_ip.osmux.use) {
lchan_osmux_send_frame(lchan, msg->data, msg->len,
diff --git a/src/osmo-bts-lc15/tch.c b/src/osmo-bts-lc15/tch.c
index 526b2dd..0aaea22 100644
--- a/src/osmo-bts-lc15/tch.c
+++ b/src/osmo-bts-lc15/tch.c
@@ -363,17 +363,18 @@
uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 };
struct msgb *rmsg = NULL;
struct gsm_lchan *lchan =
&trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];
+ uint16_t ber10k = data_ind->measParam.fBer * 10000;
+ int16_t lqual_cb = data_ind->measParam.fLinkQuality * 10;
if (is_recv_only(lchan->abis_ip.speech_mode))
return -EAGAIN;
- if (data_ind->msgUnitParam.u8Size < 1) {
+ if (data_ind->msgUnitParam.u8Size < 1 || lqual_cb <
trx->bts->min_qual_norm) {
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "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, 0, 0, 0);
+ ber10k, lqual_cb, 0, 0, 0);
}
payload_type = data_ind->msgUnitParam.u8Buffer[0];
@@ -462,8 +463,7 @@
if (rmsg)
return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn,
- data_ind->measParam.fBer * 10000,
- data_ind->measParam.fLinkQuality * 10, 0, 0, 0);
+ ber10k, lqual_cb, 0, 0, 0);
return 0;
diff --git a/src/osmo-bts-oc2g/tch.c b/src/osmo-bts-oc2g/tch.c
index 09ee1e7..0e504ad 100644
--- a/src/osmo-bts-oc2g/tch.c
+++ b/src/osmo-bts-oc2g/tch.c
@@ -363,17 +363,18 @@
uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 };
struct msgb *rmsg = NULL;
struct gsm_lchan *lchan =
&trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];
+ uint16_t ber10k = data_ind->measParam.fBer * 10000;
+ int16_t lqual_cb = data_ind->measParam.fLinkQuality * 10;
if (is_recv_only(lchan->abis_ip.speech_mode))
return -EAGAIN;
- if (data_ind->msgUnitParam.u8Size < 1) {
+ if (data_ind->msgUnitParam.u8Size < 1 || lqual_cb <
trx->bts->min_qual_norm) {
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "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, 0, 0, 0);
+ ber10k, lqual_cb, 0, 0, 0);
}
payload_type = data_ind->msgUnitParam.u8Buffer[0];
@@ -474,8 +475,7 @@
if (rmsg)
return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn,
- data_ind->measParam.fBer * 10000,
- data_ind->measParam.fLinkQuality * 10, 0, 0, 0);
+ ber10k, lqual_cb, 0, 0, 0);
return 0;
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
index 8c9557c..6a5d2c3 100644
--- a/src/osmo-bts-sysmo/tch.c
+++ b/src/osmo-bts-sysmo/tch.c
@@ -507,20 +507,20 @@
uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 };
struct msgb *rmsg = NULL;
struct gsm_lchan *lchan =
&trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];
+ uint16_t ber10k = data_ind->measParam.fBer * 10000;
+ int16_t lqual_cb = data_ind->measParam.fLinkQuality * 10;
+ int8_t rssi = data_ind->measParam.fRssi;
+ int16_t ta_offs = data_ind->measParam.i16BurstTiming * 64;
if (is_recv_only(lchan->abis_ip.speech_mode))
return -EAGAIN;
- if (data_ind->msgUnitParam.u8Size < 1) {
+ if (data_ind->msgUnitParam.u8Size < 1 || lqual_cb <
trx->bts->min_qual_norm) {
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "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,
- data_ind->measParam.fRssi,
- data_ind->measParam.i16BurstTiming * 64,
- 0);
+ ber10k, lqual_cb, rssi, ta_offs, 0);
}
payload_type = data_ind->msgUnitParam.u8Buffer[0];
@@ -614,11 +614,7 @@
if (rmsg)
return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn,
- data_ind->measParam.fBer * 10000,
- data_ind->measParam.fLinkQuality * 10,
- data_ind->measParam.fRssi,
- data_ind->measParam.i16BurstTiming * 64,
- 0);
+ ber10k, lqual_cb, rssi, ta_offs, 0);
return 0;
diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c
index 256125b..a7e45aa 100644
--- a/src/osmo-bts-trx/sched_lchan_tchf.c
+++ b/src/osmo-bts-trx/sched_lchan_tchf.c
@@ -75,6 +75,7 @@
{
struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan];
struct gsm_lchan *lchan = chan_state->lchan;
+ struct gsm_bts *bts = lchan->ts->trx->bts;
sbit_t *burst, **bursts_p = &chan_state->ul_bursts;
uint8_t *mask = &chan_state->ul_mask;
uint8_t rsl_cmode = chan_state->rsl_cmode;
@@ -281,9 +282,12 @@
bfi:
if (rsl_cmode == RSL_CMOD_SPD_SPEECH) {
- /* indicate bad frame */
- if (lchan->tch.dtx.ul_sid) {
- /* DTXu: pause in progress. Push empty payload to upper layers */
+ /* Indicate bad frame. We push an empty payload to
+ * upper layers under two conditions:
+ *
+ * 1) If there is a DTXu pause in progress, or
+ * 2) If the link quality is too low. */
+ if (lchan->tch.dtx.ul_sid || meas_avg.ci_cb < bts->min_qual_norm) {
rc = 0;
goto compose_l1sap;
}
diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c
index 37fd59d..2b6f4c3 100644
--- a/src/osmo-bts-trx/sched_lchan_tchh.c
+++ b/src/osmo-bts-trx/sched_lchan_tchh.c
@@ -97,6 +97,7 @@
{
struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan];
struct gsm_lchan *lchan = chan_state->lchan;
+ struct gsm_bts *bts = lchan->ts->trx->bts;
sbit_t *burst, **bursts_p = &chan_state->ul_bursts;
uint8_t *mask = &chan_state->ul_mask;
uint8_t rsl_cmode = chan_state->rsl_cmode;
@@ -319,9 +320,12 @@
/* A FACCH/H frame replaces two speech frames, so we need to send two BFIs.
* One is sent here, another will be sent two bursts later (see above). */
if (rsl_cmode == RSL_CMOD_SPD_SPEECH) {
- /* indicate bad frame */
- if (lchan->tch.dtx.ul_sid) {
- /* DTXu: pause in progress. Push empty payload to upper layers */
+ /* Indicate bad frame. We push an empty payload to
+ * upper layers under two conditions:
+ *
+ * 1) If there is a DTXu pause in progress, or
+ * 2) If the link quality is too low. */
+ if (lchan->tch.dtx.ul_sid || meas_avg.ci_cb < bts->min_qual_norm) {
rc = 0;
goto compose_l1sap;
}
--
To view, visit
https://gerrit.osmocom.org/c/osmo-bts/+/32097
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: Id95e48a578b7a8ce576862655abbe553c5b9a7bf
Gerrit-Change-Number: 32097
Gerrit-PatchSet: 1
Gerrit-Owner: falconia <falcon(a)freecalypso.org>
Gerrit-MessageType: newchange