aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc/gsm_04_08.c
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-12-07 18:32:28 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-01-14 17:37:02 +0100
commita83d511b618c1e18b324e04db433a2fd111b2d6f (patch)
tree4870eaf8238a807b595756842b0c3bf9e2648c38 /openbsc/src/libmsc/gsm_04_08.c
parent7d8fa3418ff6c589eba10e562da8b96995e19f7a (diff)
Each BTS can be configured for speech support (other than GSM full rate)
Speech codings which are not supported by BTS will be removed from the bearer capability information element after parsing. This way it is not required for the MNCC application to consider support of each BTS. Only GSM full rate is supported by default.
Diffstat (limited to 'openbsc/src/libmsc/gsm_04_08.c')
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 9063f9815..54f5f7072 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -79,6 +79,29 @@ struct gsm_lai {
uint16_t lac;
};
+static int apply_codec_restrictions(struct gsm_bts *bts,
+ struct gsm_mncc_bearer_cap *bcap)
+{
+ int i, j;
+
+ /* remove unsupported speech versions from list */
+ for (i = 0, j = 0; bcap->speech_ver[i] >= 0; i++) {
+ if (bcap->speech_ver[i] == GSM48_BCAP_SV_FR)
+ bcap->speech_ver[j++] = GSM48_BCAP_SV_FR;
+ if (bcap->speech_ver[i] == GSM48_BCAP_SV_EFR && bts->codec.efr)
+ bcap->speech_ver[j++] = GSM48_BCAP_SV_EFR;
+ if (bcap->speech_ver[i] == GSM48_BCAP_SV_AMR_F && bts->codec.amr)
+ bcap->speech_ver[j++] = GSM48_BCAP_SV_AMR_F;
+ if (bcap->speech_ver[i] == GSM48_BCAP_SV_HR && bts->codec.hr)
+ bcap->speech_ver[j++] = GSM48_BCAP_SV_HR;
+ if (bcap->speech_ver[i] == GSM48_BCAP_SV_AMR_H && bts->codec.amr)
+ bcap->speech_ver[j++] = GSM48_BCAP_SV_AMR_H;
+ }
+ bcap->speech_ver[j] = -1;
+
+ return 0;
+}
+
static uint32_t new_callref = 0x80000001;
void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg)
@@ -1799,6 +1822,7 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
setup.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&setup.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ apply_codec_restrictions(trans->conn->bts, &setup.bearer_cap);
}
/* facility */
if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
@@ -1952,6 +1976,7 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
call_conf.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&call_conf.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ apply_codec_restrictions(trans->conn->bts, &call_conf.bearer_cap);
}
/* cause */
if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
@@ -2640,6 +2665,7 @@ static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
modify.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY);
@@ -2682,6 +2708,7 @@ static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg
modify.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
new_cc_state(trans, GSM_CSTATE_ACTIVE);
@@ -2722,6 +2749,7 @@ static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
modify.fields |= GSM48_IE_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
/* cause */
if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {