aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2016-10-19 19:41:07 +0200
committerMax <msuraev@sysmocom.de>2016-10-24 08:55:19 +0000
commitced9a5d0e2c7e3371760f1c07df7b41cfe7ab71d (patch)
treec1edcf4bc0d6674b879069e29ee8cf8b34c6b26b
parent5a4f4d12e14c23073644a3717f62949bc822db1f (diff)
Fix DTX DL AMR SIDscheduling logic
Previously SID UPDATE was sometimes scheduled incorrectly. Fix this by: * avoid rounding error when computing scheduling time difference from FN * properly saving and updating cached SID type and FN Change-Id: I7acffae4792e7bddc2ae19a2f04ee921dc194c36 Related: OS#1801
-rw-r--r--src/common/msg_utils.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c
index 393ae90..9c6f20f 100644
--- a/src/common/msg_utils.c
+++ b/src/common/msg_utils.c
@@ -116,8 +116,11 @@ void dtx_cache_payload(struct gsm_lchan *lchan, const uint8_t *l1_payload,
ARRAY_SIZE(lchan->tch.dtx.cache) - amr);
lchan->tch.dtx.len = copy_len + amr;
- lchan->tch.dtx.fn = fn;
- lchan->tch.dtx.is_update = update;
+ /* SID FIRST is special because it's both sent and cached: */
+ if (update == 0) {
+ lchan->tch.dtx.fn = fn;
+ lchan->tch.dtx.is_update = false; /* Mark SID FIRST explicitly */
+ }
memcpy(lchan->tch.dtx.cache + amr, l1_payload, copy_len);
}
@@ -128,6 +131,7 @@ void dtx_cache_payload(struct gsm_lchan *lchan, const uint8_t *l1_payload,
* \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[in] marker RTP Marker bit
* \param[out] len Length of expected L1 payload
* \param[out] ft_out Frame Type to be populated after decoding
* \returns 0 in case of success; negative on error
@@ -219,18 +223,18 @@ int dtx_dl_amr_fsm_step(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
static inline bool dtx_amr_sid_optional(const struct gsm_lchan *lchan,
uint32_t fn)
{
- /* Compute approx. time delta based on Fn duration */
- uint32_t delta = GSM_FN_TO_MS(fn - lchan->tch.dtx.fn);
+ /* Compute approx. time delta x26 based on Fn duration */
+ uint32_t dx26 = 120 * (fn - lchan->tch.dtx.fn);
- /* according to 3GPP TS 26.093 A.5.1.1: */
- if (lchan->tch.dtx.is_update) {
- /* SID UPDATE should be repeated every 8th RTP frame */
- if (delta < GSM_RTP_FRAME_DURATION_MS * 8)
+ /* according to 3GPP TS 26.093 A.5.1.1:
+ (*26) to avoid float math, add 1 FN tolerance (-120) */
+ if (lchan->tch.dtx.is_update) { /* SID UPDATE: every 8th RTP frame */
+ if (dx26 < GSM_RTP_FRAME_DURATION_MS * 8 * 26 - 120)
return true;
return false;
}
/* 3rd frame after SID FIRST should be SID UPDATE */
- if (delta < GSM_RTP_FRAME_DURATION_MS * 3)
+ if (dx26 < GSM_RTP_FRAME_DURATION_MS * 3 * 26 - 120)
return true;
return false;
}
@@ -289,6 +293,7 @@ uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn)
if (lchan->tch.dtx.len) {
memcpy(dst, lchan->tch.dtx.cache, lchan->tch.dtx.len);
lchan->tch.dtx.fn = fn;
+ lchan->tch.dtx.is_update = true; /* SID UPDATE sent */
return lchan->tch.dtx.len + 1;
}