[PATCH] libosmocore[master]: GSUP: add USSD messages support according to 3GPP TS 09.02

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

Vadim Yanitskiy gerrit-no-reply at lists.osmocom.org
Mon Apr 9 19:32:42 UTC 2018


Hello Harald Welte, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/7600

to look at the new patch set (#4).

GSUP: add USSD messages support according to 3GPP TS 09.02

In order to be able to transfer USSD messages via GSUP,
this change introduces the new message types:

  - OSMO_GSUP_MSGT_PROC_USS_REQ,
  - OSMO_GSUP_MSGT_USS_REQ,
  - OSMO_GSUP_MSGT_USS_NOTIFY,

which correspond to MAP message types defined by 3GPP
TS 09.02 "Mobile Application Part (MAP) specification".

The 'osmo_gsup_message' structure was extended with a child
structure that represents a single decoded and/or to be
encoded SS/USSD message.

Change-Id: Ie17a78043a35fffbdd59e80fd2b2da39cce5e532
Related: OS#1597
---
M TODO-RELEASE
M include/osmocom/gsm/gsup.h
M src/gsm/gsup.c
M tests/gsup/gsup_test.c
M tests/gsup/gsup_test.err
M tests/gsup/gsup_test.ok
6 files changed, 289 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/00/7600/4

diff --git a/TODO-RELEASE b/TODO-RELEASE
index 65b0fa8..a7cc302 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -15,3 +15,4 @@
 						ussd_data_len, and ussd_data_dcs => ABI changed
 gsup		gsup.h				the 'osmo_gsup_message' struct extended with
 						session information => ABI changed
+						SS/USSD information => ABI changed
diff --git a/include/osmocom/gsm/gsup.h b/include/osmocom/gsm/gsup.h
index 08f89e1..a152fde 100644
--- a/include/osmocom/gsm/gsup.h
+++ b/include/osmocom/gsm/gsup.h
@@ -93,6 +93,18 @@
 	 */
 	OSMO_GSUP_SESSION_ID_IE			= 0x30,
 	OSMO_GSUP_SESSION_STATE_IE		= 0x31,
+
+	/**
+	 * 3GPP TS 09.02 "Mobile Application Part (MAP) specification",
+	 * Section 7.6.4 "Supplementary services parameters"
+	 * Section 7.6.3 "Subscriber management parameters"
+	 * Section 7.6.1 "Common parameters"
+	 */
+	OSMO_GSUP_SS_INFO_IE			= 0x35,
+	OSMO_GSUP_SS_INVOKE_ID_IE		= 0x36,
+	OSMO_GSUP_SS_ALERTING_PATTERN_IE	= 0x37,
+	OSMO_GSUP_USSD_STRING_DCS_IE		= 0x38,
+	OSMO_GSUP_USSD_STRING_IE		= 0x39,
 };
 
 /*! GSUP message type */
@@ -135,6 +147,42 @@
 	OSMO_GSUP_MSGT_SESSION_ID_REQUEST	= 0b00100000,
 	OSMO_GSUP_MSGT_SESSION_ID_ERROR		= 0b00100001,
 	OSMO_GSUP_MSGT_SESSION_ID_RESULT	= 0b00100010,
+
+	/**
+	 * 3GPP TS 09.02 "Mobile Application Part (MAP) specification",
+	 * Section 11 "Supplementary services related services",
+	 * Call independent supplementary services
+	 */
+
+	/**
+	 * Section 11.9 "MAP_PROCESS_UNSTRUCTURED_SS_REQUEST service"
+	 * Is used to relay information in order to allow unstructured
+	 * supplementary service operation.
+	 */
+	OSMO_GSUP_MSGT_PROC_USS_REQ_REQUEST	= 0b00100100,
+	OSMO_GSUP_MSGT_PROC_USS_REQ_ERROR	= 0b00100101,
+	OSMO_GSUP_MSGT_PROC_USS_REQ_RESULT	= 0b00100110,
+
+	/**
+	 * Section 11.10 "MAP_UNSTRUCTURED_SS_REQUEST service"
+	 * Is used when the invoking entity requires information
+	 * from the mobile user, in connection with unstructured
+	 * supplementary service handling.
+	 */
+	OSMO_GSUP_MSGT_USS_REQ_REQUEST		= 0b00101000,
+	OSMO_GSUP_MSGT_USS_REQ_ERROR		= 0b00101001,
+	OSMO_GSUP_MSGT_USS_REQ_RESULT		= 0b00101010,
+
+
+	/**
+	 * Section 11.11 "MAP_UNSTRUCTURED_SS_NOTIFY service"
+	 * Is used when the invoking entity requires a notification
+	 * to be sent to the mobile user, in connection with
+	 * unstructured supplementary services handling.
+	 */
+	OSMO_GSUP_MSGT_USS_NOTIFY_REQUEST	= 0b00101100,
+	OSMO_GSUP_MSGT_USS_NOTIFY_ERROR		= 0b00101101,
+	OSMO_GSUP_MSGT_USS_NOTIFY_RESULT	= 0b00101110,
 };
 
 #define OSMO_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00)
