FreeCalypso > hg > themwi-system-sw
view osmo-patches/osmo-bts-rtp-bfi.patch @ 184:f8c40090a0a8
librtpalloc: new library for talking to themwi-rtp-mgr
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 11 Mar 2023 23:48:14 -0800 |
parents | f5c4f9a764be |
children | c76f42e0cd3f |
line wrap: on
line source
diff --git a/src/common/l1sap.c b/src/common/l1sap.c 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 static bool rtppayload_is_valid(struct gsm_lchan *lchan, struct msgb *resp_msg) { + /* Discard Themyscira BFI packets - because we have our own + * TDMA timing, there is no difference for us between receiving + * an explicit BFI packet vs receiving nothing at all. */ + if (resp_msg->len == 2 && resp_msg->data[0] == 0xBF) + return false; + /* Avoid sending bw-efficient AMR to lower layers, most bts models * don't support it. */ if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR && @@ -1574,6 +1580,7 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct gsm_lchan *lchan; uint8_t chan_nr; uint32_t fn; + uint8_t bfi[2]; chan_nr = tch_ind->chan_nr; fn = tch_ind->fn; @@ -1619,13 +1626,19 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, /* Only clear the marker bit once we have sent a RTP packet with it */ lchan->rtp_tx_marker = false; } else { - DEBUGPGT(DRTP, &g_time, "Skipping RTP frame with lost payload (chan_nr=0x%02x)\n", - chan_nr); - if (lchan->abis_ip.osmux.use) - lchan_osmux_skipped_frame(lchan, fn_ms_adj(fn, lchan)); - else if (lchan->abis_ip.rtp_socket) - osmo_rtp_skipped_frame(lchan->abis_ip.rtp_socket, fn_ms_adj(fn, lchan)); - lchan->rtp_tx_marker = true; + /* Themyscira change: send explicit BFI packets instead of + * gaps in the RTP stream. */ + bfi[0] = 0xBF; + 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); + } else if (lchan->abis_ip.rtp_socket) { + osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket, + bfi, 2, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker); + } + /* clear the marker like in the regular code path */ + lchan->rtp_tx_marker = false; } 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;