aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc/codec_pref.c
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2019-01-22 11:29:06 +0100
committerPhilipp Maier <pmaier@sysmocom.de>2019-02-21 10:17:37 +0100
commitbb66d1095bdbe2c8eceaa9ea32d3c64cdfc835a9 (patch)
treec0c09f5b4e2a77ee5033cefb8526038a69e61a73 /src/osmo-bsc/codec_pref.c
parentfad4bbc517ef2a55988f0fd7874d98dbc5303b14 (diff)
assignment_fsm: fix channel allocator preferences
When the MSC allocates a channel through the ASSIGNMENT REQUEST, it may ask for a TCH/H and a TCH/F at the same time and tell which of the two types it prefers. The process of channel allocation currently selects, based on the BTS, MSC and MS capabilites exactly one apropriate codec/rate (e.g. TCH/H) and then tries to allocate it. If that allocation fails, there is no way to try the second choice and the assignment fails. For example: The MSC asks for TCH/F and TCH/H, prefering TCH/F, then the channel allocator will try TCH/F and if it fails (all TCH/F are currently in use), then TCH/H is never tried. Since the BSC currently only trys the first best codec/rate that is supported it also ignores the preference. Lets fix those problems by including the preference information and both possible codec/rate settings into the channel allocation decision. Change-Id: I5239e05c1cfbcb8af28f43373a58fa6c2d216c51 Related: OS#3503
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;
}