[MERGED] openbsc[master]: Update SI data structures and generation

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 Jun 15 14:58:25 UTC 2017


Max has submitted this change and it was merged.

Change subject: Update SI data structures and generation
......................................................................


Update SI data structures and generation

To support segmented SI2quater as per 3GPP TS 44.018 we'll have to
support multiple SI messages (up to 16 for SI2q) for a given type in
contrast to existing 1:1 mapping:

* expand storage space to hold up to 16 SI messages (spec limit)
* add assertions for budget calculations
* generate multiple SI2q messages
* adjust SI2q-related tests
* use precise check for number of SIq messages instead of approximate
  estimation

Change-Id: Ic516ec9f0b821557d9461ae9f1c0afdd786f3b05
Related: OS#1660
---
M openbsc/include/openbsc/gsm_data.h
M openbsc/include/openbsc/gsm_data_shared.h
M openbsc/include/openbsc/system_information.h
M openbsc/src/libbsc/bsc_init.c
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
M openbsc/tests/gsm0408/gsm0408_test.ok
9 files changed, 353 insertions(+), 164 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 05d834e..5ab7c3f 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -29,6 +29,13 @@
 
 #define tmsi_from_string(str) strtoul(str, NULL, 10)
 
+/* 3-bit long values */
+#define EARFCN_PRIO_INVALID 8
+#define EARFCN_MEAS_BW_INVALID 8
+/* 5-bit long values */
+#define EARFCN_QRXLV_INVALID 32
+#define EARFCN_THRESH_LOW_INVALID 32
+
 enum gsm_security_event {
 	GSM_SECURITY_NOAVAIL,
 	GSM_SECURITY_AUTH_FAILED,
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index a507606..d3fd757 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -26,7 +26,8 @@
 
 #include <openbsc/common_cs.h>
 
-/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018: 4-bit index is used (2#1111 = 10#15) */
+/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1:
+   4-bit index is used (2#1111 = 10#15) */
 #define SI2Q_MAX_NUM 16
 /* length in bits (for single SI2quater message) */
 #define SI2Q_MAX_LEN 160
@@ -301,8 +302,9 @@
 		/* bitmask of all SI that are present/valid in si_buf */
 		uint32_t valid;
 		uint32_t last;
-		/* buffers where we put the pre-computed SI */
-		sysinfo_buf_t buf[_MAX_SYSINFO_TYPE];
+		/* buffers where we put the pre-computed SI:
+		   SI2Q_MAX_NUM is the max number of SI2quater messages (see 3GPP TS 44.018) */
+		sysinfo_buf_t buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
 	} si;
 	struct {
 		uint8_t flags;
@@ -491,10 +493,10 @@
 	struct gsm_bts_trx_ts ts[TRX_NR_TS];
 };
 
-#define GSM_BTS_SI2Q(bts)	(struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater])
+#define GSM_BTS_SI2Q(bts, i)   (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
 #define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
-#define GSM_BTS_SI(bts, i)	(void *)((bts)->si_buf[i])
-#define GSM_LCHAN_SI(lchan, i)	(void *)((lchan)->si.buf[i])
+#define GSM_BTS_SI(bts, i)     (void *)((bts)->si_buf[i][0])
+#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0])
 
 enum gsm_bts_type {
 	GSM_BTS_TYPE_UNKNOWN,
@@ -739,7 +741,7 @@
 	uint8_t si2q_index; /* distinguish individual SI2quater messages */
 	uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
 	/* buffers where we put the pre-computed SI */
-	sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
+	sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
 	/* offsets used while generating SI2quater */
 	size_t e_offset;
 	size_t u_offset;
diff --git a/openbsc/include/openbsc/system_information.h b/openbsc/include/openbsc/system_information.h
index 21016b8..71bea26 100644
--- a/openbsc/include/openbsc/system_information.h
+++ b/openbsc/include/openbsc/system_information.h
@@ -14,6 +14,8 @@
 int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w,
 		 int f0, uint8_t *chan_list);
 uint8_t si2q_num(struct gsm_bts *bts);
+int bts_earfcn_add(struct gsm_bts *bts, uint16_t earfcn, uint8_t thresh_hi, uint8_t thresh_lo, uint8_t prio,
+		   uint8_t qrx, uint8_t meas_bw);
 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_init.c b/openbsc/src/libbsc/bsc_init.c
index 25f3fdc..b95c7b0 100644
--- a/openbsc/src/libbsc/bsc_init.c
+++ b/openbsc/src/libbsc/bsc_init.c
@@ -101,7 +101,7 @@
 static int rsl_si(struct gsm_bts_trx *trx, enum osmo_sysinfo_type i, int si_len)
 {
 	struct gsm_bts *bts = trx->bts;
-	int rc;
+	int rc, j;
 
 	DEBUGP(DRR, "SI%s: %s\n", get_value_string(osmo_sitype_strs, i),
 		osmo_hexdump(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN));
@@ -114,6 +114,10 @@
 		rc = rsl_sacch_filling(trx, osmo_sitype2rsl(i),
 				       GSM_BTS_SI(bts, i), si_len);
 		break;
+	case SYSINFO_TYPE_2quater:
+		for (j = 0; j <= bts->si2q_count; j++)
+			rc = rsl_bcch_info(trx, i, (const uint8_t *)GSM_BTS_SI2Q(bts, j), GSM_MACBLOCK_LEN);
+		break;
 	default:
 		rc = rsl_bcch_info(trx, osmo_sitype2rsl(i),
 				   GSM_BTS_SI(bts, i), si_len);
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index b05d3d9..2fc39ab 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -2774,6 +2774,7 @@
 	return CMD_SUCCESS;
 }
 
+/* help text should be kept in sync with EARFCN_*_INVALID defines */
 DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
       "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
       "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
@@ -2791,54 +2792,37 @@
 	uint16_t arfcn = atoi(argv[0]);
 	uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
 		prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
-	int r = osmo_earfcn_add(e, arfcn,
-				(meas < 8) ? meas : OSMO_EARFCN_MEAS_INVALID);
+	int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
 
-	if (r < 0) {
-		vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r),
-			VTY_NEWLINE);
-		return CMD_WARNING;
+	switch (r) {
+	case 1:
+		vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
+			thresh_hi, VTY_NEWLINE);
+		break;
+	case EARFCN_THRESH_LOW_INVALID:
+		vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
+			thresh_lo, VTY_NEWLINE);
+		break;
+	case EARFCN_QRXLV_INVALID + 1:
+		vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
+			qrx, VTY_NEWLINE);
+		break;
+	case EARFCN_PRIO_INVALID:
+		vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
+			prio, VTY_NEWLINE);
+		break;
+	default:
+		if (r < 0) {
+			vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
+			return CMD_WARNING;
+		}
 	}
 