@@ -190,6 +238,22 @@
 	size_t				pdp_charg_enc_len;
 };
 
+/*! parsed/decoded SS/USSD information */
+struct osmo_gsup_ss_info {
+	/*! Should this IE be taken into account? */
+	bool				have_info;
+	/*! Invoke ID, helps to relate the response to request */
+	uint32_t			invoke_id;
+	/*! USSD request or response string DCS (Data Coding Scheme) */
+	uint8_t				ussd_string_dcs;
+	/*! USSD request or response string length */
+	size_t				ussd_string_len;
+	/*! USSD request or response string */
+	const uint8_t			*ussd_string;
+	/*! SS notification alerting pattern */
+	const uint8_t			*ss_ap;
+};
+
 /*! parsed/decoded GSUP protocol message */
 struct osmo_gsup_message {
 	enum osmo_gsup_message_type	message_type;
@@ -211,10 +275,9 @@
 	enum osmo_gsup_cn_domain	cn_domain;
 	const uint8_t			*pdp_charg_enc;
 	size_t				pdp_charg_enc_len;
-
-	/*! Session management fields */
 	enum osmo_gsup_session_state	session_state;
 	uint32_t			session_id;
+	struct osmo_gsup_ss_info	ss_info;
 };
 
 int osmo_gsup_decode(const uint8_t *data, size_t data_len,
diff --git a/src/gsm/gsup.c b/src/gsm/gsup.c
index 78818c5..a31c272 100644
--- a/src/gsm/gsup.c
+++ b/src/gsm/gsup.c
@@ -67,6 +67,18 @@
 	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_SESSION_ID_ERROR),
 	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_SESSION_ID_RESULT),
 
+	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_PROC_USS_REQ_REQUEST),
+	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_PROC_USS_REQ_ERROR),
+	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_PROC_USS_REQ_RESULT),
+
+	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_USS_REQ_REQUEST),
+	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_USS_REQ_ERROR),
+	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_USS_REQ_RESULT),
+
+	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_USS_NOTIFY_REQUEST),
+	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_USS_NOTIFY_ERROR),
+	OSMO_VALUE_STRING(OSMO_GSUP_MSGT_USS_NOTIFY_RESULT),
+
 	{ 0, NULL }
 };
 
@@ -213,6 +225,54 @@
 	     "GSUP IE type %d, length %zu invalid in PDP info\n", iei, value_len);
 
 	return -1;
