diff options
author | Keith <keith@rhizomatica.org> | 2023-03-27 19:39:16 -0600 |
---|---|---|
committer | Keith <keith@rhizomatica.org> | 2023-03-27 19:39:16 -0600 |
commit | 9153cac1d08c144b4399157702be523dd9d9ae37 (patch) | |
tree | ea6cf7d410033aba722a38d15bb2e9a617386c72 | |
parent | 069ba5838e234d0c7e2ff968369eb8a5700d3bf0 (diff) |
bad hacks: Add all changes in working treekeith/dtx-hacking
Change-Id: I999f821ea362f4a3e15741d39a7a5194f6e93a69
-rw-r--r-- | src/common/l1sap.c | 79 | ||||
-rw-r--r-- | src/common/rsl.c | 2 | ||||
-rw-r--r-- | src/common/scheduler.c | 2 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/femtobts.h | 2 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/l1_if.c | 5 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/tch.c | 50 | ||||
-rw-r--r-- | src/osmo-bts-trx/sched_lchan_tchf.c | 2 |
7 files changed, 99 insertions, 43 deletions
diff --git a/src/common/l1sap.c b/src/common/l1sap.c index efde4064..28a045d0 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -137,17 +137,24 @@ static uint32_t fn_ms_adj(uint32_t fn, const struct gsm_lchan *lchan) /* 12/13 frames usable for audio in TCH, 160 samples per RTP packet, 1 RTP packet per 4 frames */ + + /*! Return the difference of two specified TDMA frame numbers (subtraction) */ + const uint32_t _num_fn = (fn - lchan->tch.last_fn) * 12 * 160 / (13 * 4); //GSM_TDMA_FN_SUB(fn, lchan->tch.last_fn); const uint32_t num_fn = GSM_TDMA_FN_SUB(fn, lchan->tch.last_fn); + samples_passed = num_fn * 12 * 160 / (13 * 4); + //LOGPLCHAN(lchan, DRTP, LOGL_NOTICE, "OLD [%d], NEW [%d]\n", _num_fn, samples_passed); /* round number of samples to the nearest multiple of - GSM_RTP_DURATION */ + GSM_RTP_DURATION = 160 */ r = samples_passed + GSM_RTP_DURATION / 2; r -= r % GSM_RTP_DURATION; - if (r != GSM_RTP_DURATION) + if (r != GSM_RTP_DURATION) { LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "RTP clock out of sync with lower layer:" - " %"PRIu32" vs %d (%"PRIu32"->%"PRIu32")\n", - r, GSM_RTP_DURATION, lchan->tch.last_fn, fn); + " %"PRIu32" vs %d (%"PRIu32"->%"PRIu32") DIFF[%d] SAMPLES[%d]\n ", + r, GSM_RTP_DURATION, lchan->tch.last_fn, fn, num_fn, samples_passed); + //return r; + } } return GSM_RTP_DURATION; } @@ -181,7 +188,8 @@ int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg, { struct osmo_phsap_prim *l1sap; - LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "Rx -> RTP: %s\n", osmo_hexdump(rmsg->data, rmsg->len)); + if (rmsg->len > 0) + LOGPLCHAN(lchan, DL1P, LOGL_INFO, "Rx -> RTP: %s\n", osmo_hexdump(rmsg->data, rmsg->len)); rmsg->l2h = rmsg->data; rmsg->l1h = msgb_push(rmsg, sizeof(*l1sap)); @@ -635,7 +643,7 @@ static int l1sap_info_time_ind(struct gsm_bts *bts, unsigned int frames_expired; unsigned int i; - DEBUGPFN(DL1P, info_time_ind->fn, "Rx MPH_INFO time ind\n"); + //DEBUGPFN(DL1P, info_time_ind->fn, "Rx MPH_INFO time ind\n"); /* Calculate and check frame difference */ frames_expired = GSM_TDMA_FN_SUB(info_time_ind->fn, bts->gsm_time.fn); @@ -1603,35 +1611,54 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, * 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) { - /* hand msg to RTP code for transmission */ - if (lchan->abis_ip.osmux.use) { - lchan_osmux_send_frame(lchan, msg->data, msg->len, - 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, - msg->data, msg->len, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker); - } - /* if loopback is enabled, also queue received RTP data */ - if (lchan->loopback) { - /* add new frame to queue, make sure the queue doesn't get too long */ - lchan_dl_tch_queue_enqueue(lchan, msg, 1); - /* Return 1 to signal that we're still using msg and it should not be freed */ - return 1; - } - /* 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", + //if (1 == 1) { + if (!msg->len || (tch_ind->lqual_cb / 10 < bts->min_qual_norm)) { + LOGPGT(DRTP, LOGL_NOTICE, &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; + lchan->tch.last_fn = fn; + //lchan->tch.dtx.is_speech_resume = false; + return 0; + } + + if (lchan->abis_ip.osmux.use) { + lchan_osmux_send_frame(lchan, msg->data, msg->len, + fn_ms_adj(fn, lchan), lchan->rtp_tx_marker); + } else if (lchan->abis_ip.rtp_socket) { + if (msg->len > 0 || lchan->rtp_tx_marker) + LOGPGT(DL1P, LOGL_INFO, &g_time, "Send RTP Frame [%d]--> %s\n", + msg->len, osmo_hexdump(msg->data, msg->len)); + /* + int osmo_rtp_send_frame_ext(struct osmo_rtp_socket *rs, const uint8_t *payload, + unsigned int payload_len, unsigned int duration, + bool marker); + + --> duration in number of RTP clock ticks. + The duration is the timestamp increase + + */ + osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket, + msg->data, msg->len, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker); + } + /* if loopback is enabled, also queue received RTP data */ + if (lchan->loopback) { + /* add new frame to queue, make sure the queue doesn't get too long */ + lchan_dl_tch_queue_enqueue(lchan, msg, 1); + /* Return 1 to signal that we're still using msg and it should not be freed */ + return 1; } + /* Only clear the marker bit once we have sent a RTP packet with it */ + //lchan->rtp_tx_marker = false; lchan->tch.last_fn = fn; + if (lchan->tch.dtx.is_speech_resume) + lchan->tch.dtx.is_speech_resume = false; + return 0; } diff --git a/src/common/rsl.c b/src/common/rsl.c index 8f1ff5d6..36b9f77b 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -1677,7 +1677,7 @@ static int parse_multirate_config(struct gsm_lchan *lchan, } parsed: - amr_log_mr_conf(DRTP, LOGL_DEBUG, gsm_lchan_name(lchan), &lchan->tch.amr_mr); + amr_log_mr_conf(DRTP, LOGL_INFO, gsm_lchan_name(lchan), &lchan->tch.amr_mr); lchan->tch.last_cmr = AMR_CMR_NONE; return 0; } diff --git a/src/common/scheduler.c b/src/common/scheduler.c index 25aefe84..9e5022c9 100644 --- a/src/common/scheduler.c +++ b/src/common/scheduler.c @@ -819,7 +819,7 @@ int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn, if (tch_len) memcpy(msg->l2h, tch, tch_len); - LOGL1S(DL1P, LOGL_DEBUG, l1ts, chan, l1sap->u.data.fn, "%s Rx -> RTP: %s\n", + LOGL1S(DL1P, LOGL_INFO, l1ts, chan, l1sap->u.data.fn, "%s Rx -> RTP: %s\n", gsm_lchan_name(lchan), osmo_hexdump(msgb_l2(msg), msgb_l2len(msg))); /* forward primitive */ l1sap_up(l1ts->ts->trx, l1sap); diff --git a/src/osmo-bts-sysmo/femtobts.h b/src/osmo-bts-sysmo/femtobts.h index b048fc4e..87e40e65 100644 --- a/src/osmo-bts-sysmo/femtobts.h +++ b/src/osmo-bts-sysmo/femtobts.h @@ -56,7 +56,7 @@ enum l1prim_type { }; #if !defined(SUPERFEMTO_API_VERSION) || SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,1,0) -enum uperfemto_clk_src { +enum Superfemto_clk_src { SF_CLKSRC_NONE = 0, SF_CLKSRC_OCXO = 1, SF_CLKSRC_TCXO = 2, diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 646cf016..8658b5f6 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -966,7 +966,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i gsm_fn2gsmtime(&g_time, fn); - DEBUGPGT(DL1P, &g_time, "Rx PH-DATA.ind %s (hL2 %08x): %s, " LOG_FMT_MEAS "\n", + LOGPGT(DL1P, LOGL_INFO, &g_time, "Rx PH-DATA.ind %s (hL2 %08x): %s, " LOG_FMT_MEAS "\n", get_value_string(femtobts_l1sapi_names, data_ind->sapi), data_ind->hLayer2, osmo_hexdump(data_ind->msgUnitParam.u8Buffer, data_ind->msgUnitParam.u8Size), LOG_PARAM_MEAS(&data_ind->measParam)); @@ -980,6 +980,9 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i return rc; } + if (data_ind->sapi == GsmL1_Sapi_FacchF) + LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "Rx SAPI FACCH\n"); + /* 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/tch.c b/src/osmo-bts-sysmo/tch.c index a390c8ca..f0c67ec5 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -56,6 +56,7 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len { struct msgb *msg; uint8_t *cur; + bool t; msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP"); if (!msg) @@ -76,8 +77,9 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len cur[0] |= 0xD0; #endif /* USE_L1_RTP_MODE */ - - lchan_set_marker(osmo_fr_check_sid(l1_payload, payload_len), lchan); + t = osmo_fr_check_sid(l1_payload, payload_len); + lchan_set_marker(t, lchan); + LOGP(DL1P, LOGL_ERROR, "FR SID:%d\n", t); return msg; } @@ -280,11 +282,12 @@ static struct msgb *l1_to_rtppayload_amr(uint8_t *l1_payload, uint8_t payload_le * Audiocode's MGW doesn't like receiving CMRs that are not * the same as the previous one. This means we need to patch * the content here. - */ + if ((cur[0] & 0xF0) == 0xF0) cur[0]= lchan->tch.last_cmr << 4; else lchan->tch.last_cmr = cur[0] >> 4; + */ #else u_int8_t cmr; uint8_t ft = l1_payload[2] & 0xF; @@ -508,12 +511,13 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) 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)]; + int len; if (is_recv_only(lchan->abis_ip.speech_mode)) return -EAGAIN; if (data_ind->msgUnitParam.u8Size < 1) { - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "chan_nr %d Rx Payload size 0\n", chan_nr); + LOGPFN(DL1P, LOGL_NOTICE, 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, @@ -528,6 +532,10 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) payload = data_ind->msgUnitParam.u8Buffer + 1; payload_len = data_ind->msgUnitParam.u8Size - 1; + /* clear RTP marker if the marker has previously sent */ + if (!lchan->tch.dtx.is_speech_resume) + lchan->rtp_tx_marker = false; + switch (payload_type) { case GsmL1_TchPlType_Fr: #if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE) @@ -544,40 +552,47 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) if (lchan->type != GSM_LCHAN_TCH_H && lchan->type != GSM_LCHAN_TCH_F) goto err_payload_match; + LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received Speech from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_Onset: if (lchan->type != GSM_LCHAN_TCH_H && lchan->type != GSM_LCHAN_TCH_F) goto err_payload_match; + LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received ONSET from L1 " + "(%d bytes)\n", payload_len); /* according to 3GPP TS 26.093 ONSET frames precede the first speech frame of a speech burst - set the marker for next RTP frame */ + lchan->tch.dtx.is_speech_resume = true; lchan->rtp_tx_marker = true; break; case GsmL1_TchPlType_Amr_SidFirstP1: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 " + LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 " "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidFirstP2: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 " + LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 " "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidFirstInH: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; + lchan->tch.dtx.is_speech_resume = true; lchan->rtp_tx_marker = true; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 " + LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 " "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidUpdateInH: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; + lchan->tch.dtx.is_speech_resume = true; lchan->rtp_tx_marker = true; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 " + LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 " "(%d bytes)\n", payload_len); break; default: @@ -587,7 +602,6 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) break; } - switch (payload_type) { case GsmL1_TchPlType_Fr: rmsg = l1_to_rtppayload_fr(payload, payload_len, lchan); @@ -603,12 +617,24 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) case GsmL1_TchPlType_Amr: rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); break; + case GsmL1_TchPlType_Amr_Onset: + /*memcpy(sid_first+2, payload, payload_len); + len = osmo_amr_rtp_enc(sid_first, 15, AMR_SID, AMR_GOOD); + LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "ONSET resulted in length [%d]\n", len); + if (len < 0) + return 0; + len = len+2; + rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);*/ + break; case GsmL1_TchPlType_Amr_SidFirstP1: - memcpy(sid_first, payload, payload_len); - int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); + rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); + lchan->rtp_tx_marker = false; + /*memcpy(sid_first, payload, payload_len); + len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); + LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "SID P1 resulted in length [%d]\n", len); if (len < 0) return 0; - rmsg = l1_to_rtppayload_amr(sid_first, len, lchan); + rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);*/ break; /* FIXME: what about GsmL1_TchPlType_Amr_SidBad? not well documented. */ } diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c index eff0f63a..b9d29be6 100644 --- a/src/osmo-bts-trx/sched_lchan_tchf.c +++ b/src/osmo-bts-trx/sched_lchan_tchf.c @@ -434,7 +434,7 @@ struct msgb *tch_dl_dequeue(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br if (chan_state->codec[i] == ft_codec) ft = i; } - if (ft < 0) { + if (ft_codec != 8 && ft < 0) { LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Codec (FT = %d) of RTP frame not in list\n", ft_codec); goto free_bad_msg; |