sysmo: emit empty RTP ticks during FACCH stealing on TCH/F

When FACCH stealing occurs and sysmoBTS L1 delivers GsmL1_Sapi_FacchF
instead of GsmL1_Sapi_TchF, that 20 ms unit still needs to be
accounted for in the RTP timestamp cadence, and if we run with
rtp continuous-streaming enabled, then an actual BFI packet needs
to be emitted.  The original code failed to do either; the present
change implements correct behavior for TCH/F.

The present patch only covers the case of TCH/F; handling of TCH/H
is left as a FIXME for other/later developers.

Related: OS#5974
Change-Id: I39d15faade28fb7d670493a99a0e0bdb654e2a4a
This commit is contained in:
Mychaela N. Falconia 2023-03-28 20:29:58 +00:00 committed by laforge
parent 50710f4e8e
commit 61e7fdbb3f
3 changed files with 44 additions and 0 deletions

View File

@ -980,6 +980,25 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
return rc;
}
/* If we got FACCH, the RTP clock needs to account for it,
* and if we have rtp continuous-streaming enabled,
* an actual BFI packet will be emitted.
*
* Only the case of TCH/F is currently handled; the task of
* supporting TCH/H is left as a FIXME for other/later
* developers. The difficulty with supporting FACCH/H is that
* only one GsmL1_Sapi_FacchH message will be received,
* covering 40 ms of time, but two RTP "tick" output calls
* will need to be made, with appropriately adjusted frame
* numbers. As a further consideration for rtp continuous-streaming
* mode, having the two RTP BFI packets sent directly back to back,
* as opposed to proper 20 ms timing, may be so undesirable
* that some deployments may rather disable TCH/H (use only TCH/F)
* than deal with the extra pain, or use TCH/H only on SDR-based
* BTS with osmo-bts-trx where correct timing is easily achieved. */
if (data_ind->sapi == GsmL1_Sapi_FacchF)
l1if_tch_rx_facch(trx, chan_nr, l1p_msg);
/* fill L1SAP header */
sap_msg = l1sap_msgb_alloc(data_ind->msgUnitParam.u8Size);
l1sap = msgb_l1sap_prim(sap_msg);

View File

@ -129,6 +129,8 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn,
bool use_cache, bool marker);
int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg);
int l1if_tch_rx_facch(struct gsm_bts_trx *trx, uint8_t chan_nr,
struct msgb *l1p_msg);
int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer);
struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn);

View File

@ -623,6 +623,29 @@ err_payload_match:
return -EINVAL;
}
/*! \brief provide an RTP empty payload "tick" to upper layers upon FACCH */
int l1if_tch_rx_facch(struct gsm_bts_trx *trx, uint8_t chan_nr,
struct msgb *l1p_msg)
{
GsmL1_Prim_t *l1p = msgb_l1prim(l1p_msg);
GsmL1_PhDataInd_t *data_ind = &l1p->u.phDataInd;
struct msgb *rmsg = NULL;
struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];
if (is_recv_only(lchan->abis_ip.speech_mode))
return -EAGAIN;
LOGPLCFN(lchan, DL1P, LOGL_DEBUG, data_ind->u32Fn, "chan_nr %d Rx FACCH\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, /* suppress RSSI like in osmo-bts-trx */
data_ind->measParam.i16BurstTiming * 64,
0);
}
struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn)
{
struct msgb *msg;