+}
+
+static int decode_ss_info(uint8_t *data, size_t data_len,
+	struct osmo_gsup_ss_info *ss_info)
+{
+	enum osmo_gsup_iei iei;
+	size_t value_len;
+	uint8_t *value;
+	uint8_t tag;
+	int rc;
+
+	/* SS/USSD message parts */
+	while (data_len > 0) {
+		rc = osmo_shift_tlv(&data, &data_len, &tag, &value, &value_len);
+		if (rc < 0)
+			return -GMM_CAUSE_PROTO_ERR_UNSPEC;
+
+		iei = tag;
+
+		switch (iei) {
+		case OSMO_GSUP_SS_INVOKE_ID_IE:
+			ss_info->invoke_id = osmo_decode_big_endian(value, value_len);
+			break;
+
+		case OSMO_GSUP_SS_ALERTING_PATTERN_IE:
+			ss_info->ss_ap = value;
+			break;
+
+		case OSMO_GSUP_USSD_STRING_DCS_IE:
+			ss_info->ussd_string_dcs = *value;
+			break;
+
+		case OSMO_GSUP_USSD_STRING_IE:
+			ss_info->ussd_string_len = value_len;
+			ss_info->ussd_string = value;
+			break;
+
+		default:
+			LOGP(DLGSUP, LOGL_ERROR,
+				"GSUP IE type %d not expected in SS/USSD info\n", iei);
+			continue;
+		}
+	}
+
+	/* Indicate that SS/USSD information was decoded */
+	ss_info->have_info = true;
+
+	return 0;
 }
 
 /*! Decode (parse) a GSUP message
@@ -398,6 +458,12 @@
 			gsup_msg->session_state = *value;
 			break;
 
+		case OSMO_GSUP_SS_INFO_IE:
+			rc = decode_ss_info(value, value_len, &gsup_msg->ss_info);
+			if (rc < 0)
+				return rc;
+			break;
+
 		default:
 			LOGP(DLGSUP, LOGL_NOTICE,
 			     "GSUP IE type %d unknown\n", iei);
@@ -479,6 +545,38 @@
 
 		msgb_tlv_put(msg, OSMO_GSUP_RES_IE,
 			     auth_vector->res_len, auth_vector->res);
+	}
+
+	/* Update length field */
+	*len_field = msgb_length(msg) - old_len;
+}
+
+static void encode_ss_info(struct msgb *msg, enum osmo_gsup_iei iei,
+	const struct osmo_gsup_ss_info *ss_info)
+{
+	uint8_t *len_field;
+	size_t old_len, len;
+
+	len_field = msgb_tlv_put(msg, iei, 0, NULL) - 1;
+	old_len = msgb_length(msg);
+
+	/* Invoke ID (uint32_t => 4 bytes) */
+	len = sizeof(ss_info->invoke_id);
+	msgb_tlv_put(msg, OSMO_GSUP_SS_INVOKE_ID_IE,
+		len, osmo_encode_big_endian(ss_info->invoke_id, len));
+
+	/* Alerting pattern in case of SS Notification */
+	if (ss_info->ss_ap) {
+		msgb_tlv_put(msg, OSMO_GSUP_SS_ALERTING_PATTERN_IE,
+			sizeof(uint8_t), ss_info->ss_ap);
+	}
+
+	/* If preset, USSD string and its DCS (Data Coding Scheme) */
+	if (ss_info->ussd_string && ss_info->ussd_string_len > 0) {
+		msgb_tlv_put(msg, OSMO_GSUP_USSD_STRING_DCS_IE,
+			sizeof(ss_info->ussd_string_dcs), &ss_info->ussd_string_dcs);
+		msgb_tlv_put(msg, OSMO_GSUP_USSD_STRING_IE,
+			ss_info->ussd_string_len, ss_info->ussd_string);
 	}
 
 	/* Update length field */
@@ -585,6 +683,9 @@
 		msgb_tlv_put(msg, OSMO_GSUP_SESSION_STATE_IE, sizeof(u8), &u8);
 	}
 
+	if (gsup_msg->ss_info.have_info)
+		encode_ss_info(msg, OSMO_GSUP_SS_INFO_IE, &gsup_msg->ss_info);
+
 	return 0;
 }
 
diff --git a/tests/gsup/gsup_test.c b/tests/gsup/gsup_test.c
index fb17e15..ea92fdd 100644
--- a/tests/gsup/gsup_test.c
+++ b/tests/gsup/gsup_test.c
@@ -185,6 +185,88 @@
 		0x31, 0x01, 0x01,
 	};
 
