# HG changeset patch # User Mychaela Falconia # Date 1676687223 28800 # Node ID f5c4f9a764be1168afe4d73ed53711bf463e9eff # Parent 623c64ae6102a8e9c63d50a26dbb99a86844f3a9 osmo-bts-rtp-bfi.patch: updated version This version of the osmo-bts patch sets the TAF bit correctly in generated RTP BFI packets, correctly generates RTP BFI in the case of FACCH stealing on sysmoBTS, and removes one EFR-specific bogon from sysmoBTS code. diff -r 623c64ae6102 -r f5c4f9a764be osmo-patches/osmo-bts-rtp-bfi.patch --- a/osmo-patches/osmo-bts-rtp-bfi.patch Tue Jan 10 18:05:55 2023 -0800 +++ b/osmo-patches/osmo-bts-rtp-bfi.patch Fri Feb 17 18:27:03 2023 -0800 @@ -1,5 +1,5 @@ diff --git a/src/common/l1sap.c b/src/common/l1sap.c -index 8bcd417..bfdc37f 100644 +index 8bcd417..42c97c4 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -1244,6 +1244,12 @@ static bool rtppayload_is_octet_aligned(const uint8_t *rtp_pl, uint8_t payload_l @@ -37,7 +37,7 @@ + /* Themyscira change: send explicit BFI packets instead of + * gaps in the RTP stream. */ + bfi[0] = 0xBF; -+ bfi[1] = 0; /* TAF will go here */ ++ bfi[1] = (fn % 104 == 52); /* TAF */ + if (lchan->abis_ip.osmux.use) { + lchan_osmux_send_frame(lchan, bfi, 2, + fn_ms_adj(fn, lchan), lchan->rtp_tx_marker); @@ -50,3 +50,91 @@ } lchan->tch.last_fn = fn; +diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c +index 5c99824..e35fc2e 100644 +--- a/src/osmo-bts-sysmo/l1_if.c ++++ b/src/osmo-bts-sysmo/l1_if.c +@@ -981,6 +981,10 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i + return rc; + } + ++ /* Themyscira addition: empty RTP "ticks" on FACCH */ ++ 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); +diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h +index 8691eef..5b2da04 100644 +--- a/src/osmo-bts-sysmo/l1_if.h ++++ b/src/osmo-bts-sysmo/l1_if.h +@@ -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); + +diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c +index a390c8c..f38d9fe 100644 +--- a/src/osmo-bts-sysmo/tch.c ++++ b/src/osmo-bts-sysmo/tch.c +@@ -131,12 +131,16 @@ static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, + + cur[0] |= 0xC0; + #endif /* USE_L1_RTP_MODE */ ++ ++/* this code is a bogon: osmo_amr_rtp_dec() won't grok EFR RTP format! */ ++#if 0 + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + uint8_t cmr; + int8_t sti, cmi; + osmo_amr_rtp_dec(l1_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); + lchan_set_marker(ft == AMR_GSM_EFR_SID, lchan); ++#endif + + return msg; + } +@@ -630,6 +634,38 @@ err_payload_match: + return -EINVAL; + } + ++/* ++ * The following function is a Themyscira Wireless addition: we want to have ++ * an RTP packet sent out on *every* 20 ms "tick", even during times when ++ * TCH was stolen for FACCH. During FACCH stealing times, it appears that ++ * sysmoBTS PHY sends GsmL1_Sapi_FacchF and no GsmL1_Sapi_TchF, and with ++ * the original code l1if_tch_rx(), the function that feeds "ticks" to the ++ * RTP output mechanism, was never called. Our added l1if_tch_rx_facch() ++ * function sends an empty payload to the upper layers, and we call it ++ * from the GsmL1_Sapi_FacchF code path. ++ */ ++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; ++ ++ LOGPFN(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;