diff options
author | Max <msuraev@sysmocom.de> | 2017-06-02 11:41:58 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2017-06-15 19:18:47 +0000 |
commit | 340cff51f49f6e798cb5fb6d1b9febdd09902906 (patch) | |
tree | c7b9ac126e9beec32c5137747ab01c8c22d8a7e3 | |
parent | 0b7a3e9f62bd3eaf2a9bf2c75028a91c8072d389 (diff) |
RSL: receive and send multiple SI2q messages
* change BCCH Info handler to explicitly support multiple SI2quater
messages sent from BSC
* change SI scheduler to send SI2q in round-robin way
Change-Id: I3aeb90804edab1b0325c3eb7347526ae995dbf51
Related: OS#1660
-rw-r--r-- | src/common/rsl.c | 61 | ||||
-rw-r--r-- | src/common/sysinfo.c | 16 |
2 files changed, 49 insertions, 28 deletions
diff --git a/src/common/rsl.c b/src/common/rsl.c index eab93797..bb05decf 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -264,7 +264,7 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg) { struct gsm_bts *bts = trx->bts; struct tlv_parsed tp; - uint8_t rsl_si, si2q_index, si2q_count; + uint8_t rsl_si, count; enum osmo_sysinfo_type osmo_si; struct gsm48_system_information_type_2quater *si2q; struct bitvec bv; @@ -292,36 +292,43 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg) len = sizeof(sysinfo_buf_t); } bts->si_valid |= (1 << osmo_si); - memset(bts->si_buf[osmo_si], 0x2b, sizeof(sysinfo_buf_t)); - memcpy(bts->si_buf[osmo_si], - TLVP_VAL(&tp, RSL_IE_FULL_BCCH_INFO), len); - LOGP(DRSL, LOGL_INFO, " Rx RSL BCCH INFO (SI%s, %u bytes)\n", - get_value_string(osmo_sitype_strs, osmo_si), len); - - if (SYSINFO_TYPE_3 == osmo_si && trx->nr == 0 && - num_agch(trx, "RSL") != 1) { - lchan_deactivate(&trx->bts->c0->ts[0].lchan[CCCH_LCHAN]); - /* will be reactivated by sapi_deactivate_cb() */ - trx->bts->c0->ts[0].lchan[CCCH_LCHAN].rel_act_kind = - LCHAN_REL_ACT_REACT; - } - if (SYSINFO_TYPE_2quater == osmo_si) { - si2q = (struct gsm48_system_information_type_2quater *) - bts->si_buf[SYSINFO_TYPE_2quater]; + switch (osmo_si) { + case SYSINFO_TYPE_2quater: + si2q = (struct gsm48_system_information_type_2quater *) TLVP_VAL(&tp, RSL_IE_FULL_BCCH_INFO); bv.data = si2q->rest_octets; - bv.data_len = 20; + bv.data_len = GSM_MACBLOCK_LEN; bv.cur_bit = 3; - si2q_index = (uint8_t) bitvec_get_uint(&bv, 4); - si2q_count = (uint8_t) bitvec_get_uint(&bv, 4); - if (si2q_index || si2q_count) { - LOGP(DRSL, LOGL_ERROR, - " Rx RSL SI2quater witn unsupported " - "index %u, count %u\n", - si2q_index, si2q_count); - return rsl_tx_error_report(trx, - RSL_ERR_IE_CONTENT); + bts->si2q_index = (uint8_t) bitvec_get_uint(&bv, 4); + + count = (uint8_t) bitvec_get_uint(&bv, 4); + if (bts->si2q_count && bts->si2q_count != count) { + LOGP(DRSL, LOGL_ERROR, " Rx RSL SI2quater count changed while receiving: %u -> %d\n", + bts->si2q_count, count); + return rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT); + } + + bts->si2q_count = count; + if (bts->si2q_index > bts->si2q_count) { + LOGP(DRSL, LOGL_ERROR, " Rx RSL SI2quater witn index %u > count %u\n", + bts->si2q_index, bts->si2q_count); + return rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT); } + + memset(GSM_BTS_SI2Q(bts, bts->si2q_index), GSM_MACBLOCK_PADDING, sizeof(sysinfo_buf_t)); + memcpy(GSM_BTS_SI2Q(bts, bts->si2q_index), TLVP_VAL(&tp, RSL_IE_FULL_BCCH_INFO), len); + break; + case SYSINFO_TYPE_3: + if (trx->nr == 0 && num_agch(trx, "RSL") != 1) { + lchan_deactivate(&trx->bts->c0->ts[0].lchan[CCCH_LCHAN]); + /* will be reactivated by sapi_deactivate_cb() */ + trx->bts->c0->ts[0].lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_REACT; + } /* intentional fall-through to copy SI3 data */ + default: + memset(bts->si_buf[osmo_si], GSM_MACBLOCK_PADDING, sizeof(sysinfo_buf_t)); + memcpy(bts->si_buf[osmo_si], TLVP_VAL(&tp, RSL_IE_FULL_BCCH_INFO), len); + LOGP(DRSL, LOGL_INFO, " Rx RSL BCCH INFO (SI%s, %u bytes)\n", + get_value_string(osmo_sitype_strs, osmo_si), len); } } else if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) { uint16_t len = TLVP_LEN(&tp, RSL_IE_L3_INFO); diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c index 7a536274..9276c7bb 100644 --- a/src/common/sysinfo.c +++ b/src/common/sysinfo.c @@ -25,6 +25,16 @@ #include <osmo-bts/logging.h> #include <osmo-bts/gsm_data.h> +/* properly increment SI2q index and return SI2q data for scheduling */ +static inline uint8_t *get_si2q_inc_index(struct gsm_bts *bts) +{ + uint8_t i = bts->si2q_index; + /* si2q_count is the max si2q_index value, not the number of messages */ + bts->si2q_index = (bts->si2q_index + 1) % (bts->si2q_count + 1); + + return (uint8_t *)GSM_BTS_SI2Q(bts, i); +} + /* Apply the rules from 05.02 6.3.1.3 Mapping of BCCH Data */ uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time) { @@ -99,6 +109,10 @@ uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time) else { /* increment static counter by one, modulo count */ btsb->si.tc4_ctr = (btsb->si.tc4_ctr + 1) % tc4_cnt; + + if (tc4_sub[btsb->si.tc4_ctr] == SYSINFO_TYPE_2quater) + return get_si2q_inc_index(bts); + return GSM_BTS_SI(bts, tc4_sub[btsb->si.tc4_ctr]); } case 5: @@ -114,7 +128,7 @@ uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time) else if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2quater) && !GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2bis) && !GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2ter)) - return GSM_BTS_SI(bts, SYSINFO_TYPE_2quater); + return get_si2q_inc_index(bts); break; case 6: return GSM_BTS_SI(bts, SYSINFO_TYPE_3); |