diff osmo-patches/osmo-bts-rtp-bfi.patch @ 176:f5c4f9a764be

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.
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 17 Feb 2023 18:27:03 -0800
parents 60e2d6379fce
children c76f42e0cd3f
line wrap: on
line diff
--- 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;