This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Max gerrit-no-reply at lists.osmocom.orgHello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/969 to look at the new patch set (#4). DTX: move ONSET detection into separate function Move code from tch.c (lc15, sysmo) into generic function which: - check if talkspurt is happening - cache SID if necessary or invalidate cache - fill in CMR & CMI prefix This also fixes the problem when SID FIRST was cached without sending just like SID UPDATE instead of being sent right away. Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 --- M include/osmo-bts/msg_utils.h M src/common/msg_utils.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/tch.c 4 files changed, 96 insertions(+), 70 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/4 diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f07623d..f99f3c4 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -29,6 +29,9 @@ void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload, size_t length, uint32_t fn, int update, uint8_t cmr, int8_t cmi); +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out); uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 4b944dc..adff134 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -29,7 +29,7 @@ #include <osmocom/trau/osmo_ortp.h> #include <arpa/inet.h> - +#include <errno.h> static int check_fom(struct abis_om_hdr *omh, size_t len) { @@ -99,7 +99,7 @@ } } -/* store the last SID frame in lchan context */ + /*! \brief Store the last SID frame in lchan context * \param[in] lchan Logical channel on which we check scheduling * \param[in] l1_payload buffer with SID data @@ -126,6 +126,59 @@ memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len); } +/*! \brief Check current and cached SID to decide if talkspurt takes place + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] rtp_pl buffer with RTP data + * \param[in] rtp_pl_len length of rtp_pl + * \param[in] fn Frame Number for which we check scheduling + * \param[in] l1_payload buffer where CMR and CMI prefix should be added + * \param[out] ft_out Frame Type to be populated after decoding + * \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added: + * caller must adjust length as necessary), + * 1 if ONSET event is detected + * negative if no sending is necessary (either error or cached SID + * UPDATE) + */ +int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload, + uint8_t *ft_out) +{ + uint8_t cmr; + enum osmo_amr_type ft; + enum osmo_amr_quality bfi; + int8_t sti, cmi; + osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti); + *ft_out = ft; + + if (ft == AMR_SID) { + save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi); + if (sti) /* SID_UPDATE should be cached and send later */ + return -EAGAIN; + else { /* SID_FIRST got to be send right away */ + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, + cmi, cmr); + return 0; + } + } + + if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { + LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft); + return -ENOTSUP; + } + + if (osmo_amr_is_speech(ft)) { + if (lchan->tch.last_sid.len) { /* force ONSET */ + lchan->tch.last_sid.len = 0; + return 1; + } + /* We received AMR SPEECH frame - invalidate saved SID */ + lchan->tch.last_sid.len = 0; + } + + amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); + return 0; +} + /*! \brief Check if enough time has passed since last SID (if any) to repeat it * \param[in] lchan Logical channel on which we check scheduling * \param[in] fn Frame Number for which we check scheduling diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index 46ad24c..08c64ab 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -199,12 +199,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { - memcpy(l1_payload+2, rtp_payload, payload_len); - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + memcpy(l1_payload, rtp_payload, payload_len); + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -226,11 +224,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -264,35 +259,25 @@ /* FIXME: detect and save EFR SID */ break; case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index 81cd791..3eb9bfd 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -282,10 +282,10 @@ */ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload, uint8_t payload_len, - struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi) + struct gsm_lchan *lchan, uint8_t ft) { #ifdef USE_L1_RTP_MODE - memcpy(l1_payload+2, rtp_payload, payload_len); + memcpy(l1_payload, rtp_payload, payload_len); #else uint8_t amr_if2_core_len = payload_len - 2; @@ -298,9 +298,7 @@ /* lower 4 bit of first FR2 byte contains FT */ l1_payload[2] |= ft; #endif /* USE_L1_RTP_MODE */ - amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr); - - return payload_len + 2; + return payload_len; } #define RTP_MSGB_ALLOC_SIZE 512 @@ -322,11 +320,8 @@ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker) { uint8_t *payload_type; - uint8_t *l1_payload, cmr; - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - int8_t sti, cmi; - int rc; + uint8_t *l1_payload, ft; + int rc = 0; bool is_sid = false; DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), @@ -362,35 +357,25 @@ break; #endif case GSM48_CMODE_SPEECH_AMR: - osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, - &sti); - if (ft == AMR_SID) { - save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, - cmi); - return false; - } - if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) { - LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", - ft); - return false; - } - if (osmo_amr_is_speech(ft)) { - if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */ - marker = true; - } - /* We received AMR SPEECH frame - invalidate saved SID */ - lchan->tch.last_sid.len = 0; - } - if (marker) { + rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn, + l1_payload, &ft); + + if (marker || rc) { *payload_type = GsmL1_TchPlType_Amr_Onset; - rc = 0; - LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n", + *len = 1; + if (rc != 0) { + LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without" + " Marker: ONSET forced\n", + get_value_string(osmo_amr_type_names, ft)); + return true; + } + LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n", get_value_string(osmo_amr_type_names, ft)); } else { *payload_type = GsmL1_TchPlType_Amr; - rc = rtppayload_to_l1_amr(l1_payload, rtp_pl, - rtp_pl_len, lchan, cmr, cmi); + rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, + rtp_pl_len, lchan, ft); } break; default: -- To view, visit https://gerrit.osmocom.org/969 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max <msuraev at sysmocom.de> Gerrit-Reviewer: Jenkins Builder