-	if (e->thresh_hi && thresh_hi != e->thresh_hi)
-		vty_out(vty, "Warning: multiple threshold-high are not "
-			"supported, overriding previous threshold %u%s",
-			e->thresh_hi, VTY_NEWLINE);
-
-	e->thresh_hi = thresh_hi;
-
-	if (thresh_lo != 32) {
-		if (e->thresh_lo_valid && e->thresh_lo != thresh_lo)
-			vty_out(vty, "Warning: multiple threshold-low are not "
-				"supported, overriding previous threshold %u%s",
-				e->thresh_lo, VTY_NEWLINE);
-		e->thresh_lo = thresh_lo;
-		e->thresh_lo_valid = true;
-	}
-
-	if (qrx != 32) {
-		if (e->qrxlm_valid && e->qrxlm != qrx)
-			vty_out(vty, "Warning: multiple QRXLEVMIN are not "
-				"supported, overriding previous value %u%s",
-				e->qrxlm, VTY_NEWLINE);
-		e->qrxlm = qrx;
-		e->qrxlm_valid = true;
-	}
-
-	if (prio != 8) {
-		if (e->prio_valid && e->prio != prio)
-			vty_out(vty, "Warning: multiple priorities are not "
-				"supported, overriding previous value %u%s",
-				e->prio, VTY_NEWLINE);
-		e->prio = prio;
-		e->prio_valid = true;
-	}
-
-	if (si2q_num(bts) < 2) /* FIXME: use SI2Q_MAX_NUM */
+	if (si2q_num(bts) <= SI2Q_MAX_NUM)
 		return CMD_SUCCESS;
 
 	vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
-		bts->si2q_count, 2, arfcn, VTY_NEWLINE); /* FIXME: use SI2Q_MAX_NUM */
+		bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
 	osmo_earfcn_del(e, arfcn);
 
 	return CMD_WARNING;
@@ -2877,16 +2861,14 @@
 
 	switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
 	case -ENOMEM:
-		vty_out(vty, "Unable to add arfcn: max number of UARFCNs (%u) "
-			"reached%s", MAX_EARFCN_LIST, VTY_NEWLINE);
+		vty_out(vty, "Unable to add UARFCN: max number of UARFCNs (%u) reached%s", MAX_EARFCN_LIST, VTY_NEWLINE);
 		return CMD_WARNING;
 	case -ENOSPC:
-		vty_out(vty, "Warning: not enough space in si2quater for a "
-			"given arfcn%s", VTY_NEWLINE);
+		vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
+			arfcn, scramble, VTY_NEWLINE);
 		return CMD_WARNING;
 	case -EADDRINUSE:
-		vty_out(vty, "Unable to add arfcn: (%u, %u) is already added%s",
-			arfcn, scramble, VTY_NEWLINE);
+		vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
 		return CMD_WARNING;
 	}
 
diff --git a/openbsc/src/libbsc/rest_octets.c b/openbsc/src/libbsc/rest_octets.c
index a6fdf46..fdab70a 100644
--- a/openbsc/src/libbsc/rest_octets.c
+++ b/openbsc/src/libbsc/rest_octets.c
@@ -65,6 +65,12 @@
 	unsigned i, skip = 0;
 	size_t offset = bts->e_offset;
 	uint8_t rem = budget - 6, earfcn_budget; /* account for mandatory stop bit and THRESH_E-UTRAN_high */
