From fd3708976ab894cd3a8529d3956b32d39344ca24 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 15 Jun 2010 08:52:12 +0200 Subject: [BSC] Generate MA for each timeslot that has hopping enabled The MA is used in 04.08 channel assignment related messages --- openbsc/include/openbsc/gsm_data.h | 4 ++++ openbsc/src/bsc_init.c | 44 ++++++++++++++++++++++++++++++++++++++ openbsc/src/gsm_data.c | 2 ++ 3 files changed, 50 insertions(+) (limited to 'openbsc') 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; -- cgit v1.2.3