diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-03-22 03:25:11 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-03-24 06:16:04 +0100 |
commit | 22481bf76d129d3c41d20b96b6587ef085be485b (patch) | |
tree | 8c8de852e945dd5422a83bc7e0c37548d2911fe2 /openbsc/src/gsm_data.c | |
parent | b973955295b720b8ba7c556d0165750ed9bfb381 (diff) | |
parent | 61b4232c6363ff9d78ef73b9dbf47ec16c94d610 (diff) |
Merge remote branch 'origin/master' into on-waves/bsc-master
* Move to libosmocore
* Move to new debugging architecture
* Register the BTS types
* Has only been compile tested
Conflicts:
openbsc/include/openbsc/Makefile.am
openbsc/include/openbsc/gsm_data.h
openbsc/include/openbsc/ipaccess.h
openbsc/include/openbsc/mgcp.h
openbsc/include/openbsc/msgb.h
openbsc/include/openbsc/tlv.h
openbsc/src/Makefile.am
openbsc/src/abis_rsl.c
openbsc/src/bsc_init.c
openbsc/src/bsc_mgcp.c
openbsc/src/chan_alloc.c
openbsc/src/debug.c
openbsc/src/gsm_subscriber_base.c
openbsc/src/msgb.c
openbsc/src/rest_octets.c
openbsc/src/sccp/sccp.c
openbsc/src/vty/command.c
openbsc/src/vty_interface.c
openbsc/tests/Makefile.am
Diffstat (limited to 'openbsc/src/gsm_data.c')
-rw-r--r-- | openbsc/src/gsm_data.c | 195 |
1 files changed, 139 insertions, 56 deletions
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index 8330b5190..bd331911e 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -1,4 +1,4 @@ -/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org> +/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org> * * All Rights Reserved * @@ -26,23 +26,14 @@ #include <ctype.h> #include <openbsc/gsm_data.h> -#include <openbsc/talloc.h> +#include <osmocore/talloc.h> +#include <osmocore/gsm_utils.h> #include <openbsc/abis_nm.h> +#include <osmocore/statistics.h> void *tall_bsc_ctx; -const char *get_value_string(const struct value_string *vs, u_int32_t val) -{ - int i; - - for (i = 0;; i++) { - if (vs[i].value == 0 && vs[i].str == NULL) - break; - if (vs[i].value == val) - return vs[i].str; - } - return "unknown"; -} +static LLIST_HEAD(bts_models); void set_ts_e1link(struct gsm_bts_trx_ts *ts, u_int8_t e1_nr, u_int8_t e1_ts, u_int8_t e1_ts_ss) @@ -92,7 +83,7 @@ static const char *lchan_names[] = { [GSM_LCHAN_UNKNOWN] = "UNKNOWN", }; -const char *gsm_lchan_name(enum gsm_chan_t c) +const char *gsm_lchant_name(enum gsm_chan_t c) { if (c >= ARRAY_SIZE(lchan_names)) return "INVALID"; @@ -100,6 +91,20 @@ const char *gsm_lchan_name(enum gsm_chan_t c) return lchan_names[c]; } +static const struct value_string lchan_s_names[] = { + { LCHAN_S_NONE, "NONE" }, + { LCHAN_S_ACT_REQ, "ACTIVATION REQUESTED" }, + { LCHAN_S_ACTIVE, "ACTIVE" }, + { LCHAN_S_INACTIVE, "INACTIVE" }, + { LCHAN_S_REL_REQ, "RELEASE REQUESTED" }, + { 0, NULL }, +}; + +const char *gsm_lchans_name(enum gsm_lchan_state s) +{ + return get_value_string(lchan_s_names, s); +} + static const char *chreq_names[] = { [GSM_CHREQ_REASON_EMERG] = "EMERGENCY", [GSM_CHREQ_REASON_PAG] = "PAGING", @@ -116,6 +121,29 @@ const char *gsm_chreq_name(enum gsm_chreq_reason_t c) return chreq_names[c]; } +static struct gsm_bts_model *bts_model_find(enum gsm_bts_type type) +{ + struct gsm_bts_model *model; + + llist_for_each_entry(model, &bts_models, list) { + if (model->type == type) + return model; + } + + return NULL; +} + +int gsm_bts_model_register(struct gsm_bts_model *model) +{ + if (bts_model_find(model->type)) + return -EEXIST; + + tlv_def_patch(&model->nm_att_tlvdef, &nm_att_tlvdef); + llist_add_tail(&model->list, &bts_models); + return 0; +} + + struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts) { struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx); @@ -126,6 +154,7 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts) trx->bts = bts; trx->nr = bts->num_trx++; + trx->nm_state.administrative = NM_STATE_UNLOCKED; for (k = 0; k < TRX_NR_TS; k++) { struct gsm_bts_trx_ts *ts = &trx->ts[k]; @@ -145,6 +174,9 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts) } } + if (trx->nr != 0) + trx->nominal_power = bts->c0->nominal_power; + llist_add_tail(&trx->list, &bts->trx_list); return trx; @@ -154,14 +186,21 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type, u_int8_t tsc, u_int8_t bsic) { struct gsm_bts *bts = talloc_zero(net, struct gsm_bts); + struct gsm_bts_model *model = bts_model_find(type); int i; if (!bts) return NULL; + if (!model && type != GSM_BTS_TYPE_UNKNOWN) { + talloc_free(bts); + return NULL; + } + bts->network = net; bts->nr = net->num_bts++; bts->type = type; + bts->model = model; bts->tsc = tsc; bts->bsic = bsic; bts->num_trx = 0; @@ -175,6 +214,10 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type, bts->si_common.cell_alloc.data = bts->si_common.data.cell_alloc; bts->si_common.cell_alloc.data_len = sizeof(bts->si_common.data.cell_alloc); + bts->si_common.rach_control.re = 1; /* no re-establishment */ + bts->si_common.rach_control.tx_integer = 9; /* 12 slots spread - 217/115 slots delay */ + bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */ + bts->si_common.rach_control.t2 = 4; /* no emergency calls */ for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) { bts->gprs.nsvc[i].bts = bts; @@ -206,6 +249,7 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c net->country_code = country_code; net->network_code = network_code; net->num_bts = 0; + net->reject_cause = GSM48_REJECT_ROAMING_NOT_ALLOWED; net->T3101 = GSM_T3101_DEFAULT; net->T3113 = GSM_T3113_DEFAULT; /* FIXME: initialize all other timers! */ @@ -222,6 +266,32 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c INIT_LLIST_HEAD(&net->upqueue); INIT_LLIST_HEAD(&net->bts_list); + net->stats.chreq.total = counter_alloc("net.chreq.total"); + net->stats.chreq.no_channel = counter_alloc("net.chreq.no_channel"); + net->stats.handover.attempted = counter_alloc("net.handover.attempted"); + net->stats.handover.no_channel = counter_alloc("net.handover.no_channel"); + net->stats.handover.timeout = counter_alloc("net.handover.timeout"); + net->stats.handover.completed = counter_alloc("net.handover.completed"); + net->stats.handover.failed = counter_alloc("net.handover.failed"); + net->stats.loc_upd_type.attach = counter_alloc("net.loc_upd_type.attach"); + net->stats.loc_upd_type.normal = counter_alloc("net.loc_upd_type.normal"); + net->stats.loc_upd_type.periodic = counter_alloc("net.loc_upd_type.periodic"); + net->stats.loc_upd_type.detach = counter_alloc("net.imsi_detach.count"); + net->stats.loc_upd_resp.reject = counter_alloc("net.loc_upd_resp.reject"); + net->stats.loc_upd_resp.accept = counter_alloc("net.loc_upd_resp.accept"); + net->stats.paging.attempted = counter_alloc("net.paging.attempted"); + net->stats.paging.detached = counter_alloc("net.paging.detached"); + net->stats.paging.completed = counter_alloc("net.paging.completed"); + net->stats.paging.expired = counter_alloc("net.paging.expired"); + net->stats.sms.submitted = counter_alloc("net.sms.submitted"); + net->stats.sms.no_receiver = counter_alloc("net.sms.no_receiver"); + net->stats.sms.delivered = counter_alloc("net.sms.delivered"); + net->stats.sms.rp_err_mem = counter_alloc("net.sms.rp_err_mem"); + net->stats.sms.rp_err_other = counter_alloc("net.sms.rp_err_other"); + net->stats.call.dialled = counter_alloc("net.call.dialled"); + net->stats.call.alerted = counter_alloc("net.call.alerted"); + net->stats.call.connected = counter_alloc("net.call.connected"); + net->mncc_recv = mncc_recv; net->core_country_code = -1; @@ -282,6 +352,15 @@ struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num) static char ts2str[255]; +char *gsm_trx_name(struct gsm_bts_trx *trx) +{ + snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d)", + trx->bts->nr, trx->nr); + + return ts2str; +} + + char *gsm_ts_name(struct gsm_bts_trx_ts *ts) { snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d)", @@ -290,6 +369,16 @@ char *gsm_ts_name(struct gsm_bts_trx_ts *ts) return ts2str; } +char *gsm_lchan_name(struct gsm_lchan *lchan) +{ + struct gsm_bts_trx_ts *ts = lchan->ts; + + snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d,ss=%d)", + ts->trx->bts->nr, ts->trx->nr, ts->nr, lchan->nr); + + return ts2str; +} + static const char *bts_types[] = { [GSM_BTS_TYPE_UNKNOWN] = "unknown", [GSM_BTS_TYPE_BS11] = "bs11", @@ -313,6 +402,17 @@ const char *btstype2str(enum gsm_bts_type type) return bts_types[type]; } +struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr) +{ + struct gsm_bts_trx *trx; + + llist_for_each_entry(trx, &bts->trx_list, list) { + if (trx->nr == nr) + return trx; + } + return NULL; +} + /* Search for a BTS in the given Location Area; optionally start searching * with start_bts (for continuing to search after the first result) */ struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac, @@ -340,47 +440,6 @@ struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac, return NULL; } -char *gsm_band_name(enum gsm_band band) -{ - switch (band) { - case GSM_BAND_400: - return "GSM400"; - case GSM_BAND_850: - return "GSM850"; - case GSM_BAND_900: - return "GSM900"; - case GSM_BAND_1800: - return "DCS1800"; - case GSM_BAND_1900: - return "PCS1900"; - } - return "invalid"; -} - -enum gsm_band gsm_band_parse(const char* mhz) -{ - while (*mhz && !isdigit(*mhz)) - mhz++; - - if (*mhz == '\0') - return -EINVAL; - - switch (atoi(mhz)) { - case 400: - return GSM_BAND_400; - case 850: - return GSM_BAND_850; - case 900: - return GSM_BAND_900; - case 1800: - return GSM_BAND_1800; - case 1900: - return GSM_BAND_1900; - default: - return -EINVAL; - } -} - static const char *gsm_auth_policy_names[] = { [GSM_AUTH_POLICY_CLOSED] = "closed", [GSM_AUTH_POLICY_ACCEPT_ALL] = "accept-all", @@ -440,3 +499,27 @@ struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan) return meas_rep; } + +int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type) +{ + struct gsm_bts_model *model; + + model = bts_model_find(type); + if (!model) + return -EINVAL; + + bts->type = type; + bts->model = model; + + switch (bts->type) { + case GSM_BTS_TYPE_NANOBTS: + /* Set the default OML Stream ID to 0xff */ + bts->oml_tei = 0xff; + bts->c0->nominal_power = 23; + break; + case GSM_BTS_TYPE_BS11: + break; + } + + return 0; +} |