Change in libosmocore[master]: gprs_bssgp: add IE parser/generator for RIM Routing Information

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/.

laforge gerrit-no-reply at lists.osmocom.org
Thu Dec 17 13:06:17 UTC 2020


laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/21721 )

Change subject: gprs_bssgp: add IE parser/generator for RIM Routing Information
......................................................................

gprs_bssgp: add IE parser/generator for RIM Routing Information

The RIM Routing Information IE (see also 3GPP TS 48.018, section
11.3.70) is used to control the flow of BSSGP rim messages at the SGSN.

Change-Id: I6f88a9aeeb50a612d32e9efd23040c9740bc4f11
Related: SYS#5103
---
M include/Makefile.am
M include/osmocom/gprs/gprs_bssgp.h
A include/osmocom/gprs/protocol/gsm_24_301.h
M src/gb/gprs_bssgp.c
M src/gb/libosmogb.map
M tests/Makefile.am
M tests/gb/gprs_bssgp_test.c
M tests/gb/gprs_bssgp_test.ok
8 files changed, 324 insertions(+), 1 deletion(-)

Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved



diff --git a/include/Makefile.am b/include/Makefile.am
index 0cb9cd2..842b872 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -76,6 +76,7 @@
                        osmocom/gprs/protocol/gsm_04_60.h \
                        osmocom/gprs/protocol/gsm_08_16.h \
                        osmocom/gprs/protocol/gsm_08_18.h \
+                       osmocom/gprs/protocol/gsm_24_301.h \
                        osmocom/gsm/a5.h \
                        osmocom/gsm/abis_nm.h \
                        osmocom/gsm/apn.h \
diff --git a/include/osmocom/gprs/gprs_bssgp.h b/include/osmocom/gprs/gprs_bssgp.h
index dfbd9b7..7077044 100644
--- a/include/osmocom/gprs/gprs_bssgp.h
+++ b/include/osmocom/gprs/gprs_bssgp.h
@@ -10,6 +10,7 @@
 #include <osmocom/gsm/prim.h>
 
 #include <osmocom/gprs/protocol/gsm_08_18.h>
+#include <osmocom/gprs/protocol/gsm_24_301.h>
 
 /* gprs_bssgp_util.c */
 
@@ -175,6 +176,37 @@
 int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid,
 			 uint16_t cid);
 
+enum bssgp_rim_routing_info_discr {
+	BSSGP_RIM_ROUTING_INFO_GERAN,
+	BSSGP_RIM_ROUTING_INFO_UTRAN,
+	BSSGP_RIM_ROUTING_INFO_EUTRAN,
+};
+
+/*! BSSGP RIM Routing information, see also 3GPP TS 48.018, section 11.3.70 */
+struct bssgp_rim_routing_info {
+	enum bssgp_rim_routing_info_discr discr;
+	union {
+		struct {
+			struct gprs_ra_id raid;
+			uint16_t cid;
+		} geran;
+		struct {
+			struct gprs_ra_id raid;
+			uint16_t rncid;
+		} utran;
+		struct {
+			struct osmo_eutran_tai tai;
+			/* See also 3GPP TS 36.413 9.2.1.37 and 3GPP TS 36.401 */
+			uint8_t global_enb_id[8];
+			uint8_t global_enb_id_len;
+		} eutran;
+	};
+};
+
+int bssgp_parse_rim_ri(struct bssgp_rim_routing_info *ri, const uint8_t *buf,
+		       unsigned int len);
+int bssgp_create_rim_ri(uint8_t *buf, const struct bssgp_rim_routing_info *ri);
+
 /* Wrapper around TLV parser to parse BSSGP IEs */
 static inline int bssgp_tlv_parse(struct tlv_parsed *tp, const uint8_t *buf, int len)
 {
diff --git a/include/osmocom/gprs/protocol/gsm_24_301.h b/include/osmocom/gprs/protocol/gsm_24_301.h
new file mode 100644
index 0000000..d4bcd87
--- /dev/null
+++ b/include/osmocom/gprs/protocol/gsm_24_301.h
@@ -0,0 +1,11 @@
+/*! \file gsm_24_301.h */
+
+#pragma once
+
+/*! Tracking area TS 24.301, section 9.9.3.32 */
+struct osmo_eutran_tai {
+	uint16_t mcc;
+	uint16_t mnc;
+	bool mnc_3_digits;
+	uint16_t tac;
+};
diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c
index 696c451..09f6373 100644
--- a/src/gb/gprs_bssgp.c
+++ b/src/gb/gprs_bssgp.c
@@ -326,6 +326,93 @@
 	return 8;
 }
 
