aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc/codec_pref.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bsc/codec_pref.c')
-rw-r--r--src/osmo-bsc/codec_pref.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/src/osmo-bsc/codec_pref.c b/src/osmo-bsc/codec_pref.c
index c99c38335..a94d6a834 100644
--- a/src/osmo-bsc/codec_pref.c
+++ b/src/osmo-bsc/codec_pref.c
@@ -266,21 +266,18 @@ static uint16_t gen_bss_supported_amr_s15_s0(const struct bsc_msc_data *msc, con
/*! Match the codec preferences from local config with a received codec preferences IEs received from the
* MSC and the BTS' codec configuration.
- * \param[out] chan_mode GSM 04.08 channel mode.
- * \param[out] full_rate true if full-rate.
- * \param[out] s15_s0 codec configuration bits S15-S0 (AMR)
+ * \param[out] ch_mode_rate resulting codec and rate information
* \param[in] ct GSM 08.08 channel type received from MSC.
* \param[in] scl GSM 08.08 speech codec list received from MSC (optional).
* \param[in] msc associated msc (current codec settings).
* \param[in] bts associated bts (current codec settings).
+ * \param[in] pref selected rate preference (full, half or none).
* \returns 0 on success, -1 in case no match was found */
-int match_codec_pref(enum gsm48_chan_mode *chan_mode,
- bool *full_rate,
- uint16_t *s15_s0,
+int match_codec_pref(struct channel_mode_and_rate *ch_mode_rate,
const struct gsm0808_channel_type *ct,
const struct gsm0808_speech_codec_list *scl,
const struct bsc_msc_data *msc,
- const struct gsm_bts *bts)
+ const struct gsm_bts *bts, enum rate_pref rate_pref)
{
unsigned int i;
uint8_t perm_spch;
@@ -297,6 +294,18 @@ int match_codec_pref(enum gsm48_chan_mode *chan_mode,
/* Pick a permitted speech value from the global codec configuration list */
perm_spch = audio_support_to_gsm88(msc->audio_support[i]);
+ /* Determine if the result is a half or full rate codec */
+ rc = full_rate_from_perm_spch(&ch_mode_rate->full_rate, perm_spch);
+ if (rc < 0)
+ return -EINVAL;
+
+ /* If we have a preference for FR or HR in our request, we
+ * discard the potential match */
+ if (rate_pref == RATE_PREF_HR && ch_mode_rate->full_rate)
+ continue;
+ if (rate_pref == RATE_PREF_FR && !ch_mode_rate->full_rate)
+ continue;
+
/* Check this permitted speech value against the BTS specific parameters.
* if the BTS does not support the codec, try the next one */
if (!test_codec_support_bts(bts, perm_spch))
@@ -312,19 +321,14 @@ int match_codec_pref(enum gsm48_chan_mode *chan_mode,
/* Exit without result, in case no match can be deteched */
if (!match) {
- *full_rate = false;
- *chan_mode = GSM48_CMODE_SIGN;
- *s15_s0 = 0;
+ ch_mode_rate->full_rate = false;
+ ch_mode_rate->chan_mode = GSM48_CMODE_SIGN;
+ ch_mode_rate->s15_s0 = 0;
return -1;
}
- /* Determine if the result is a half or full rate codec */
- rc = full_rate_from_perm_spch(full_rate, perm_spch);
- if (rc < 0)
- return -EINVAL;
-
/* Lookup a channel mode for the selected codec */
- *chan_mode = gsm88_to_chan_mode(perm_spch);
+ ch_mode_rate->chan_mode = gsm88_to_chan_mode(perm_spch);
/* Special handling for AMR */
if (perm_spch == GSM0808_PERM_HR3 || perm_spch == GSM0808_PERM_FR3) {
@@ -337,9 +341,9 @@ int match_codec_pref(enum gsm48_chan_mode *chan_mode,
* result */
amr_s15_s0_supported = gen_bss_supported_amr_s15_s0(msc, bts, (perm_spch == GSM0808_PERM_HR3));
if (sc_match)
- *s15_s0 = sc_match->cfg & amr_s15_s0_supported;
+ ch_mode_rate->s15_s0 = sc_match->cfg & amr_s15_s0_supported;
else
- *s15_s0 = amr_s15_s0_supported;
+ ch_mode_rate->s15_s0 = amr_s15_s0_supported;
/* NOTE: The function test_codec_pref() will populate the
* sc_match pointer from the searched speech codec list. For
@@ -349,7 +353,7 @@ int match_codec_pref(enum gsm48_chan_mode *chan_mode,
* However s15_s0 is always populated with a meaningful value,
* regardless if AoIP is in use or not. */
} else
- *s15_s0 = 0;
+ ch_mode_rate->s15_s0 = 0;
return 0;
}