+	static const uint8_t send_ussd_req[] = {
+		0x24, /* OSMO_GSUP_MSGT_PROC_USS_REQ_REQUEST */
+		TEST_IMSI_IE,
+
+		/* Session ID and state */
+		0x30, 0x04, 0xde, 0xad, 0xbe, 0xef,
+		0x31, 0x01, 0x01,
+
+		/* SS/USSD information IE */
+		0x35, 0x11,
+			/* Invoke ID */
+			0x36, 0x04, 0xde, 0xad, 0xbe, 0xef,
+
+			/**
+			 * DCS (Data Coding Scheme)
+			 * Coding Group: the GSM 7 bit default alphabet
+			 * Language: Language unspecified
+			 */
+			0x38, 0x01, 0x0f,
+
+			/* USSD string: "*#100#" */
+			0x39, 0x06,
+			0xaa, 0x51, 0x0c, 0x06, 0x1b, 0x01,
+	};
+
+	static const uint8_t send_ussd_res[] = {
+		0x26, /* OSMO_GSUP_MSGT_PROC_USS_REQ_RESULT */
+		TEST_IMSI_IE,
+
+		/* Session ID and state */
+		0x30, 0x04, 0xde, 0xad, 0xbe, 0xef,
+		0x31, 0x01, 0x03,
+
+		/* SS/USSD information IE */
+		0x35, 0x21,
+			/* Invoke ID */
+			0x36, 0x04, 0xde, 0xad, 0xbe, 0xef,
+
+			/**
+			 * DCS (Data Coding Scheme)
+			 * Coding Group: the GSM 7 bit default alphabet
+			 * Language: Language unspecified
+			 */
+			0x38, 0x01, 0x0f,
+
+			/* USSD string: "Your extension is 01393" */
+			0x39, 0x16,
+			0xd9, 0x77, 0x5d, 0x0e, 0x2a, 0xe3, 0xe9, 0x65,
+			0xf7, 0x3c, 0xfd, 0x76, 0x83, 0xd2, 0x73, 0x10,
+			0x2c, 0x36, 0xcb, 0xcd, 0x1a, 0x0d,
+	};
+
+	static const uint8_t send_ussd_ntf[] = {
+		0x2c, /* OSMO_GSUP_MSGT_USS_NOTIFY_REQUEST */
+		TEST_IMSI_IE,
+
+		/* Session ID and state */
+		0x30, 0x04, 0xde, 0xad, 0xbe, 0xef,
+		0x31, 0x01, 0x03,
+
+		/* SS/USSD information IE */
+		0x35, 0x24,
+			/* Invoke ID */
+			0x36, 0x04, 0xde, 0xad, 0xbe, 0xef,
+
+			/* Alerting pattern */
+			0x37, 0x01, 0xff,
+
+			/**
+			 * DCS (Data Coding Scheme)
+			 * Coding Group: the GSM 7 bit default alphabet
+			 * Language: Language unspecified
+			 */
+			0x38, 0x01, 0x0f,
+
+			/* USSD string: "Your extension is 01393" */
+			0x39, 0x16,
+			0xd9, 0x77, 0x5d, 0x0e, 0x2a, 0xe3, 0xe9, 0x65,
+			0xf7, 0x3c, 0xfd, 0x76, 0x83, 0xd2, 0x73, 0x10,
+			0x2c, 0x36, 0xcb, 0xcd, 0x1a, 0x0d,
+	};
+
 	static const struct test {
 		char *name;
 		const uint8_t *data;
@@ -222,6 +304,12 @@
 			send_session_id_req, sizeof(send_session_id_req)},
 		{"Session ID response",
 			send_session_id_res, sizeof(send_session_id_res)},
+		{"USSD Request",
+			send_ussd_req, sizeof(send_ussd_req)},
+		{"USSD Result",
+			send_ussd_res, sizeof(send_ussd_res)},
+		{"USSD Notify",
+			send_ussd_ntf, sizeof(send_ussd_ntf)},
 	};
 
 	printf("Test GSUP message decoding/encoding\n");
@@ -285,7 +373,11 @@
 					osmo_hexdump(t->data + j, ie_end - j));
 
 				OSMO_ASSERT(j <= ie_end - 2);
-				OSMO_ASSERT(t->data[j+0] <= OSMO_GSUP_SESSION_STATE_IE);
+				/**
+				 * FIXME: share the maximal IE value somehow
+				 * in order to avoid manual updating of this
+				 */
+				OSMO_ASSERT(t->data[j+0] <= OSMO_GSUP_USSD_STRING_IE);
 				OSMO_ASSERT(t->data[j+1] <= ie_end - j - 2);
 
 				ie_end = j;
diff --git a/tests/gsup/gsup_test.err b/tests/gsup/gsup_test.err
index 6e56b95..1e7e00f 100644
--- a/tests/gsup/gsup_test.err
+++ b/tests/gsup/gsup_test.err
@@ -46,6 +46,15 @@
   generated message: 22 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 01 
   original message:  22 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 01 
   IMSI:              123456789012345