+
+	if (budget <= 6)
+		return;
+
+	OSMO_ASSERT(budget <= SI2Q_MAX_LEN);
+
 	/* first we have to properly adjust budget requirements */
 	if (e->prio_valid) /* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
 		rem -= 4;
@@ -87,16 +93,17 @@
 			if (skip < offset) {
 				skip++; /* ignore EARFCNs added on previous calls */
 			} else {
-				earfcn_budget = 17; /* computer budget per-EARFCN */
+				earfcn_budget = 17; /* compute budget per-EARFCN */
 				if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
 					earfcn_budget++;
 				else
 					earfcn_budget += 4;
 
-				if (rem - earfcn_budget < 0) {
+				if (rem - earfcn_budget < 0)
 					break;
-				} else {
+				else {
 					bts->e_offset++;
+					rem -= earfcn_budget;
 					bitvec_set_bit(bv, 1); /* EARFCN: */
 					bitvec_set_uint(bv, e->arfcn[i], 16);
 
@@ -143,6 +150,12 @@
 
 static inline void append_earfcn(struct bitvec *bv, struct gsm_bts *bts, uint8_t budget)
 {
+	int rem = budget - 25;
+	if (rem <= 0)
+		return;
+
+	OSMO_ASSERT(budget <= SI2Q_MAX_LEN);
+
 	/* Additions in Rel-5: */
 	bitvec_set_bit(bv, H);
 	/* No 3G Additional Measurement Param. Descr. */
@@ -191,7 +204,7 @@
 	bitvec_set_bit(bv, 1);
 
 	/* N. B: 25 bits are set in append_earfcn() - keep it in sync with budget adjustment below: */
-	append_eutran_neib_cell(bv, bts, budget - 25);
+	append_eutran_neib_cell(bv, bts, rem);
 
 	/* stop bit - end of Repeated E-UTRAN Neighbour Cells sequence: */
 	bitvec_set_bit(bv, 0);
@@ -267,7 +280,12 @@
 	const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list;
 	int i, j, k, rc, st = 0, a[bts->si_common.uarfcn_length];
 	uint16_t cu = u[bts->u_offset]; /* caller ensures that length is positive */
-	uint8_t rem = budget - 7; /* account for constant bits right away */
+	uint8_t rem = budget - 7, offset_diff; /* account for constant bits right away */
+
+	OSMO_ASSERT(budget <= SI2Q_MAX_LEN);
+
+	if (budget <= 7)
+		return -ENOMEM;
 
 	/* 3G Neighbour Cell Description */
 	bitvec_set_bit(bv, 1);
@@ -282,20 +300,22 @@
 	bitvec_set_bit(bv, 0);
 
 	for (i = bts->u_offset; i < bts->si_common.uarfcn_length; i++) {
-		for (j = st, k = 0; j < i; j++)
+		offset_diff = 0;
+		for (j = st, k = 0; j < i; j++) {
 			a[k++] = sc[j]; /* copy corresponding SCs */
-
+			offset_diff++; /* compute proper offset step */
+		}
 		if (u[i] != cu) { /* we've reached new UARFCN */
 			rc = append_utran_fdd_length(cu, a, bts->si_common.uarfcn_length, k);
 			if (rc < 0) { /* estimate bit length requirements */
 				return rc;
 			}
 
-			if (rem - rc < 0) {
+			if (rem - rc <= 0)
 				break; /* we have ran out of budget in current SI2q */
-			} else {
+			else {
 				rem -= append_utran_fdd(bv, cu, a, k);
-				bts->u_offset++;
+				bts->u_offset += offset_diff;
 			}
 			cu = u[i];
 			st = i; /* update start position */
@@ -303,9 +323,11 @@
 	}
 
 	if (rem > 22) {	/* add last UARFCN not covered by previous cycle if it could possibly fit into budget */
-		for (i = st, k = 0; i < bts->si_common.uarfcn_length; i++)
+		offset_diff = 0;
+		for (i = st, k = 0; i < bts->si_common.uarfcn_length; i++) {
 			a[k++] = sc[i];
-
+			offset_diff++;
+		}
 		rc = append_utran_fdd_length(cu, a, bts->si_common.uarfcn_length, k);
 		if (rc < 0) {
 			return rc;
@@ -313,7 +335,7 @@
 
 		if (rem - rc >= 0) {
 			rem -= append_utran_fdd(bv, cu, a, k);
-			bts->u_offset++;
+			bts->u_offset += offset_diff;
 		}
 	}
 
@@ -331,6 +353,10 @@
 {
 	int rc;
 	struct bitvec bv;
+
+	if (bts->si2q_count < bts->si2q_index)
+		return -EINVAL;
+
 	bv.data = data;
 	bv.data_len = 20;
 	bitvec_zero(&bv);
@@ -362,34 +388,28 @@
 	/* No extension (length) */
 	bitvec_set_bit(&bv, 0);
 
-	if (bts->si_common.uarfcn_length) {
-		/* Even if we do not append EARFCN we still need to set 3 bits */
-		rc = append_uarfcns(&bv, bts, SI2Q_MAX_LEN - (bv.cur_bit + 3));
+	rc = SI2Q_MAX_LEN - (bv.cur_bit + 3);
+	if (rc > 0 && bts->si_common.uarfcn_length - bts->u_offset > 0) {
+		rc = append_uarfcns(&bv, bts, rc);
 		if (rc < 0) {
-			LOGP(DRR, LOGL_ERROR, "SI2quater: failed to append %zu UARFCNs due to range encoding failure: %s\n",
-			     bts->si_common.uarfcn_length, strerror(-rc));
+			LOGP(DRR, LOGL_ERROR, "SI2quater [%u/%u]: failed to append %zu UARFCNs due to range encoding "
+			     "failure: %s\n",
+			     bts->si2q_index, bts->si2q_count, bts->si_common.uarfcn_length, strerror(-rc));
 			return rc;
 		}
-	} else { /* No 3G Neighbour Cell Description */
+	} else /* No 3G Neighbour Cell Description */
 		bitvec_set_bit(&bv, 0);
-	}
 
 	/* No 3G Measurement Parameters Description */
 	bitvec_set_bit(&bv, 0);
 	/* No GPRS_3G_MEASUREMENT Parameters Descr. */
 	bitvec_set_bit(&bv, 0);
 
-	if (si2q_earfcn_count(&bts->si_common.si2quater_neigh_list)) {
-		append_earfcn(&bv, bts, SI2Q_MAX_LEN - bv.cur_bit);
-
-		/* FIXME: remove following check once multiple SI2q are properly supported */
-		if ((bts->e_offset != si2q_earfcn_count(&bts->si_common.si2quater_neigh_list)) ||
-		    si2q_earfcn_count(&bts->si_common.si2quater_neigh_list) > 5)
-			return -ENOMEM;
-	} else {
-		/* No Additions in Rel-5: */
+	rc = SI2Q_MAX_LEN - bv.cur_bit;
+	if (rc > 0 && si2q_earfcn_count(&bts->si_common.si2quater_neigh_list) - bts->e_offset > 0)
+		append_earfcn(&bv, bts, rc);
+	else /* No Additions in Rel-5: */
 		bitvec_set_bit(&bv, L);
-	}
 
 	bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
 	return bv.data_len;
diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c
index a074a78..dcabbbd 100644
--- a/openbsc/src/libbsc/system_information.c
+++ b/openbsc/src/libbsc/system_information.c
@@ -122,50 +122,73 @@
 	}
 }
 
-static inline unsigned earfcn_size(const struct gsm_bts *bts)
+size_t si2q_earfcn_count(const struct osmo_earfcn_si2q *e)
 {
-	const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; /* EARFCN */
+	unsigned i, ret = 0;
 
-	/* account for all the constant bits in append_earfcn() */
-	return 25 + osmo_earfcn_bit_size_ext(e, bts->e_offset);
+	if (!e)
+		return 0;
+
+	for (i = 0; i < e->length; i++)
+		if (e->arfcn[i] != OSMO_EARFCN_INVALID)
+			ret++;
+
+	return ret;
 }
 
-static inline unsigned uarfcn_size(const struct gsm_bts *bts)
+/* generate SI2quater messages, return rest octets length of last generated message or negative error code */
+static int make_si2quaters(struct gsm_bts *bts, bool counting)
 {
-	const uint16_t *u = bts->si_common.data.uarfcn_list;
-	uint16_t cu = u[bts->u_offset]; /* UARFCN */
-	/* account for all the constant bits in append_uarfcns() */
-	unsigned s = 7, append = 22, r = 0, i, st = 0, j, k;
+	int rc;
+	bool memory_exceeded = true;
+	struct gsm48_system_information_type_2quater *si2q;
 
-	for (i = bts->u_offset; i < bts->si_common.uarfcn_length; i++) {
-		for (j = st, k = 0; j < i; j++, k++);
-		if (u[i] != cu) { /* we've reached new UARFCN */
-			r += (append + range1024_p(k));
-			cu = u[i];
-			st = i; /* update start position */
+	for (bts->si2q_index = 0; bts->si2q_index < SI2Q_MAX_NUM; bts->si2q_index++) {
+		si2q = GSM_BTS_SI2Q(bts, bts->si2q_index);
+		if (counting) { /* that's legitimate if we're called for counting purpose: */
+			if (bts->si2q_count < bts->si2q_index)
+				bts->si2q_count = bts->si2q_index;
+		} else {
+			memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
+
+			si2q->header.l2_plen = GSM48_LEN2PLEN(22);
+			si2q->header.rr_protocol_discriminator = GSM48_PDISC_RR;
+			si2q->header.skip_indicator = 0;
+			si2q->header.system_information = GSM48_MT_RR_SYSINFO_2quater;
+		}
+
+		rc = rest_octets_si2quater(si2q->rest_octets, bts);
+		if (rc < 0)
+			return rc;
+
+		if (bts->u_offset >= bts->si_common.uarfcn_length &&
+		    bts->e_offset >= si2q_earfcn_count(&bts->si_common.si2quater_neigh_list)) {
+			memory_exceeded = false;
+			break;
 		}
 	}
 
-	/* add last UARFCN not covered by previous cycle */
-	for (i = st, k = 0; i < bts->si_common.uarfcn_length; i++, k++);
+	if (memory_exceeded)
+		return -ENOMEM;
 
-	return s + r + append + range1024_p(k);
+	return rc;
 }
 
+/* we generate SI2q rest octets twice to get proper estimation but it's one time cost anyway */
 uint8_t si2q_num(struct gsm_bts *bts)
 {
-	size_t est, e_sz = 1, u_sz = 1;
+	int rc = make_si2quaters(bts, true);
+	uint8_t num = bts->si2q_index + 1; /* number of SI2quater messages */
 
-	if (&bts->si_common.si2quater_neigh_list) /* EARFCN */
-		e_sz = earfcn_size(bts);
+	/* N. B: si2q_num() should NEVER be called during actualSI2q rest octets generation
+	   we're not re-entrant because of the following code: */
+	bts->u_offset = 0;
+	bts->e_offset = 0;
 
-	if (bts->si_common.uarfcn_length) /* UARFCN */
-		u_sz = uarfcn_size(bts);
+	if (rc < 0)
+		return 0xFF; /* return impossible index as an indicator of error in generating SI2quater */
 
-	/* 2 bits are used in between UARFCN and EARFCN structs */
-	est = 1 + (e_sz + u_sz) / (SI2Q_MAX_LEN - (SI2Q_MIN_LEN + 2));
-
-	return est;
+	return num;
 }
 
 /* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */
@@ -174,6 +197,44 @@
 	if (diversity)
 		return scramble | (1 << 9);
 	return scramble;
+}
+
+int bts_earfcn_add(struct gsm_bts *bts, uint16_t earfcn, uint8_t thresh_hi, uint8_t thresh_lo, uint8_t prio,
+		   uint8_t qrx, uint8_t meas_bw)
+{
+	struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
+	int r = osmo_earfcn_add(e, earfcn, (meas_bw < EARFCN_MEAS_BW_INVALID) ? meas_bw : OSMO_EARFCN_MEAS_INVALID);
+
+	if (r < 0)
+		return r;
+
+	if (e->thresh_hi && thresh_hi != e->thresh_hi)
+		r = 1;
+
+	e->thresh_hi = thresh_hi;
+
+	if (thresh_lo != EARFCN_THRESH_LOW_INVALID) {
+		if (e->thresh_lo_valid && e->thresh_lo != thresh_lo)
+			r = EARFCN_THRESH_LOW_INVALID;
+		e->thresh_lo = thresh_lo;
+		e->thresh_lo_valid = true;
+	}
+
+	if (qrx != EARFCN_QRXLV_INVALID) {
+		if (e->qrxlm_valid && e->qrxlm != qrx)
+			r = EARFCN_QRXLV_INVALID + 1;
+		e->qrxlm = qrx;
+		e->qrxlm_valid = true;
+	}
+
+	if (prio != EARFCN_PRIO_INVALID) {
+		if (e->prio_valid && e->prio != prio)
+			r = EARFCN_PRIO_INVALID;
+		e->prio = prio;
+		e->prio_valid = true;
+	}
+
+	return r;
 }
 
 int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble)
@@ -237,8 +298,10 @@
 	scl[k] = scr;
 	bts->si_common.uarfcn_length++;
 
-	if (si2q_num(bts) < 2) /* FIXME: use SI2Q_MAX_NUM */
+	if (si2q_num(bts) <= SI2Q_MAX_NUM) {
+		bts->si2q_count = si2q_num(bts) - 1;
 		return 0;
+	}
 
 	bts_uarfcn_del(bts, arfcn, scramble);
 	return -ENOSPC;
@@ -689,39 +752,26 @@
 	return false;
 }
 
-size_t si2q_earfcn_count(const struct osmo_earfcn_si2q *e)
-{
-	unsigned i, ret = 0;
-
-	if (!e)
-		return 0;
-
-	for (i = 0; i < e->length; i++)
-		if (e->arfcn[i] != OSMO_EARFCN_INVALID)
-			ret++;
-
-	return ret;
-}
-
 static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts)
 {
 	int rc;
-	struct gsm48_system_information_type_2quater *si2q = GSM_BTS_SI2Q(bts);
+	struct gsm48_system_information_type_2quater *si2q;
 
 	if (si2quater_not_needed(bts)) /* generate rest_octets for SI2q only when necessary */
 		return GSM_MACBLOCK_LEN;
 
-	memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN);
+	bts->u_offset = 0;
+	bts->e_offset = 0;
+	bts->si2q_index = 0;
+	bts->si2q_count = si2q_num(bts) - 1;
 
-	si2q->header.l2_plen = GSM48_LEN2PLEN(22);
-	si2q->header.rr_protocol_discriminator = GSM48_PDISC_RR;
-	si2q->header.skip_indicator = 0;
-	si2q->header.system_information = GSM48_MT_RR_SYSINFO_2quater;
-
-	rc = rest_octets_si2quater(si2q->rest_octets, bts);
+	rc = make_si2quaters(bts, false);
 	if (rc < 0)
 		return rc;
 
+	OSMO_ASSERT(bts->si2q_count == bts->si2q_index);
+	OSMO_ASSERT(bts->si2q_count <= SI2Q_MAX_NUM);
+
 	return sizeof(*si2q) + rc;
 }
 
diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c
index 5a78505..5a8c6ca 100644
--- a/openbsc/tests/gsm0408/gsm0408_test.c
+++ b/openbsc/tests/gsm0408/gsm0408_test.c
@@ -89,25 +89,19 @@
 {
 	int r;
 
-	bts->u_offset = 0;
-	bts->e_offset = 0;
-	bts->si2q_index = 0;
-	bts->si2q_count = 0;
 	bts->si_valid = 0;
 	bts->si_valid |= (1 << SYSINFO_TYPE_2quater);
-
-	/* should be no-op as entire buffer is filled with padding: */
-	memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN);
 
 	printf("generating SI2quater for %zu EARFCNs and %zu UARFCNs...\n",
 	       si2q_earfcn_count(&bts->si_common.si2quater_neigh_list), bts->si_common.uarfcn_length);
 
 	r = gsm_generate_si(bts, SYSINFO_TYPE_2quater);
 	if (r > 0)
-		printf("generated %s SI2quater [%02u/%02u]: [%d] %s\n",
-		       GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2quater) ? "valid" : "invalid",
-		       bts->si2q_index, bts->si2q_count, r,
-		       osmo_hexdump((void *)GSM_BTS_SI2Q(bts), GSM_MACBLOCK_LEN));
+		for (bts->si2q_index = 0; bts->si2q_index < bts->si2q_count + 1; bts->si2q_index++)
+			printf("generated %s SI2quater [%02u/%02u]: [%d] %s\n",
+			       GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2quater) ? "valid" : "invalid",
+			       bts->si2q_index, bts->si2q_count, r,
+			       osmo_hexdump((void *)GSM_BTS_SI2Q(bts, bts->si2q_index), GSM_MACBLOCK_LEN));
 	else
 		printf("%s() failed to generate SI2quater: %s\n", s, strerror(-r));
 }
