Change in libosmocore[master]: add gsm0808_cell_id_from_cgi(), gsm0808_cell_id_to_cgi()

Harald Welte gerrit-no-reply at lists.osmocom.org
Fri Mar 8 11:12:49 UTC 2019


Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/13122 )

Change subject: add gsm0808_cell_id_from_cgi(), gsm0808_cell_id_to_cgi()
......................................................................

add gsm0808_cell_id_from_cgi(), gsm0808_cell_id_to_cgi()

CGI to Cell ID: for example, for Paging, osmo-msc has a CGI for a subscriber
and needs to send out a Cell Identifier IE. Makes sense to add this conversion
here.

Cell ID to CGI: for a Layer 3 Complete, a subscriber sends the current cell in
the form of a Cell Identifier, which we store as a CGI, if necessary enriched
with the local PLMN.

Add enum with bitmask values to identify parts of a CGI, for the return value
of gsm0808_cell_id_to_cgi(). Can't use enum CELL_IDENT for that, because it
doesn't have a value for just a PLMN (and is not a bitmask).

Change-Id: Ib9af67b100c4583342a2103669732dab2e577b04
---
M include/osmocom/gsm/gsm0808_utils.h
M include/osmocom/gsm/gsm23003.h
M src/gsm/gsm0808_utils.c
M src/gsm/libosmogsm.map
M tests/gsm0808/gsm0808_test.c
M tests/gsm0808/gsm0808_test.ok
6 files changed, 270 insertions(+), 8 deletions(-)

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



diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h
index 2b48be7..53f145c 100644
--- a/include/osmocom/gsm/gsm0808_utils.h
+++ b/include/osmocom/gsm/gsm0808_utils.h
@@ -84,6 +84,9 @@
 bool gsm0808_cell_ids_match(const struct gsm0808_cell_id *id1, const struct gsm0808_cell_id *id2, bool exact_match);
 int gsm0808_cell_id_matches_list(const struct gsm0808_cell_id *id, const struct gsm0808_cell_id_list2 *list,
 				 unsigned int match_nr, bool exact_match);
+void gsm0808_cell_id_from_cgi(struct gsm0808_cell_id *cid, enum CELL_IDENT id_discr,
+			      const struct osmo_cell_global_id *cgi);
+int gsm0808_cell_id_to_cgi(struct osmo_cell_global_id *cgi, const struct gsm0808_cell_id *cid);
 
 uint8_t gsm0808_enc_cause(struct msgb *msg, uint16_t cause);
 uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg,
diff --git a/include/osmocom/gsm/gsm23003.h b/include/osmocom/gsm/gsm23003.h
index b34a677..cf622ce 100644
--- a/include/osmocom/gsm/gsm23003.h
+++ b/include/osmocom/gsm/gsm23003.h
@@ -30,6 +30,15 @@
 	uint16_t cell_identity;
 };
 
+/*! Bitmask of items contained in a struct osmo_cell_global_id.
+ * See also gsm0808_cell_id_to_cgi().
+ */
+enum osmo_cgi_part {
+	OSMO_CGI_PART_PLMN = 1,
+	OSMO_CGI_PART_LAC = 2,
+	OSMO_CGI_PART_CI = 4,
+};
+
 /* Actually defined in 3GPP TS 48.008 3.2.2.27 Cell Identifier List,
  * but conceptually belongs with the above structures. */
 struct osmo_lac_and_ci_id {
diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c
index 5477598..dd14d3c 100644
--- a/src/gsm/gsm0808_utils.c
+++ b/src/gsm/gsm0808_utils.c
@@ -1577,6 +1577,93 @@
 	return -1;
 }
 