+  generated message: 24 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 01 35 11 36 04 de ad be ef 38 01 0f 39 06 aa 51 0c 06 1b 01 
+  original message:  24 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 01 35 11 36 04 de ad be ef 38 01 0f 39 06 aa 51 0c 06 1b 01 
+  IMSI:              123456789012345
+  generated message: 26 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 35 21 36 04 de ad be ef 38 01 0f 39 16 d9 77 5d 0e 2a e3 e9 65 f7 3c fd 76 83 d2 73 10 2c 36 cb cd 1a 0d 
+  original message:  26 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 35 21 36 04 de ad be ef 38 01 0f 39 16 d9 77 5d 0e 2a e3 e9 65 f7 3c fd 76 83 d2 73 10 2c 36 cb cd 1a 0d 
+  IMSI:              123456789012345
+  generated message: 2c 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 35 24 36 04 de ad be ef 37 01 ff 38 01 0f 39 16 d9 77 5d 0e 2a e3 e9 65 f7 3c fd 76 83 d2 73 10 2c 36 cb cd 1a 0d 
+  original message:  2c 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 35 24 36 04 de ad be ef 37 01 ff 38 01 0f 39 16 d9 77 5d 0e 2a e3 e9 65 f7 3c fd 76 83 d2 73 10 2c 36 cb cd 1a 0d 
+  IMSI:              123456789012345
   message 0: tested 11 truncations, 11 parse failures
   message 1: tested 14 truncations, 13 parse failures
   message 2: tested 83 truncations, 81 parse failures
@@ -62,20 +71,26 @@
   message 13: tested 45 truncations, 43 parse failures
   message 14: tested 11 truncations, 11 parse failures
   message 15: tested 20 truncations, 18 parse failures
+  message 16: tested 39 truncations, 36 parse failures
+  message 17: tested 55 truncations, 52 parse failures
+  message 18: tested 58 truncations, 55 parse failures
 DLGSUP Stopping DLGSUP logging
   message 0: tested 2816 modifications, 510 parse failures
-  message 1: tested 3584 modifications, 768 parse failures
+  message 1: tested 3584 modifications, 769 parse failures
   message 2: tested 21248 modifications, 2571 parse failures
   message 3: tested 2816 modifications, 510 parse failures
-  message 4: tested 3584 modifications, 768 parse failures
-  message 5: tested 20736 modifications, 4010 parse failures
-  message 6: tested 3584 modifications, 769 parse failures
-  message 7: tested 3584 modifications, 768 parse failures
+  message 4: tested 3584 modifications, 769 parse failures
+  message 5: tested 20736 modifications, 4013 parse failures
+  message 6: tested 3584 modifications, 770 parse failures
+  message 7: tested 3584 modifications, 769 parse failures
   message 8: tested 2816 modifications, 510 parse failures
   message 9: tested 2816 modifications, 510 parse failures
-  message 10: tested 3584 modifications, 768 parse failures
+  message 10: tested 3584 modifications, 769 parse failures
   message 11: tested 3328 modifications, 767 parse failures
   message 12: tested 54016 modifications, 4622 parse failures
-  message 13: tested 11520 modifications, 1026 parse failures
+  message 13: tested 11520 modifications, 1028 parse failures
   message 14: tested 2816 modifications, 510 parse failures
-  message 15: tested 5120 modifications, 1026 parse failures
+  message 15: tested 5120 modifications, 1028 parse failures
+  message 16: tested 9984 modifications, 2036 parse failures
+  message 17: tested 14080 modifications, 2036 parse failures
+  message 18: tested 14848 modifications, 2285 parse failures
diff --git a/tests/gsup/gsup_test.ok b/tests/gsup/gsup_test.ok
index 960e516..adc5a96 100644
--- a/tests/gsup/gsup_test.ok
+++ b/tests/gsup/gsup_test.ok
@@ -31,4 +31,10 @@
           Session ID request OK
   Testing Session ID response
           Session ID response OK
+  Testing USSD Request
+          USSD Request OK
+  Testing USSD Result
+          USSD Result OK
+  Testing USSD Notify
+          USSD Notify OK
 Done.

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

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: Ie17a78043a35fffbdd59e80fd2b2da39cce5e532
Gerrit-PatchSet: 4
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
Gerrit-Reviewer: Alexander Chemeris <Alexander.Chemeris at gmail.com>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Vadim Yanitskiy <axilirator at gmail.com>



More information about the gerrit-log mailing list