Prepare for extended SI2quater support

Supporting SI2quater as per 3GPP TS 44.018 will require chnages to the
way System Information is stored because it uses 1:n instead of 1:1
mapping between SI type and generated SI content. This should not affect
other SI types though. To facilitate this transition:

* convert the code to always use GSM_BTS_SI helper instead of accessing
  buffer directly
* make helper more robust by adding extra parenthesis
* add similar helper for gsm_lchan
* add function estimating number of SI2quater message to hold configured
  number of (U|E)ARFCNs
* add SI2q index/count fields and pass them to rest_octets generator
  explicitly
* internalize buffer access in generate_si* functions

Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd
Related: RT#8792
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 242889a..166de16 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -483,7 +483,8 @@
 	struct gsm_bts_trx_ts ts[TRX_NR_TS];
 };
 
-#define GSM_BTS_SI(bts, i)	(void *)(bts->si_buf[i])
+#define GSM_BTS_SI(bts, i)	(void *)((bts)->si_buf[i])
+#define GSM_LCHAN_SI(lchan, i)	(void *)((lchan)->si.buf[i])
 
 enum gsm_bts_type {
 	GSM_BTS_TYPE_UNKNOWN,
@@ -702,6 +703,9 @@
 
 	/* bitmask of all SI that are present/valid in si_buf */
 	uint32_t si_valid;
+	/* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
+	uint8_t si2q_index;
+	uint8_t si2q_count;
 	/* buffers where we put the pre-computed SI */
 	sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
 
diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h
index 3b4e598..73ce57b 100644
--- a/openbsc/include/openbsc/rest_octets.h
+++ b/openbsc/include/openbsc/rest_octets.h
@@ -5,12 +5,15 @@
 #include <openbsc/gsm_04_08.h>
 #include <osmocom/gsm/sysinfo.h>
 
+/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018: 4-bit index is used */
+#define SI2Q_MAX_NUM 16
+/* length in bits (for single SI2quater message) */
 #define SI2Q_MAX_LEN 160
 #define SI2Q_MIN_LEN 18
 
 /* generate SI1 rest octets */
 int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net);
-int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e,
+int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e,
 			  const uint16_t *u, const uint16_t *sc, size_t u_len);
 int rest_octets_si6(uint8_t *data, bool is1800_net);
 
diff --git a/openbsc/include/openbsc/system_information.h b/openbsc/include/openbsc/system_information.h
index 1b19c8b..b012107 100644
--- a/openbsc/include/openbsc/system_information.h
+++ b/openbsc/include/openbsc/system_information.h
@@ -14,7 +14,7 @@
 unsigned range512_q(unsigned m);
 int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w,
 		 int f0, uint8_t *chan_list);
-bool si2q_size_check(const struct gsm_bts *bts);
+uint8_t si2q_num(const struct gsm_bts *bts);
 int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble);
 int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble,
 		   bool diversity);