<p>dexter has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/25296">View Change</a></p><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 idfentifer. 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>M tests/testsuite.at<br>6 files changed, 104 insertions(+), 11 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/96/25296/1</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..ada6146 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,78 @@</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 the 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%);">+  uint32_t fn_26 = fn_begin % 26;</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (fn_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%);">+     uint32_t fn_26 = fn_begin % 26;</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (fn_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/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: 1 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>