Change in libosmocore[master]: gsm/gsm0480: refactor and expose gsm0480_parse_facility_ie()

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

Harald Welte gerrit-no-reply at lists.osmocom.org
Mon Jun 11 17:13:08 UTC 2018


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

Change subject: gsm/gsm0480: refactor and expose gsm0480_parse_facility_ie()
......................................................................

gsm/gsm0480: refactor and expose gsm0480_parse_facility_ie()

This function can be used when there is only a part of GSM 04.80
message available - Facility IE, e.g. when a message is carried
over GSUP/MAP. Let's expose it.

Refactoring includes the following:

  - adding the 'gsm0480_' prefix;
  - correcting inverted return value;
  - cosmetic code style changes.

Change-Id: I623c39ffbe6cdee65eade8435a2faa04d0da193e
---
M include/osmocom/gsm/gsm0480.h
M src/gsm/gsm0480.c
M src/gsm/libosmogsm.map
M tests/ussd/ussd_test.c
M tests/ussd/ussd_test.ok
5 files changed, 81 insertions(+), 16 deletions(-)

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



diff --git a/include/osmocom/gsm/gsm0480.h b/include/osmocom/gsm/gsm0480.h
index b31f8a7..fafa1f4 100644
--- a/include/osmocom/gsm/gsm0480.h
+++ b/include/osmocom/gsm/gsm0480.h
@@ -93,6 +93,8 @@
 
 int gsm0480_extract_ie_by_tag(const struct gsm48_hdr *hdr, uint16_t msg_len,
 			      uint8_t **ie, uint16_t *ie_len, uint8_t ie_tag);
+int gsm0480_parse_facility_ie(const uint8_t *facility_ie, uint16_t length,
+			      struct ss_request *req);
 int gsm0480_decode_ss_request(const struct gsm48_hdr *hdr, uint16_t len,
 				struct ss_request *request);
 
diff --git a/src/gsm/gsm0480.c b/src/gsm/gsm0480.c
index dfd9877..300c0ed 100644
--- a/src/gsm/gsm0480.c
+++ b/src/gsm/gsm0480.c
@@ -201,8 +201,6 @@
 			     struct ss_request *req);
 static int parse_ss_info_elements(const uint8_t *ss_ie, uint16_t len,
 				  struct ss_request *req);
-static int parse_facility_ie(const uint8_t *facility_ie, uint16_t length,
-			     struct ss_request *req);
 static int parse_ss_invoke(const uint8_t *invoke_data, uint16_t length,
 					struct ss_request *req);
 static int parse_ss_return_result(const uint8_t *rr_data, uint16_t length,
@@ -419,7 +417,7 @@
 	if (len - 1 < facility_length)
 		return 0;
 
-	return parse_facility_ie(ss_facility + 1, facility_length, req);
+	return !gsm0480_parse_facility_ie(ss_facility + 1, facility_length, req);
 }
 
 static int parse_ss_info_elements(const uint8_t *ss_ie, uint16_t len,
@@ -445,7 +443,7 @@
 	case GSM48_IE_CAUSE:
 		break;
 	case GSM0480_IE_FACILITY:
-		rc = parse_facility_ie(ss_ie + 2, iei_length, req);
+		rc = !gsm0480_parse_facility_ie(ss_ie + 2, iei_length, req);
 		break;
 	case GSM0480_IE_SS_VERSION:
 		break;
@@ -464,31 +462,40 @@
 	return rc;
 }
 
-static int parse_facility_ie(const uint8_t *facility_ie, uint16_t length,
-			     struct ss_request *req)
+/*! Parse the components of a given Facility IE
+ * \param[in]  facility_ie  The Facility IE
+ * \param[in]  length       The length of Facility IE
+ * \param[out] req          Abstract representation of SS message
+ * \return     0 in case of success, otherwise -ERRNO
+ */
+int gsm0480_parse_facility_ie(const uint8_t *facility_ie, uint16_t length,
+			      struct ss_request *req)
 {
-	int rc = 1;
+	uint8_t component_length;
+	uint8_t component_type;
 	uint8_t offset = 0;
+	int rc = 1;
 
+	/* Iterate over components within IE */
 	while (offset + 2 <= length) {
 		/* Component Type tag - table 3.7 */
-		uint8_t component_type = facility_ie[offset];
-		uint8_t component_length = facility_ie[offset+1];
+		component_type = facility_ie[offset];
+		component_length = facility_ie[offset + 1];
 
-		/* size check */
+		/* Make sure that there is no overflow */
 		if (offset + 2 + component_length > length) {
 			LOGP(0, LOGL_ERROR, "Component does not fit.\n");
-			return 0;
+			return -EINVAL;
 		}
 
 		switch (component_type) {
 		case GSM0480_CTYPE_INVOKE:
-			rc &= parse_ss_invoke(facility_ie+2,
+			rc &= parse_ss_invoke(facility_ie + 2,
 					      component_length,
 					      req);
 			break;
 		case GSM0480_CTYPE_RETURN_RESULT:
-			rc &= parse_ss_return_result(facility_ie+2,
+			rc &= parse_ss_return_result(facility_ie + 2,
 						     component_length,
 						     req);
 			break;
@@ -502,10 +509,17 @@
 			rc = 0;
 			break;
 		}
-		offset += (component_length+2);
-	};
 
-	return rc;
+		offset += (component_length + 2);
+	}
+
+	/**
+	 * The internal functions are using inverted return
+	 * codes, where '0' means error/failure. While a
+	 * common approach is to return negative errno in
+	 * case of any failure, and '0' if all is ok.
+	 */
+	return (rc == 0) ? -EINVAL : 0;
 }
 
 /* Parse an Invoke component - see table 3.3 */
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 4aaed46..0a6742c 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -90,6 +90,7 @@
 gsm0480_create_ussd_notify;
 gsm0480_create_ussd_release_complete;
 gsm0480_extract_ie_by_tag;
+gsm0480_parse_facility_ie;
 gsm0480_decode_ussd_request;
 gsm0480_decode_ss_request;
 gsm0480_wrap_facility;
diff --git a/tests/ussd/ussd_test.c b/tests/ussd/ussd_test.c
index 23fd739..8025071 100644
--- a/tests/ussd/ussd_test.c
+++ b/tests/ussd/ussd_test.c
@@ -188,6 +188,43 @@
 	printf("\n");
 }
 
