diff options
Diffstat (limited to 'openbsc/src/gsm_data.c')
-rw-r--r-- | openbsc/src/gsm_data.c | 151 |
1 files changed, 100 insertions, 51 deletions
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index 80020e509..81facdf04 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -25,6 +25,7 @@ #include <errno.h> #include <openbsc/gsm_data.h> +#include <openbsc/talloc.h> 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) @@ -84,74 +85,122 @@ const char *gsm_chreq_name(enum gsm_chreq_reason_t c) return chreq_names[c]; } -struct gsm_network *gsm_network_init(unsigned int num_bts, enum gsm_bts_type bts_type, - u_int16_t country_code, u_int16_t network_code, - int (*mncc_recv)(struct gsm_network *, int, void *)) +struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts) { - int i; - struct gsm_network *net; + struct gsm_bts_trx *trx = talloc(bts, struct gsm_bts_trx); + int k; - if (num_bts > GSM_MAX_BTS) + if (!trx) return NULL; - net = malloc(sizeof(*net)); + memset(trx, 0, sizeof(*trx)); + trx->bts = bts; + trx->nr = bts->num_trx++; + + for (k = 0; k < TRX_NR_TS; k++) { + struct gsm_bts_trx_ts *ts = &trx->ts[k]; + int l; + + ts->trx = trx; + ts->nr = k; + ts->pchan = GSM_PCHAN_NONE; + + for (l = 0; l < TS_MAX_LCHAN; l++) { + struct gsm_lchan *lchan; + lchan = &ts->lchan[l]; + + lchan->ts = ts; + lchan->nr = l; + lchan->type = GSM_LCHAN_NONE; + } + } + + llist_add(&trx->list, &bts->trx_list); + + return trx; +} + +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(net, struct gsm_bts); + + if (!bts) + return NULL; + + memset(bts, 0, sizeof(*bts)); + bts->network = net; + bts->nr = net->num_bts++; + bts->type = type; + bts->tsc = tsc; + bts->bsic = bsic; + bts->num_trx = 0; + INIT_LLIST_HEAD(&bts->trx_list); + + /* create our primary TRX */ + bts->c0 = gsm_bts_trx_alloc(bts); + if (!bts->c0) { + talloc_free(bts); + return NULL; + } + bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4; + + llist_add(&bts->list, &net->bts_list); + + return bts; +} + +struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_code, + int (*mncc_recv)(struct gsm_network *, int, void *)) +{ + struct gsm_network *net; + + net = talloc(tall_bsc_ctx, struct gsm_network); if (!net) return NULL; memset(net, 0, sizeof(*net)); net->country_code = country_code; net->network_code = network_code; - net->num_bts = num_bts; + net->num_bts = 0; INIT_LLIST_HEAD(&net->trans_list); INIT_LLIST_HEAD(&net->upqueue); + INIT_LLIST_HEAD(&net->bts_list); net->mncc_recv = mncc_recv; - for (i = 0; i < num_bts; i++) { - struct gsm_bts *bts = &net->bts[i]; - int j; - - bts->network = net; - bts->nr = i; - bts->type = bts_type; - bts->tsc = HARDCODED_TSC; - bts->bsic = HARDCODED_BSIC; - - for (j = 0; j < BTS_MAX_TRX; j++) { - struct gsm_bts_trx *trx = &bts->trx[j]; - int k; - - trx->bts = bts; - trx->nr = j; - - for (k = 0; k < TRX_NR_TS; k++) { - struct gsm_bts_trx_ts *ts = &trx->ts[k]; - int l; - - ts->trx = trx; - ts->nr = k; - ts->pchan = GSM_PCHAN_NONE; - - for (l = 0; l < TS_MAX_LCHAN; l++) { - struct gsm_lchan *lchan; - lchan = &ts->lchan[l]; - - lchan->ts = ts; - lchan->nr = l; - lchan->type = GSM_LCHAN_NONE; - } - } - } + return net; +} + +struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num) +{ + struct gsm_bts *bts; + + if (num >= net->num_bts) + return NULL; + + llist_for_each_entry(bts, &net->bts_list, list) { + if (bts->nr == num) + return bts; + } + + return NULL; +} + +struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num) +{ + struct gsm_bts_trx *trx; + + if (num >= bts->num_trx) + return NULL; - bts->num_trx = 1; /* FIXME */ -#ifdef HAVE_TRX1 - bts->num_trx++; -#endif - bts->c0 = &bts->trx[0]; - bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4; + llist_for_each_entry(trx, &bts->trx_list, list) { + if (trx->nr == num) + return trx; } - return net; + + return NULL; } static char ts2str[255]; @@ -201,7 +250,7 @@ struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac, skip = 1; for (i = 0; i < net->num_bts; i++) { - bts = &net->bts[i]; + bts = gsm_bts_num(net, i); if (skip) { if (start_bts == bts) |