+/*! Copy information from a CGI to form a Cell Identifier of the specified kind.
+ * \param [out] cid  Compose new Cell Identifier here.
+ * \param [in] id_discr  Which kind of Cell Identifier to compose.
+ * \param [in] cgi  Cell Global Identifier to form the Cell Identifier from.
+ */
+void gsm0808_cell_id_from_cgi(struct gsm0808_cell_id *cid, enum CELL_IDENT id_discr,
+			      const struct osmo_cell_global_id *cgi)
+{
+	*cid = (struct gsm0808_cell_id){
+		.id_discr = id_discr,
+	};
+
+	switch (id_discr) {
+	case CELL_IDENT_WHOLE_GLOBAL:
+		cid->id.global = *cgi;
+		return;
+
+	case CELL_IDENT_LAC_AND_CI:
+		cid->id.lac_and_ci = (struct osmo_lac_and_ci_id){
+			.lac = cgi->lai.lac,
+			.ci = cgi->cell_identity,
+		};
+		return;
+
+	case CELL_IDENT_CI:
+		cid->id.ci = cgi->cell_identity;
+		return;
+
+	case CELL_IDENT_LAI:
+		cid->id.lai_and_lac = cgi->lai;
+		return;
+
+	case CELL_IDENT_LAC:
+		cid->id.lac = cgi->lai.lac;
+		return;
+
+	case CELL_IDENT_NO_CELL:
+	case CELL_IDENT_BSS:
+	case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
+	case CELL_IDENT_UTRAN_RNC:
+	case CELL_IDENT_UTRAN_LAC_RNC:
+	default:
+		return;
+	};
+}
+
+/*! Overwrite parts of cgi with values from a Cell Identifier.
+ * Place only those items given in cid into cgi, leaving other values unchanged.
+ * \param[out] cgi  Cell Global Identity to write to.
+ * \param[in] cid  Cell Identity to read from.
+ * \return a bitmask of items that were set: OSMO_CGI_PART_PLMN | OSMO_CGI_PART_LAC | OSMO_CGI_PART_CI; 0 if nothing was
+ *         written to cgi.
+ */
+int gsm0808_cell_id_to_cgi(struct osmo_cell_global_id *cgi, const struct gsm0808_cell_id *cid)
+{
+	switch (cid->id_discr) {
+	case CELL_IDENT_WHOLE_GLOBAL:
+		*cgi = cid->id.global;
+		return OSMO_CGI_PART_PLMN | OSMO_CGI_PART_LAC | OSMO_CGI_PART_CI;
+
+	case CELL_IDENT_LAC_AND_CI:
+		cgi->lai.lac = cid->id.lac_and_ci.lac;
+		cgi->cell_identity = cid->id.lac_and_ci.ci;
+		return OSMO_CGI_PART_LAC | OSMO_CGI_PART_CI;
+
+	case CELL_IDENT_CI:
+		cgi->cell_identity = cid->id.ci;
+		return OSMO_CGI_PART_CI;
+
+	case CELL_IDENT_LAI:
+		cgi->lai = cid->id.lai_and_lac;
+		return OSMO_CGI_PART_PLMN | OSMO_CGI_PART_LAC;
+
+	case CELL_IDENT_LAC:
+		cgi->lai.lac = cid->id.lac;
+		return OSMO_CGI_PART_LAC;
+
+	case CELL_IDENT_NO_CELL:
+	case CELL_IDENT_BSS:
+	case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
+	case CELL_IDENT_UTRAN_RNC:
+	case CELL_IDENT_UTRAN_LAC_RNC:
+	default:
+		return 0;
+	};
+}
+
 /*! value_string[] for enum CELL_IDENT. */
 const struct value_string gsm0808_cell_id_discr_names[] = {
 	{ CELL_IDENT_WHOLE_GLOBAL, "CGI" },
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 2d47d7a..3fadc5a 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -205,6 +205,8 @@
 gsm0808_dec_cell_id_list2;
 gsm0808_cell_id_list_add;
 gsm0808_cell_id_to_list;
+gsm0808_cell_id_to_cgi;
+gsm0808_cell_id_from_cgi;
 gsm0808_enc_cell_id;
 gsm0808_dec_cell_id;
 gsm0808_cell_id_name;
diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c
index af90d00..c448f43 100644
--- a/tests/gsm0808/gsm0808_test.c
+++ b/tests/gsm0808/gsm0808_test.c
@@ -2206,29 +2206,96 @@
 	return true;
 }
 
