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