aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/system_information.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-12-14 22:07:14 +0100
committerHarald Welte <laforge@gnumonks.org>2009-12-14 22:07:14 +0100
commit6c40def716b757a1aa683d9414b2320d3fc20c8a (patch)
tree469aa8d0086f78fb4051e0424cf92bc35106181b /openbsc/src/system_information.c
parentd57f163bd4040cddf59cb145affba2c2d2570c42 (diff)
system_information: use bitvec to generate frequency lists
We use a 1024-bit-sized bitvec to generate the BA and neighbor frequency list. This bitvec is still generated from the list of all BTS's inside the BSC, but this patch is the first step to generalize this, i.e. generate arbitrary neighbor lists.
Diffstat (limited to 'openbsc/src/system_information.c')
-rw-r--r--openbsc/src/system_information.c115
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;