+const enum CELL_IDENT cell_ident_discrs[] = {
+	CELL_IDENT_LAC, CELL_IDENT_CI, CELL_IDENT_LAC_AND_CI, CELL_IDENT_LAI_AND_LAC,
+	CELL_IDENT_WHOLE_GLOBAL,
+};
+
+
 static void test_cell_id_list_matching(bool test_match)
 {
 	int i, j;
 	bool ok = true;
 
-	const enum CELL_IDENT discrs[] = {
-		CELL_IDENT_LAC, CELL_IDENT_CI, CELL_IDENT_LAC_AND_CI, CELL_IDENT_LAI_AND_LAC,
-		CELL_IDENT_WHOLE_GLOBAL,
-	};
-
 	printf("\n%s(%s)\n", __func__, test_match ? "test match" : "test mismatch");
 
 	/* Autogenerate Cell ID lists from above dataset, which should match / not match. */
-	for (i = 0; i < ARRAY_SIZE(discrs); i++) {
-		for (j = 0; j < ARRAY_SIZE(discrs); j++)
+	for (i = 0; i < ARRAY_SIZE(cell_ident_discrs); i++) {
+		for (j = 0; j < ARRAY_SIZE(cell_ident_discrs); j++)
 			if (!test_cell_id_list_matching_discrs(test_match,
-							       discrs[i], discrs[j]))
+							       cell_ident_discrs[i], cell_ident_discrs[j]))
 				ok = false;
 	}
 
 	OSMO_ASSERT(ok);
 }
 
+
+static const struct gsm0808_cell_id test_gsm0808_cell_id_to_from_cgi_data[] = {
+	lac_23,
+	lac_42,
+	ci_5,
+	ci_6,
+	lac_ci_23_5,
+	lac_ci_42_6,
+	lai_23_042_23,
+	lai_23_042_42,
+	lai_23_99_23,
+	lai_23_42_23,
+	cgi_23_042_23_5,
+	cgi_23_042_42_6,
+	cgi_23_99_23_5,
+	{ .id_discr = CELL_IDENT_NO_CELL },
+	{ .id_discr = 423 },
+};
+
+static void test_gsm0808_cell_id_to_from_cgi()
+{
+	int i;
+	int j;
+
+	printf("\n%s()\n", __func__);
+
+	for (i = 0; i < ARRAY_SIZE(test_gsm0808_cell_id_to_from_cgi_data); i++) {
+		const struct gsm0808_cell_id *from_cid = &test_gsm0808_cell_id_to_from_cgi_data[i];
+		struct osmo_cell_global_id cgi = {
+			.lai = {
+				.plmn = {
+					.mcc = 777,
+					.mnc = 7,
+					.mnc_3_digits = true,
+				},
+				.lac = 7777,
+			},
+			.cell_identity = 7777,
+		};
+		struct gsm0808_cell_id cid = {};
+		int rc;
+
+		rc = gsm0808_cell_id_to_cgi(&cgi, from_cid);
+		printf("cid %s -> cgi %s", gsm0808_cell_id_name(from_cid), osmo_cgi_name(&cgi));
+
+		if (rc & OSMO_CGI_PART_PLMN)
+			printf(" PLMN");
+		if (rc & OSMO_CGI_PART_LAC)
+			printf(" LAC");
+		if (rc & OSMO_CGI_PART_CI)
+			printf(" CI");
+
+		gsm0808_cell_id_from_cgi(&cid, from_cid->id_discr, &cgi);
+		printf(" -> cid %s\n", gsm0808_cell_id_name(&cid));
+		if (!gsm0808_cell_ids_match(from_cid, &cid, true))
+			printf("      MISMATCH!\n");
+
+		for (j = 0; j < ARRAY_SIZE(cell_ident_discrs); j++) {
+			enum CELL_IDENT discr = cell_ident_discrs[j];
+
+			gsm0808_cell_id_from_cgi(&cid, discr, &cgi);
+			printf("  --> gsm0808_cell_id{%s} = %s\n", gsm0808_cell_id_discr_name(discr), gsm0808_cell_id_name(&cid));
+		}
+	}
+}
+
 int main(int argc, char **argv)
 {
 	void *ctx = talloc_named_const(NULL, 0, "gsm0808 test");
@@ -2300,6 +2367,8 @@
 	test_cell_id_list_matching(true);
 	test_cell_id_list_matching(false);
 
+	test_gsm0808_cell_id_to_from_cgi();
+
 	printf("Done\n");
 	return EXIT_SUCCESS;
 }
diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok
index e7df007..6035326 100644
--- a/tests/gsm0808/gsm0808_test.ok
+++ b/tests/gsm0808/gsm0808_test.ok
@@ -629,4 +629,96 @@
 CGI:023-042-23-5 and LAC-CI[1]:{42-6}: mismatch
 CGI:023-042-23-5 and LAI[3]:{023-042-42, 023-99-23, 023-42-23}: mismatch
 CGI:023-042-23-5 and CGI[2]:{023-042-42-6, 023-99-23-5}: mismatch
+
+test_gsm0808_cell_id_to_from_cgi()
+cid LAC:23 -> cgi 777-007-23-7777 LAC -> cid LAC:23
+  --> gsm0808_cell_id{LAC} = LAC:23
+  --> gsm0808_cell_id{CI} = CI:7777
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:23-7777
+  --> gsm0808_cell_id{LAI} = LAI:777-007-23
+  --> gsm0808_cell_id{CGI} = CGI:777-007-23-7777
+cid LAC:42 -> cgi 777-007-42-7777 LAC -> cid LAC:42
+  --> gsm0808_cell_id{LAC} = LAC:42
+  --> gsm0808_cell_id{CI} = CI:7777
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:42-7777
+  --> gsm0808_cell_id{LAI} = LAI:777-007-42
+  --> gsm0808_cell_id{CGI} = CGI:777-007-42-7777
+cid CI:5 -> cgi 777-007-7777-5 CI -> cid CI:5
+  --> gsm0808_cell_id{LAC} = LAC:7777
+  --> gsm0808_cell_id{CI} = CI:5
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:7777-5
+  --> gsm0808_cell_id{LAI} = LAI:777-007-7777
+  --> gsm0808_cell_id{CGI} = CGI:777-007-7777-5
+cid CI:6 -> cgi 777-007-7777-6 CI -> cid CI:6
+  --> gsm0808_cell_id{LAC} = LAC:7777
+  --> gsm0808_cell_id{CI} = CI:6
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:7777-6
+  --> gsm0808_cell_id{LAI} = LAI:777-007-7777
+  --> gsm0808_cell_id{CGI} = CGI:777-007-7777-6
+cid LAC-CI:23-5 -> cgi 777-007-23-5 LAC CI -> cid LAC-CI:23-5
+  --> gsm0808_cell_id{LAC} = LAC:23
+  --> gsm0808_cell_id{CI} = CI:5
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:23-5
+  --> gsm0808_cell_id{LAI} = LAI:777-007-23
+  --> gsm0808_cell_id{CGI} = CGI:777-007-23-5
+cid LAC-CI:42-6 -> cgi 777-007-42-6 LAC CI -> cid LAC-CI:42-6
+  --> gsm0808_cell_id{LAC} = LAC:42
+  --> gsm0808_cell_id{CI} = CI:6
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:42-6
+  --> gsm0808_cell_id{LAI} = LAI:777-007-42
+  --> gsm0808_cell_id{CGI} = CGI:777-007-42-6
+cid LAI:023-042-23 -> cgi 023-042-23-7777 PLMN LAC -> cid LAI:023-042-23
+  --> gsm0808_cell_id{LAC} = LAC:23
+  --> gsm0808_cell_id{CI} = CI:7777
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:23-7777
+  --> gsm0808_cell_id{LAI} = LAI:023-042-23
+  --> gsm0808_cell_id{CGI} = CGI:023-042-23-7777
+cid LAI:023-042-42 -> cgi 023-042-42-7777 PLMN LAC -> cid LAI:023-042-42
+  --> gsm0808_cell_id{LAC} = LAC:42
+  --> gsm0808_cell_id{CI} = CI:7777
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:42-7777
+  --> gsm0808_cell_id{LAI} = LAI:023-042-42
+  --> gsm0808_cell_id{CGI} = CGI:023-042-42-7777
+cid LAI:023-99-23 -> cgi 023-99-23-7777 PLMN LAC -> cid LAI:023-99-23
+  --> gsm0808_cell_id{LAC} = LAC:23
+  --> gsm0808_cell_id{CI} = CI:7777
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:23-7777
+  --> gsm0808_cell_id{LAI} = LAI:023-99-23
+  --> gsm0808_cell_id{CGI} = CGI:023-99-23-7777
+cid LAI:023-42-23 -> cgi 023-42-23-7777 PLMN LAC -> cid LAI:023-42-23
+  --> gsm0808_cell_id{LAC} = LAC:23
+  --> gsm0808_cell_id{CI} = CI:7777
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:23-7777
+  --> gsm0808_cell_id{LAI} = LAI:023-42-23
+  --> gsm0808_cell_id{CGI} = CGI:023-42-23-7777
+cid CGI:023-042-23-5 -> cgi 023-042-23-5 PLMN LAC CI -> cid CGI:023-042-23-5
+  --> gsm0808_cell_id{LAC} = LAC:23
+  --> gsm0808_cell_id{CI} = CI:5
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:23-5
+  --> gsm0808_cell_id{LAI} = LAI:023-042-23
+  --> gsm0808_cell_id{CGI} = CGI:023-042-23-5
+cid CGI:023-042-42-6 -> cgi 023-042-42-6 PLMN LAC CI -> cid CGI:023-042-42-6
+  --> gsm0808_cell_id{LAC} = LAC:42
+  --> gsm0808_cell_id{CI} = CI:6
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:42-6
+  --> gsm0808_cell_id{LAI} = LAI:023-042-42
+  --> gsm0808_cell_id{CGI} = CGI:023-042-42-6
+cid CGI:023-99-23-5 -> cgi 023-99-23-5 PLMN LAC CI -> cid CGI:023-99-23-5
+  --> gsm0808_cell_id{LAC} = LAC:23
+  --> gsm0808_cell_id{CI} = CI:5
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:23-5
+  --> gsm0808_cell_id{LAI} = LAI:023-99-23
+  --> gsm0808_cell_id{CGI} = CGI:023-99-23-5
+cid NO-CELL:NO-CELL -> cgi 777-007-7777-7777 -> cid NO-CELL:NO-CELL
+  --> gsm0808_cell_id{LAC} = LAC:7777
+  --> gsm0808_cell_id{CI} = CI:7777
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:7777-7777
+  --> gsm0808_cell_id{LAI} = LAI:777-007-7777
+  --> gsm0808_cell_id{CGI} = CGI:777-007-7777-7777
+cid unknown 0x1a7:unknown 0x1a7 -> cgi 777-007-7777-7777 -> cid unknown 0x1a7:unknown 0x1a7
+  --> gsm0808_cell_id{LAC} = LAC:7777
+  --> gsm0808_cell_id{CI} = CI:7777
+  --> gsm0808_cell_id{LAC-CI} = LAC-CI:7777-7777
+  --> gsm0808_cell_id{LAI} = LAI:777-007-7777
+  --> gsm0808_cell_id{CGI} = CGI:777-007-7777-7777
 Done

-- 
To view, visit https://gerrit.osmocom.org/13122
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib9af67b100c4583342a2103669732dab2e577b04
Gerrit-Change-Number: 13122
Gerrit-PatchSet: 6
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder (1000002)
Gerrit-Reviewer: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190308/17b41faa/attachment.html>


More information about the gerrit-log mailing list