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 <axilira...@gmail.com>
Gerrit-Reviewer: Alexander Chemeris <alexander.cheme...@gmail.com>
Gerrit-Reviewer: Harald Welte <lafo...@gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Vadim Yanitskiy <axilira...@gmail.com>

Reply via email to