aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-06-15 08:52:12 +0200
committerHarald Welte <laforge@gnumonks.org>2010-06-20 10:44:53 +0200
commitfd3708976ab894cd3a8529d3956b32d39344ca24 (patch)
tree40b91aec2ea9849425f0da302867278c5b3654e3 /openbsc
parentc2fb3d0c3d0e8b12db01db70ca718914a6caad92 (diff)
[BSC] Generate MA for each timeslot that has hopping enabled
The MA is used in 04.08 channel assignment related messages
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gsm_data.h4
-rw-r--r--openbsc/src/bsc_init.c44
-rw-r--r--openbsc/src/gsm_data.c2
3 files changed, 50 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 8cb09d2eb..170ebab0b 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -338,11 +338,15 @@ struct gsm_bts_trx_ts {
u_int8_t nm_chan_comb;
struct {
+ /* Parameters below are configured by VTY */
int enabled;
u_int8_t maio;
u_int8_t hsn;
struct bitvec arfcns;
u_int8_t arfcns_data[1024/8];
+ /* This is the pre-computed MA for channel assignments */
+ struct bitvec ma;
+ u_int8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */
} hopping;
/* To which E1 subslot are we connected */
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index ddb53ba04..b69aebd70 100644
--- a/openbsc/src/bsc_init.c
+++ b/openbsc/src/bsc_init.c
@@ -915,14 +915,58 @@ static void patch_nm_tables(struct gsm_bts *bts)
}
}
+/* Produce a MA as specified in 10.5.2.21 */
+static int 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 */
+ struct bitvec *cell_chan = &ts->trx->bts->si_common.cell_alloc;
+ struct bitvec *ts_arfcn = &ts->hopping.arfcns;
+ struct bitvec *ma = &ts->hopping.ma;
+ int i;
+
+ /* re-set the MA to all-zero */
+ ma->cur_bit = 0;
+ memset(ma->data, 0, ma->data_len);
+
+ if (!ts->hopping.enabled)
+ return 0;
+
+ for (i = 1; i < 1024; i++) {
+ if (!bitvec_get_bit_pos(cell_chan, i))
+ continue;
+ /* append a bit to the MA */
+ if (bitvec_get_bit_pos(ts_arfcn, i))
+ bitvec_set_bit(ma, 1);
+ else
+ bitvec_set_bit(ma, 0);
+ }
+
+ /* ARFCN 0 is special: It is coded last in the bitmask */
+ if (bitvec_get_bit_pos(cell_chan, 0)) {
+ /* append a bit to the MA */
+ if (bitvec_get_bit_pos(ts_arfcn, 0))
+ bitvec_set_bit(ma, 1);
+ else
+ bitvec_set_bit(ma, 0);
+ }
+
+ return 0;
+}
+
static void bootstrap_rsl(struct gsm_bts_trx *trx)
{
+ unsigned int i;
+
LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
"on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u TSC=%u\n",
trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
bsc_gsmnet->network_code, trx->bts->location_area_code,
trx->bts->cell_identity, trx->bts->bsic, trx->bts->tsc);
set_system_infos(trx);
+
+ for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
+ generate_ma_for_ts(&trx->ts[i]);
}
void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index bbf150a40..de3a08d98 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -156,6 +156,8 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
ts->hopping.arfcns.data_len = sizeof(ts->hopping.arfcns_data);
ts->hopping.arfcns.data = ts->hopping.arfcns_data;
+ ts->hopping.ma.data_len = sizeof(ts->hopping.ma_data);
+ ts->hopping.ma.data = ts->hopping.ma_data;
for (l = 0; l < TS_MAX_LCHAN; l++) {
struct gsm_lchan *lchan;