+/*! Parse a RIM Routing information IE (3GPP TS 48.018, chapter 11.3.70).
+ *  \param[out] ri user provided memory to store the parsed results.
+ *  \param[in] buf input buffer of the value part of the IE.
+ *  \returns length of parsed octets, -EINVAL on error. */
+int bssgp_parse_rim_ri(struct bssgp_rim_routing_info *ri, const uint8_t *buf,
+		       unsigned int len)
+{
+	struct gprs_ra_id raid_temp;
+
+	memset(ri, 0, sizeof(*ri));
+	if (len < 2)
+		return -EINVAL;
+
+	ri->discr = buf[0] & 0x0f;
+
+	switch (ri->discr) {
+	case BSSGP_RIM_ROUTING_INFO_GERAN:
+		if (len < 9)
+			return -EINVAL;
+		ri->geran.cid = bssgp_parse_cell_id(&ri->geran.raid, buf + 1);
+		return 9;
+	case BSSGP_RIM_ROUTING_INFO_UTRAN:
+		if (len < 9)
+			return -EINVAL;
+		gsm48_parse_ra(&ri->utran.raid, buf + 1);
+		ri->utran.rncid = osmo_load16be(buf + 7);
+		return 9;
+	case BSSGP_RIM_ROUTING_INFO_EUTRAN:
+		if (len < 7 || len > 14)
+			return -EINVAL;
+		/* Note: 3GPP TS 24.301 Figure 9.9.3.32.1 and 3GPP TS 24.008
+		 * Figure 10.5.130 specify MCC/MNC encoding in the same way,
+		 * so we can re-use gsm48_parse_ra() for that. */
+		gsm48_parse_ra(&raid_temp, buf + 1);
+		ri->eutran.tai.mcc = raid_temp.mcc;
+		ri->eutran.tai.mnc = raid_temp.mnc;
+		ri->eutran.tai.mnc_3_digits = raid_temp.mnc_3_digits;
+		ri->eutran.tai.tac = osmo_load16be(buf + 4);
+		memcpy(ri->eutran.global_enb_id, buf + 6, len - 6);
+	        ri->eutran.global_enb_id_len = len - 6;
+		return len;
+	default:
+		return -EINVAL;
+	}
+}
+
+/*! Encode a RIM Routing information IE (3GPP TS 48.018, chapter 11.3.70).
+ *  \param[out] buf user provided memory (at least 14 byte) for the generated value part of the IE.
+ *  \param[in] ri user provided input data struct.
+ *  \returns length of encoded octets, -EINVAL on error. */
+int bssgp_create_rim_ri(uint8_t *buf, const struct bssgp_rim_routing_info *ri)
+{
+	int rc;
+	struct gprs_ra_id raid_temp;
+
+	buf[0] = ri->discr & 0x0f;
+	buf++;
+
+	switch (ri->discr) {
+	case BSSGP_RIM_ROUTING_INFO_GERAN:
+		rc = bssgp_create_cell_id(buf, &ri->geran.raid, ri->geran.cid);
+		if (rc < 0)
+			return -EINVAL;
+		return rc + 1;
+	case BSSGP_RIM_ROUTING_INFO_UTRAN:
+		gsm48_encode_ra((struct gsm48_ra_id *)buf, &ri->utran.raid);
+		osmo_store16be(ri->utran.rncid, buf + 6);
+		return 9;
+	case BSSGP_RIM_ROUTING_INFO_EUTRAN:
+		/* Note: 3GPP TS 24.301 Figure 9.9.3.32.1 and 3GPP TS 24.008
+		 * Figure 10.5.130 specify MCC/MNC encoding in the same way,
+		 * so we can re-use gsm48_encode_ra() for that. */
+		raid_temp.mcc = ri->eutran.tai.mcc;
+		raid_temp.mnc = ri->eutran.tai.mnc;
+		raid_temp.mnc_3_digits = ri->eutran.tai.mnc_3_digits;
+		gsm48_encode_ra((struct gsm48_ra_id *)buf, &raid_temp);
+		osmo_store16be(ri->eutran.tai.tac, buf + 3);
+		OSMO_ASSERT(ri->eutran.global_enb_id_len <=
+			    sizeof(ri->eutran.global_enb_id));
+		memcpy(buf + 5, ri->eutran.global_enb_id,
+		       ri->eutran.global_enb_id_len);
+		return ri->eutran.global_enb_id_len + 6;
+	default:
+		return -EINVAL;
+	}
+}
+
 /* Chapter 8.4 BVC-Reset Procedure */
 static int bssgp_rx_bvc_reset(struct msgb *msg, struct tlv_parsed *tp,
 			      uint16_t ns_bvci)
diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map
index 59405b0..8f638ff 100644
--- a/src/gb/libosmogb.map
+++ b/src/gb/libosmogb.map
@@ -2,6 +2,7 @@
 global:
 bssgp_cause_str;
 bssgp_create_cell_id;
+bssgp_create_rim_ri;
 bssgp_pdu_str;
 bssgp_fc_in;
 bssgp_fc_init;
@@ -13,6 +14,7 @@
 bssgp_msgb_tlli_put;
 bssgp_msgb_ra_put;
 bssgp_parse_cell_id;
+bssgp_parse_rim_ri;
 bssgp_set_bssgp_callback;
 bssgp_tx_bvc_block;
 bssgp_tx_bvc_reset;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ed87aca..cb683f7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -172,7 +172,8 @@
 gb_gprs_bssgp_test_SOURCES = gb/gprs_bssgp_test.c
 gb_gprs_bssgp_test_LDADD = $(LDADD) $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DLSYM) \
 			   $(top_builddir)/src/vty/libosmovty.la \
-			   $(top_builddir)/src/gsm/libosmogsm.la
+			   $(top_builddir)/src/gsm/libosmogsm.la \
+			   $(top_builddir)/src/gb/libosmogb.la
 
 gb_gprs_ns_test_SOURCES = gb/gprs_ns_test.c
 gb_gprs_ns_test_LDADD = $(LDADD) $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DLSYM) \
diff --git a/tests/gb/gprs_bssgp_test.c b/tests/gb/gprs_bssgp_test.c
index 52e986e..e1c920a 100644
--- a/tests/gb/gprs_bssgp_test.c
+++ b/tests/gb/gprs_bssgp_test.c
@@ -289,6 +289,137 @@
 	printf("----- %s END\n", __func__);
 }
 
