aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2022-05-16 19:40:45 +0300
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2022-05-16 20:13:13 +0300
commita2bee8bc88800b8998c4378dc944820af4e5dbc5 (patch)
tree9f58351abdfb32925550398904a55f15729cc06e
parent71e8091c9d369b5f91cd2593e84d9db8264d47b4 (diff)
coding: prevent marking FACCH frames as AMR's special DTX frames
Both gsm0503_tch_a[fh]s_decode_dtx() functions accept an optional 'dtx' pointer, which is used to indicate type of a received AMR block to the caller in DTX mode of operation. If not NULL, it's expected to be updated by gsm0503_detect_a[fh]s_dtx_frame() every time one of the mentioned functions is called. However, in case of FACCH both functions return early, so the value of dtx remains unchanged and thus FACCH frames may be misinterpreted as AMR's special DTX frames. This is rather critical during the DTX silence periods, when all special DTX frames (e.g. SID_UPDATE) are being treated as SUB frames. Each unsuccessful FACCH decoding attempt will 'poison' SUB measurements, causing unexpected RxQual- SUB values in the Uplink measurement reports. Fix this by resetting *dtx to AMR_OTHER in the FACCH specific path. Change-Id: I2e6f4b748c6445725211e264ab5f3f5a2712087a Related: SYS#5853
-rw-r--r--src/coding/gsm0503_coding.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/coding/gsm0503_coding.c b/src/coding/gsm0503_coding.c
index 98439e37..e81bf026 100644
--- a/src/coding/gsm0503_coding.c
+++ b/src/coding/gsm0503_coding.c
@@ -2171,6 +2171,12 @@ int gsm0503_tch_afs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts,
gsm0503_tch_fr_deinterleave(cB, iB);
if (steal > 0) {
+ /* If not NULL, dtx indicates type of previously decoded TCH/AFS frame.
+ * It's normally updated by gsm0503_detect_afs_dtx_frame(), which is not
+ * reached in case of FACCH. Reset it here to avoid FACCH/F frames being
+ * misinterpreted as AMR's special DTX frames. */
+ if (dtx != NULL)
+ *dtx = AMR_OTHER;
rv = _xcch_decode_cB(tch_data, cB, n_errors, n_bits_total);
if (rv) {
/* Error decoding FACCH frame */
@@ -2633,6 +2639,13 @@ int gsm0503_tch_ahs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts, int odd,
/* if we found a stole FACCH, but only at correct alignment */
if (steal > 0) {
+ /* If not NULL, dtx indicates type of previously decoded TCH/AHS frame.
+ * It's normally updated by gsm0503_detect_ahs_dtx_frame(), which is not
+ * reached in case of FACCH. Reset it here to avoid FACCH/H frames being
+ * misinterpreted as AMR's special DTX frames. */
+ if (dtx != NULL)
+ *dtx = AMR_OTHER;
+
for (i = 0; i < 6; i++) {
gsm0503_tch_burst_unmap(&iB[i * 114],
&bursts[i * 116], NULL, i >> 2);