diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/osmo-bsc/bsc_vty.c | 27 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_main.c | 39 | ||||
-rw-r--r-- | src/osmo-bsc/system_information.c | 61 |
3 files changed, 91 insertions, 36 deletions
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c index 6a6411f1a..5eb23936d 100644 --- a/src/osmo-bsc/bsc_vty.c +++ b/src/osmo-bsc/bsc_vty.c @@ -5334,6 +5334,12 @@ DEFUN_USRATTR(cfg_trx_arfcn, trx->arfcn = arfcn; + /* Update Cell Allocation (list of all the frequencies allocated to a cell) */ + if (generate_cell_chan_alloc(trx->bts) != 0) { + vty_out(vty, "%% Failed to re-generate Cell Allocation%s", VTY_NEWLINE); + return CMD_WARNING; + } + /* FIXME: patch ARFCN into SYSTEM INFORMATION */ /* FIXME: use OML layer to update the ARFCN */ /* FIXME: use RSL layer to update SYSTEM INFORMATION */ @@ -5604,6 +5610,13 @@ DEFUN_USRATTR(cfg_ts_arfcn_add, bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1); + /* Update Cell Allocation (list of all the frequencies allocated to a cell) */ + if (generate_cell_chan_alloc(ts->trx->bts) != 0) { + vty_out(vty, "%% Failed to re-generate Cell Allocation%s", VTY_NEWLINE); + bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ZERO); /* roll-back */ + return CMD_WARNING; + } + return CMD_SUCCESS; } @@ -5630,6 +5643,13 @@ DEFUN_USRATTR(cfg_ts_arfcn_del, bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0); + /* Update Cell Allocation (list of all the frequencies allocated to a cell) */ + if (generate_cell_chan_alloc(ts->trx->bts) != 0) { + vty_out(vty, "%% Failed to re-generate Cell Allocation%s", VTY_NEWLINE); + /* It's unlikely to happen on removal, so we don't roll-back */ + return CMD_WARNING; + } + return CMD_SUCCESS; } @@ -5644,6 +5664,13 @@ DEFUN_USRATTR(cfg_ts_arfcn_del_all, bitvec_zero(&ts->hopping.arfcns); + /* Update Cell Allocation (list of all the frequencies allocated to a cell) */ + if (generate_cell_chan_alloc(ts->trx->bts) != 0) { + vty_out(vty, "%% Failed to re-generate Cell Allocation%s", VTY_NEWLINE); + /* It's unlikely to happen on removal, so we don't roll-back */ + return CMD_WARNING; + } + return CMD_SUCCESS; } diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c index 6c7c2753a..2b4224fd6 100644 --- a/src/osmo-bsc/osmo_bsc_main.c +++ b/src/osmo-bsc/osmo_bsc_main.c @@ -260,10 +260,10 @@ static void generate_ma_for_ts(struct gsm_bts_trx_ts *ts) { /* we have three bitvecs: the per-timeslot ARFCNs, the cell chan ARFCNs * and the MA */ + const size_t num_cell_arfcns = ts->trx->bts->si_common.cell_chan_num; const struct bitvec *cell_chan = &ts->trx->bts->si_common.cell_alloc; const struct bitvec *ts_arfcn = &ts->hopping.arfcns; struct bitvec *ma = &ts->hopping.ma; - unsigned int num_cell_arfcns; int i; /* re-set the MA to all-zero */ @@ -273,13 +273,6 @@ static void generate_ma_for_ts(struct gsm_bts_trx_ts *ts) if (!ts->hopping.enabled) return; - /* count the number of ARFCNs in the cell channel allocation */ - num_cell_arfcns = 0; - for (i = 0; i < 1024; i++) { - if (bitvec_get_bit_pos(cell_chan, i)) - num_cell_arfcns++; - } - /* pad it to octet-aligned number of bits */ ts->hopping.ma_len = OSMO_BYTES_FOR_BITS(num_cell_arfcns); ma->cur_bit = (ts->hopping.ma_len * 8) - 1; @@ -305,6 +298,20 @@ static void generate_ma_for_ts(struct gsm_bts_trx_ts *ts) } } +static void generate_ma_for_bts(struct gsm_bts *bts) +{ + struct gsm_bts_trx *trx; + unsigned int tn; + + OSMO_ASSERT(bts->si_common.cell_chan_num > 0); + OSMO_ASSERT(bts->si_common.cell_chan_num <= 64); + + llist_for_each_entry(trx, &bts->trx_list, list) { + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) + generate_ma_for_ts(&trx->ts[tn]); + } +} + static void bootstrap_rsl(struct gsm_bts_trx *trx) { unsigned int i; @@ -388,19 +395,9 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal, switch (signal) { case S_L_INP_TEI_UP: if (isd->link_type == E1INP_SIGN_OML) { - /* TODO: this is required for the Nokia BTS, hopping is configured - during OML, other MA is not set. */ - struct gsm_bts_trx *cur_trx; - uint8_t ca[20]; - /* has to be called before generate_ma_for_ts to - set bts->si_common.cell_alloc */ - generate_cell_chan_list(ca, trx->bts); - - llist_for_each_entry(cur_trx, &trx->bts->trx_list, list) { - int i; - for (i = 0; i < ARRAY_SIZE(cur_trx->ts); i++) - generate_ma_for_ts(&cur_trx->ts[i]); - } + /* Generate Mobile Allocation bit-masks for all timeslots. + * This needs to be done here, because it's used for TS configuration. */ + generate_ma_for_bts(trx->bts); } if (isd->link_type == E1INP_SIGN_RSL) bootstrap_rsl(trx); diff --git a/src/osmo-bsc/system_information.c b/src/osmo-bsc/system_information.c index e2ac04d4e..0dbf53c19 100644 --- a/src/osmo-bsc/system_information.c +++ b/src/osmo-bsc/system_information.c @@ -574,31 +574,62 @@ static int bitvec2freq_list(uint8_t *chan_list, const struct bitvec *bv, return -EINVAL; } -/* generate a cell channel list as per Section 10.5.2.1b of 04.08 */ -int generate_cell_chan_list(uint8_t *chan_list, struct gsm_bts *bts) +/* (Re)generate Cell Allocation (basically a bit-vector of all cell channels) */ +int generate_cell_chan_alloc(struct gsm_bts *bts) { - struct bitvec *bv = &bts->si_common.cell_alloc; const struct gsm_bts_trx *trx; + unsigned int chan, chan_num; + unsigned int tn; + + /* Temporary Cell Allocation bit-vector */ + uint8_t ca[1024 / 8] = { 0 }; + struct bitvec bv = { + .data_len = sizeof(ca), + .data = &ca[0], + }; - /* Zero-initialize the bit-vector */ - memset(bv->data, 0, bv->data_len); - - /* first we generate a bitvec of all TRX ARFCN's in our BTS */ + /* Calculate a bit-mask of all assigned ARFCNs */ llist_for_each_entry(trx, &bts->trx_list, list) { - unsigned int i, j; /* Always add the TRX's ARFCN */ - bitvec_set_bit_pos(bv, trx->arfcn, 1); - for (i = 0; i < ARRAY_SIZE(trx->ts); i++) { - const struct gsm_bts_trx_ts *ts = &trx->ts[i]; + bitvec_set_bit_pos(&bv, trx->arfcn, 1); + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { + const struct gsm_bts_trx_ts *ts = &trx->ts[tn]; /* Add any ARFCNs present in hopping channels */ - for (j = 0; j < 1024; j++) { - if (bitvec_get_bit_pos(&ts->hopping.arfcns, j)) - bitvec_set_bit_pos(bv, j, 1); + for (chan = 0; chan < sizeof(ca) * 8; chan++) { + if (bitvec_get_bit_pos(&ts->hopping.arfcns, chan) == ONE) + bitvec_set_bit_pos(&bv, chan, ONE); } } } - /* then we generate a GSM 04.08 frequency list from the bitvec */ + /* Calculate the overall number of assigned ARFCNs */ + for (chan_num = 0, chan = 0; chan < sizeof(ca) * 8; chan++) { + if (bitvec_get_bit_pos(&bv, chan) == ONE) + chan_num++; + } + + /* The Mobile Allocation IE may contain up to 64 bits, so here we + * cannot allow more than 64 channels in Cell Allocation. */ + if (chan_num > 64) { + LOGP(DRR, LOGL_ERROR, "Failed to (re)generate Cell Allocation: " + "number of channels (%u) exceeds the maximum number of " + "ARFCNs in Mobile Allocation (64)\n", chan_num); + return -E2BIG; + } + + /* Commit the new Channel Allocation */ + memcpy(&bts->si_common.data.cell_alloc[0], ca, sizeof(ca)); + bts->si_common.cell_chan_num = chan_num; + + return 0; +} + +/* generate a cell channel list as per Section 10.5.2.1b of 04.08 */ +int generate_cell_chan_list(uint8_t *chan_list, struct gsm_bts *bts) +{ + const struct bitvec *bv = &bts->si_common.cell_alloc; + + /* generate a Frequency List from the Cell Allocation */ return bitvec2freq_list(chan_list, bv, bts, false, false); } |