[MERGED] openbsc[master]: SI2q: add support for multiple UARFCNs

Harald Welte gerrit-no-reply at lists.osmocom.org
Mon Jan 23 13:31:31 UTC 2017


Harald Welte has submitted this change and it was merged.

Change subject: SI2q: add support for multiple UARFCNs
......................................................................


SI2q: add support for multiple UARFCNs

Support multiple UARFCNs with the same Scrambler Code.

Fixes: RT#7379
Change-Id: If1c32e8b547a28325180faaaddd21f80c37f7337
---
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
4 files changed, 107 insertions(+), 34 deletions(-)

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



diff --git a/openbsc/src/libbsc/rest_octets.c b/openbsc/src/libbsc/rest_octets.c
index fc0282e..6fae9cd 100644
--- a/openbsc/src/libbsc/rest_octets.c
+++ b/openbsc/src/libbsc/rest_octets.c
@@ -180,11 +180,40 @@
 	bitvec_set_bit(bv, L);
 }
 
-static inline int append_uarfcn(struct bitvec *bv, const uint16_t *u,
+/* Append single FDD UARFCN */
+static inline int append_utran_fdd(struct bitvec *bv, uint16_t u, int *sc,
+				   size_t length)
+{
+	int f0, w[RANGE_ENC_MAX_ARFCNS] = { 0 };
+	uint8_t chan_list[16] = {0};
+	/* Repeated UTRAN FDD Neighbour Cells */
+	bitvec_set_bit(bv, 1);
+
+	/* FDD-ARFCN */
+	bitvec_set_bit(bv, 0);
+	bitvec_set_uint(bv, u, 14);
+
+	f0 = range_encode(ARFCN_RANGE_1024, sc, length, w, 0, chan_list);
+	if (f0 < 0)
+		return f0;
+
+	/* FDD_Indic0: parameter value '0000000000' is a member of the set? */
+	bitvec_set_bit(bv, f0);
+	/* NR_OF_FDD_CELLS */
+	bitvec_set_uint(bv, length, 5);
+
+	f0 = bv->cur_bit;
+	bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
+	bv->cur_bit = f0 + range1024_p(length);
+	return 0;
+}
+
+/* Append multiple FDD UARFCNs */
+static inline int append_uarfcns(struct bitvec *bv, const uint16_t *u,
 				 const uint16_t *sc, size_t length)
 {
-	int f0_inc, i, w[RANGE_ENC_MAX_ARFCNS] = { 0 }, a[length];
-	uint8_t chan_list[16] = {0};
+	int i, j, k, rc, st = 0, a[length];
+	uint16_t cu = u[0]; /* caller ensures that length is positive */
 
 	/* 3G Neighbour Cell Description */
 	bitvec_set_bit(bv, 1);
@@ -198,31 +227,24 @@
 	/* No Bandwidth_FDD */
 	bitvec_set_bit(bv, 0);
 
-	memset(w, 0, sizeof(w));
-	for (i = 0; i < length; i++)
-		a[i] = sc[i];
+	for (i = 0; i < length; i++) {
+		for (j = st, k = 0; j < i; j++)
+			a[k++] = sc[j]; /* copy corresponding SCs */
+		if (u[i] != cu) { /* we've reached new UARFCN */
+			rc = append_utran_fdd(bv, cu, a, k);
+			if (rc < 0)
+				return rc;
+			cu = u[i];
+			st = i; /* update start position */
+		}
+	}
 
-	/* Note: we do not support repeating Neighbour Cells ATM */
-	/* Repeated UTRAN FDD Neighbour Cells */
-	bitvec_set_bit(bv, 1);
-
-	/* FDD-ARFCN */
-	bitvec_set_bit(bv, 0);
-	/* Note: we do not support multiple UARFCN values ATM: */
-	bitvec_set_uint(bv, u[0], 14);
-
-	f0_inc = range_encode(ARFCN_RANGE_1024, a, length, w, 0, chan_list);
-	if (f0_inc < 0)
-		return f0_inc;
-
-	/* FDD_Indic0: parameter value '0000000000' is not a member of the set */
-	bitvec_set_bit(bv, f0_inc);
-	/* NR_OF_FDD_CELLS */
-	bitvec_set_uint(bv, length, 5);
-
-	i = bv->cur_bit;
-	bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
-	bv->cur_bit = i + range1024_p(length);
+	/* add last UARFCN not covered by previous cycle */
+	for (i = st, k = 0; i < length; i++)
+		a[k++] = sc[i];
+	rc = append_utran_fdd(bv, cu, a, k);
+	if (rc < 0)
+		return rc;
 
 	/* stop bit - end of Repeated UTRAN FDD Neighbour Cells */
 	bitvec_set_bit(bv, 0);
@@ -282,7 +304,8 @@
 			     SI2Q_MAX_LEN);
 			return -ENOMEM;
 		}
-		rc = append_uarfcn(&bv, u, sc, u_len);
+
+		rc = append_uarfcns(&bv, u, sc, u_len);
 		if (rc < 0) {
 			LOGP(DRR, LOGL_ERROR, "SI2quater: failed to append %zu "
 			     "UARFCNs due to range encoding failure: %s\n",
diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c
index 20c3915..e71490e 100644
--- a/openbsc/src/libbsc/system_information.c
+++ b/openbsc/src/libbsc/system_information.c
@@ -130,8 +130,23 @@
 
 unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len)
 {
-	/*account for all the constant bits in append_uarfcn() */
-	return 29 + range1024_p(u_len);
+	/*account for all the constant bits in append_uarfcns() */
+	unsigned s = 7, append = 22, r = 0, i, st = 0, j, k;
+	uint16_t cu = u[0];
+
+	for (i = 0; i < u_len; 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 */
+		}
+	}
+
+	/* add last UARFCN not covered by previous cycle */
+	for (i = st, k = 0; i < u_len; i++, k++);
+
+	return s + r + append + range1024_p(k);
 }
 
 bool si2q_size_check(const struct gsm_bts *bts)