@@ -145,8 +139,10 @@
 	r = bts_uarfcn_add(bts, arfcn, scramble, diversity);
 	if (r < 0)
 		printf("failed to add UARFCN to SI2quater: %s\n", strerror(-r));
-	else
+	else {
+		bts->si2q_count = si2q_num(bts) - 1;
 		gen(bts, __func__);
+	}
 }
 
 static inline void test_si2q_segfault(void)
@@ -181,7 +177,6 @@
 	_bts_uarfcn_add(bts, 10613, 64, 0);
 	_bts_uarfcn_add(bts, 10613, 164, 0);
 	_bts_uarfcn_add(bts, 10613, 14, 0);
-	gen(bts, __func__);
 }
 
 static inline void test_si2q_u(void)
@@ -192,10 +187,12 @@
 
 	if (!network)
 		exit(1);
+
 	bts = gsm_bts_alloc(network);
 
 	/* first generate invalid SI as no UARFCN added */
 	gen(bts, __func__);
+
 	/* subsequent calls should produce valid SI if there's enough memory */
 	_bts_uarfcn_add(bts, 1982, 13, 1);
 	_bts_uarfcn_add(bts, 1982, 44, 0);
@@ -208,7 +205,6 @@
 	_bts_uarfcn_add(bts, 1982, 223, 1);
 	_bts_uarfcn_add(bts, 1982, 14, 0);
 	_bts_uarfcn_add(bts, 1982, 88, 0);
