Change in osmo-bts[master]: sched_lchan_tch_x: use functions to determine AMR tranmssion phase

dexter gerrit-no-reply at lists.osmocom.org
Tue Aug 31 15:00:05 UTC 2021


dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/25296 )


Change subject: sched_lchan_tch_x: use functions to determine AMR tranmssion phase
......................................................................

sched_lchan_tch_x: use functions to determine AMR tranmssion phase

The AMR transmission phase directly depends on the frame number. The
transmission phase is used to tell if a received AMR frame contains a
CMI (frame type that is currently used) or CMR (frame type that the
receiver should use). codec idfentifer. The formulas in the present
implementation seem to be correct but they do not reflect the numbers in
the spec very well, nor do they have unit-tests. Lets replace them with
more readble functions and test those functions with unit-tests.

Change-Id: I94a934a6b3b397b4cd0e9da3577325de58814335
Related: SYS#5549
---
M configure.ac
M src/osmo-bts-trx/sched_lchan_tchf.c
M src/osmo-bts-trx/sched_lchan_tchh.c
M src/osmo-bts-trx/sched_utils.h
M tests/Makefile.am
M tests/testsuite.at
6 files changed, 104 insertions(+), 11 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/96/25296/1

diff --git a/configure.ac b/configure.ac
index 1b4c6e7..4f2e889 100644
--- a/configure.ac
+++ b/configure.ac
@@ -411,6 +411,7 @@
     tests/tx_power/Makefile
     tests/power/Makefile
     tests/meas/Makefile
+    tests/amr/Makefile
     doc/Makefile
     doc/examples/Makefile
     doc/manuals/Makefile
diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c
index 00efcf8..c5d60e4 100644
--- a/src/osmo-bts-trx/sched_lchan_tchf.c
+++ b/src/osmo-bts-trx/sched_lchan_tchf.c
@@ -65,6 +65,7 @@
 	uint16_t ber10k;
 	uint8_t is_sub = 0;
 	uint8_t ft;
+	bool amr_is_cmr;
 
 	/* If handover RACH detection is turned on, treat this burst as an Access Burst.
 	 * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */
@@ -129,6 +130,8 @@
 		 * the first FN 4,13,21 defines that CMR is included in frame.
 		 * NOTE: A frame ends 7 FN after start.
 		 */
+		fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_F);
+		amr_is_cmr = !ul_amr_fn_is_cmi(fn_begin);
 
 		/* The AFS_ONSET frame itself does not result into an RTP frame
 		 * since it only contains a recognition pattern that marks the
@@ -144,8 +147,7 @@
 		 * know this before we actually decode the frame) */
 		amr = 2;
 		rc = gsm0503_tch_afs_decode_dtx(tch_data + amr, *bursts_p,
-			(((bi->fn + 26 - 7) % 26) >> 2) & 1, chan_state->codec,
-			chan_state->codecs, &chan_state->ul_ft,
+			amr_is_cmr, chan_state->codec, chan_state->codecs, &chan_state->ul_ft,
 			&chan_state->ul_cmr, &n_errors, &n_bits_total, &chan_state->amr_last_dtx);
 
 		/* Tag all frames that are not regular AMR voice frames as
@@ -419,6 +421,7 @@
 		enum osmo_amr_type ft_codec;
 		enum osmo_amr_quality bfi;
 		int8_t sti, cmi;
+		bool amr_is_cmr = !dl_amr_fn_is_cmi(br->fn);
 
 		if (rsl_cmode != RSL_CMOD_SPD_SPEECH) {
 			LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Dropping speech frame, "
@@ -463,7 +466,7 @@
 					"Codec (FT = %d) of RTP frame not in list\n", ft_codec);
 				goto free_bad_msg;
 			}
-			if (fn_is_codec_mode_request(br->fn) && chan_state->dl_ft != ft) {
+			if (amr_is_cmr && chan_state->dl_ft != ft) {
 				LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Codec (FT = %d) "
 					" of RTP cannot be changed now, but in next frame\n", ft_codec);
 				goto free_bad_msg;
@@ -552,7 +555,7 @@
 		 * the first FN 0,8,17 defines that CMR is included in frame.
 		 */
 		gsm0503_tch_afs_encode(*bursts_p, msg_tch->l2h + 2,
-			msgb_l2len(msg_tch) - 2, fn_is_codec_mode_request(br->fn),
+			msgb_l2len(msg_tch) - 2, !dl_amr_fn_is_cmi(br->fn),
 			chan_state->codec, chan_state->codecs,
 			chan_state->dl_ft,
 			chan_state->dl_cmr);
diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c
index 9402204..2106a67 100644
--- a/src/osmo-bts-trx/sched_lchan_tchh.c
+++ b/src/osmo-bts-trx/sched_lchan_tchh.c
@@ -72,6 +72,7 @@
 	uint8_t is_sub = 0;
 	uint8_t ft;
 	bool mask_stolen_tch_block = false;
+	bool fn_is_cmi;
 
 	/* If handover RACH detection is turned on, treat this burst as an Access Burst.
 	 * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */
@@ -164,10 +165,21 @@
 			break;
 		}
 
+		/* Calculate the frame number where the block begins */
+		if (bi->fn % 13 < 4)
+			fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 5);
+		else
+			fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 4);
+		if (lchan->nr == 0)
+			fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H0);
+		else
+			fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H1);
+		fn_is_cmi = ul_amr_fn_is_cmi(fn_begin);
+
 		/* See comment in function rx_tchf_fn() */
 		amr = 2;
 		rc = gsm0503_tch_ahs_decode_dtx(tch_data + amr, *bursts_p,
-			fn_is_odd, fn_is_odd, chan_state->codec,
+			fn_is_odd, !fn_is_cmi, chan_state->codec,
 			chan_state->codecs, &chan_state->ul_ft,
 			&chan_state->ul_cmr, &n_errors, &n_bits_total, &chan_state->amr_last_dtx);
 
