aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith <keith@rhizomatica.org>2023-03-27 19:39:16 -0600
committerKeith <keith@rhizomatica.org>2023-03-27 19:39:16 -0600
commit9153cac1d08c144b4399157702be523dd9d9ae37 (patch)
treeea6cf7d410033aba722a38d15bb2e9a617386c72
parent069ba5838e234d0c7e2ff968369eb8a5700d3bf0 (diff)
bad hacks: Add all changes in working treekeith/dtx-hacking
-rw-r--r--src/common/l1sap.c79
-rw-r--r--src/common/rsl.c2
-rw-r--r--src/common/scheduler.c2
-rw-r--r--src/osmo-bts-sysmo/femtobts.h2
-rw-r--r--src/osmo-bts-sysmo/l1_if.c5
-rw-r--r--src/osmo-bts-sysmo/tch.c50
-rw-r--r--src/osmo-bts-trx/sched_lchan_tchf.c2
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;