-	gen(bts, __func__);
 }
 
 static inline void test_si2q_e(void)
@@ -219,6 +215,7 @@
 
 	if (!network)
 		exit(1);
+
 	bts = gsm_bts_alloc(network);
 
 	bts->si_common.si2quater_neigh_list.arfcn = bts->si_common.data.earfcn_list;
@@ -227,8 +224,10 @@
 	bts->si_common.si2quater_neigh_list.thresh_hi = 5;
 
 	osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);
+
 	/* first generate invalid SI as no EARFCN added */
 	gen(bts, __func__);
+
 	/* subsequent calls should produce valid SI if there's enough memory and EARFCNs */
 	add_earfcn_b(bts, 1917, 5);
 	del_earfcn_b(bts, 1917);
@@ -239,6 +238,54 @@
 	add_earfcn_b(bts, 1965, OSMO_EARFCN_MEAS_INVALID);
 	add_earfcn_b(bts, 1967, 4);
 	add_earfcn_b(bts, 1982, 3);
+}
+
+static inline void test_si2q_long(void)
+{
+	struct gsm_bts *bts;
+	struct gsm_network *network = bsc_network_init(tall_bsc_ctx, 1, 1, NULL);
+	printf("Testing SYSINFO_TYPE_2quater combined EARFCN & UARFCN generation:\n");
+
+	if (!network)
+		exit(1);
+
+	bts = gsm_bts_alloc(network);
+
+	bts->si_common.si2quater_neigh_list.arfcn = bts->si_common.data.earfcn_list;
+	bts->si_common.si2quater_neigh_list.meas_bw = bts->si_common.data.meas_bw_list;
+	bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;
+	bts->si_common.si2quater_neigh_list.thresh_hi = 5;
+
+	osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);
+
+	bts_earfcn_add(bts, 1922, 11, 22, 8,32, 8);
+	bts_earfcn_add(bts, 1922, 11, 22, 8, 32, 8);
+	bts_earfcn_add(bts, 1924, 11, 12, 6, 11, 5);
+	bts_earfcn_add(bts, 1923, 11, 12, 6, 11, 5);
+	bts_earfcn_add(bts, 1925, 11, 12, 6, 11, 5);
+	bts_earfcn_add(bts, 2111, 11, 12, 6, 11, 5);
+	bts_earfcn_add(bts, 2112, 11, 12, 6, 11, 4);
+	bts_earfcn_add(bts, 2113, 11, 12, 6, 11, 3);
+	bts_earfcn_add(bts, 2114, 11, 12, 6, 11, 2);
+	bts_earfcn_add(bts, 2131, 11, 12, 6, 11, 5);
+	bts_earfcn_add(bts, 2132, 11, 12, 6, 11, 4);
+	bts_earfcn_add(bts, 2133, 11, 12, 6, 11, 3);
+	bts_earfcn_add(bts, 2134, 11, 12, 6, 11, 2);
+	bts_earfcn_add(bts, 2121, 11, 12, 6, 11, 5);
+	bts_earfcn_add(bts, 2122, 11, 12, 6, 11, 4);
+	bts_earfcn_add(bts, 2123, 11, 12, 6, 11, 3);
+	bts_earfcn_add(bts, 2124, 11, 12, 6, 11, 2);
+	_bts_uarfcn_add(bts, 1976, 13, 1);
+	_bts_uarfcn_add(bts, 1976, 38, 1);
+	_bts_uarfcn_add(bts, 1976, 44, 1);
+	_bts_uarfcn_add(bts, 1976, 120, 1);
+	_bts_uarfcn_add(bts, 1976, 140, 1);
+	_bts_uarfcn_add(bts, 1976, 163, 1);
+	_bts_uarfcn_add(bts, 1976, 166, 1);
+	_bts_uarfcn_add(bts, 1976, 217, 1);
+	_bts_uarfcn_add(bts, 1976, 224, 1);
+	_bts_uarfcn_add(bts, 1976, 225, 1);
+	_bts_uarfcn_add(bts, 1976, 226, 1);
 }
 
 static void test_mi_functionality(void)