@@ -343,7 +355,6 @@
 		fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 5);
 	else
 		fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 4);
-	
 	if (lchan->nr == 0)
 		fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H0);
 	else
@@ -441,7 +452,7 @@
 		 * in frame, the first FN 0,8,17 or 1,9,18 defines that CMR is
 		 * included in frame. */
 		gsm0503_tch_ahs_encode(*bursts_p, msg_tch->l2h + 2,
-			msgb_l2len(msg_tch) - 2, fn_is_codec_mode_request(br->fn),
+			msgb_l2len(msg_tch) - 2, !dl_amr_fn_is_cmi(br->fn),
 			chan_state->codec, chan_state->codecs,
 			chan_state->dl_ft,
 			chan_state->dl_cmr);
diff --git a/src/osmo-bts-trx/sched_utils.h b/src/osmo-bts-trx/sched_utils.h
index 4a1aaf5..ada6146 100644
--- a/src/osmo-bts-trx/sched_utils.h
+++ b/src/osmo-bts-trx/sched_utils.h
@@ -23,6 +23,8 @@
 
 #include <stdint.h>
 #include <errno.h>
+#include <stdbool.h>
+#include <osmo-bts/scheduler.h>
 
 extern void *tall_bts_ctx;
 
@@ -35,8 +37,78 @@
 		return 10000 * n_errors / n_bits_total;
 }
 
-/* determine if the FN is transmitting a CMR (1) or not (0) */
-static inline int fn_is_codec_mode_request(uint32_t fn)
+/*! determine the whether an uplink AMR block is CMI according to 3GPP TS 45.009.
+ *  \param[in] fn_begin frame number of the beginning of the block.
+ *  \returns true in case of CMI; false otherwise. */
+static inline bool ul_amr_fn_is_cmi(uint32_t fn_begin)
 {
-	return (((fn + 4) % 26) >> 2) & 1;
+	uint32_t fn_26 = fn_begin % 26;
+	switch (fn_26) {
+		/*! See also: 3GPP TS 45.009, section 3.2.1.3 Transmitter/Receiver Synchronisation */
+		/* valid for AHS subslot 0 and AFS: */
+	case 0:
+	case 8:
+	case 17:
+		/* valid for AHS subslot 1: */
+	case 1:
+	case 9:
+	case 18:
+		return true;
+		break;
+		/* Complementary values for sanity check */
+		/* valid for AHS subslot 0 and AFS: */
+	case 4:
+	case 13:
+	case 21:
+		/* valid for AHS subslot 1: */
+	case 5:
+	case 14:
+	case 22:
+		return false;
+		break;
+	default:
+		LOGP(DL1P, LOGL_DEBUG,
+		     "uplink frame number fn_begin=%u does not mark the beginning of a voice block!\n", fn_begin);
+		OSMO_ASSERT(false);
+		return false;
+		break;
+	}
+}
+
+/*! determine the whether a downlink AMR block is CMI according to 3GPP TS 45.009.
+ *  \param[in] fn_begin frame number of the beginning of the block.
+ *  \returns true in case of CMI; false otherwise. */
+static inline bool dl_amr_fn_is_cmi(uint32_t fn_begin)
+{
+	uint32_t fn_26 = fn_begin % 26;
+	switch (fn_26) {
+		/*! See also: 3GPP TS 45.009, section 3.2.1.3 Transmitter/Receiver Synchronisation */
+		/* valid for AHS subslot 0 and AFS: */
+	case 4:
+	case 13:
+	case 21:
+		/* valid for AHS subslot 1: */
+	case 5:
+	case 14:
+	case 22:
+		return true;
+		break;
+		/* Complementary values for sanity check */
+		/* valid for AHS subslot 0 and AFS: */
+	case 0:
+	case 8:
+	case 17:
+		/* valid for AHS subslot 1: */
+	case 1:
+	case 9:
+	case 18:
+		return false;
+		break;
+	default:
+		LOGP(DL1P, LOGL_DEBUG,
+		     "downlink frame number fn_begin=%u does not mark the beginning of a voice block!\n", fn_begin);
+		OSMO_ASSERT(false);
+		return false;
+		break;
+	}
 }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8d19e6e..a1d04a7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = paging cipher agch misc handover tx_power power meas ta_control
+SUBDIRS = paging cipher agch misc handover tx_power power meas ta_control amr
 
 if ENABLE_SYSMOBTS
 SUBDIRS += sysmobts
diff --git a/tests/testsuite.at b/tests/testsuite.at
index ba5a409..f2d17fb 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -63,3 +63,9 @@
 cat $abs_srcdir/ta_control/ta_control_test.ok > expout
 AT_CHECK([$abs_top_builddir/tests/ta_control/ta_control_test], [], [expout], [ignore])
 AT_CLEANUP
+
+AT_SETUP([amr])
+AT_KEYWORDS([amr])
+cat $abs_srcdir/amr/amr_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/amr/amr_test], [], [expout], [ignore])
+AT_CLEANUP

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/25296
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I94a934a6b3b397b4cd0e9da3577325de58814335
Gerrit-Change-Number: 25296
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210831/d0705208/attachment-0001.htm>


More information about the gerrit-log mailing list