+void dump_rim_ri(struct bssgp_rim_routing_info *ri)
+{
+	switch (ri->discr) {
+	case BSSGP_RIM_ROUTING_INFO_GERAN:
+		printf("GERAN cell identifier\n");
+		printf(" * mcc: %u\n", ri->geran.raid.mcc);
+		printf("   mnc: %u\n", ri->geran.raid.mnc);
+		printf("   mnc 3 digits: %u\n", ri->geran.raid.mnc_3_digits);
+		printf("   lac: %u\n", ri->geran.raid.lac);
+		printf("   rac: %u\n", ri->geran.raid.rac);
+		printf(" * cell id: %04x\n", ri->geran.cid);
+		break;
+	case BSSGP_RIM_ROUTING_INFO_UTRAN:
+		printf("UTRAN RNC identifier\n");
+		printf(" * mcc: %u\n", ri->utran.raid.mcc);
+		printf("   mnc: %u\n", ri->utran.raid.mnc);
+		printf("   mnc 3 digits: %u\n", ri->utran.raid.mnc_3_digits);
+		printf("   lac: %u\n", ri->utran.raid.lac);
+		printf("   rac: %u\n", ri->utran.raid.rac);
+		printf(" * rnc id: %04x\n", ri->utran.rncid);
+		break;
+	case BSSGP_RIM_ROUTING_INFO_EUTRAN:
+		printf("EUTRAN eNB identifier\n");
+		printf(" * mcc: %u\n", ri->eutran.tai.mcc);
+		printf("   mnc: %u\n", ri->eutran.tai.mnc);
+		printf("   mnc 3 digits: %u\n", ri->eutran.tai.mnc_3_digits);
+		printf("   tac: %u\n", ri->eutran.tai.tac);
+		printf(" * global_enb_id: %s\n",
+		       osmo_hexdump_nospc(ri->eutran.global_enb_id,
+					  ri->eutran.global_enb_id_len));
+		break;
+	default:
+		OSMO_ASSERT(false);
+	}
+}
+
+static void test_bssgp_parse_rim_ri()
+{
+	int rc;
+	struct bssgp_rim_routing_info result;
+	uint8_t testvec_geran[] =
+	    { 0x00, 0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };
+	uint8_t testvec_utran[] =
+	    { 0x01, 0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };
+	uint8_t testvec_eutran[] =
+	    { 0x02, 0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };
+
+	printf("----- %s START\n", __func__);
+
+	rc = bssgp_parse_rim_ri(&result, testvec_geran,
+				sizeof(testvec_geran));
+	printf("rc=%d\n", rc);
+	dump_rim_ri(&result);
+	printf("\n");
+
+	rc = bssgp_parse_rim_ri(&result, testvec_utran,
+				sizeof(testvec_utran));
+	printf("rc=%d\n", rc);
+	dump_rim_ri(&result);
+	printf("\n");
+
+	rc = bssgp_parse_rim_ri(&result, testvec_eutran,
+				sizeof(testvec_eutran));
+	printf("rc=%d\n", rc);
+	dump_rim_ri(&result);
+	printf("\n");
+
+	printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_create_rim_ri()
+{
+	int rc;
+	struct bssgp_rim_routing_info ri;
+	uint8_t result[15];
+
+	printf("----- %s START\n", __func__);
+	memset(&ri, 0, sizeof(ri));
+	memset(result, 0, sizeof(result));
+	ri.discr = BSSGP_RIM_ROUTING_INFO_GERAN;
+
+	ri.geran.raid.mcc = 262;
+	ri.geran.raid.mnc = 42;
+	ri.geran.raid.mnc_3_digits = false;
+	ri.geran.raid.lac = 13200;
+	ri.geran.raid.rac = 0;
+	ri.geran.cid = 0x51e1;
+	dump_rim_ri(&ri);
+	rc = bssgp_create_rim_ri(result, &ri);
+	printf("rc=%d, ", rc);
+	if (rc > 0)
+		printf("result=%s", osmo_hexdump_nospc(result, rc));
+	printf("\n\n");
+
+	memset(&ri, 0, sizeof(ri));
+	memset(result, 0, sizeof(result));
+	ri.discr = BSSGP_RIM_ROUTING_INFO_UTRAN;
+	ri.utran.raid.mcc = 262;
+	ri.utran.raid.mnc = 42;
+	ri.utran.raid.mnc_3_digits = 0;
+	ri.utran.raid.lac = 13200;
+	ri.utran.raid.rac = 0;
+	ri.utran.rncid = 0x51e1;
+	dump_rim_ri(&ri);
+	rc = bssgp_create_rim_ri(result, &ri);
+	printf("rc=%d, ", rc);
+	if (rc > 0)
+		printf("result=%s", osmo_hexdump_nospc(result, rc));
+	printf("\n\n");
+
+	memset(&ri, 0, sizeof(ri));
+	memset(result, 0, sizeof(result));
+	ri.discr = BSSGP_RIM_ROUTING_INFO_EUTRAN;
+	ri.eutran.tai.mcc = 262;
+	ri.eutran.tai.mnc = 42;
+	ri.eutran.tai.mnc_3_digits = 0;
+	ri.eutran.tai.tac = 13200;
+	ri.eutran.global_enb_id[0] = 0x00;
+	ri.eutran.global_enb_id[1] = 0x51;
+	ri.eutran.global_enb_id[2] = 0xe1;
+	ri.eutran.global_enb_id_len = 3;
+	dump_rim_ri(&ri);
+	rc = bssgp_create_rim_ri(result, &ri);
+	printf("rc=%d, ", rc);
+	if (rc > 0)
+		printf("result=%s", osmo_hexdump_nospc(result, rc));
+	printf("\n\n");
+
+	printf("----- %s END\n", __func__);
+}
+
 static struct log_info info = {};
 
 int main(int argc, char **argv)
@@ -317,6 +448,8 @@
 	test_bssgp_bad_reset();
 	test_bssgp_flow_control_bvc();
 	test_bssgp_msgb_copy();
+	test_bssgp_parse_rim_ri();
+	test_bssgp_create_rim_ri();
 	printf("===== BSSGP test END\n\n");
 
 	exit(EXIT_SUCCESS);
diff --git a/tests/gb/gprs_bssgp_test.ok b/tests/gb/gprs_bssgp_test.ok
index c5b3e7d..744f1a7 100644
--- a/tests/gb/gprs_bssgp_test.ok
+++ b/tests/gb/gprs_bssgp_test.ok
@@ -17,5 +17,61 @@
 Old msgb: [L3]> 22 04 82 00 02 07 81 08 
 New msgb: [L3]> 22 04 82 00 02 07 81 08 
 ----- test_bssgp_msgb_copy END
+----- test_bssgp_parse_rim_ri START
+rc=9
+GERAN cell identifier
+ * mcc: 262
+   mnc: 42
+   mnc 3 digits: 0
+   lac: 13200
+   rac: 0
+ * cell id: 51e1
+
+rc=9
+UTRAN RNC identifier
+ * mcc: 262
+   mnc: 42
+   mnc 3 digits: 0
+   lac: 13200
+   rac: 0
+ * rnc id: 51e1
+
+rc=9
+EUTRAN eNB identifier
+ * mcc: 262
+   mnc: 42
+   mnc 3 digits: 0
+   tac: 13200
+ * global_enb_id: 0051e1
+
+----- test_bssgp_parse_rim_ri END
+----- test_bssgp_create_rim_ri START
+GERAN cell identifier
+ * mcc: 262
+   mnc: 42
+   mnc 3 digits: 0
+   lac: 13200
+   rac: 0
+ * cell id: 51e1
+rc=9, result=0062f22433900051e1
+
+UTRAN RNC identifier
+ * mcc: 262
+   mnc: 42
+   mnc 3 digits: 0
+   lac: 13200
+   rac: 0
+ * rnc id: 51e1
+rc=9, result=0162f22433900051e1
+
+EUTRAN eNB identifier
+ * mcc: 262
+   mnc: 42
+   mnc 3 digits: 0
+   tac: 13200
+ * global_enb_id: 0051e1
+rc=9, result=0262f22433900051e1
+
+----- test_bssgp_create_rim_ri END
 ===== BSSGP test END
 

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

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I6f88a9aeeb50a612d32e9efd23040c9740bc4f11
Gerrit-Change-Number: 21721
Gerrit-PatchSet: 4
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20201217/c7abd602/attachment.htm>


More information about the gerrit-log mailing list