@@ -642,6 +689,9 @@
 	test_si2q_e();
 	test_si2q_u();
 	test_si2q_mu();
+	test_si2q_long();
+
 	printf("Done.\n");
+
 	return EXIT_SUCCESS;
 }
diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok
index 5e0b9d5..d30f421 100644
--- a/openbsc/tests/gsm0408/gsm0408_test.ok
+++ b/openbsc/tests/gsm0408/gsm0408_test.ok
@@ -71,11 +71,11 @@
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 52 e8 0a 7f 52 88 0a 7e 0b 2b 2b 2b 2b 2b 2b 2b 2b 
 Testing SYSINFO_TYPE_2quater EARFCN generation:
 generating SI2quater for 0 EARFCNs and 0 UARFCNs...
-generated invalid SI2quater [00/00]: [23] ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae 
+generated invalid SI2quater [00/00]: [23] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 added EARFCN 1917 - generating SI2quater for 1 EARFCNs and 0 UARFCNs...
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 04 86 59 83 be e8 50 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 removed EARFCN 1917 - generating SI2quater for 0 EARFCNs and 0 UARFCNs...
-generated invalid SI2quater [00/00]: [23] ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae 
+generated invalid SI2quater [00/00]: [23] 59 06 07 c0 00 04 86 59 83 be e8 50 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 added EARFCN 1917 - generating SI2quater for 1 EARFCNs and 0 UARFCNs...
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 04 86 59 83 be c8 50 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 added EARFCN 1932 - generating SI2quater for 2 EARFCNs and 0 UARFCNs...
@@ -87,12 +87,14 @@
 added EARFCN 1965 - generating SI2quater for 5 EARFCNs and 0 UARFCNs...
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 04 86 59 83 be cc 1e 31 07 91 a8 3c ca 0f 5a 0a 03 2b 
 added EARFCN 1967 - generating SI2quater for 6 EARFCNs and 0 UARFCNs...
-add_earfcn_b() failed to generate SI2quater: Cannot allocate memory
+generated valid SI2quater [00/01]: [23] 59 06 07 c0 20 04 86 59 83 be cc 1e 31 07 91 a8 3c ca 0f 5a 0a 03 2b 
+generated valid SI2quater [01/01]: [23] 59 06 07 c2 20 04 86 59 83 d7 e0 50 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 added EARFCN 1982 - generating SI2quater for 7 EARFCNs and 0 UARFCNs...
-add_earfcn_b() failed to generate SI2quater: Cannot allocate memory
+generated valid SI2quater [00/01]: [23] 59 06 07 c0 20 04 86 59 83 be cc 1e 31 07 91 a8 3c ca 0f 5a 0a 03 2b 
+generated valid SI2quater [01/01]: [23] 59 06 07 c2 20 04 86 59 83 d7 e4 1e fa c2 80 2b 2b 2b 2b 2b 2b 2b 2b 
 Testing SYSINFO_TYPE_2quater UARFCN generation:
 generating SI2quater for 0 EARFCNs and 0 UARFCNs...
-generated invalid SI2quater [00/00]: [23] ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae ae 
+generated invalid SI2quater [00/00]: [23] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 generating SI2quater for 0 EARFCNs and 1 UARFCNs...
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 0f 7c 0c 1a 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 generating SI2quater for 0 EARFCNs and 2 UARFCNs...
@@ -111,10 +113,10 @@
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 0f 7c 40 58 1d 22 fa ce 88 85 7b 0b 2b 2b 2b 2b 2b 
 generating SI2quater for 0 EARFCNs and 9 UARFCNs...
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 0f 7c 4c 7a 34 0e 64 77 85 43 55 c8 0b 2b 2b 2b 2b 
-failed to add UARFCN to SI2quater: No space left on device
-failed to add UARFCN to SI2quater: No space left on device
-generating SI2quater for 0 EARFCNs and 9 UARFCNs...
-generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 0f 7c 4c 7a 34 0e 64 77 85 43 55 c8 0b 2b 2b 2b 2b 
+generating SI2quater for 0 EARFCNs and 10 UARFCNs...
+generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 0f 7c 50 1c 3b 31 fa dd 88 85 7b c4 1c 2b 2b 2b 2b 
+generating SI2quater for 0 EARFCNs and 11 UARFCNs...
+generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 0f 7c 58 1c 3b 25 7a ea 08 91 fb c4 1f b0 2b 2b 2b 
 Test SI2quater multiple UARFCNs:
 generating SI2quater for 0 EARFCNs and 1 UARFCNs...
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 52 88 0a 7c 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
@@ -124,9 +126,79 @@
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 52 e8 12 7e e0 a9 44 05 3e 0b 2b 2b 2b 2b 2b 2b 2b 
 generating SI2quater for 0 EARFCNs and 4 UARFCNs...
 generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 52 e8 18 3f f4 90 54 a2 02 9f 03 2b 2b 2b 2b 2b 2b 
