From f3d8e92731dbdc05ed4214ab9ff2bbb9189f42ad Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 14 Jun 2010 22:44:42 +0200 Subject: [PATCH] [BSC] introduce the concept of 'BTS features' We can then check if a bts supports a certain feature or not. --- openbsc/include/openbsc/gsm_data.h | 13 +++++++++++++ openbsc/src/bsc_vty.c | 16 +++++++++++++++- openbsc/src/bts_ipaccess_nanobts.c | 6 ++++++ openbsc/src/bts_siemens_bs11.c | 6 ++++++ openbsc/src/gsm_data.c | 10 ++++++++++ 5 files changed, 50 insertions(+), 1 deletion(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 107434476..8cb09d2eb 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -402,6 +402,17 @@ struct gsm_bts_model { const char *name; struct tlv_definition nm_att_tlvdef; + + struct bitvec features; + uint8_t _features_data[128/8]; +}; + +enum gsm_bts_features { + BTS_FEAT_HSCSD, + BTS_FEAT_GPRS, + BTS_FEAT_EGPRS, + BTS_FEAT_ECSD, + BTS_FEAT_HOPPING, }; /** @@ -792,6 +803,8 @@ int gsm48_ra_id_by_bts(u_int8_t *buf, struct gsm_bts *bts); void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts); struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan); +int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat); +int gsm_bts_has_feature(struct gsm_bts *bts, enum gsm_bts_features feat); int gsm_bts_model_register(struct gsm_bts_model *model); #endif diff --git a/openbsc/src/bsc_vty.c b/openbsc/src/bsc_vty.c index 5eacb22af..46a13d36a 100644 --- a/openbsc/src/bsc_vty.c +++ b/openbsc/src/bsc_vty.c @@ -1817,8 +1817,22 @@ DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd, "EGPRS (EDGE) Enabled on this BTS\n") { struct gsm_bts *bts = vty->index; + enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0]); - bts->gprs.mode = bts_gprs_mode_parse(argv[0]); + if (mode != BTS_GPRS_NONE && + !gsm_bts_has_feature(bts, BTS_FEAT_GPRS)) { + vty_out(vty, "This BTS type does not support %s%s", argv[0], + VTY_NEWLINE); + return CMD_WARNING; + } + if (mode == BTS_GPRS_EGPRS && + !gsm_bts_has_feature(bts, BTS_FEAT_EGPRS)) { + vty_out(vty, "This BTS type does not support %s%s", argv[0], + VTY_NEWLINE); + return CMD_WARNING; + } + + bts->gprs.mode = mode; return CMD_SUCCESS; } diff --git a/openbsc/src/bts_ipaccess_nanobts.c b/openbsc/src/bts_ipaccess_nanobts.c index cb48ea98a..92ab41a40 100644 --- a/openbsc/src/bts_ipaccess_nanobts.c +++ b/openbsc/src/bts_ipaccess_nanobts.c @@ -80,5 +80,11 @@ static struct gsm_bts_model model_nanobts = { int bts_model_nanobts_init(void) { + model_nanobts.features.data = &model_nanobts._features_data; + model_nanobts.features.data_len = sizeof(model_nanobts._features_data); + + gsm_btsmodel_set_feature(&model_nanobts, BTS_FEAT_GPRS); + gsm_btsmodel_set_feature(&model_nanobts, BTS_FEAT_EGPRS); + return gsm_bts_model_register(&model_nanobts); } diff --git a/openbsc/src/bts_siemens_bs11.c b/openbsc/src/bts_siemens_bs11.c index c966825ee..3d4dddaae 100644 --- a/openbsc/src/bts_siemens_bs11.c +++ b/openbsc/src/bts_siemens_bs11.c @@ -62,5 +62,11 @@ static struct gsm_bts_model model_bs11 = { int bts_model_bs11_init(void) { + model_bs11.features.data = &model_bs11._features_data; + model_bs11.features.data_len = sizeof(model_bs11._features_data); + + gsm_btsmodel_set_feature(&model_bs11, BTS_FEAT_HOPPING); + gsm_btsmodel_set_feature(&model_bs11, BTS_FEAT_HSCSD); + return gsm_bts_model_register(&model_bs11); } diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index ede1c003d..bbf150a40 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -519,6 +519,16 @@ struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan) return meas_rep; } +int gsm_btsmodel_set_feature(struct gsm_bts_model *bts, enum gsm_bts_features feat) +{ + return bitvec_set_bit_pos(&bts->features, feat, 1); +} + +int gsm_bts_has_feature(struct gsm_bts *bts, enum gsm_bts_features feat) +{ + return bitvec_get_bit_pos(&bts->model->features, feat); +} + int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type) { struct gsm_bts_model *model;