@@ -184,7 +199,7 @@
 int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble,
 		   bool diversity)
 {
-	size_t len = bts->si_common.uarfcn_length, i, k;
+	size_t len = bts->si_common.uarfcn_length, i, k = 0;
 	uint16_t scr, chk,
 		*ual = bts->si_common.data.uarfcn_list,
 		*scl = bts->si_common.data.scramble_list,
@@ -197,7 +212,11 @@
 	if (len == MAX_EARFCN_LIST)
 		return -ENOMEM;
 
-	for (i = 0, k = 0; i < len; i++) {
+	for (i = 0; i < len; i++) /* find the position of arfcn if any */
+		if (arfcn == ual[i])
+			break;
+
+	for (k = 0; i < len; i++) {
 		if (arfcn == ual[i] && (scr == scl[i] || chk == scl[i]))
 			return -EADDRINUSE;
 		if (scr > scl[i])
@@ -209,6 +228,7 @@
 		memmove(ual + k + 1, ual + k, (len - k) * 2);
 		memmove(scl + k + 1, scl + k, (len - k) * 2);
 	}
+
 	ual[k] = arfcn;
 	scl[k] = scr;
 	bts->si_common.uarfcn_length++;
diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c
index 472c2ae..08cf43f 100644
--- a/openbsc/tests/gsm0408/gsm0408_test.c
+++ b/openbsc/tests/gsm0408/gsm0408_test.c
@@ -135,6 +135,26 @@
 	gen(bts);
 }
 
+static inline void test_si2q_mu(void)
+{
+	struct gsm_bts *bts;
+	struct gsm_network *network = bsc_network_init(tall_bsc_ctx, 1, 1, NULL);
+	printf("Test SI2quater multiple UARFCNs:\n");
+
+	if (!network)
+		exit(1);
+	bts = gsm_bts_alloc(network);
+
+	_bts_uarfcn_add(bts, 10564, 318, 0);
+	_bts_uarfcn_add(bts, 10612, 319, 0);
+	_bts_uarfcn_add(bts, 10612, 31, 0);
+	_bts_uarfcn_add(bts, 10612, 19, 0);
+	_bts_uarfcn_add(bts, 10613, 64, 0);
+	_bts_uarfcn_add(bts, 10613, 164, 0);
+	_bts_uarfcn_add(bts, 10613, 14, 0);
+	gen(bts);
+}
+
 static inline void test_si2q_u(void)
 {
 	struct gsm_bts *bts;
@@ -608,6 +628,7 @@
 	test_si2q_segfault();
 	test_si2q_e();
 	test_si2q_u();
+	test_si2q_mu();
 	printf("Done.\n");
 	return EXIT_SUCCESS;
 }
diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok
index 1118dd9..1c02dfd 100644
--- a/openbsc/tests/gsm0408/gsm0408_test.ok
+++ b/openbsc/tests/gsm0408/gsm0408_test.ok
@@ -64,8 +64,8 @@
 Allocated reference: 1
 Test SI2quater UARFCN (same scrambling code and diversity):
 generated valid SI2quater: [23] 59 06 07 c0 00 25 52 88 0a 7e 10 99 64 00 0b 2b 2b 2b 2b 2b 2b 2b 2b 
-failed to generate SI2quater: Invalid argument
-failed to generate SI2quater: Invalid argument
+generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 0a 7f 52 88 0a 7e 10 99 64 00 0b 2b 2b 2b 2b 
+generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 0a 7f 52 88 0a 7e 10 99 64 00 0b 2b 2b 2b 2b 
 Testing SYSINFO_TYPE_2quater EARFCN generation:
 generated invalid SI2quater: [23] 59 06 07 c0 00 04 86 59 0a 03 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
 added EARFCN 1917 - generated valid SI2quater: [23] 59 06 07 c0 00 04 86 59 83 be c8 50 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
@@ -89,4 +89,13 @@
 failed to add UARFCN to SI2quater: No space left on device
 failed to add UARFCN to SI2quater: No space left on device
 generated valid SI2quater: [23] 59 06 07 c0 00 25 0f 7c 4c 7a 34 0e 64 77 85 43 55 c8 10 99 64 00 0b 
+Test SI2quater multiple UARFCNs:
+generated valid SI2quater: [23] 59 06 07 c0 00 25 52 88 0a 7c 10 99 64 00 0b 2b 2b 2b 2b 2b 2b 2b 2b 
+generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 0a 7f 52 88 0a 7c 10 99 64 00 0b 2b 2b 2b 2b 
+generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 12 7e e0 a9 44 05 3e 00 44 b2 00 03 2b 2b 2b 
+generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 18 3f f4 90 54 a2 02 9f 04 86 59 00 03 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
+generated valid SI2quater: [23] 59 06 07 c0 00 25 52 e8 18 3f f4 90 54 a2 02 9f 04 86 59 00 03 2b 2b 
 Done.

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

Gerrit-MessageType: merged
Gerrit-Change-Id: If1c32e8b547a28325180faaaddd21f80c37f7337
Gerrit-PatchSet: 4
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


More information about the gerrit-log mailing list