-failed to add UARFCN to SI2quater: No space left on device
-failed to add UARFCN to SI2quater: No space left on device
-failed to add UARFCN to SI2quater: No space left on device
-generating SI2quater for 0 EARFCNs and 4 UARFCNs...
-generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 52 e8 18 3f f4 90 54 a2 02 9f 03 2b 2b 2b 2b 2b 2b 
+generating SI2quater for 0 EARFCNs and 5 UARFCNs...
+generated valid SI2quater [00/00]: [23] 59 06 07 c0 00 25 52 ea 08 81 52 e8 18 3f f4 90 54 a2 02 9f 03 2b 2b 
+generating SI2quater for 0 EARFCNs and 6 UARFCNs...
+generated valid SI2quater [00/01]: [23] 59 06 07 c0 20 25 52 ea 08 81 52 e8 10 3f f4 a9 75 04 a4 0b 2b 2b 2b 
+generated valid SI2quater [01/01]: [23] 59 06 07 c2 20 25 52 e8 28 81 df 7f fa 32 d4 a2 02 9f 03 2b 2b 2b 2b 
+generating SI2quater for 0 EARFCNs and 7 UARFCNs...
+generated valid SI2quater [00/01]: [23] 59 06 07 c0 20 25 52 ea 10 81 ce a9 74 08 1f fa 54 ba 82 52 03 2b 2b 
+generated valid SI2quater [01/01]: [23] 59 06 07 c2 20 25 52 e8 30 81 d3 7f fd b2 86 54 a2 02 9f 03 2b 2b 2b 
+Testing SYSINFO_TYPE_2quater combined EARFCN & UARFCN generation:
+generating SI2quater for 17 EARFCNs and 1 UARFCNs...
+generated valid SI2quater [00/04]: [23] 59 06 07 c0 80 25 0f 70 0c 1a 10 99 66 0f 04 83 c1 1c bb 2b 03 2b 2b 
+generated valid SI2quater [01/04]: [23] 59 06 07 c2 80 04 86 59 83 c2 6c 1e 0f 60 f0 bb 08 3f d7 2e ca c1 2b 
+generated valid SI2quater [02/04]: [23] 59 06 07 c4 80 04 86 59 84 20 64 21 06 e1 08 55 08 53 d7 2e ca c1 2b 
+generated valid SI2quater [03/04]: [23] 59 06 07 c6 80 04 86 59 84 2a 64 21 56 e1 0a d5 08 49 d7 2e ca c1 2b 
+generated valid SI2quater [04/04]: [23] 59 06 07 c8 80 04 86 59 84 25 64 21 2e e1 09 94 e5 d9 58 2b 2b 2b 2b 
+generating SI2quater for 17 EARFCNs and 2 UARFCNs...
+generated valid SI2quater [00/04]: [23] 59 06 07 c0 80 25 0f 70 14 4d e7 00 44 b3 07 82 41 e0 8e 5d 95 83 2b 
+generated valid SI2quater [01/04]: [23] 59 06 07 c2 80 04 86 59 83 c2 6c 1e 0f 60 f0 bb 08 3f d7 2e ca c1 2b 
+generated valid SI2quater [02/04]: [23] 59 06 07 c4 80 04 86 59 84 20 64 21 06 e1 08 55 08 53 d7 2e ca c1 2b 
+generated valid SI2quater [03/04]: [23] 59 06 07 c6 80 04 86 59 84 2a 64 21 56 e1 0a d5 08 49 d7 2e ca c1 2b 
+generated valid SI2quater [04/04]: [23] 59 06 07 c8 80 04 86 59 84 25 64 21 2e e1 09 94 e5 d9 58 2b 2b 2b 2b 
+generating SI2quater for 17 EARFCNs and 3 UARFCNs...
+generated valid SI2quater [00/04]: [23] 59 06 07 c0 80 25 0f 70 1c 4d e7 03 04 86 59 83 c1 20 f0 47 2e ca c1 
+generated valid SI2quater [01/04]: [23] 59 06 07 c2 80 04 86 59 83 c2 6c 1e 0f 60 f0 bb 08 3f d7 2e ca c1 2b 
+generated valid SI2quater [02/04]: [23] 59 06 07 c4 80 04 86 59 84 20 64 21 06 e1 08 55 08 53 d7 2e ca c1 2b 
+generated valid SI2quater [03/04]: [23] 59 06 07 c6 80 04 86 59 84 2a 64 21 56 e1 0a d5 08 49 d7 2e ca c1 2b 
+generated valid SI2quater [04/04]: [23] 59 06 07 c8 80 04 86 59 84 25 64 21 2e e1 09 94 e5 d9 58 2b 2b 2b 2b 
+generating SI2quater for 17 EARFCNs and 4 UARFCNs...
+generated valid SI2quater [00/04]: [23] 59 06 07 c0 80 25 0f 70 24 59 fa 26 73 84 86 59 83 c1 1c bb 2b 03 2b 
+generated valid SI2quater [01/04]: [23] 59 06 07 c2 80 04 86 59 83 c1 20 f0 9b 07 83 d8 3c 2e b9 76 56 0b 2b 
+generated valid SI2quater [02/04]: [23] 59 06 07 c4 80 04 86 59 84 1f ec 21 03 21 08 37 08 42 a7 2e ca c1 2b 
+generated valid SI2quater [03/04]: [23] 59 06 07 c6 80 04 86 59 84 29 ec 21 53 21 0a b7 08 56 a7 2e ca c1 2b 
+generated valid SI2quater [04/04]: [23] 59 06 07 c8 80 04 86 59 84 24 ec 21 2b 21 09 77 08 4c a7 2e ca c1 2b 
+generating SI2quater for 17 EARFCNs and 5 UARFCNs...
+generated valid SI2quater [00/04]: [23] 59 06 07 c0 80 25 0f 70 2c 59 fa 30 73 f6 04 86 59 83 c1 1c bb 2b 03 
+generated valid SI2quater [01/04]: [23] 59 06 07 c2 80 04 86 59 83 c1 20 f0 9b 07 83 d8 3c 2e b9 76 56 0b 2b 
+generated valid SI2quater [02/04]: [23] 59 06 07 c4 80 04 86 59 84 1f ec 21 03 21 08 37 08 42 a7 2e ca c1 2b 
+generated valid SI2quater [03/04]: [23] 59 06 07 c6 80 04 86 59 84 29 ec 21 53 21 0a b7 08 56 a7 2e ca c1 2b 
+generated valid SI2quater [04/04]: [23] 59 06 07 c8 80 04 86 59 84 24 ec 21 2b 21 09 77 08 4c a7 2e ca c1 2b 
+generating SI2quater for 17 EARFCNs and 6 UARFCNs...
+generated valid SI2quater [00/05]: [23] 59 06 07 c0 a0 25 0f 70 34 f1 ae 15 f3 f4 83 04 86 59 72 ec ac 0b 2b 
+generated valid SI2quater [01/05]: [23] 59 06 07 c2 a0 04 86 59 83 c1 20 f0 48 3c 26 c1 e0 f5 cb b2 b0 2b 2b 
+generated valid SI2quater [02/05]: [23] 59 06 07 c4 a0 04 86 59 83 c2 ec 20 ff 61 08 19 08 41 b7 2e ca c1 2b 
+generated valid SI2quater [03/05]: [23] 59 06 07 c6 a0 04 86 59 84 21 54 21 4f 61 0a 99 08 55 b7 2e ca c1 2b 
+generated valid SI2quater [04/05]: [23] 59 06 07 c8 a0 04 86 59 84 2b 54 21 27 61 09 59 08 4b b7 2e ca c1 2b 
+generated valid SI2quater [05/05]: [23] 59 06 07 ca a0 04 86 59 84 26 53 97 65 60 2b 2b 2b 2b 2b 2b 2b 2b 2b 
+generating SI2quater for 17 EARFCNs and 7 UARFCNs...
+generated valid SI2quater [00/05]: [23] 59 06 07 c0 a0 25 0f 70 3c f1 ae 15 f3 f4 83 01 84 86 59 72 ec ac 0b 
+generated valid SI2quater [01/05]: [23] 59 06 07 c2 a0 04 86 59 83 c1 20 f0 48 3c 26 c1 e0 f5 cb b2 b0 2b 2b 
+generated valid SI2quater [02/05]: [23] 59 06 07 c4 a0 04 86 59 83 c2 ec 20 ff 61 08 19 08 41 b7 2e ca c1 2b 
+generated valid SI2quater [03/05]: [23] 59 06 07 c6 a0 04 86 59 84 21 54 21 4f 61 0a 99 08 55 b7 2e ca c1 2b 
+generated valid SI2quater [04/05]: [23] 59 06 07 c8 a0 04 86 59 84 2b 54 21 27 61 09 59 08 4b b7 2e ca c1 2b 
+generated valid SI2quater [05/05]: [23] 59 06 07 ca a0 04 86 59 84 26 53 97 65 60 2b 2b 2b 2b 2b 2b 2b 2b 2b 
+generating SI2quater for 17 EARFCNs and 8 UARFCNs...
+generated valid SI2quater [00/02]: [23] 59 06 07 c0 40 25 0f 70 45 19 a0 0d 7d 7e a6 19 e7 00 44 b3 07 82 41 
+generated valid SI2quater [01/02]: [23] 59 06 07 c2 40 04 86 59 84 2b 54 21 27 61 09 59 08 4b b7 2e ca c1 2b 
+generated valid SI2quater [02/02]: [23] 59 06 07 c4 40 04 86 59 84 26 53 97 65 60 2b 2b 2b 2b 2b 2b 2b 2b 2b 
+generating SI2quater for 17 EARFCNs and 9 UARFCNs...
+generated valid SI2quater [00/02]: [23] 59 06 07 c0 40 25 0f 70 4d 19 a0 26 fd 66 a6 03 e7 fa 10 99 66 0f 04 
+generated valid SI2quater [01/02]: [23] 59 06 07 c2 40 04 86 59 84 2b 54 21 27 61 09 59 08 4b b7 2e ca c1 2b 
+generated valid SI2quater [02/02]: [23] 59 06 07 c4 40 04 86 59 84 26 53 97 65 60 2b 2b 2b 2b 2b 2b 2b 2b 2b 
+generating SI2quater for 17 EARFCNs and 10 UARFCNs...
+generated valid SI2quater [00/05]: [23] 59 06 07 c0 a0 25 0f 70 55 47 89 1e fd 7c b0 00 e7 9b b0 04 12 c8 2b 
+generated valid SI2quater [01/05]: [23] 59 06 07 c2 a0 04 86 59 83 c1 20 f0 48 3c 26 c1 e0 f5 cb b2 b0 2b 2b 
+generated valid SI2quater [02/05]: [23] 59 06 07 c4 a0 04 86 59 83 c2 ec 20 ff 61 08 19 08 41 b7 2e ca c1 2b 
+generated valid SI2quater [03/05]: [23] 59 06 07 c6 a0 04 86 59 84 21 54 21 4f 61 0a 99 08 55 b7 2e ca c1 2b 
+generated valid SI2quater [04/05]: [23] 59 06 07 c8 a0 04 86 59 84 2b 54 21 27 61 09 59 08 4b b7 2e ca c1 2b 
+generated valid SI2quater [05/05]: [23] 59 06 07 ca a0 04 86 59 84 26 53 97 65 60 2b 2b 2b 2b 2b 2b 2b 2b 2b 
+generating SI2quater for 17 EARFCNs and 11 UARFCNs...
+generated valid SI2quater [00/05]: [23] 59 06 07 c0 a0 25 0f 70 5d 47 89 1e fd 7c b0 01 67 9b b3 f8 2b 2b 2b 
+generated valid SI2quater [01/05]: [23] 59 06 07 c2 a0 04 86 59 83 c1 20 f0 48 3c 26 c1 e0 f5 cb b2 b0 2b 2b 
+generated valid SI2quater [02/05]: [23] 59 06 07 c4 a0 04 86 59 83 c2 ec 20 ff 61 08 19 08 41 b7 2e ca c1 2b 
+generated valid SI2quater [03/05]: [23] 59 06 07 c6 a0 04 86 59 84 21 54 21 4f 61 0a 99 08 55 b7 2e ca c1 2b 
+generated valid SI2quater [04/05]: [23] 59 06 07 c8 a0 04 86 59 84 2b 54 21 27 61 09 59 08 4b b7 2e ca c1 2b 
+generated valid SI2quater [05/05]: [23] 59 06 07 ca a0 04 86 59 84 26 53 97 65 60 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 Done.

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ic516ec9f0b821557d9461ae9f1c0afdd786f3b05
Gerrit-PatchSet: 6
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Max <msuraev at sysmocom.de>



More information about the gerrit-log mailing list