aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-03-10 09:45:26 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2013-07-29 12:34:23 +0200
commit762a6237f121976c83a714be3036f3e92a5d3b4b (patch)
tree2af435f23a75927bbbc305c530c438b84e2dab4c
parentceee3634d2450772c6c65bc29a4f96d5dfcbcdad (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.
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h10
-rw-r--r--openbsc/src/libbsc/bsc_vty.c179
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c28
3 files changed, 217 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 3ef145765..ded00307a 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -142,6 +142,13 @@ struct bts_ul_meas {
uint8_t inv_rssi;
};
+struct bts_codec_conf {
+ uint8_t hr;
+ uint8_t efr;
+ uint8_t afs;
+ uint8_t ahs;
+};
+
struct amr_mode {
uint8_t mode;
uint8_t threshold;
@@ -703,6 +710,9 @@ struct gsm_bts {
/* exclude the BTS from the global RF Lock handling */
int excl_from_rf_lock;
+
+ /* supported codecs beside FR */
+ struct bts_codec_conf codec;
#endif /* ROLE_BSC */
void *role;
};
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 45df90f5f..75e95cbde 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -593,6 +593,17 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
}
}
+ vty_out(vty, " codec-support fr");
+ if (bts->codec.hr)
+ vty_out(vty, " hr");
+ if (bts->codec.efr)
+ vty_out(vty, " efr");
+ if (bts->codec.afs)
+ vty_out(vty, " afs");
+ if (bts->codec.ahs)
+ vty_out(vty, " ahs");
+ vty_out(vty, "%s", VTY_NEWLINE);
+
config_write_bts_gprs(vty, bts);
if (bts->excl_from_rf_lock)
@@ -2502,6 +2513,169 @@ DEFUN(cfg_bts_no_excl_rf_lock,
return CMD_SUCCESS;
}
+DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
+ "codec-support (fr|hr|efr|afs|ahs)",
+ "Codec Support settings\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n")
+{
+ struct gsm_bts *bts = vty->index;
+ struct bts_codec_conf *codec = &bts->codec;
+ int i;
+
+ codec->hr = 0;
+ codec->efr = 0;
+ codec->afs = 0;
+ codec->ahs = 0;
+ for (i = 0; i < 1; i++) {
+ if (!strcmp(argv[i], "hr"))
+ codec->hr = 1;
+ if (!strcmp(argv[i], "efr"))
+ codec->efr = 1;
+ if (!strcmp(argv[i], "afs"))
+ codec->afs = 1;
+ if (!strcmp(argv[i], "ahs"))
+ codec->ahs = 1;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
+ "codec-support (fr|hr|efr|afs|ahs) (fr|hr|efr|afs|ahs)",
+ "Codec Support settings\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n")
+{
+ struct gsm_bts *bts = vty->index;
+ struct bts_codec_conf *codec = &bts->codec;
+ int i;
+
+ codec->hr = 0;
+ codec->efr = 0;
+ codec->afs = 0;
+ codec->ahs = 0;
+ for (i = 0; i < 2; i++) {
+ if (!strcmp(argv[i], "hr"))
+ codec->hr = 1;
+ if (!strcmp(argv[i], "efr"))
+ codec->efr = 1;
+ if (!strcmp(argv[i], "afs"))
+ codec->afs = 1;
+ if (!strcmp(argv[i], "ahs"))
+ codec->ahs = 1;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
+ "codec-support (fr|hr|efr|afs|ahs) (fr|hr|efr|afs|ahs)"
+ " (fr|hr|efr|afs|ahs)",
+ "Codec Support settings\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n")
+{
+ struct gsm_bts *bts = vty->index;
+ struct bts_codec_conf *codec = &bts->codec;
+ int i;
+
+ codec->hr = 0;
+ codec->efr = 0;
+ codec->afs = 0;
+ codec->ahs = 0;
+ for (i = 0; i < 3; i++) {
+ if (!strcmp(argv[i], "hr"))
+ codec->hr = 1;
+ if (!strcmp(argv[i], "efr"))
+ codec->efr = 1;
+ if (!strcmp(argv[i], "afs"))
+ codec->afs = 1;
+ if (!strcmp(argv[i], "ahs"))
+ codec->ahs = 1;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
+ "codec-support (fr|hr|efr|afs|ahs) (fr|hr|efr|afs|ahs)"
+ " (fr|hr|efr|afs|ahs) (fr|hr|efr|afs|ahs)",
+ "Codec Support settings\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n")
+{
+ struct gsm_bts *bts = vty->index;
+ struct bts_codec_conf *codec = &bts->codec;
+ int i;
+
+ codec->hr = 0;
+ codec->efr = 0;
+ codec->afs = 0;
+ codec->ahs = 0;
+ for (i = 0; i < 4; i++) {
+ if (!strcmp(argv[i], "hr"))
+ codec->hr = 1;
+ if (!strcmp(argv[i], "efr"))
+ codec->efr = 1;
+ if (!strcmp(argv[i], "afs"))
+ codec->afs = 1;
+ if (!strcmp(argv[i], "ahs"))
+ codec->ahs = 1;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_codec5, cfg_bts_codec5_cmd,
+ "codec-support (fr|hr|efr|afs|ahs) (fr|hr|efr|afs|ahs)"
+ " (fr|hr|efr|afs|ahs) (fr|hr|efr|afs|ahs) (fr|hr|efr|afs|ahs)",
+ "Codec Support settings\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n"
+ "Full Rate (mandatory)\nHalf Rate\nEnhanced Full Rate\n"
+ "Adaptive Multirate on TCH/F\nAdaptive Multirate on TCH/H\n")
+{
+ struct gsm_bts *bts = vty->index;
+ struct bts_codec_conf *codec = &bts->codec;
+ int i;
+
+ codec->hr = 0;
+ codec->efr = 0;
+ codec->afs = 0;
+ codec->ahs = 0;
+ for (i = 0; i < 5; i++) {
+ if (!strcmp(argv[i], "hr"))
+ codec->hr = 1;
+ if (!strcmp(argv[i], "efr"))
+ codec->efr = 1;
+ if (!strcmp(argv[i], "afs"))
+ codec->afs = 1;
+ if (!strcmp(argv[i], "ahs"))
+ codec->ahs = 1;
+ }
+
+ return CMD_SUCCESS;
+}
+
#define TRX_TEXT "Radio Transceiver\n"
/* per TRX configuration */
@@ -3099,6 +3273,11 @@ int bsc_vty_init(const struct log_info *cat)
install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
+ install_element(BTS_NODE, &cfg_bts_codec1_cmd);
+ install_element(BTS_NODE, &cfg_bts_codec2_cmd);
+ install_element(BTS_NODE, &cfg_bts_codec3_cmd);
+ install_element(BTS_NODE, &cfg_bts_codec4_cmd);
+ install_element(BTS_NODE, &cfg_bts_codec5_cmd);
install_element(BTS_NODE, &cfg_trx_cmd);
install_node(&trx_node, dummy_config_write);
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 0767c722f..45d132e1b 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] == 0)
+ bcap->speech_ver[j++] = 0;
+ if (bcap->speech_ver[i] == 2 && bts->codec.efr)
+ bcap->speech_ver[j++] = 2;
+ if (bcap->speech_ver[i] == 4 && bts->codec.afs)
+ bcap->speech_ver[j++] = 4;
+ if (bcap->speech_ver[i] == 1 && bts->codec.hr)
+ bcap->speech_ver[j++] = 1;
+ if (bcap->speech_ver[i] == 5 && bts->codec.ahs)
+ bcap->speech_ver[j++] = 5;
+ }
+ 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)
@@ -1914,6 +1937,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)) {
@@ -2067,6 +2091,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)) {
@@ -2755,6 +2780,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);
@@ -2797,6 +2823,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);
@@ -2837,6 +2864,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)) {