aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2017-06-02 11:41:58 +0200
committerHarald Welte <laforge@gnumonks.org>2017-06-15 19:18:47 +0000
commit340cff51f49f6e798cb5fb6d1b9febdd09902906 (patch)
treec7b9ac126e9beec32c5137747ab01c8c22d8a7e3
parent0b7a3e9f62bd3eaf2a9bf2c75028a91c8072d389 (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.c61
-rw-r--r--src/common/sysinfo.c16
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);