diff options
Diffstat (limited to 'openbsc/src/system_information.c')
-rw-r--r-- | openbsc/src/system_information.c | 115 |
1 files changed, 49 insertions, 66 deletions
diff --git a/openbsc/src/system_information.c b/openbsc/src/system_information.c index 60a8219b2..2d4ba20a4 100644 --- a/openbsc/src/system_information.c +++ b/openbsc/src/system_information.c @@ -23,6 +23,7 @@ #include <errno.h> #include <string.h> +#include <stdio.h> #include <sys/types.h> #include <netinet/in.h> @@ -30,6 +31,7 @@ #include <openbsc/gsm_data.h> #include <openbsc/abis_rsl.h> #include <openbsc/rest_octets.h> +#include <openbsc/bitvec.h> #define GSM48_CELL_CHAN_DESC_SIZE 16 #define GSM_MACBLOCK_LEN 23 @@ -38,7 +40,7 @@ /* Frequency Lists as per TS 04.08 10.5.2.13 */ /* 10.5.2.13.2: Bit map 0 format */ -static int cchan_list_bm0_set_arfcn(u_int8_t *chan_list, unsigned int arfcn) +static int freq_list_bm0_set_arfcn(u_int8_t *chan_list, unsigned int arfcn) { unsigned int byte, bit; @@ -57,7 +59,7 @@ static int cchan_list_bm0_set_arfcn(u_int8_t *chan_list, unsigned int arfcn) } /* 10.5.2.13.7: Variable bit map format */ -static int cchan_list_bmrel_set_arfcn(u_int8_t *chan_list, unsigned int arfcn) +static int freq_list_bmrel_set_arfcn(u_int8_t *chan_list, unsigned int arfcn) { unsigned int byte, bit; unsigned int min_arfcn; @@ -86,20 +88,23 @@ static int cchan_list_bmrel_set_arfcn(u_int8_t *chan_list, unsigned int arfcn) } /* generate a cell channel list as per Section 10.5.2.1b of 04.08 */ -static int generate_cell_chan_list(u_int8_t *chan_list, const struct gsm_bts *bts) +static int bitvec2freq_list(u_int8_t *chan_list, struct bitvec *bv, + const struct gsm_bts *bts) { - struct gsm_bts_trx *trx; - int rc, min = 1024, max = 0; + int i, rc, min = 1024, max = 0; memset(chan_list, 0, 16); /* GSM900-only handsets only support 'bit map 0 format' */ if (bts->band == GSM_BAND_900) { chan_list[0] = 0; - llist_for_each_entry(trx, &bts->trx_list, list) { - rc = cchan_list_bm0_set_arfcn(chan_list, trx->arfcn); - if (rc < 0) - return rc; + + for (i = 0; i < bv->data_len*8; i++) { + if (bitvec_get_bit_pos(bv, i)) { + rc = freq_list_bm0_set_arfcn(chan_list, i); + if (rc < 0) + return rc; + } } return 0; } @@ -107,11 +112,13 @@ static int generate_cell_chan_list(u_int8_t *chan_list, const struct gsm_bts *bt /* We currently only support the 'Variable bitmap format' */ chan_list[0] = 0x8e; - llist_for_each_entry(trx, &bts->trx_list, list) { - if (trx->arfcn < min) - min = trx->arfcn; - if (trx->arfcn > max) - max = trx->arfcn; + for (i = 0; i < bv->data_len*8; i++) { + if (bitvec_get_bit_pos(bv, i)) { + if (i < min) + min = i; + if (i > max) + max = i; + } } if ((max - min) > 111) @@ -121,8 +128,8 @@ static int generate_cell_chan_list(u_int8_t *chan_list, const struct gsm_bts *bt chan_list[1] = (min >> 1); chan_list[2] = (min & 1) << 7; - llist_for_each_entry(trx, &bts->trx_list, list) { - rc = cchan_list_bmrel_set_arfcn(chan_list, trx->arfcn); + for (i = 0; i < bv->data_len*8; i++) { + rc = freq_list_bmrel_set_arfcn(chan_list, i); if (rc < 0) return rc; } @@ -131,61 +138,37 @@ static int generate_cell_chan_list(u_int8_t *chan_list, const struct gsm_bts *bt } /* generate a cell channel list as per Section 10.5.2.1b of 04.08 */ -static int generate_bcch_chan_list(u_int8_t *chan_list, const struct gsm_bts *bts) +static int generate_cell_chan_list(u_int8_t *chan_list, struct gsm_bts *bts) { - struct gsm_bts *cur_bts; struct gsm_bts_trx *trx; - int rc, min = 1024, max = 0; - - memset(chan_list, 0, 16); - - /* GSM900-only handsets only support 'bit map 0 format' */ - if (bts->band == GSM_BAND_900) { - chan_list[0] = 0; - llist_for_each_entry(cur_bts, &bts->list, list) { - if (&cur_bts->list == &bts->network->bts_list) - continue; - trx = cur_bts->c0; - rc = cchan_list_bm0_set_arfcn(chan_list, trx->arfcn); - if (rc < 0) - return rc; - } - return 0; - } - - /* We currently only support the 'Variable bitmap format' */ - chan_list[0] = 0x8e; + struct bitvec *bv = &bts->si_common.cell_alloc; - llist_for_each_entry(cur_bts, &bts->list, list) { - if (&cur_bts->list == &bts->network->bts_list) - continue; - trx = cur_bts->c0; - if (trx->arfcn < min) - min = trx->arfcn; - if (trx->arfcn > max) - max = trx->arfcn; - } + /* first we generate a bitvec of all TRX ARFCN's in our BTS */ + llist_for_each_entry(trx, &bts->trx_list, list) + bitvec_set_bit_pos(bv, trx->arfcn, 1); - if ((max - min) > 111) - return -EINVAL; + /* then we generate a GSM 04.08 frequency list from the bitvec */ + return bitvec2freq_list(chan_list, bv, bts); +} - chan_list[0] |= (min >> 9) & 1; - chan_list[1] = (min >> 1); - chan_list[2] = (min & 1) << 7; +/* generate a cell channel list as per Section 10.5.2.1b of 04.08 */ +static int generate_bcch_chan_list(u_int8_t *chan_list, struct gsm_bts *bts) +{ + struct gsm_bts *cur_bts; + struct bitvec *bv = &bts->si_common.neigh_list; - llist_for_each_entry(cur_bts, &bts->list, list) { - if (&cur_bts->list == &bts->network->bts_list) + /* first we generate a bitvec of the BCCH ARFCN's in our BSC */ + llist_for_each_entry(cur_bts, &bts->network->bts_list, list) { + if (cur_bts == bts) continue; - trx = cur_bts->c0; - rc = cchan_list_bmrel_set_arfcn(chan_list, trx->arfcn); - if (rc < 0) - return rc; + bitvec_set_bit_pos(bv, cur_bts->c0->arfcn, 1); } - return 0; + /* then we generate a GSM 04.08 frequency list from the bitvec */ + return bitvec2freq_list(chan_list, bv, bts); } -static int generate_si1(u_int8_t *output, const struct gsm_bts *bts) +static int generate_si1(u_int8_t *output, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_1 *si1 = @@ -210,7 +193,7 @@ static int generate_si1(u_int8_t *output, const struct gsm_bts *bts) return GSM_MACBLOCK_LEN; } -static int generate_si2(u_int8_t *output, const struct gsm_bts *bts) +static int generate_si2(u_int8_t *output, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2 *si2 = @@ -257,7 +240,7 @@ struct gsm48_si_ro_info si_info = { .break_ind = 0, }; -static int generate_si3(u_int8_t *output, const struct gsm_bts *bts) +static int generate_si3(u_int8_t *output, struct gsm_bts *bts) { struct gsm48_system_information_type_3 *si3 = (struct gsm48_system_information_type_3 *) output; @@ -287,7 +270,7 @@ static int generate_si3(u_int8_t *output, const struct gsm_bts *bts) return GSM_MACBLOCK_LEN; } -static int generate_si4(u_int8_t *output, const struct gsm_bts *bts) +static int generate_si4(u_int8_t *output, struct gsm_bts *bts) { struct gsm48_system_information_type_4 *si4 = (struct gsm48_system_information_type_4 *) output; @@ -319,7 +302,7 @@ static int generate_si4(u_int8_t *output, const struct gsm_bts *bts) return GSM_MACBLOCK_LEN; } -static int generate_si5(u_int8_t *output, const struct gsm_bts *bts) +static int generate_si5(u_int8_t *output, struct gsm_bts *bts) { struct gsm48_system_information_type_5 *si5 = (struct gsm48_system_information_type_5 *) output; @@ -339,7 +322,7 @@ static int generate_si5(u_int8_t *output, const struct gsm_bts *bts) return 18; } -static int generate_si6(u_int8_t *output, const struct gsm_bts *bts) +static int generate_si6(u_int8_t *output, struct gsm_bts *bts) { struct gsm48_system_information_type_6 *si6 = (struct gsm48_system_information_type_6 *) output; @@ -390,7 +373,7 @@ static struct gsm48_si13_info si13_default = { }, }; -static int generate_si13(u_int8_t *output, const struct gsm_bts *bts) +static int generate_si13(u_int8_t *output, struct gsm_bts *bts) { struct gsm48_system_information_type_13 *si13 = (struct gsm48_system_information_type_13 *) output; |