[PATCH] openbsc[master]: Prepare for extended SI2quater support

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Thu Apr 13 12:26:03 UTC 2017


Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/2312

to look at the new patch set (#6).

Prepare for extended SI2quater support

Supporting SI2quater support 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
---
M openbsc/include/openbsc/gsm_data_shared.h
M openbsc/include/openbsc/rest_octets.h
M openbsc/include/openbsc/system_information.h
M openbsc/src/libbsc/bsc_vty.c
M openbsc/src/libbsc/rest_octets.c
M openbsc/src/libbsc/system_information.c
M openbsc/tests/gsm0408/gsm0408_test.c
7 files changed, 57 insertions(+), 61 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/12/2312/6

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..6da58ea 100644
--- a/openbsc/include/openbsc/rest_octets.h
+++ b/openbsc/include/openbsc/rest_octets.h
@@ -10,7 +10,7 @@
 
 /* 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);
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index c1882fc..657dfe3 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -644,7 +644,7 @@
 				get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
 			vty_out(vty, "  system-information %s static %s%s",
 				get_value_string(osmo_sitype_strs, i),
-				osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])),
+				osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
 				VTY_NEWLINE);
 		}
 	}
@@ -2688,11 +2688,11 @@
 	}
 
 	/* Fill buffer with padding pattern */
-	memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type]));
+	memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
 
 	/* Parse the user-specified SI in hex format, [partially] overwriting padding */
-	rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0]));
-	if (rc < 0 || rc > sizeof(bts->si_buf[0])) {
+	rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
+	if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
 		vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
 		return CMD_WARNING;
 	}
@@ -2830,7 +2830,7 @@
 		e->prio_valid = true;
 	}
 
-	if (si2q_size_check(bts))
+	if (si2q_num(bts) < 2)
 		return CMD_SUCCESS;
 
 	vty_out(vty, "Warning: not enough space in SI2quater for a given EARFCN "
diff --git a/openbsc/src/libbsc/rest_octets.c b/openbsc/src/libbsc/rest_octets.c
index ed6c573..af660f1 100644
--- a/openbsc/src/libbsc/rest_octets.c
+++ b/openbsc/src/libbsc/rest_octets.c
@@ -256,7 +256,7 @@
 }
 
 /* generate SI2quater rest octets: 3GPP TS 44.018 § 10.5.2.33b */
-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 rc;
@@ -275,9 +275,9 @@
 
 	/* we do not support multiple si2quater messages at the moment: */
 	/* SI2quater_INDEX */
-	bitvec_set_uint(&bv, 0, 4);
+	bitvec_set_uint(&bv, index, 4);
 	/* SI2quater_COUNT */
-	bitvec_set_uint(&bv, 0, 4);
+	bitvec_set_uint(&bv, count, 4);
 
 	/* No Measurement_Parameters Description */
 	bitvec_set_bit(&bv, 0);
diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c
index 2610331..37395f0 100644
--- a/openbsc/src/libbsc/system_information.c
+++ b/openbsc/src/libbsc/system_information.c
@@ -149,18 +149,13 @@
 	return s + r + append + range1024_p(k);
 }
 
-bool si2q_size_check(const struct gsm_bts *bts)
+uint8_t si2q_num(const struct gsm_bts *bts)
 {
-	const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
-	const uint16_t *u = bts->si_common.data.uarfcn_list,
-		*sc = bts->si_common.data.scramble_list;
-	size_t len = bts->si_common.uarfcn_length;
-	unsigned e_sz = e ? earfcn_size(e) : 1,
-		u_sz = len ? uarfcn_size(u, sc, len) : 1;
+	const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; /* EARFCN */
+	const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list; /* UARFCN */
+	size_t l = bts->si_common.uarfcn_length, e_sz = e ? earfcn_size(e) : 1, u_sz = l ? uarfcn_size(u, sc, l) : 1;
 	/* 2 bits are used in between UARFCN and EARFCN structs */
-	if (SI2Q_MIN_LEN + u_sz + 2 + e_sz > SI2Q_MAX_LEN)
-		return false;
-	return true;
+	return 1 + (e_sz + u_sz) / (SI2Q_MAX_LEN - (SI2Q_MIN_LEN + 2));
 }
 
 /* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */
@@ -233,7 +228,7 @@
 	scl[k] = scr;
 	bts->si_common.uarfcn_length++;
 
-	if (si2q_size_check(bts))
+	if (si2q_num(bts) < 2)
 		return 0;
 
 	bts_uarfcn_del(bts, arfcn, scramble);
@@ -557,11 +552,10 @@
 	return n;
 }
 
