<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/11060">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">codec_pref: handle S0-S15 in ASSIGNMENT REQUEST<br><br>Opposed to all other codecs that are common in GSM, AMR requires a codec<br>configuration that is expressed by a bitmask (S0 to S15) in the speech<br>codec list in the ASSIGNMENT REQUEST. Also the BSC acknowledges those<br>configuration in the ASSIGNMENT COMPLETE message.<br><br>At the moment osmo-bsc ignores all incoming configuration bits. The bits<br>in the ASSIGNMENT COMPLETE speech codec (choosen) field are hardcoded.<br><br>- Store the configuration bits while parsing the ASSIGNMENT COMPLETE<br>- Create an intersection with the configuration that is actually<br>  supported by the BSS<br>- Return the resulting (chosen) configuration bits with the assignment<br>  complete message.<br>- Use the (highest of the) agreed codec rates in RSL channel activation.<br><br>Change-Id: I2d8ded51b3eb4c003fe2da6f2d6f48d001b73737<br>Related: OS#3529<br>---<br>M include/osmocom/bsc/codec_pref.h<br>M include/osmocom/bsc/gsm_data.h<br>M include/osmocom/bsc/lchan_fsm.h<br>M src/osmo-bsc/assignment_fsm.c<br>M src/osmo-bsc/codec_pref.c<br>M src/osmo-bsc/handover_fsm.c<br>M src/osmo-bsc/lchan_fsm.c<br>M src/osmo-bsc/osmo_bsc_bssap.c<br>M tests/codec_pref/codec_pref_test.c<br>M tests/codec_pref/codec_pref_test.ok<br>10 files changed, 190 insertions(+), 101 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/codec_pref.h b/include/osmocom/bsc/codec_pref.h</span><br><span>index 09aaa60..3085ad4 100644</span><br><span>--- a/include/osmocom/bsc/codec_pref.h</span><br><span>+++ b/include/osmocom/bsc/codec_pref.h</span><br><span>@@ -12,11 +12,11 @@</span><br><span> </span><br><span> int match_codec_pref(enum gsm48_chan_mode *chan_mode,</span><br><span>                 bool *full_rate,</span><br><span style="color: hsl(120, 100%, 40%);">+              uint16_t *s15_s0,</span><br><span>                    const struct gsm0808_channel_type *ct,</span><br><span>               const struct gsm0808_speech_codec_list *scl,</span><br><span style="color: hsl(0, 100%, 40%);">-                    struct gsm_audio_support * const *audio_support,</span><br><span style="color: hsl(0, 100%, 40%);">-                int audio_length,</span><br><span style="color: hsl(0, 100%, 40%);">-               const struct bts_codec_conf *bts_codec);</span><br><span style="color: hsl(120, 100%, 40%);">+              const struct bsc_msc_data *msc,</span><br><span style="color: hsl(120, 100%, 40%);">+               const struct gsm_bts *bts);</span><br><span> </span><br><span> void gen_bss_supported_codec_list(struct gsm0808_speech_codec_list *scl,</span><br><span>                               const struct bsc_msc_data *msc,</span><br><span>diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h</span><br><span>index 33a5a8d..7c91e59 100644</span><br><span>--- a/include/osmocom/bsc/gsm_data.h</span><br><span>+++ b/include/osmocom/bsc/gsm_data.h</span><br><span>@@ -109,6 +109,7 @@</span><br><span> </span><br><span>     enum gsm48_chan_mode chan_mode;</span><br><span>      bool full_rate;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t s15_s0;</span><br><span> };</span><br><span> </span><br><span> struct assignment_fsm_data {</span><br><span>diff --git a/include/osmocom/bsc/lchan_fsm.h b/include/osmocom/bsc/lchan_fsm.h</span><br><span>index 9fbf9b3..d2e8724 100644</span><br><span>--- a/include/osmocom/bsc/lchan_fsm.h</span><br><span>+++ b/include/osmocom/bsc/lchan_fsm.h</span><br><span>@@ -58,6 +58,7 @@</span><br><span>      /* This always is for a specific lchan, so its lchan->type indicates full or half rate.</span><br><span>    * When a dyn TS was selected, the lchan->type has been set to the desired rate. */</span><br><span>       enum gsm48_chan_mode chan_mode;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t s15_s0;</span><br><span>     bool requires_voice_stream;</span><br><span>  bool wait_before_switching_rtp;</span><br><span>      uint16_t msc_assigned_cic;</span><br><span>diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c</span><br><span>index 2410adb..3f553ff 100644</span><br><span>--- a/src/osmo-bsc/assignment_fsm.c</span><br><span>+++ b/src/osmo-bsc/assignment_fsm.c</span><br><span>@@ -169,8 +169,8 @@</span><br><span>             * assignment complete message. */</span><br><span>           if (gscon_is_aoip(conn)) {</span><br><span>                   /* Extrapolate speech codec from speech mode */</span><br><span style="color: hsl(0, 100%, 40%);">-                 /* FIXME: AMR codec configuration must be derived from lchan1! */</span><br><span>                    gsm0808_speech_codec_from_chan_type(&sc, perm_spch);</span><br><span style="color: hsl(120, 100%, 40%);">+                      sc.cfg = conn->assignment.req.s15_s0;</span><br><span>                     sc_ptr = &sc;</span><br><span>            }</span><br><span>    }</span><br><span>@@ -382,6 +382,7 @@</span><br><span>              .activ_for = FOR_ASSIGNMENT,</span><br><span>                 .for_conn = conn,</span><br><span>            .chan_mode = req->chan_mode,</span><br><span style="color: hsl(120, 100%, 40%);">+               .s15_s0 = req->s15_s0,</span><br><span>            .requires_voice_stream = conn->assignment.requires_voice_stream,</span><br><span>          .msc_assigned_cic = req->msc_assigned_cic,</span><br><span>                .old_lchan = conn->lchan,</span><br><span>diff --git a/src/osmo-bsc/codec_pref.c b/src/osmo-bsc/codec_pref.c</span><br><span>index c998e60..afecaa3 100644</span><br><span>--- a/src/osmo-bsc/codec_pref.c</span><br><span>+++ b/src/osmo-bsc/codec_pref.c</span><br><span>@@ -94,14 +94,18 @@</span><br><span>  * matches one of the permitted speech settings of the channel type element.</span><br><span>  * The matched permitted speech value is then also compared against the</span><br><span>  * speech codec list. (optional, only relevant for AoIP) */</span><br><span style="color: hsl(0, 100%, 40%);">-static bool test_codec_pref(const struct gsm0808_channel_type *ct,</span><br><span style="color: hsl(0, 100%, 40%);">-                     const struct gsm0808_speech_codec_list *scl, uint8_t perm_spch)</span><br><span style="color: hsl(120, 100%, 40%);">+static bool test_codec_pref(const struct gsm0808_speech_codec **sc_match,</span><br><span style="color: hsl(120, 100%, 40%);">+                            const struct gsm0808_speech_codec_list *scl,</span><br><span style="color: hsl(120, 100%, 40%);">+                          const struct gsm0808_channel_type *ct,</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint8_t perm_spch)</span><br><span> {</span><br><span>  unsigned int i;</span><br><span>      bool match = false;</span><br><span>  struct gsm0808_speech_codec sc;</span><br><span>      int rc;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   *sc_match = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* Try to find the given permitted speech value in the</span><br><span>        * codec list of the channel type element */</span><br><span>         for (i = 0; i < ct->perm_spch_len; i++) {</span><br><span>@@ -129,8 +133,10 @@</span><br><span>       /* Try to find extrapolated speech codec data in</span><br><span>      * the speech codec list */</span><br><span>  for (i = 0; i < scl->len; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-          if (sc.type == scl->codec[i].type)</span><br><span style="color: hsl(120, 100%, 40%);">+         if (sc.type == scl->codec[i].type) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       *sc_match = &scl->codec[i];</span><br><span>                   return true;</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span>    }</span><br><span> </span><br><span>        return false;</span><br><span>@@ -168,40 +174,74 @@</span><br><span>        return false;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Generate the bss supported amr configuration bits (S0-S15) */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint16_t gen_bss_supported_amr_s15_s0(const struct bsc_msc_data *msc, const struct gsm_bts *bts, bool hr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gsm48_multi_rate_conf *amr_cfg_bts;</span><br><span style="color: hsl(120, 100%, 40%);">+      const struct gsm48_multi_rate_conf *amr_cfg_msc;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t amr_s15_s0_bts;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t amr_s15_s0_msc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Lookup the BTS specific AMR rate configuration. This config is set</span><br><span style="color: hsl(120, 100%, 40%);">+  * via the VTY for each BTS individually. In cases where no configuration</span><br><span style="color: hsl(120, 100%, 40%);">+      * is set we will assume a safe default */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (hr) {</span><br><span style="color: hsl(120, 100%, 40%);">+             amr_cfg_bts = (struct gsm48_multi_rate_conf *)&bts->mr_half.gsm48_ie;</span><br><span style="color: hsl(120, 100%, 40%);">+          amr_s15_s0_bts = gsm0808_sc_cfg_from_gsm48_mr_cfg(amr_cfg_bts, false);</span><br><span style="color: hsl(120, 100%, 40%);">+        } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              amr_cfg_bts = (struct gsm48_multi_rate_conf *)&bts->mr_full.gsm48_ie;</span><br><span style="color: hsl(120, 100%, 40%);">+          amr_s15_s0_bts = gsm0808_sc_cfg_from_gsm48_mr_cfg(amr_cfg_bts, true);</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%);">+   /* Lookup the AMR rate configuration that is set for the MSC */</span><br><span style="color: hsl(120, 100%, 40%);">+       amr_cfg_msc = &msc->amr_conf;</span><br><span style="color: hsl(120, 100%, 40%);">+  amr_s15_s0_msc = gsm0808_sc_cfg_from_gsm48_mr_cfg(amr_cfg_msc, true);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Calculate the intersection of the two configurations and update S0-S15</span><br><span style="color: hsl(120, 100%, 40%);">+      * in the codec list. */</span><br><span style="color: hsl(120, 100%, 40%);">+      return amr_s15_s0_bts & amr_s15_s0_msc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Match the codec preferences from local config with a received codec preferences IEs received from the</span><br><span>  * MSC and the BTS' codec configuration.</span><br><span>  *  \param[out] chan_mode GSM 04.08 channel mode.</span><br><span>  *  \param[out] full_rate true if full-rate.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] s15_s0 codec configuration bits S15-S0 (AMR)</span><br><span>  *  \param[in] ct GSM 08.08 channel type received from MSC.</span><br><span>  *  \param[in] scl GSM 08.08 speech codec list received from MSC (optional).</span><br><span style="color: hsl(0, 100%, 40%);">- *  \param[in] audio_support List of allowed codecs as from local config.</span><br><span style="color: hsl(0, 100%, 40%);">- *  \param[in] audio_length Number of items in audio_support.</span><br><span style="color: hsl(0, 100%, 40%);">- *  \param[in] bts_codec BTS codec configuration.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] msc associated msc (current codec settings).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] bts associated bts (current codec settings).</span><br><span>  *  \returns 0 on success, -1 in case no match was found */</span><br><span> int match_codec_pref(enum gsm48_chan_mode *chan_mode,</span><br><span>                  bool *full_rate,</span><br><span style="color: hsl(120, 100%, 40%);">+              uint16_t *s15_s0,</span><br><span>                    const struct gsm0808_channel_type *ct,</span><br><span>               const struct gsm0808_speech_codec_list *scl,</span><br><span style="color: hsl(0, 100%, 40%);">-                    struct gsm_audio_support * const *audio_support,</span><br><span style="color: hsl(0, 100%, 40%);">-                int audio_length,</span><br><span style="color: hsl(0, 100%, 40%);">-               const struct bts_codec_conf *bts_codec)</span><br><span style="color: hsl(120, 100%, 40%);">+               const struct bsc_msc_data *msc,</span><br><span style="color: hsl(120, 100%, 40%);">+               const struct gsm_bts *bts)</span><br><span> {</span><br><span>         unsigned int i;</span><br><span>      uint8_t perm_spch;</span><br><span>   bool match = false;</span><br><span style="color: hsl(120, 100%, 40%);">+   const struct gsm0808_speech_codec *sc_match = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint16_t amr_s15_s0_supported;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      for (i = 0; i < audio_length; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Note: Normally the MSC should never try to advertise a codec that</span><br><span style="color: hsl(120, 100%, 40%);">+   * we did not advertise as supported before. In order to ensure that</span><br><span style="color: hsl(120, 100%, 40%);">+   * no unsupported codec is accepted, we make sure that the codec is</span><br><span style="color: hsl(120, 100%, 40%);">+    * indeed available with the current BTS and MSC configuration */</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < msc->audio_length; i++) {</span><br><span>              /* Pick a permitted speech value from the global codec configuration list */</span><br><span style="color: hsl(0, 100%, 40%);">-            perm_spch = audio_support_to_gsm88(audio_support[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+         perm_spch = audio_support_to_gsm88(msc->audio_support[i]);</span><br><span> </span><br><span>            /* Check this permitted speech value against the BTS specific parameters.</span><br><span>             * if the BTS does not support the codec, try the next one */</span><br><span style="color: hsl(0, 100%, 40%);">-           if (!test_codec_support_bts(bts_codec, perm_spch))</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!test_codec_support_bts(&bts->codec, perm_spch))</span><br><span>                  continue;</span><br><span> </span><br><span>                /* Match the permitted speech value against the codec lists that were</span><br><span>                 * advertised by the MS and the MSC */</span><br><span style="color: hsl(0, 100%, 40%);">-          if (test_codec_pref(ct, scl, perm_spch)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (test_codec_pref(&sc_match, scl, ct, perm_spch)) {</span><br><span>                    match = true;</span><br><span>                        break;</span><br><span>               }</span><br><span>@@ -211,6 +251,7 @@</span><br><span>      if (!match) {</span><br><span>                *full_rate = false;</span><br><span>          *chan_mode = GSM48_CMODE_SIGN;</span><br><span style="color: hsl(120, 100%, 40%);">+                *s15_s0 = 0;</span><br><span>                 return -1;</span><br><span>   }</span><br><span> </span><br><span>@@ -240,6 +281,31 @@</span><br><span>         /* Lookup a channel mode for the selected codec */</span><br><span>   *chan_mode = gsm88_to_chan_mode(perm_spch);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       /* Special handling for AMR */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (perm_spch == GSM0808_PERM_HR3 || perm_spch == GSM0808_PERM_FR3) {</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Normally the MSC should never try to advertise an AMR codec</span><br><span style="color: hsl(120, 100%, 40%);">+                 * configuration that we did not previously advertise as</span><br><span style="color: hsl(120, 100%, 40%);">+               * supported. However, to ensure that no unsupported AMR codec</span><br><span style="color: hsl(120, 100%, 40%);">+                 * configuration enters the further processing steps we again</span><br><span style="color: hsl(120, 100%, 40%);">+          * lookup what we support and generate an intersection. All</span><br><span style="color: hsl(120, 100%, 40%);">+            * further processing is then done with this intersection</span><br><span style="color: hsl(120, 100%, 40%);">+              * result */</span><br><span style="color: hsl(120, 100%, 40%);">+          amr_s15_s0_supported = gen_bss_supported_amr_s15_s0(msc, bts, (perm_spch == GSM0808_PERM_HR3));</span><br><span style="color: hsl(120, 100%, 40%);">+               if (sc_match)</span><br><span style="color: hsl(120, 100%, 40%);">+                 *s15_s0 = sc_match->cfg & amr_s15_s0_supported;</span><br><span style="color: hsl(120, 100%, 40%);">+                else</span><br><span style="color: hsl(120, 100%, 40%);">+                  *s15_s0 = amr_s15_s0_supported;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             /* NOTE: The function test_codec_pref() will populate the</span><br><span style="color: hsl(120, 100%, 40%);">+              * sc_match pointer from the searched speech codec list. For</span><br><span style="color: hsl(120, 100%, 40%);">+           * AoIP based networks, no speech codec list will be present</span><br><span style="color: hsl(120, 100%, 40%);">+           * and therefore no sc_match will be populated. For those</span><br><span style="color: hsl(120, 100%, 40%);">+              * cases only the local configuration will influence s15_s0.</span><br><span style="color: hsl(120, 100%, 40%);">+           * However s15_s0 is always populated with a meaningful value,</span><br><span style="color: hsl(120, 100%, 40%);">+                 * regardless if AoIP is in use or not. */</span><br><span style="color: hsl(120, 100%, 40%);">+    } else</span><br><span style="color: hsl(120, 100%, 40%);">+                *s15_s0 = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -254,11 +320,6 @@</span><br><span>    uint8_t perm_spch;</span><br><span>   unsigned int i;</span><br><span>      int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- uint16_t amr_s15_s0_bts;</span><br><span style="color: hsl(0, 100%, 40%);">-        uint16_t amr_s15_s0_msc;</span><br><span style="color: hsl(0, 100%, 40%);">-        uint16_t amr_s15_s0;</span><br><span style="color: hsl(0, 100%, 40%);">-    const struct gsm48_multi_rate_conf *amr_cfg_bts;</span><br><span style="color: hsl(0, 100%, 40%);">-        const struct gsm48_multi_rate_conf *amr_cfg_msc;</span><br><span> </span><br><span>         memset(scl, 0, sizeof(*scl));</span><br><span> </span><br><span>@@ -280,28 +341,8 @@</span><br><span>             /* AMR (HR/FR version 3) is the only codec that requires a codec</span><br><span>              * configuration (S0-S15). Determine the current configuration and update</span><br><span>             * the cfg flag. */</span><br><span style="color: hsl(0, 100%, 40%);">-             if (msc->audio_support[i]->ver == 3) {</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* First lookup the BTS specific AMR rate configuration. Thsi config</span><br><span style="color: hsl(0, 100%, 40%);">-                     * is set via the VTY for each BTS individually. In cases where no</span><br><span style="color: hsl(0, 100%, 40%);">-                       * configuration is set we will assume a safe default */</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (msc->audio_support[i]->hr) {</span><br><span style="color: hsl(0, 100%, 40%);">-                          amr_cfg_bts = (struct gsm48_multi_rate_conf *)&bts->mr_half.gsm48_ie;</span><br><span style="color: hsl(0, 100%, 40%);">-                            amr_s15_s0_bts = gsm0808_sc_cfg_from_gsm48_mr_cfg(amr_cfg_bts, false);</span><br><span style="color: hsl(0, 100%, 40%);">-                  } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                amr_cfg_bts = (struct gsm48_multi_rate_conf *)&bts->mr_full.gsm48_ie;</span><br><span style="color: hsl(0, 100%, 40%);">-                            amr_s15_s0_bts = gsm0808_sc_cfg_from_gsm48_mr_cfg(amr_cfg_bts, true);</span><br><span style="color: hsl(0, 100%, 40%);">-                   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       /* At next, lookup the AMR rate configuration that is set for the MSC */</span><br><span style="color: hsl(0, 100%, 40%);">-                        amr_cfg_msc = &msc->amr_conf;</span><br><span style="color: hsl(0, 100%, 40%);">-                    amr_s15_s0_msc = gsm0808_sc_cfg_from_gsm48_mr_cfg(amr_cfg_msc, true);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                   /* Calculate the intersection of the two configurations and update S0-S15</span><br><span style="color: hsl(0, 100%, 40%);">-                        * in the codec list. */</span><br><span style="color: hsl(0, 100%, 40%);">-                        amr_s15_s0 = amr_s15_s0_bts & amr_s15_s0_msc;</span><br><span style="color: hsl(0, 100%, 40%);">-                       scl->codec[scl->len].cfg = amr_s15_s0;</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (msc->audio_support[i]->ver == 3)</span><br><span style="color: hsl(120, 100%, 40%);">+                    scl->codec[scl->len].cfg = gen_bss_supported_amr_s15_s0(msc, bts, msc->audio_support[i]->hr);</span><br><span> </span><br><span>                scl->len++;</span><br><span>       }</span><br><span>diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c</span><br><span>index 9d558bc..0ba5061 100644</span><br><span>--- a/src/osmo-bsc/handover_fsm.c</span><br><span>+++ b/src/osmo-bsc/handover_fsm.c</span><br><span>@@ -522,6 +522,7 @@</span><br><span>     int match_idx;</span><br><span>       enum gsm48_chan_mode mode;</span><br><span>   bool full_rate;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t s15_s0;</span><br><span>     struct osmo_fsm_inst *fi;</span><br><span> </span><br><span>        handover_fsm_alloc(conn);</span><br><span>@@ -560,8 +561,7 @@</span><br><span>                     bts->nr, req->cell_id_target_name);</span><br><span> </span><br><span>                 /* Figure out channel type */</span><br><span style="color: hsl(0, 100%, 40%);">-           if (match_codec_pref(&mode, &full_rate, &req->ct, &req->scl, msc->audio_support,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    msc->audio_length, &bts->codec)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (match_codec_pref(&mode, &full_rate, &s15_s0, &req->ct, &req->scl, msc, bts)) {</span><br><span>                         LOG_HO(conn, LOGL_DEBUG,</span><br><span>                            "BTS %u has no matching channel codec (%s, speech codec list len = %u)",</span><br><span>                           bts->nr, gsm0808_channel_type_name(&req->ct), req->scl.len);</span><br><span>@@ -606,6 +606,7 @@</span><br><span>               .activ_for = FOR_HANDOVER,</span><br><span>           .for_conn = conn,</span><br><span>            .chan_mode = mode,</span><br><span style="color: hsl(120, 100%, 40%);">+            .s15_s0 = s15_s0,</span><br><span>            .requires_voice_stream = chan_mode_is_tch(mode),</span><br><span>             .msc_assigned_cic = req->msc_assigned_cic,</span><br><span>        };</span><br><span>diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c</span><br><span>index c80d8a1..4aaedde 100644</span><br><span>--- a/src/osmo-bsc/lchan_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_fsm.c</span><br><span>@@ -425,11 +425,48 @@</span><br><span>      };</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Mask all rates instead of the highest possible */</span><br><span style="color: hsl(120, 100%, 40%);">+static void lchan_mr_config_mask(struct gsm48_multi_rate_conf *mr_conf)</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 highest_seen = false;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t *_mr_conf = (uint8_t *) mr_conf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* FIXME: At the moment we can not support multiple codec rates in one</span><br><span style="color: hsl(120, 100%, 40%);">+         * struct gsm48_multi_rate_conf, because the struct lacks the fields</span><br><span style="color: hsl(120, 100%, 40%);">+   * for Threshold and Hysteresis. Those fields are not needed when only</span><br><span style="color: hsl(120, 100%, 40%);">+         * a single codec rate is in place, but as soon as multiple codec</span><br><span style="color: hsl(120, 100%, 40%);">+      * rates are used the parameters are mandatory. The layout for the</span><br><span style="color: hsl(120, 100%, 40%);">+     * struct would then also be different because each rate needs its</span><br><span style="color: hsl(120, 100%, 40%);">+     * own Threshold and Hysteresis value. (See also 3GPP TS 04.08,</span><br><span style="color: hsl(120, 100%, 40%);">+        * chapter 10.5.2.21aa MultiRate configuration).</span><br><span style="color: hsl(120, 100%, 40%);">+       *</span><br><span style="color: hsl(120, 100%, 40%);">+     * Since we are unable to signal multiple codec rates properly, we just</span><br><span style="color: hsl(120, 100%, 40%);">+        * remove all codec rates from the active set, except the highest</span><br><span style="color: hsl(120, 100%, 40%);">+      * possible. Doing so we lack the functionality to switch towards the</span><br><span style="color: hsl(120, 100%, 40%);">+  * other, lower codec rates that were offered by the MSC, but it is</span><br><span style="color: hsl(120, 100%, 40%);">+    * still guaranteed that a rate is selected that is supported by all</span><br><span style="color: hsl(120, 100%, 40%);">+   * entities.</span><br><span style="color: hsl(120, 100%, 40%);">+   *</span><br><span style="color: hsl(120, 100%, 40%);">+     * To fix this problem, we should implement a proper encoder for</span><br><span style="color: hsl(120, 100%, 40%);">+       * struct gsm48_multi_rate_conf, in libosmocore and use it here.</span><br><span style="color: hsl(120, 100%, 40%);">+       * struct amr_mode already seems to have members for threshold and</span><br><span style="color: hsl(120, 100%, 40%);">+     * hysteresis we can use. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 7; i > 0; i--) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (_mr_conf[1] & (1 << i) && highest_seen == false) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      highest_seen = true;</span><br><span style="color: hsl(120, 100%, 40%);">+          } else if (highest_seen)</span><br><span style="color: hsl(120, 100%, 40%);">+                      _mr_conf[1] &= ~(1 << i);</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> static void lchan_fsm_unused(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span> {</span><br><span>    struct lchan_activate_info *info = data;</span><br><span>     struct gsm_lchan *lchan = lchan_fi_lchan(fi);</span><br><span>        struct gsm_bts *bts = lchan->ts->trx->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm48_multi_rate_conf mr_conf;</span><br><span> </span><br><span>    switch (event) {</span><br><span> </span><br><span>@@ -469,8 +506,12 @@</span><br><span>                   * - TA is still zero, to be determined by RACH. */</span><br><span>          }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           if (info->chan_mode == GSM48_CMODE_SPEECH_AMR)</span><br><span style="color: hsl(0, 100%, 40%);">-                       lchan_mr_config(lchan, &info->for_conn->sccp.msc->amr_conf);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (info->chan_mode == GSM48_CMODE_SPEECH_AMR) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   gsm48_mr_cfg_from_gsm0808_sc_cfg(&mr_conf, info->s15_s0);</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* FIXME: See above. */</span><br><span style="color: hsl(120, 100%, 40%);">+                       lchan_mr_config_mask(&mr_conf);</span><br><span style="color: hsl(120, 100%, 40%);">+                   lchan_mr_config(lchan, &mr_conf);</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span> </span><br><span>                switch (info->chan_mode) {</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c</span><br><span>index 97daa5c..537b851 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_bssap.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_bssap.c</span><br><span>@@ -603,6 +603,7 @@</span><br><span>     uint16_t cic = 0;</span><br><span>    enum gsm48_chan_mode chan_mode = GSM48_CMODE_SIGN;</span><br><span>   bool full_rate = false;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t s15_s0 = 0;</span><br><span>         bool aoip = false;</span><br><span>   struct sockaddr_storage rtp_addr;</span><br><span>    struct gsm0808_channel_type ct;</span><br><span>@@ -706,9 +707,8 @@</span><br><span> </span><br><span>            /* Match codec information from the assignment command against the</span><br><span>            * local preferences of the BSC and BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-              rc = match_codec_pref(&chan_mode, &full_rate, &ct, &conn->codec_list,</span><br><span style="color: hsl(0, 100%, 40%);">-                                      msc->audio_support, msc->audio_length,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    &conn_get_bts(conn)->codec);</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = match_codec_pref(&chan_mode, &full_rate, &s15_s0, &ct, &conn->codec_list,</span><br><span style="color: hsl(120, 100%, 40%);">+                               msc, conn_get_bts(conn));</span><br><span>              if (rc < 0) {</span><br><span>                     LOGP(DMSC, LOGL_ERROR, "No supported audio type found for channel_type ="</span><br><span>                       " { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=[ %s] }\n",</span><br><span>@@ -730,6 +730,7 @@</span><br><span>                    .msc_assigned_cic = cic,</span><br><span>                     .chan_mode = chan_mode,</span><br><span>                      .full_rate = full_rate,</span><br><span style="color: hsl(120, 100%, 40%);">+                       .s15_s0 = s15_s0</span><br><span>             };</span><br><span>           if (aoip) {</span><br><span>                  unsigned int rc = osmo_sockaddr_to_str_and_uint(req.msc_rtp_addr,</span><br><span>diff --git a/tests/codec_pref/codec_pref_test.c b/tests/codec_pref/codec_pref_test.c</span><br><span>index 20e3525..e2876e2 100644</span><br><span>--- a/tests/codec_pref/codec_pref_test.c</span><br><span>+++ b/tests/codec_pref/codec_pref_test.c</span><br><span>@@ -374,6 +374,7 @@</span><br><span>         unsigned int i;</span><br><span>      bool full_rate;</span><br><span>      enum gsm48_chan_mode chan_mode;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t s15_s0;</span><br><span> </span><br><span>         printf("Determining channel mode and rate:\n");</span><br><span> </span><br><span>@@ -398,8 +399,9 @@</span><br><span>  printf("   codec->efr=%u\n", bts->codec.efr);</span><br><span>        printf("   codec->amr=%u\n", bts->codec.amr);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       rc = match_codec_pref(&chan_mode, &full_rate, ct, scl, msc->audio_support, msc->audio_length, &bts->codec);</span><br><span style="color: hsl(0, 100%, 40%);">-        printf(" * result: rc=%i, full_rate=%i, chan_mode=%s\n", rc, full_rate, gsm48_chan_mode_name(chan_mode));</span><br><span style="color: hsl(120, 100%, 40%);">+   rc = match_codec_pref(&chan_mode, &full_rate, &s15_s0, ct, scl, msc, bts);</span><br><span style="color: hsl(120, 100%, 40%);">+        printf(" * result: rc=%i, full_rate=%i, s15_s0=%04x, chan_mode=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+              rc, full_rate, s15_s0, gsm48_chan_mode_name(chan_mode));</span><br><span> </span><br><span>  printf("\n");</span><br><span> </span><br><span>diff --git a/tests/codec_pref/codec_pref_test.ok b/tests/codec_pref/codec_pref_test.ok</span><br><span>index befc497..16d86ba 100644</span><br><span>--- a/tests/codec_pref/codec_pref_test.ok</span><br><span>+++ b/tests/codec_pref/codec_pref_test.ok</span><br><span>@@ -12,7 +12,7 @@</span><br><span>    codec->hr=0</span><br><span>    codec->efr=0</span><br><span>    codec->amr=0</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -26,7 +26,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=0</span><br><span>    codec->amr=0</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=0, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=0, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -40,7 +40,7 @@</span><br><span>    codec->hr=0</span><br><span>    codec->efr=1</span><br><span>    codec->amr=0</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_EFR</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_EFR</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -54,7 +54,7 @@</span><br><span>    codec->hr=0</span><br><span>    codec->efr=0</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_AMR</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=57ff, chan_mode=SPEECH_AMR</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -68,7 +68,7 @@</span><br><span>    codec->hr=0</span><br><span>    codec->efr=0</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=0, chan_mode=SPEECH_AMR</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=0, s15_s0=073f, chan_mode=SPEECH_AMR</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (2 items):</span><br><span>@@ -85,7 +85,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=0</span><br><span>    codec->amr=0</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (3 items):</span><br><span>@@ -105,7 +105,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=0</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (3 items):</span><br><span>@@ -125,7 +125,7 @@</span><br><span>    codec->hr=0</span><br><span>    codec->efr=0</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -151,7 +151,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> ============== test_ms ==============</span><br><span> </span><br><span>@@ -175,7 +175,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -197,7 +197,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=0, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=0, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -219,7 +219,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_EFR</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_EFR</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -241,7 +241,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_AMR</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=57ff, chan_mode=SPEECH_AMR</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -263,7 +263,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=0, chan_mode=SPEECH_AMR</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=0, s15_s0=073f, chan_mode=SPEECH_AMR</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (2 items):</span><br><span>@@ -286,7 +286,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (3 items):</span><br><span>@@ -310,7 +310,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (3 items):</span><br><span>@@ -334,7 +334,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -360,7 +360,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> ============== test_ct ==============</span><br><span> </span><br><span>@@ -384,7 +384,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -406,7 +406,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=0, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=0, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -428,7 +428,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_EFR</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_EFR</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -450,7 +450,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_AMR</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=57ff, chan_mode=SPEECH_AMR</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -472,7 +472,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=0, chan_mode=SPEECH_AMR</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=0, s15_s0=073f, chan_mode=SPEECH_AMR</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -495,7 +495,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -519,7 +519,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -543,7 +543,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -569,7 +569,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> ============== test_msc ==============</span><br><span> </span><br><span>@@ -597,7 +597,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -623,7 +623,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -649,7 +649,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -675,7 +675,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -701,7 +701,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -727,7 +727,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -753,7 +753,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -779,7 +779,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -805,7 +805,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> ============== test_selected_working ==============</span><br><span> </span><br><span>@@ -826,7 +826,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -843,7 +843,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -860,7 +860,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=0, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=0, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (3 items):</span><br><span>@@ -879,7 +879,7 @@</span><br><span>    codec->hr=0</span><br><span>    codec->efr=0</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -896,7 +896,7 @@</span><br><span>    codec->hr=0</span><br><span>    codec->efr=1</span><br><span>    codec->amr=0</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=1, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=1, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -913,7 +913,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=0</span><br><span>    codec->amr=0</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=0, full_rate=0, chan_mode=SPEECH_V1</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=0, full_rate=0, s15_s0=0000, chan_mode=SPEECH_V1</span><br><span> </span><br><span> ============== test_selected_non_working ==============</span><br><span> </span><br><span>@@ -932,7 +932,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=-1, full_rate=0, chan_mode=SIGNALLING</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=-1, full_rate=0, s15_s0=0000, chan_mode=SIGNALLING</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -949,7 +949,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=-1, full_rate=0, chan_mode=SIGNALLING</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=-1, full_rate=0, s15_s0=0000, chan_mode=SIGNALLING</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -965,7 +965,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=-1, full_rate=0, chan_mode=SIGNALLING</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=-1, full_rate=0, s15_s0=0000, chan_mode=SIGNALLING</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -981,7 +981,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=-1, full_rate=0, chan_mode=SIGNALLING</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=-1, full_rate=0, s15_s0=0000, chan_mode=SIGNALLING</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (1 items):</span><br><span>@@ -996,7 +996,7 @@</span><br><span>    codec->hr=1</span><br><span>    codec->efr=1</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=-1, full_rate=0, chan_mode=SIGNALLING</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=-1, full_rate=0, s15_s0=0000, chan_mode=SIGNALLING</span><br><span> </span><br><span> Determining channel mode and rate:</span><br><span>  * MS: speech codec list (5 items):</span><br><span>@@ -1016,7 +1016,7 @@</span><br><span>    codec->hr=0</span><br><span>    codec->efr=0</span><br><span>    codec->amr=1</span><br><span style="color: hsl(0, 100%, 40%);">- * result: rc=-1, full_rate=0, chan_mode=SIGNALLING</span><br><span style="color: hsl(120, 100%, 40%);">+ * result: rc=-1, full_rate=0, s15_s0=0000, chan_mode=SIGNALLING</span><br><span> </span><br><span> ============== test_gen_bss_supp_codec_list_cfgs ==============</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11060">change 11060</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/11060"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I2d8ded51b3eb4c003fe2da6f2d6f48d001b73737 </div>
<div style="display:none"> Gerrit-Change-Number: 11060 </div>
<div style="display:none"> Gerrit-PatchSet: 10 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Assignee: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-CC: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>