From e441d9c36174037f50245a0dc47c4ec41b3b5421 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 21 Jun 2009 16:17:15 +0200 Subject: switch to dynamically allocated BTS and TRX data structures This makes it much easier to do run-time configuration using the vty interface. --- openbsc/include/openbsc/gsm_data.h | 22 ++++-- openbsc/src/abis_nm.c | 16 ++-- openbsc/src/bs11_config.c | 21 ++++-- openbsc/src/bsc_hack.c | 23 +++--- openbsc/src/chan_alloc.c | 13 ++-- openbsc/src/gsm_04_08.c | 4 +- openbsc/src/gsm_data.c | 151 ++++++++++++++++++++++++------------- openbsc/src/input/ipaccess.c | 4 +- openbsc/src/ipaccess-config.c | 5 +- openbsc/src/vty_interface.c | 73 ++++++++++-------- 10 files changed, 204 insertions(+), 128 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index f300d31bb..9b4cf9df3 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -46,8 +46,6 @@ enum gsm_chreq_reason_t { #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#define GSM_MAX_BTS 8 -#define BTS_MAX_TRX 8 #define TRX_NR_TS 8 #define TS_MAX_LCHAN 8 @@ -216,6 +214,9 @@ struct gsm_bts_trx_ts { /* One TRX in a BTS */ struct gsm_bts_trx { + /* list header in bts->trx_list */ + struct llist_head list; + struct gsm_bts *bts; /* number of this TRX in the BTS */ u_int8_t nr; @@ -297,6 +298,9 @@ struct gsm_envabtse { /* One BTS */ struct gsm_bts { + /* list header in net->bts_list */ + struct llist_head list; + struct gsm_network *network; /* number of ths BTS in network */ u_int8_t nr; @@ -351,7 +355,7 @@ struct gsm_bts { /* transceivers */ int num_trx; - struct gsm_bts_trx trx[BTS_MAX_TRX+1]; + struct llist_head trx_list; }; struct gsm_network { @@ -367,8 +371,7 @@ struct gsm_network { struct llist_head trans_list; unsigned int num_bts; - /* private lists */ - struct gsm_bts bts[GSM_MAX_BTS+1]; + struct llist_head bts_list; }; #define SMS_HDR_SIZE 128 @@ -382,9 +385,14 @@ struct gsm_sms { char text[SMS_TEXT_SIZE]; }; -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, +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_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type, + u_int8_t tsc, u_int8_t bsic); +struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts); + +struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num); +struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num); const char *gsm_pchan_name(enum gsm_phys_chan_config c); const char *gsm_lchan_name(enum gsm_chan_t c); diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c index bd3ba19e1..5040541e0 100644 --- a/openbsc/src/abis_nm.c +++ b/openbsc/src/abis_nm.c @@ -544,19 +544,19 @@ objclass2nmstate(struct gsm_bts *bts, u_int8_t obj_class, case NM_OC_RADIO_CARRIER: if (obj_inst->trx_nr >= bts->num_trx) return NULL; - trx = &bts->trx[obj_inst->trx_nr]; + trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); nm_state = &trx->nm_state; break; case NM_OC_BASEB_TRANSC: if (obj_inst->trx_nr >= bts->num_trx) return NULL; - trx = &bts->trx[obj_inst->trx_nr]; + trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); nm_state = &trx->bb_transc.nm_state; break; case NM_OC_CHANNEL: if (obj_inst->trx_nr > bts->num_trx) return NULL; - trx = &bts->trx[obj_inst->trx_nr]; + trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); if (obj_inst->ts_nr >= TRX_NR_TS) return NULL; nm_state = &trx->ts[obj_inst->ts_nr].nm_state; @@ -572,13 +572,13 @@ objclass2nmstate(struct gsm_bts *bts, u_int8_t obj_class, case BS11_OBJ_BBSIG: if (obj_inst->ts_nr > bts->num_trx) return NULL; - trx = &bts->trx[obj_inst->ts_nr]; + trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); nm_state = &trx->bs11.bbsig.nm_state; break; case BS11_OBJ_PA: if (obj_inst->ts_nr > bts->num_trx) return NULL; - trx = &bts->trx[obj_inst->ts_nr]; + trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); nm_state = &trx->bs11.pa.nm_state; break; default: @@ -611,19 +611,19 @@ objclass2obj(struct gsm_bts *bts, u_int8_t obj_class, case NM_OC_RADIO_CARRIER: if (obj_inst->trx_nr >= bts->num_trx) return NULL; - trx = &bts->trx[obj_inst->trx_nr]; + trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); obj = trx; break; case NM_OC_BASEB_TRANSC: if (obj_inst->trx_nr >= bts->num_trx) return NULL; - trx = &bts->trx[obj_inst->trx_nr]; + trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); obj = &trx->bb_transc; break; case NM_OC_CHANNEL: if (obj_inst->trx_nr > bts->num_trx) return NULL; - trx = &bts->trx[obj_inst->trx_nr]; + trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); if (obj_inst->ts_nr >= TRX_NR_TS) return NULL; obj = &trx->ts[obj_inst->ts_nr]; diff --git a/openbsc/src/bs11_config.c b/openbsc/src/bs11_config.c index 386b865ca..0fb7cd7a6 100644 --- a/openbsc/src/bs11_config.c +++ b/openbsc/src/bs11_config.c @@ -94,7 +94,7 @@ static int create_objects(struct gsm_bts *bts) abis_nm_bs11_conn_oml_tei(bts, 0, 1, 0xff, TEI_OML); - abis_nm_bs11_set_trx_power(&bts->trx[0], BS11_TRX_POWER_GSM_30mW); + abis_nm_bs11_set_trx_power(bts->c0, BS11_TRX_POWER_GSM_30mW); sleep(1); @@ -109,6 +109,10 @@ static int create_trx1(struct gsm_bts *bts) { u_int8_t bbsig1_attr[sizeof(obj_bbsig0_attr)+12]; u_int8_t *cur = bbsig1_attr; + struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, 1); + + if (!trx) + trx = gsm_bts_trx_alloc(bts); fprintf(stdout, "Crating Objects for TRX1\n"); @@ -123,7 +127,7 @@ static int create_trx1(struct gsm_bts *bts) sizeof(bbsig1_attr), bbsig1_attr); abis_nm_bs11_create_object(bts, BS11_OBJ_PA, 1, sizeof(obj_pa0_attr), obj_pa0_attr); - abis_nm_bs11_set_trx_power(&bts->trx[1], BS11_TRX_POWER_GSM_30mW); + abis_nm_bs11_set_trx_power(trx, BS11_TRX_POWER_GSM_30mW); return 0; } @@ -437,13 +441,17 @@ static int print_attr(struct tlv_parsed *tp) static void cmd_query(void) { + struct gsm_bts_trx *trx = g_bts->c0; + bs11cfg_state = STATE_QUERY; abis_nm_bs11_get_serno(g_bts); abis_nm_bs11_get_oml_tei_ts(g_bts); abis_nm_bs11_get_pll_mode(g_bts); abis_nm_bs11_get_cclk(g_bts); - abis_nm_bs11_get_trx_power(&g_bts->trx[0]); - abis_nm_bs11_get_trx_power(&g_bts->trx[1]); + abis_nm_bs11_get_trx_power(trx); + trx = gsm_bts_trx_num(g_bts, 1); + if (trx) + abis_nm_bs11_get_trx_power(trx); sleep(1); abis_nm_bs11_factory_logon(g_bts, 0); command = NULL; @@ -775,12 +783,13 @@ int main(int argc, char **argv) handle_options(argc, argv); - gsmnet = gsm_network_init(1, 1, 1, GSM_BTS_TYPE_BS11, NULL); + gsmnet = gsm_network_init(1, 1, NULL); if (!gsmnet) { fprintf(stderr, "Unable to allocate gsm network\n"); exit(1); } - g_bts = &gsmnet->bts[0]; + g_bts = gsm_bts_alloc(gsmnet, GSM_BTS_TYPE_BS11, HARDCODED_TSC, + HARDCODED_BSIC); rc = rs232_setup(serial_port, delay_ms, g_bts); if (rc < 0) { diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c index ae67ade31..e3e3a407f 100644 --- a/openbsc/src/bsc_hack.c +++ b/openbsc/src/bsc_hack.c @@ -490,7 +490,7 @@ static void bootstrap_om_nanobts(struct gsm_bts *bts) static void bootstrap_om_bs11(struct gsm_bts *bts) { - struct gsm_bts_trx *trx = &bts->trx[0]; + struct gsm_bts_trx *trx = bts->c0; /* stop sending event reports */ abis_nm_event_reports(bts, 0); @@ -608,10 +608,11 @@ static int shutdown_om(struct gsm_bts *bts) static int shutdown_net(struct gsm_network *net) { - int i; - for (i = 0; i < net->num_bts; i++) { + struct gsm_bts *bts; + + llist_for_each_entry(bts, &net->bts_list, list) { int rc; - rc = shutdown_om(&net->bts[i]); + rc = shutdown_om(bts); if (rc < 0) return rc; } @@ -849,8 +850,8 @@ static int set_system_infos(struct gsm_bts_trx *trx) */ static void patch_tables(struct gsm_bts *bts) { - u_int8_t arfcn_low = bts->trx[0].arfcn & 0xff; - u_int8_t arfcn_high = (bts->trx[0].arfcn >> 8) & 0x0f; + u_int8_t arfcn_low = bts->c0->arfcn & 0xff; + u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f; /* covert the raw packet to the struct */ struct gsm48_system_information_type_3 *type_3 = (struct gsm48_system_information_type_3*)&si3; @@ -933,7 +934,7 @@ static int bootstrap_bts(struct gsm_bts *bts) { bts->band = BAND; bts->location_area_code = LAC; - bts->trx[0].arfcn = ARFCN; + bts->c0->arfcn = ARFCN; /* Control Channel Description */ memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr)); @@ -947,7 +948,7 @@ static int bootstrap_bts(struct gsm_bts *bts) paging_init(bts); if (bts->type == GSM_BTS_TYPE_BS11) { - struct gsm_bts_trx *trx = &bts->trx[0]; + struct gsm_bts_trx *trx = bts->c0; set_ts_e1link(&trx->ts[0], 0, 1, 0xff); set_ts_e1link(&trx->ts[1], 0, 2, 1); set_ts_e1link(&trx->ts[2], 0, 2, 2); @@ -998,14 +999,14 @@ static int bootstrap_network(void) } /* initialize our data structures */ - gsmnet = gsm_network_init(2, BTS_TYPE, MCC, MNC, mncc_recv); + gsmnet = gsm_network_init(MCC, MNC, mncc_recv); if (!gsmnet) return -ENOMEM; gsmnet->name_long = "OpenBSC"; gsmnet->name_short = "OpenBSC"; - bts = &gsmnet->bts[0]; + bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC); bootstrap_bts(bts); if (db_init(database_name)) { @@ -1033,7 +1034,7 @@ static int bootstrap_network(void) bts->ip_access.site_id = 1801; bts->ip_access.bts_id = 0; - bts = &gsmnet->bts[1]; + bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC); bootstrap_bts(bts); bts->ip_access.site_id = 1800; bts->ip_access.bts_id = 0; diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c index 96632bcb9..241d5895b 100644 --- a/openbsc/src/chan_alloc.c +++ b/openbsc/src/chan_alloc.c @@ -38,7 +38,7 @@ static void auto_release_channel(void *_lchan); struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts, enum gsm_phys_chan_config pchan) { - struct gsm_bts_trx *trx = &bts->trx[0]; + struct gsm_bts_trx *trx = bts->c0; struct gsm_bts_trx_ts *ts = &trx->ts[0]; if (pchan != GSM_PCHAN_CCCH && @@ -68,7 +68,7 @@ struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts, { int i, j; for (i = 0; i < bts->num_trx; i++) { - struct gsm_bts_trx *trx = &bts->trx[i]; + struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, i); int from, to; /* the following constraints are pure policy, @@ -124,7 +124,7 @@ _lc_find(struct gsm_bts *bts, enum gsm_phys_chan_config pchan) struct gsm_bts_trx_ts *ts; int i, j, ss; for (i = 0; i < bts->num_trx; i++) { - trx = &bts->trx[i]; + trx = gsm_bts_trx_num(bts, i); for (j = 0; j < 8; j++) { ts = &trx->ts[j]; if (ts->pchan != pchan) @@ -239,13 +239,14 @@ static void auto_release_channel(void *_lchan) } struct gsm_lchan* lchan_find(struct gsm_bts *bts, struct gsm_subscriber *subscr) { - int trx, ts_no, lchan_no; + struct gsm_bts_trx *trx; + int ts_no, lchan_no; - for (trx = 0; trx < bts->num_trx; ++trx) { + llist_for_each_entry(trx, &bts->trx_list, list) { for (ts_no = 0; ts_no < 8; ++ts_no) { for (lchan_no = 0; lchan_no < TS_MAX_LCHAN; ++lchan_no) { struct gsm_lchan *lchan = - &bts->trx[trx].ts[ts_no].lchan[lchan_no]; + &trx->ts[ts_no].lchan[lchan_no]; if (subscr == lchan->subscr) return lchan; } diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 49234f8d8..c081b45c2 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -3444,9 +3444,9 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg) trans->subscr = subscr; /* Find lchan */ for (i = 0; i < net->num_bts; i++) { - bts = &net->bts[i]; + bts = gsm_bts_num(net, i); for (j = 0; j < bts->num_trx; j++) { - trx = &bts->trx[j]; + trx = gsm_bts_trx_num(bts, j); for (k = 0; k < TRX_NR_TS; k++) { ts = &trx->ts[k]; for (l = 0; l < TS_MAX_LCHAN; l++) { 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 #include +#include 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) diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c index ccc178d17..c16bf1b60 100644 --- a/openbsc/src/input/ipaccess.c +++ b/openbsc/src/input/ipaccess.c @@ -112,10 +112,10 @@ static int ipac_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len) struct gsm_bts *find_bts_by_unitid(struct gsm_network *net, u_int16_t site_id, u_int16_t bts_id) { + struct gsm_bts *bts; int i; - for (i = 0; i < net->num_bts; i++) { - struct gsm_bts *bts = &net->bts[i]; + llist_for_each_entry(bts, &net->bts_list, list) { if (!is_ipaccess_bts(bts)) continue; diff --git a/openbsc/src/ipaccess-config.c b/openbsc/src/ipaccess-config.c index cc8a6c9bc..d3f3176b3 100644 --- a/openbsc/src/ipaccess-config.c +++ b/openbsc/src/ipaccess-config.c @@ -170,11 +170,12 @@ int main(int argc, char **argv) exit(2); } - gsmnet = gsm_network_init(1, GSM_BTS_TYPE_NANOBTS_900, 1, 1, NULL); + gsmnet = gsm_network_init(1, 1, NULL); if (!gsmnet) exit(1); - bts = &gsmnet->bts[0]; + bts = gsm_bts_alloc(gsmnet, GSM_BTS_TYPE_NANOBTS_900, HARDCODED_TSC, + HARDCODED_BSIC); printf("Trying to connect to ip.access BTS ...\n"); diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index 1b6004631..12d5ae94a 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -147,12 +147,12 @@ DEFUN(show_bts, show_bts_cmd, "show bts [number]", VTY_NEWLINE); return CMD_WARNING; } - bts_dump_vty(vty, &net->bts[bts_nr]); + bts_dump_vty(vty, gsm_bts_num(net, bts_nr)); return CMD_SUCCESS; } /* print all BTS's */ for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) - bts_dump_vty(vty, &net->bts[bts_nr]); + bts_dump_vty(vty, gsm_bts_num(net, bts_nr)); return CMD_SUCCESS; } @@ -191,7 +191,7 @@ DEFUN(show_trx, VTY_NEWLINE); return CMD_WARNING; } - bts = &net->bts[bts_nr]; + bts = gsm_bts_num(net, bts_nr); } if (argc >= 2) { trx_nr = atoi(argv[1]); @@ -200,23 +200,23 @@ DEFUN(show_trx, VTY_NEWLINE); return CMD_WARNING; } - trx = &bts->trx[trx_nr]; + trx = gsm_bts_trx_num(bts, trx_nr); trx_dump_vty(vty, trx); return CMD_SUCCESS; } if (bts) { /* print all TRX in this BTS */ for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) { - trx = &bts->trx[trx_nr]; + trx = gsm_bts_trx_num(bts, trx_nr); trx_dump_vty(vty, trx); } return CMD_SUCCESS; } for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) { - bts = &net->bts[bts_nr]; + bts = gsm_bts_num(net, bts_nr); for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) { - trx = &bts->trx[trx_nr]; + trx = gsm_bts_trx_num(bts, trx_nr); trx_dump_vty(vty, trx); } } @@ -265,7 +265,7 @@ DEFUN(show_ts, VTY_NEWLINE); return CMD_WARNING; } - bts = &net->bts[bts_nr]; + bts = gsm_bts_num(net, bts_nr); } if (argc >= 2) { trx_nr = atoi(argv[1]); @@ -274,7 +274,7 @@ DEFUN(show_ts, VTY_NEWLINE); return CMD_WARNING; } - trx = &bts->trx[trx_nr]; + trx = gsm_bts_trx_num(bts, trx_nr); } if (argc >= 3) { ts_nr = atoi(argv[2]); @@ -288,9 +288,9 @@ DEFUN(show_ts, return CMD_SUCCESS; } for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) { - bts = &net->bts[bts_nr]; + bts = gsm_bts_num(net, bts_nr); for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) { - trx = &bts->trx[trx_nr]; + trx = gsm_bts_trx_num(bts, trx_nr); for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) { ts = &trx->ts[ts_nr]; ts_dump_vty(vty, ts); @@ -379,7 +379,7 @@ DEFUN(show_lchan, VTY_NEWLINE); return CMD_WARNING; } - bts = &net->bts[bts_nr]; + bts = gsm_bts_num(net, bts_nr); } if (argc >= 2) { trx_nr = atoi(argv[1]); @@ -388,7 +388,7 @@ DEFUN(show_lchan, VTY_NEWLINE); return CMD_WARNING; } - trx = &bts->trx[trx_nr]; + trx = gsm_bts_trx_num(bts, trx_nr); } if (argc >= 3) { ts_nr = atoi(argv[2]); @@ -411,9 +411,9 @@ DEFUN(show_lchan, return CMD_SUCCESS; } for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) { - bts = &net->bts[bts_nr]; + bts = gsm_bts_num(net, bts_nr); for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) { - trx = &bts->trx[trx_nr]; + trx = gsm_bts_trx_num(bts, trx_nr); for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) { ts = &trx->ts[ts_nr]; for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; @@ -567,13 +567,13 @@ DEFUN(show_paging, VTY_NEWLINE); return CMD_WARNING; } - bts = &net->bts[bts_nr]; + bts = gsm_bts_num(net, bts_nr); bts_paging_dump_vty(vty, bts); return CMD_SUCCESS; } for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) { - bts = &net->bts[bts_nr]; + bts = gsm_bts_num(net, bts_nr); bts_paging_dump_vty(vty, bts); } @@ -612,14 +612,19 @@ DEFUN(cfg_bts, int bts_nr = atoi(argv[0]); struct gsm_bts *bts; - if (bts_nr >= GSM_MAX_BTS) { - vty_out(vty, "%% This Version of OpenBSC only supports %u BTS%s", - GSM_MAX_BTS, VTY_NEWLINE); + if (bts_nr > gsmnet->num_bts) { + vty_out(vty, "%% The next unused BTS number is %u%s", + gsmnet->num_bts, VTY_NEWLINE); + return CMD_WARNING; + } else if (bts_nr == gsmnet->num_bts) { + /* allocate a new one */ + bts = gsm_bts_alloc(gsmnet, GSM_BTS_TYPE_UNKNOWN, + HARDCODED_TSC, HARDCODED_BSIC); + } else + bts = gsm_bts_num(gsmnet, bts_nr); + + if (!bts) return CMD_WARNING; - } - bts = &gsmnet->bts[bts_nr]; - if (bts_nr >= gsmnet->num_bts) - gsmnet->num_bts = bts_nr + 1; vty->index = bts; vty->node = BTS_NODE; @@ -748,16 +753,18 @@ DEFUN(cfg_trx, struct gsm_bts *bts = vty->index; struct gsm_bts_trx *trx; - if (trx_nr > BTS_MAX_TRX) { - vty_out(vty, "%% This version of OpenBSC only supports %u TRX%s", - BTS_MAX_TRX+1, VTY_NEWLINE); + if (trx_nr > bts->num_trx) { + vty_out(vty, "%% The next unused TRX number in this BTS is %u%s", + bts->num_trx, VTY_NEWLINE); + return CMD_WARNING; + } else if (trx_nr == bts->num_trx) { + /* we need to allocate a new one */ + trx = gsm_bts_trx_alloc(bts); + } else + trx = gsm_bts_trx_num(bts, trx_nr); + + if (!trx) return CMD_WARNING; - } - - if (trx_nr >= bts->num_trx) - bts->num_trx = trx_nr+1; - - trx = &bts->trx[trx_nr]; vty->index = trx; vty->node = TRX_NODE; -- cgit v1.2.3