diff options
-rw-r--r-- | src/common/l1sap.c | 6 | ||||
-rw-r--r-- | src/osmo-bts-litecell15/tch.c | 50 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/tch.c | 50 |
3 files changed, 92 insertions, 14 deletions
diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 77fd1a09..163e1293 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -866,8 +866,8 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, /* hand msg to RTP code for transmission */ if (lchan->abis_ip.rtp_socket) - osmo_rtp_send_frame(lchan->abis_ip.rtp_socket, - msg->data, msg->len, fn_ms_adj(fn, lchan->tch.last_fn)); + osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket, + msg->data, msg->len, fn_ms_adj(fn, lchan->tch.last_fn), lchan->rtp_tx_marker); /* if loopback is enabled, also queue received RTP data */ if (lchan->loopback) { @@ -885,6 +885,8 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, msgb_enqueue(&lchan->dl_tch_queue, msg); } + + lchan->rtp_tx_marker = false; lchan->tch.last_fn = fn; return 0; } diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index ab5b8154..db8542f6 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -162,7 +162,8 @@ uint8_t *get_payload_addr(struct msgb *msg) return &msu_param->u8Buffer[1]; } -static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len) +static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len, + struct gsm_lchan *lchan) { struct msgb *msg; uint8_t *cur; @@ -175,6 +176,13 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len cur = msgb_put(msg, GSM_FR_BYTES); memcpy(cur, l1_payload, GSM_FR_BYTES); + if (osmo_fr_check_sid(l1_payload, payload_len)) + lchan->tch.ul_sid = true; + else if (lchan->tch.ul_sid) { + lchan->tch.ul_sid = false; + lchan->rtp_tx_marker = true; + } + return msg; } @@ -197,7 +205,9 @@ static int rtppayload_to_l1_fr(uint8_t *l1_payload, uint8_t *rtp_payload, return GSM_FR_BYTES; } -static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, uint8_t payload_len) +static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, + uint8_t payload_len, + struct gsm_lchan *lchan) { struct msgb *msg; uint8_t *cur; @@ -209,6 +219,17 @@ static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, uint8_t payload_le /* new L1 can deliver bits like we need them */ cur = msgb_put(msg, GSM_EFR_BYTES); memcpy(cur, l1_payload, GSM_EFR_BYTES); + 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); + if (ft == AMR_GSM_EFR_SID) + lchan->tch.ul_sid = true; + else if (lchan->tch.ul_sid) { + lchan->tch.ul_sid = false; + lchan->rtp_tx_marker = true; + } return msg; } @@ -227,7 +248,8 @@ static int rtppayload_to_l1_efr(uint8_t *l1_payload, const uint8_t *rtp_payload, return payload_len; } -static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len) +static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len, + struct gsm_lchan *lchan) { struct msgb *msg; uint8_t *cur; @@ -245,6 +267,13 @@ static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len cur = msgb_put(msg, GSM_HR_BYTES); memcpy(cur, l1_payload, GSM_HR_BYTES); + if (osmo_hr_check_sid(l1_payload, payload_len)) + lchan->tch.ul_sid = true; + else if (lchan->tch.ul_sid) { + lchan->tch.ul_sid = false; + lchan->rtp_tx_marker = true; + } + return msg; } @@ -503,6 +532,15 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) lchan->type != GSM_LCHAN_TCH_F) goto err_payload_match; break; + case GsmL1_TchPlType_Amr_Onset: + if (lchan->type != GSM_LCHAN_TCH_H && + lchan->type != GSM_LCHAN_TCH_F) + goto err_payload_match; + /* according to 3GPP TS 26.093 ONSET frames precede the first + speech frame of a speech burst - set the marker for next RTP + frame and drop last SID */ + lchan->rtp_tx_marker = true; + break; default: LOGP(DL1C, LOGL_NOTICE, "%s Rx Payload Type %s is unsupported\n", gsm_lchan_name(lchan), @@ -513,13 +551,13 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) switch (payload_type) { case GsmL1_TchPlType_Fr: - rmsg = l1_to_rtppayload_fr(payload, payload_len); + rmsg = l1_to_rtppayload_fr(payload, payload_len, lchan); break; case GsmL1_TchPlType_Hr: - rmsg = l1_to_rtppayload_hr(payload, payload_len); + rmsg = l1_to_rtppayload_hr(payload, payload_len, lchan); break; case GsmL1_TchPlType_Efr: - rmsg = l1_to_rtppayload_efr(payload, payload_len); + rmsg = l1_to_rtppayload_efr(payload, payload_len, lchan); break; case GsmL1_TchPlType_Amr: rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index d8ba16f3..322e4574 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -151,7 +151,8 @@ uint8_t *get_payload_addr(struct msgb *msg) return &msu_param->u8Buffer[1]; } -static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len) +static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len, + struct gsm_lchan *lchan) { struct msgb *msg; uint8_t *cur; @@ -176,6 +177,13 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len cur[0] |= 0xD0; #endif /* USE_L1_RTP_MODE */ + if (osmo_fr_check_sid(l1_payload, payload_len)) + lchan->tch.ul_sid = true; + else if (lchan->tch.ul_sid) { + lchan->tch.ul_sid = false; + lchan->rtp_tx_marker = true; + } + return msg; } @@ -207,7 +215,9 @@ static int rtppayload_to_l1_fr(uint8_t *l1_payload, uint8_t *rtp_payload, } #if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE) -static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, uint8_t payload_len) +static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, + uint8_t payload_len, + struct gsm_lchan *lchan) { struct msgb *msg; uint8_t *cur; @@ -231,6 +241,17 @@ static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, uint8_t payload_le cur[0] |= 0xC0; #endif /* USE_L1_RTP_MODE */ + 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); + if (ft == AMR_GSM_EFR_SID) + lchan->tch.ul_sid = true; + else if (lchan->tch.ul_sid) { + lchan->tch.ul_sid = false; + lchan->rtp_tx_marker = true; + } return msg; } @@ -256,7 +277,8 @@ static int rtppayload_to_l1_efr(uint8_t *l1_payload, const uint8_t *rtp_payload, #warning No EFR support in L1 #endif /* L1_HAS_EFR */ -static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len) +static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len, + struct gsm_lchan *lchan) { struct msgb *msg; uint8_t *cur; @@ -279,6 +301,13 @@ static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len osmo_revbytebits_buf(cur, GSM_HR_BYTES); #endif /* USE_L1_RTP_MODE */ + if (osmo_hr_check_sid(l1_payload, payload_len)) + lchan->tch.ul_sid = true; + else if (lchan->tch.ul_sid) { + lchan->tch.ul_sid = false; + lchan->rtp_tx_marker = true; + } + return msg; } @@ -596,6 +625,15 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) lchan->type != GSM_LCHAN_TCH_F) goto err_payload_match; break; + case GsmL1_TchPlType_Amr_Onset: + if (lchan->type != GSM_LCHAN_TCH_H && + lchan->type != GSM_LCHAN_TCH_F) + goto err_payload_match; + /* according to 3GPP TS 26.093 ONSET frames precede the first + speech frame of a speech burst - set the marker for next RTP + frame and drop last SID */ + lchan->rtp_tx_marker = true; + break; default: LOGP(DL1C, LOGL_NOTICE, "%s Rx Payload Type %s is unsupported\n", gsm_lchan_name(lchan), @@ -606,14 +644,14 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) switch (payload_type) { case GsmL1_TchPlType_Fr: - rmsg = l1_to_rtppayload_fr(payload, payload_len); + rmsg = l1_to_rtppayload_fr(payload, payload_len, lchan); break; case GsmL1_TchPlType_Hr: - rmsg = l1_to_rtppayload_hr(payload, payload_len); + rmsg = l1_to_rtppayload_hr(payload, payload_len, lchan); break; #if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE) case GsmL1_TchPlType_Efr: - rmsg = l1_to_rtppayload_efr(payload, payload_len); + rmsg = l1_to_rtppayload_efr(payload, payload_len, lchan); break; #endif case GsmL1_TchPlType_Amr: |