<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/25296">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">sched_lchan_tch_x: use functions to determine AMR tranmssion phase<br><br>The AMR transmission phase directly depends on the frame number. The<br>transmission phase is used to tell if a received AMR frame contains a<br>CMI (frame type that is currently used) or CMR (frame type that the<br>receiver should use) codec identifier. The formulas in the present<br>implementation seem to be correct but they do not reflect the numbers in<br>the spec very well, nor do they have unit-tests. Lets replace them with<br>more readble functions and test those functions with unit-tests.<br><br>Change-Id: I94a934a6b3b397b4cd0e9da3577325de58814335<br>Related: SYS#5549<br>---<br>M configure.ac<br>M src/osmo-bts-trx/sched_lchan_tchf.c<br>M src/osmo-bts-trx/sched_lchan_tchh.c<br>M src/osmo-bts-trx/sched_utils.h<br>M tests/Makefile.am<br>A tests/amr/Makefile.am<br>A tests/amr/amr_test.c<br>A tests/amr/amr_test.ok<br>M tests/testsuite.at<br>9 files changed, 416 insertions(+), 11 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configure.ac b/configure.ac</span><br><span>index 1b4c6e7..4f2e889 100644</span><br><span>--- a/configure.ac</span><br><span>+++ b/configure.ac</span><br><span>@@ -411,6 +411,7 @@</span><br><span>     tests/tx_power/Makefile</span><br><span>     tests/power/Makefile</span><br><span>     tests/meas/Makefile</span><br><span style="color: hsl(120, 100%, 40%);">+    tests/amr/Makefile</span><br><span>     doc/Makefile</span><br><span>     doc/examples/Makefile</span><br><span>     doc/manuals/Makefile</span><br><span>diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c</span><br><span>index 00efcf8..c5d60e4 100644</span><br><span>--- a/src/osmo-bts-trx/sched_lchan_tchf.c</span><br><span>+++ b/src/osmo-bts-trx/sched_lchan_tchf.c</span><br><span>@@ -65,6 +65,7 @@</span><br><span>        uint16_t ber10k;</span><br><span>     uint8_t is_sub = 0;</span><br><span>  uint8_t ft;</span><br><span style="color: hsl(120, 100%, 40%);">+   bool amr_is_cmr;</span><br><span> </span><br><span>         /* If handover RACH detection is turned on, treat this burst as an Access Burst.</span><br><span>      * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */</span><br><span>@@ -129,6 +130,8 @@</span><br><span>                 * the first FN 4,13,21 defines that CMR is included in frame.</span><br><span>                * NOTE: A frame ends 7 FN after start.</span><br><span>               */</span><br><span style="color: hsl(120, 100%, 40%);">+           fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_F);</span><br><span style="color: hsl(120, 100%, 40%);">+               amr_is_cmr = !ul_amr_fn_is_cmi(fn_begin);</span><br><span> </span><br><span>                /* The AFS_ONSET frame itself does not result into an RTP frame</span><br><span>               * since it only contains a recognition pattern that marks the</span><br><span>@@ -144,8 +147,7 @@</span><br><span>                  * know this before we actually decode the frame) */</span><br><span>                 amr = 2;</span><br><span>             rc = gsm0503_tch_afs_decode_dtx(tch_data + amr, *bursts_p,</span><br><span style="color: hsl(0, 100%, 40%);">-                      (((bi->fn + 26 - 7) % 26) >> 2) & 1, chan_state->codec,</span><br><span style="color: hsl(0, 100%, 40%);">-                 chan_state->codecs, &chan_state->ul_ft,</span><br><span style="color: hsl(120, 100%, 40%);">+                     amr_is_cmr, chan_state->codec, chan_state->codecs, &chan_state->ul_ft,</span><br><span>                  &chan_state->ul_cmr, &n_errors, &n_bits_total, &chan_state->amr_last_dtx);</span><br><span> </span><br><span>                 /* Tag all frames that are not regular AMR voice frames as</span><br><span>@@ -419,6 +421,7 @@</span><br><span>             enum osmo_amr_type ft_codec;</span><br><span>                 enum osmo_amr_quality bfi;</span><br><span>           int8_t sti, cmi;</span><br><span style="color: hsl(120, 100%, 40%);">+              bool amr_is_cmr = !dl_amr_fn_is_cmi(br->fn);</span><br><span> </span><br><span>          if (rsl_cmode != RSL_CMOD_SPD_SPEECH) {</span><br><span>                      LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Dropping speech frame, "</span><br><span>@@ -463,7 +466,7 @@</span><br><span>                                       "Codec (FT = %d) of RTP frame not in list\n", ft_codec);</span><br><span>                           goto free_bad_msg;</span><br><span>                   }</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (fn_is_codec_mode_request(br->fn) && chan_state->dl_ft != ft) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (amr_is_cmr && chan_state->dl_ft != ft) {</span><br><span>                              LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Codec (FT = %d) "</span><br><span>                                    " of RTP cannot be changed now, but in next frame\n", ft_codec);</span><br><span>                           goto free_bad_msg;</span><br><span>@@ -552,7 +555,7 @@</span><br><span>              * the first FN 0,8,17 defines that CMR is included in frame.</span><br><span>                 */</span><br><span>          gsm0503_tch_afs_encode(*bursts_p, msg_tch->l2h + 2,</span><br><span style="color: hsl(0, 100%, 40%);">-                  msgb_l2len(msg_tch) - 2, fn_is_codec_mode_request(br->fn),</span><br><span style="color: hsl(120, 100%, 40%);">+                 msgb_l2len(msg_tch) - 2, !dl_amr_fn_is_cmi(br->fn),</span><br><span>                       chan_state->codec, chan_state->codecs,</span><br><span>                         chan_state->dl_ft,</span><br><span>                        chan_state->dl_cmr);</span><br><span>diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c</span><br><span>index 9402204..2106a67 100644</span><br><span>--- a/src/osmo-bts-trx/sched_lchan_tchh.c</span><br><span>+++ b/src/osmo-bts-trx/sched_lchan_tchh.c</span><br><span>@@ -72,6 +72,7 @@</span><br><span>         uint8_t is_sub = 0;</span><br><span>  uint8_t ft;</span><br><span>  bool mask_stolen_tch_block = false;</span><br><span style="color: hsl(120, 100%, 40%);">+   bool fn_is_cmi;</span><br><span> </span><br><span>  /* If handover RACH detection is turned on, treat this burst as an Access Burst.</span><br><span>      * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */</span><br><span>@@ -164,10 +165,21 @@</span><br><span>                      break;</span><br><span>               }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         /* Calculate the frame number where the block begins */</span><br><span style="color: hsl(120, 100%, 40%);">+               if (bi->fn % 13 < 4)</span><br><span style="color: hsl(120, 100%, 40%);">+                    fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 5);</span><br><span style="color: hsl(120, 100%, 40%);">+           else</span><br><span style="color: hsl(120, 100%, 40%);">+                  fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (lchan->nr == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                        fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H0);</span><br><span style="color: hsl(120, 100%, 40%);">+             else</span><br><span style="color: hsl(120, 100%, 40%);">+                  fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H1);</span><br><span style="color: hsl(120, 100%, 40%);">+             fn_is_cmi = ul_amr_fn_is_cmi(fn_begin);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>            /* See comment in function rx_tchf_fn() */</span><br><span>           amr = 2;</span><br><span>             rc = gsm0503_tch_ahs_decode_dtx(tch_data + amr, *bursts_p,</span><br><span style="color: hsl(0, 100%, 40%);">-                      fn_is_odd, fn_is_odd, chan_state->codec,</span><br><span style="color: hsl(120, 100%, 40%);">+                   fn_is_odd, !fn_is_cmi, chan_state->codec,</span><br><span>                         chan_state->codecs, &chan_state->ul_ft,</span><br><span>                    &chan_state->ul_cmr, &n_errors, &n_bits_total, &chan_state->amr_last_dtx);</span><br><span> </span><br><span>@@ -343,7 +355,6 @@</span><br><span>           fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 5);</span><br><span>  else</span><br><span>                 fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 4);</span><br><span style="color: hsl(0, 100%, 40%);">-     </span><br><span>     if (lchan->nr == 0)</span><br><span>               fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H0);</span><br><span>    else</span><br><span>@@ -441,7 +452,7 @@</span><br><span>            * in frame, the first FN 0,8,17 or 1,9,18 defines that CMR is</span><br><span>                * included in frame. */</span><br><span>             gsm0503_tch_ahs_encode(*bursts_p, msg_tch->l2h + 2,</span><br><span style="color: hsl(0, 100%, 40%);">-                  msgb_l2len(msg_tch) - 2, fn_is_codec_mode_request(br->fn),</span><br><span style="color: hsl(120, 100%, 40%);">+                 msgb_l2len(msg_tch) - 2, !dl_amr_fn_is_cmi(br->fn),</span><br><span>                       chan_state->codec, chan_state->codecs,</span><br><span>                         chan_state->dl_ft,</span><br><span>                        chan_state->dl_cmr);</span><br><span>diff --git a/src/osmo-bts-trx/sched_utils.h b/src/osmo-bts-trx/sched_utils.h</span><br><span>index 4a1aaf5..f76e49b 100644</span><br><span>--- a/src/osmo-bts-trx/sched_utils.h</span><br><span>+++ b/src/osmo-bts-trx/sched_utils.h</span><br><span>@@ -23,6 +23,8 @@</span><br><span> </span><br><span> #include <stdint.h></span><br><span> #include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmo-bts/scheduler.h></span><br><span> </span><br><span> extern void *tall_bts_ctx;</span><br><span> </span><br><span>@@ -35,8 +37,76 @@</span><br><span>          return 10000 * n_errors / n_bits_total;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* determine if the FN is transmitting a CMR (1) or not (0) */</span><br><span style="color: hsl(0, 100%, 40%);">-static inline int fn_is_codec_mode_request(uint32_t fn)</span><br><span style="color: hsl(120, 100%, 40%);">+/*! determine whether an uplink AMR block is CMI according to 3GPP TS 45.009.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] fn_begin frame number of the beginning of the block.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns true in case of CMI; false otherwise. */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool ul_amr_fn_is_cmi(uint32_t fn_begin)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   return (((fn + 4) % 26) >> 2) & 1;</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (fn_begin % 26) {</span><br><span style="color: hsl(120, 100%, 40%);">+              /*! See also: 3GPP TS 45.009, section 3.2.1.3 Transmitter/Receiver Synchronisation */</span><br><span style="color: hsl(120, 100%, 40%);">+         /* valid for AHS subslot 0 and AFS: */</span><br><span style="color: hsl(120, 100%, 40%);">+        case 0:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 8:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 17:</span><br><span style="color: hsl(120, 100%, 40%);">+              /* valid for AHS subslot 1: */</span><br><span style="color: hsl(120, 100%, 40%);">+        case 1:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 9:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 18:</span><br><span style="color: hsl(120, 100%, 40%);">+              return true;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Complementary values for sanity check */</span><br><span style="color: hsl(120, 100%, 40%);">+           /* valid for AHS subslot 0 and AFS: */</span><br><span style="color: hsl(120, 100%, 40%);">+        case 4:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 13:</span><br><span style="color: hsl(120, 100%, 40%);">+      case 21:</span><br><span style="color: hsl(120, 100%, 40%);">+              /* valid for AHS subslot 1: */</span><br><span style="color: hsl(120, 100%, 40%);">+        case 5:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 14:</span><br><span style="color: hsl(120, 100%, 40%);">+      case 22:</span><br><span style="color: hsl(120, 100%, 40%);">+              return false;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DL1P, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+                     "uplink frame number fn_begin=%u does not mark the beginning of a voice block!\n", fn_begin);</span><br><span style="color: hsl(120, 100%, 40%);">+          OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+           return false;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! determine the whether a downlink AMR block is CMI according to 3GPP TS 45.009.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] fn_begin frame number of the beginning of the block.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns true in case of CMI; false otherwise. */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool dl_amr_fn_is_cmi(uint32_t fn_begin)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (fn_begin % 26) {</span><br><span style="color: hsl(120, 100%, 40%);">+              /*! See also: 3GPP TS 45.009, section 3.2.1.3 Transmitter/Receiver Synchronisation */</span><br><span style="color: hsl(120, 100%, 40%);">+         /* valid for AHS subslot 0 and AFS: */</span><br><span style="color: hsl(120, 100%, 40%);">+        case 4:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 13:</span><br><span style="color: hsl(120, 100%, 40%);">+      case 21:</span><br><span style="color: hsl(120, 100%, 40%);">+              /* valid for AHS subslot 1: */</span><br><span style="color: hsl(120, 100%, 40%);">+        case 5:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 14:</span><br><span style="color: hsl(120, 100%, 40%);">+      case 22:</span><br><span style="color: hsl(120, 100%, 40%);">+              return true;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Complementary values for sanity check */</span><br><span style="color: hsl(120, 100%, 40%);">+           /* valid for AHS subslot 0 and AFS: */</span><br><span style="color: hsl(120, 100%, 40%);">+        case 0:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 8:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 17:</span><br><span style="color: hsl(120, 100%, 40%);">+              /* valid for AHS subslot 1: */</span><br><span style="color: hsl(120, 100%, 40%);">+        case 1:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 9:</span><br><span style="color: hsl(120, 100%, 40%);">+       case 18:</span><br><span style="color: hsl(120, 100%, 40%);">+              return false;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DL1P, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+                     "downlink frame number fn_begin=%u does not mark the beginning of a voice block!\n", fn_begin);</span><br><span style="color: hsl(120, 100%, 40%);">+                OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+           return false;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span> }</span><br><span>diff --git a/tests/Makefile.am b/tests/Makefile.am</span><br><span>index 8d19e6e..a1d04a7 100644</span><br><span>--- a/tests/Makefile.am</span><br><span>+++ b/tests/Makefile.am</span><br><span>@@ -1,4 +1,4 @@</span><br><span style="color: hsl(0, 100%, 40%);">-SUBDIRS = paging cipher agch misc handover tx_power power meas ta_control</span><br><span style="color: hsl(120, 100%, 40%);">+SUBDIRS = paging cipher agch misc handover tx_power power meas ta_control amr</span><br><span> </span><br><span> if ENABLE_SYSMOBTS</span><br><span> SUBDIRS += sysmobts</span><br><span>diff --git a/tests/amr/Makefile.am b/tests/amr/Makefile.am</span><br><span>new file mode 100644</span><br><span>index 0000000..dc0f1b8</span><br><span>--- /dev/null</span><br><span>+++ b/tests/amr/Makefile.am</span><br><span>@@ -0,0 +1,11 @@</span><br><span style="color: hsl(120, 100%, 40%);">+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include</span><br><span style="color: hsl(120, 100%, 40%);">+AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) \</span><br><span style="color: hsl(120, 100%, 40%);">+        $(LIBOSMOABIS_CFLAGS) $(LIBOSMOTRAU_CFLAGS)</span><br><span style="color: hsl(120, 100%, 40%);">+LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+    $(LIBOSMOABIS_LIBS) $(LIBOSMOTRAU_LIBS)</span><br><span style="color: hsl(120, 100%, 40%);">+noinst_PROGRAMS = amr_test</span><br><span style="color: hsl(120, 100%, 40%);">+EXTRA_DIST = amr_test.ok</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+misc_test_SOURCES = amr_test.c</span><br><span style="color: hsl(120, 100%, 40%);">+misc_test_LDADD = $(top_builddir)/src/common/libbts.a \</span><br><span style="color: hsl(120, 100%, 40%);">+              $(LDADD)</span><br><span>diff --git a/tests/amr/amr_test.c b/tests/amr/amr_test.c</span><br><span>new file mode 100644</span><br><span>index 0000000..4efbf40</span><br><span>--- /dev/null</span><br><span>+++ b/tests/amr/amr_test.c</span><br><span>@@ -0,0 +1,151 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2021 by sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Philipp Maier</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmo-bts/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "../../src/osmo-bts-trx/sched_utils.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct amr_cmi_test_data {</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Frame number that marks the beginning of the voice block */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t gsm_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* In uplink: True, when the voice block is a CMI block, false otherwise. */</span><br><span style="color: hsl(120, 100%, 40%);">+  /* In downlink: False, when the voice block is a CMI block, true otherwise. */</span><br><span style="color: hsl(120, 100%, 40%);">+        bool is_cmi;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* The behavior of AHS in subslot 0 and AFS is the same */</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct amr_cmi_test_data testvec_ahs_h0_and_afs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+    { 0, true },</span><br><span style="color: hsl(120, 100%, 40%);">+  { 4, false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 8, true },</span><br><span style="color: hsl(120, 100%, 40%);">+  { 13, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 17, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 21, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 26, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 30, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 34, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 39, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 43, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 47, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 52, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 56, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 60, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 65, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 69, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 73, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 78, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 82, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 86, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 91, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 95, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 99, false },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct amr_cmi_test_data testvec_ahs_h1[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+      { 1, true },</span><br><span style="color: hsl(120, 100%, 40%);">+  { 5, false },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 9, true },</span><br><span style="color: hsl(120, 100%, 40%);">+  { 14, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 18, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 22, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 27, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 31, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 35, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 40, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 44, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 48, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 53, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 57, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 61, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 66, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 70, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 74, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 79, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 83, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 87, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 92, false },</span><br><span style="color: hsl(120, 100%, 40%);">+        { 96, true },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 100, false },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_amr_cmi_sched(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+       bool res;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("AMR transmission phase (CMI) in relation to GSM FN:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i = 0; i < ARRAY_SIZE(testvec_ahs_h0_and_afs); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         res = ul_amr_fn_is_cmi(testvec_ahs_h0_and_afs[i].gsm_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Uplink, AMR AHS on HR subslot 0: fn_begin=%u, CMI=%u\n", testvec_ahs_h0_and_afs[i].gsm_fn, res);</span><br><span style="color: hsl(120, 100%, 40%);">+            OSMO_ASSERT(res == testvec_ahs_h0_and_afs[i].is_cmi);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < ARRAY_SIZE(testvec_ahs_h0_and_afs); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         res = dl_amr_fn_is_cmi(testvec_ahs_h0_and_afs[i].gsm_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Downlink, AMR AHS on HR subslot 0: fn_begin=%u, CMI=%u\n", testvec_ahs_h0_and_afs[i].gsm_fn, res);</span><br><span style="color: hsl(120, 100%, 40%);">+          OSMO_ASSERT(res == !testvec_ahs_h0_and_afs[i].is_cmi);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < ARRAY_SIZE(testvec_ahs_h1); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         res = ul_amr_fn_is_cmi(testvec_ahs_h1[i].gsm_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Uplink, AMR AHS on HR subslot 1: fn_begin=%u, CMI=%u\n", testvec_ahs_h1[i].gsm_fn, res);</span><br><span style="color: hsl(120, 100%, 40%);">+            OSMO_ASSERT(res == testvec_ahs_h1[i].is_cmi);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < ARRAY_SIZE(testvec_ahs_h1); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         res = dl_amr_fn_is_cmi(testvec_ahs_h1[i].gsm_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Downlink, AMR AHS on HR subslot 1: fn_begin=%u, CMI=%u\n", testvec_ahs_h1[i].gsm_fn, res);</span><br><span style="color: hsl(120, 100%, 40%);">+          OSMO_ASSERT(res == !testvec_ahs_h1[i].is_cmi);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < ARRAY_SIZE(testvec_ahs_h0_and_afs); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         res = ul_amr_fn_is_cmi(testvec_ahs_h0_and_afs[i].gsm_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Uplink, AMR AFS: fn_begin=%u, CMI=%u\n", testvec_ahs_h0_and_afs[i].gsm_fn, res);</span><br><span style="color: hsl(120, 100%, 40%);">+            OSMO_ASSERT(res == testvec_ahs_h0_and_afs[i].is_cmi);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < ARRAY_SIZE(testvec_ahs_h0_and_afs); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         res = dl_amr_fn_is_cmi(testvec_ahs_h0_and_afs[i].gsm_fn);</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Downlink, AMR AFS: fn_begin=%u, CMI=%u\n", testvec_ahs_h0_and_afs[i].gsm_fn, res);</span><br><span style="color: hsl(120, 100%, 40%);">+          OSMO_ASSERT(res == !testvec_ahs_h0_and_afs[i].is_cmi);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int main(int argc, char **argv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  test_amr_cmi_sched();</span><br><span style="color: hsl(120, 100%, 40%);">+ return EXIT_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/tests/amr/amr_test.ok b/tests/amr/amr_test.ok</span><br><span>new file mode 100644</span><br><span>index 0000000..ec1d1a0</span><br><span>--- /dev/null</span><br><span>+++ b/tests/amr/amr_test.ok</span><br><span>@@ -0,0 +1,152 @@</span><br><span style="color: hsl(120, 100%, 40%);">+AMR transmission phase (CMI) in relation to GSM FN:</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=0, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=4, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=8, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=13, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=17, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=21, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=26, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=30, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=34, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=39, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=43, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=47, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=52, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=56, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=60, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=65, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=69, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=73, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=78, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=82, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=86, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=91, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=95, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 0: fn_begin=99, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=0, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=4, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=8, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=13, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=17, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=21, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=26, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=30, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=34, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=39, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=43, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=47, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=52, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=56, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=60, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=65, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=69, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=73, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=78, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=82, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=86, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=91, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=95, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 0: fn_begin=99, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=1, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=5, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=9, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=14, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=18, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=22, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=27, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=31, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=35, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=40, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=44, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=48, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=53, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=57, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=61, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=66, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=70, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=74, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=79, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=83, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=87, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=92, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=96, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AHS on HR subslot 1: fn_begin=100, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=1, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=5, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=9, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=14, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=18, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=22, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=27, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=31, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=35, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=40, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=44, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=48, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=53, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=57, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=61, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=66, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=70, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=74, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=79, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=83, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=87, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=92, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=96, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AHS on HR subslot 1: fn_begin=100, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=0, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=4, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=8, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=13, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=17, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=21, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=26, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=30, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=34, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=39, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=43, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=47, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=52, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=56, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=60, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=65, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=69, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=73, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=78, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=82, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=86, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=91, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=95, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Uplink, AMR AFS: fn_begin=99, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=0, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=4, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=8, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=13, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=17, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=21, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=26, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=30, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=34, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=39, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=43, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=47, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=52, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=56, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=60, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=65, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=69, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=73, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=78, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=82, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=86, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=91, CMI=1</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=95, CMI=0</span><br><span style="color: hsl(120, 100%, 40%);">+Downlink, AMR AFS: fn_begin=99, CMI=1</span><br><span>diff --git a/tests/testsuite.at b/tests/testsuite.at</span><br><span>index ba5a409..f2d17fb 100644</span><br><span>--- a/tests/testsuite.at</span><br><span>+++ b/tests/testsuite.at</span><br><span>@@ -63,3 +63,9 @@</span><br><span> cat $abs_srcdir/ta_control/ta_control_test.ok > expout</span><br><span> AT_CHECK([$abs_top_builddir/tests/ta_control/ta_control_test], [], [expout], [ignore])</span><br><span> AT_CLEANUP</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AT_SETUP([amr])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_KEYWORDS([amr])</span><br><span style="color: hsl(120, 100%, 40%);">+cat $abs_srcdir/amr/amr_test.ok > expout</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CHECK([$abs_top_builddir/tests/amr/amr_test], [], [expout], [ignore])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CLEANUP</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/25296">change 25296</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-bts/+/25296"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bts </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I94a934a6b3b397b4cd0e9da3577325de58814335 </div>
<div style="display:none"> Gerrit-Change-Number: 25296 </div>
<div style="display:none"> Gerrit-PatchSet: 5 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>