-static int generate_si1(uint8_t *output, struct gsm_bts *bts)
+static int generate_si1(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	int rc;
-	struct gsm48_system_information_type_1 *si1 =
-		(struct gsm48_system_information_type_1 *) output;
+	struct gsm48_system_information_type_1 *si1 = (struct gsm48_system_information_type_1 *) GSM_BTS_SI(bts, t);
 
 	memset(si1, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
 
@@ -586,11 +580,10 @@
 	return sizeof(*si1) + rc;
 }
 
-static int generate_si2(uint8_t *output, struct gsm_bts *bts)
+static int generate_si2(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	int rc;
-	struct gsm48_system_information_type_2 *si2 =
-		(struct gsm48_system_information_type_2 *) output;
+	struct gsm48_system_information_type_2 *si2 = (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, t);
 
 	memset(si2, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
 
@@ -611,11 +604,11 @@
 	return sizeof(*si2);
 }
 
-static int generate_si2bis(uint8_t *output, struct gsm_bts *bts)
+static int generate_si2bis(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	int rc;
 	struct gsm48_system_information_type_2bis *si2b =
-		(struct gsm48_system_information_type_2bis *) output;
+		(struct gsm48_system_information_type_2bis *) GSM_BTS_SI(bts, t);
 	int n;
 
 	memset(si2b, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
@@ -633,8 +626,7 @@
 	if (n) {
 		/* indicate in SI2 and SI2bis: there is an extension */
 		struct gsm48_system_information_type_2 *si2 =
-			(struct gsm48_system_information_type_2 *)
-				bts->si_buf[SYSINFO_TYPE_2];
+			(struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2);
 		si2->bcch_frequency_list[0] |= 0x20;
 		si2b->bcch_frequency_list[0] |= 0x20;
 	} else
@@ -645,11 +637,11 @@
 	return sizeof(*si2b);
 }
 
-static int generate_si2ter(uint8_t *output, struct gsm_bts *bts)
+static int generate_si2ter(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	int rc;
 	struct gsm48_system_information_type_2ter *si2t =
-		(struct gsm48_system_information_type_2ter *) output;
+		(struct gsm48_system_information_type_2ter *) GSM_BTS_SI(bts, t);
 	int n;
 
 	memset(si2t, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
@@ -670,11 +662,11 @@
 	return sizeof(*si2t);
 }
 
-static int generate_si2quater(uint8_t *output, struct gsm_bts *bts)
+static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	int rc, i = MAX_EARFCN_LIST;
 	struct gsm48_system_information_type_2quater *si2q =
-		(struct gsm48_system_information_type_2quater *) output;
+		(struct gsm48_system_information_type_2quater *) GSM_BTS_SI(bts, t);
 
 	memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
 
@@ -683,7 +675,7 @@
 	si2q->header.skip_indicator = 0;
 	si2q->header.system_information = GSM48_MT_RR_SYSINFO_2quater;
 
-	rc = rest_octets_si2quater(si2q->rest_octets,
+	rc = rest_octets_si2quater(si2q->rest_octets, bts->si2q_index, bts->si2q_count,
 				   &bts->si_common.si2quater_neigh_list,
 				   bts->si_common.data.uarfcn_list,
 				   bts->si_common.data.scramble_list,
@@ -727,11 +719,10 @@
 	.break_ind = 0,
 };
 
-static int generate_si3(uint8_t *output, struct gsm_bts *bts)
+static int generate_si3(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	int rc;
-	struct gsm48_system_information_type_3 *si3 =
-		(struct gsm48_system_information_type_3 *) output;
+	struct gsm48_system_information_type_3 *si3 = (struct gsm48_system_information_type_3 *) GSM_BTS_SI(bts, t);
 
 	memset(si3, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
 
@@ -775,11 +766,10 @@
 	return sizeof(*si3) + rc;
 }
 
-static int generate_si4(uint8_t *output, struct gsm_bts *bts)
+static int generate_si4(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	int rc;
-	struct gsm48_system_information_type_4 *si4 =
-		(struct gsm48_system_information_type_4 *) output;
+	struct gsm48_system_information_type_4 *si4 = (struct gsm48_system_information_type_4 *) GSM_BTS_SI(bts, t);
 	struct gsm_lchan *cbch_lchan;
 	uint8_t *restoct = si4->data;
 
@@ -815,14 +805,15 @@
 	/* SI4 Rest Octets (10.5.2.35), containing
 		Optional Power offset, GPRS Indicator,
 		Cell Identity, LSA ID, Selection Parameter */
-	rc = rest_octets_si4(restoct, &si_info, output + GSM_MACBLOCK_LEN - restoct);
+	rc = rest_octets_si4(restoct, &si_info, (uint8_t *)GSM_BTS_SI(bts, t) + GSM_MACBLOCK_LEN - restoct);
 
 	return l2_plen + 1 + rc;
 }
 
-static int generate_si5(uint8_t *output, struct gsm_bts *bts)
+static int generate_si5(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	struct gsm48_system_information_type_5 *si5;
+	uint8_t *output = GSM_BTS_SI(bts, t);
 	int rc, l2_plen = 18;
 
 	memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
@@ -838,7 +829,7 @@
 		break;
 	}
 
-	si5 = (struct gsm48_system_information_type_5 *) output;
+	si5 = (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, t);
 
 	/* l2 pseudo length, not part of msg: 18 */
 	si5->rr_protocol_discriminator = GSM48_PDISC_RR;
@@ -854,9 +845,10 @@
 	return l2_plen;
 }
 
-static int generate_si5bis(uint8_t *output, struct gsm_bts *bts)
+static int generate_si5bis(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	struct gsm48_system_information_type_5bis *si5b;
+	uint8_t *output = GSM_BTS_SI(bts, t);
 	int rc, l2_plen = 18;
 	int n;
 
@@ -873,7 +865,7 @@
 		break;
 	}
 
-	si5b = (struct gsm48_system_information_type_5bis *) output;
+	si5b = (struct gsm48_system_information_type_5bis *) GSM_BTS_SI(bts, t);
 
 	/* l2 pseudo length, not part of msg: 18 */
 	si5b->rr_protocol_discriminator = GSM48_PDISC_RR;
@@ -887,8 +879,7 @@
 	if (n) {
 		/* indicate in SI5 and SI5bis: there is an extension */
 		struct gsm48_system_information_type_5 *si5 =
-			(struct gsm48_system_information_type_5 *)
-				bts->si_buf[SYSINFO_TYPE_5];
+			(struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5);
 		si5->bcch_frequency_list[0] |= 0x20;
 		si5b->bcch_frequency_list[0] |= 0x20;
 	} else
@@ -898,9 +889,10 @@
 	return l2_plen;
 }
 
-static int generate_si5ter(uint8_t *output, struct gsm_bts *bts)
+static int generate_si5ter(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	struct gsm48_system_information_type_5ter *si5t;
+	uint8_t *output = GSM_BTS_SI(bts, t);
 	int rc, l2_plen = 18;
 	int n;
 
@@ -917,7 +909,7 @@
 		break;
 	}
 
-	si5t = (struct gsm48_system_information_type_5ter *) output;
+	si5t = (struct gsm48_system_information_type_5ter *) GSM_BTS_SI(bts, t);
 
 	/* l2 pseudo length, not part of msg: 18 */
 	si5t->rr_protocol_discriminator = GSM48_PDISC_RR;
@@ -935,9 +927,10 @@
 	return l2_plen;
 }
 
-static int generate_si6(uint8_t *output, struct gsm_bts *bts)
+static int generate_si6(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	struct gsm48_system_information_type_6 *si6;
+	uint8_t *output = GSM_BTS_SI(bts, t);
 	int l2_plen = 11;
 	int rc;
 
@@ -954,7 +947,7 @@
 		break;
 	}
 
-	si6 = (struct gsm48_system_information_type_6 *) output;
+	si6 = (struct gsm48_system_information_type_6 *) GSM_BTS_SI(bts, t);
 
 	/* l2 pseudo length, not part of msg: 11 */
 	si6->rr_protocol_discriminator = GSM48_PDISC_RR;
@@ -1015,10 +1008,10 @@
 	},
 };
 
-static int generate_si13(uint8_t *output, struct gsm_bts *bts)
+static int generate_si13(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	struct gsm48_system_information_type_13 *si13 =
-		(struct gsm48_system_information_type_13 *) output;
+		(struct gsm48_system_information_type_13 *) GSM_BTS_SI(bts, t);
 	int ret;
 
 	memset(si13, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
@@ -1048,7 +1041,7 @@
 	return sizeof (*si13) + ret;
 }
 
-typedef int (*gen_si_fn_t)(uint8_t *output, struct gsm_bts *bts);
+typedef int (*gen_si_fn_t)(enum osmo_sysinfo_type t, struct gsm_bts *bts);
 
 static const gen_si_fn_t gen_si_fn[_MAX_SYSINFO_TYPE] = {
 	[SYSINFO_TYPE_1] = &generate_si1,
@@ -1090,5 +1083,5 @@
 	if (!gen_si)
 		return -EINVAL;
 
-	return gen_si(bts->si_buf[si_type], bts);
+	return gen_si(si_type, bts);
 }
diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c
index 08cf43f..81dc177 100644
--- a/openbsc/tests/gsm0408/gsm0408_test.c
+++ b/openbsc/tests/gsm0408/gsm0408_test.c
@@ -99,13 +99,12 @@
 	bts->si_valid = 0;
 	bts->si_valid |= (1 << SYSINFO_TYPE_2quater);
 	/* should be no-op as entire buffer is filled with padding: */
-	memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN);
+	memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN);
 	int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater);
 	bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater);
 	if (r > 0)
 		printf("generated %s SI2quater: [%d] %s\n",
-		       v ? "valid" : "invalid", r,
-		       osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r));
+		       v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r));
 	else
 		printf("failed to generate SI2quater: %s\n", strerror(-r));
 }

-- 
To view, visit https://gerrit.osmocom.org/2312
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd
Gerrit-PatchSet: 6
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list