+static void test_parse_facility_ie(void)
+{
+	struct ss_request req;
+	uint16_t ie_len;
+	uint8_t *ie;
+	int rc;
+
+	printf("[i] Testing gsm0480_parse_facility_ie()\n");
+
+	/* Extract Facility IE from FACILITY message */
+	rc = gsm0480_extract_ie_by_tag((struct gsm48_hdr *) ussd_facility,
+		sizeof(ussd_facility), &ie, &ie_len, GSM0480_IE_FACILITY);
+	OSMO_ASSERT(rc == 0);
+	OSMO_ASSERT(ie != NULL && ie_len > 0);
+	printf("[?] FACILITY message with Facility IE "
+		"(len=%u): %s\n", ie_len, osmo_hexdump(ie, ie_len));
+
+	/* Attempt to decode */
+	memset(&req, 0x00, sizeof(req));
+	rc = gsm0480_parse_facility_ie(ie, ie_len, &req);
+	OSMO_ASSERT(rc == 0);
+
+	/* Verify expected vs decoded data */
+	printf("[?] InvokeID: expected 0x%02x, decoded 0x%02x\n",
+		0x01, req.invoke_id);
+	printf("[?] Operation code: expected 0x%02x, decoded 0x%02x\n",
+		0x3c, req.opcode);
+	printf("[?] Data Coding Scheme: expected 0x%02x, decoded 0x%02x\n",
+		0x0f, req.ussd_data_dcs);
+	printf("[?] Data length: expected 0x%02x, decoded 0x%02x\n",
+		0x01, req.ussd_data_len);
+	printf("[?] Data: expected %s, decoded %s\n", "32",
+		osmo_hexdump_nospc(req.ussd_data, req.ussd_data_len));
+
+	printf("\n");
+}
+
 int main(int argc, char **argv)
 {
 	struct ss_request req;
@@ -201,6 +238,9 @@
 	/* Test gsm0480_extract_ie_by_tag() */
 	test_extract_ie_by_tag();
 
+	/* Test gsm0480_parse_facility_ie() */
+	test_parse_facility_ie();
+
 	memset(&req, 0, sizeof(req));
 	gsm0480_decode_ss_request((struct gsm48_hdr *) ussd_request,
 		sizeof(ussd_request), &req);
diff --git a/tests/ussd/ussd_test.ok b/tests/ussd/ussd_test.ok
index 8fa4348..1137080 100644
--- a/tests/ussd/ussd_test.ok
+++ b/tests/ussd/ussd_test.ok
@@ -4,6 +4,14 @@
 [?] FACILITY message with Facility IE (len=18): a2 10 02 01 01 30 0b 02 01 3c 30 06 04 01 0f 04 01 32 
 [?] RELEASE COMPLETE message with Facility IE (len=8): a3 06 02 01 05 02 01 24 
 
+[i] Testing gsm0480_parse_facility_ie()
+[?] FACILITY message with Facility IE (len=18): a2 10 02 01 01 30 0b 02 01 3c 30 06 04 01 0f 04 01 32 
+[?] InvokeID: expected 0x01, decoded 0x01
+[?] Operation code: expected 0x3c, decoded 0x3c
+[?] Data Coding Scheme: expected 0x0f, decoded 0x0f
+[?] Data length: expected 0x01, decoded 0x01
+[?] Data: expected 32, decoded 32
+
 Tested if it still works. Text was: **321#
 interrogateSS CFU text..'' code 33
 Testing parsing a USSD request and truncated versions

-- 
To view, visit https://gerrit.osmocom.org/9529
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: I623c39ffbe6cdee65eade8435a2faa04d0da193e
Gerrit-Change-Number: 9529
Gerrit-PatchSet: 2
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180611/11f54c92/attachment.htm>


More information about the gerrit-log mailing list