<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 = ≻</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>