Hello Jenkins Builder,

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

    https://gerrit.osmocom.org/7600

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

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, 273 insertions(+), 8 deletions(-)


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

diff --git a/TODO-RELEASE b/TODO-RELEASE
index 16496d6..a412f9e 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -13,3 +13,5 @@
 fsm            fsmc / fsm.h                    added callback for graceful 
exit => ABI changed
 gsm            gsm0480.c / gsm0480.h           the 'ss_request' struct 
extended with ussd_data,
                                                ussd_data_len, and 
ussd_data_dcs => ABI changed
+gsup           gsup.h                          the 'osmo_gsup_message' struct 
extended with
+                                               SS/USSD information => ABI 
changed
diff --git a/include/osmocom/gsm/gsup.h b/include/osmocom/gsm/gsup.h
index 1a8a3b2..304dd56 100644
--- a/include/osmocom/gsm/gsup.h
+++ b/include/osmocom/gsm/gsup.h
@@ -81,6 +81,18 @@
        OSMO_GSUP_AUTS_IE                       = 0x26,
        OSMO_GSUP_RES_IE                        = 0x27,
        OSMO_GSUP_CN_DOMAIN_IE                  = 0x28,
+
+       /**
+        * 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                    = 0x30,
+       OSMO_GSUP_SS_INVOKE_ID_IE               = 0x31,
+       OSMO_GSUP_SS_ALERTING_PATTERN_IE        = 0x32,
+       OSMO_GSUP_USSD_STRING_DCS_IE            = 0x33,
+       OSMO_GSUP_USSD_STRING_IE                = 0x34,
 };
 
 /*! GSUP message type */
@@ -110,6 +122,43 @@
        OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST  = 0b00011100,
        OSMO_GSUP_MSGT_LOCATION_CANCEL_ERROR    = 0b00011101,
        OSMO_GSUP_MSGT_LOCATION_CANCEL_RESULT   = 0b00011110,
+
+       /**
+        * 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, and can be initiated
+        * either by MS, either by the network.
+        */
+       OSMO_GSUP_MSGT_PROC_USS_REQ_REQUEST     = 0b00100000,
+       OSMO_GSUP_MSGT_PROC_USS_REQ_ERROR       = 0b00100001,
+       OSMO_GSUP_MSGT_PROC_USS_REQ_RESULT      = 0b00100010,
+
+       /**
+        * 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          = 0b00100100,
+       OSMO_GSUP_MSGT_USS_REQ_ERROR            = 0b00100101,
+       OSMO_GSUP_MSGT_USS_REQ_RESULT           = 0b00100110,
+
+
+       /**
+        * 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       = 0b00101000,
+       OSMO_GSUP_MSGT_USS_NOTIFY_ERROR         = 0b00101001,
+       OSMO_GSUP_MSGT_USS_NOTIFY_RESULT        = 0b00101010,
 };
 
 #define OSMO_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00)
@@ -154,6 +203,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, identifies each given session */
+       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;
@@ -175,6 +240,7 @@
        enum osmo_gsup_cn_domain        cn_domain;
        const uint8_t                   *pdp_charg_enc;
        size_t                          pdp_charg_enc_len;
+       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 b6ac56d..9532acf 100644
--- a/src/gsm/gsup.c
+++ b/src/gsm/gsup.c
@@ -62,6 +62,19 @@
        OSMO_VALUE_STRING(OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST),
        OSMO_VALUE_STRING(OSMO_GSUP_MSGT_LOCATION_CANCEL_ERROR),
        OSMO_VALUE_STRING(OSMO_GSUP_MSGT_LOCATION_CANCEL_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 }
 };
 
@@ -208,6 +221,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
@@ -385,6 +446,12 @@
                        gsup_msg->pdp_charg_enc_len = value_len;
                        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);
@@ -466,6 +533,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 */
@@ -564,6 +663,9 @@
                                gsup_msg->pdp_charg_enc_len, 
gsup_msg->pdp_charg_enc);
        }
 
+       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 b55f1d9..e9fc94a 100644
--- a/tests/gsup/gsup_test.c
+++ b/tests/gsup/gsup_test.c
@@ -171,6 +171,73 @@
                        0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
        };
 
+       static const uint8_t send_ussd_req[] = {
+               0x20, /* OSMO_GSUP_MSGT_PROC_USS_REQ_REQUEST */
+               TEST_IMSI_IE,
+               /* SS/USSD information IE */
+               0x30, 0x11,
+                       /* Invoke ID */
+                       0x31, 0x04, 0xde, 0xad, 0xbe, 0xef,
+
+                       /**
+                        * DCS (Data Coding Scheme)
+                        * Coding Group: the GSM 7 bit default alphabet
+                        * Language: Language unspecified
+                        */
+                       0x33, 0x01, 0x0f,
+
+                       /* USSD string: "*#100#" */
+                       0x34, 0x06,
+                       0xaa, 0x51, 0x0c, 0x06, 0x1b, 0x01,
+       };
+
+       static const uint8_t send_ussd_res[] = {
+               0x22, /* OSMO_GSUP_MSGT_PROC_USS_REQ_RESULT */
+               TEST_IMSI_IE,
+               /* SS/USSD information IE */
+               0x30, 0x21,
+                       /* Invoke ID */
+                       0x31, 0x04, 0xde, 0xad, 0xbe, 0xef,
+
+                       /**
+                        * DCS (Data Coding Scheme)
+                        * Coding Group: the GSM 7 bit default alphabet
+                        * Language: Language unspecified
+                        */
+                       0x33, 0x01, 0x0f,
+
+                       /* USSD string: "Your extension is 01393" */
+                       0x34, 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[] = {
+               0x28, /* OSMO_GSUP_MSGT_USS_NOTIFY_REQUEST */
+               TEST_IMSI_IE,
+               /* SS/USSD information IE */
+               0x30, 0x24,
+                       /* Invoke ID */
+                       0x31, 0x04, 0xbe, 0xee, 0xee, 0xff,
+
+                       /* Alerting pattern */
+                       0x32, 0x01, 0xff,
+
+                       /**
+                        * DCS (Data Coding Scheme)
+                        * Coding Group: the GSM 7 bit default alphabet
+                        * Language: Language unspecified
+                        */
+                       0x33, 0x01, 0x0f,
+
+                       /* USSD string: "Your extension is 01393" */
+                       0x34, 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;
@@ -204,6 +271,9 @@
                        send_auth_info_res_umts, 
sizeof(send_auth_info_res_umts)},
                {"Send Authentication Info Request with AUTS and RAND (UMTS)",
                        send_auth_info_req_auts, 
sizeof(send_auth_info_req_auts)},
+               {"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");
@@ -267,7 +337,11 @@
                                        osmo_hexdump(t->data + j, ie_end - j));
 
                                OSMO_ASSERT(j <= ie_end - 2);
-                               OSMO_ASSERT(t->data[j+0] <= 
OSMO_GSUP_CN_DOMAIN_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 05c64fe..8ecef41 100644
--- a/tests/gsup/gsup_test.err
+++ b/tests/gsup/gsup_test.err
@@ -40,6 +40,15 @@
   generated message: 08 01 08 21 43 65 87 09 21 43 f5 26 0e 01 02 03 04 05 06 
07 08 09 0a 0b 0c 0d 0e 20 10 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 
   original message:  08 01 08 21 43 65 87 09 21 43 f5 26 0e 01 02 03 04 05 06 
07 08 09 0a 0b 0c 0d 0e 20 10 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 
   IMSI:              123456789012345
+  generated message: 20 01 08 21 43 65 87 09 21 43 f5 30 11 31 04 de ad be ef 
33 01 0f 34 06 aa 51 0c 06 1b 01 
+  original message:  20 01 08 21 43 65 87 09 21 43 f5 30 11 31 04 de ad be ef 
33 01 0f 34 06 aa 51 0c 06 1b 01 
+  IMSI:              123456789012345
+  generated message: 22 01 08 21 43 65 87 09 21 43 f5 30 21 31 04 de ad be ef 
33 01 0f 34 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:  22 01 08 21 43 65 87 09 21 43 f5 30 21 31 04 de ad be ef 
33 01 0f 34 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: 28 01 08 21 43 65 87 09 21 43 f5 30 24 31 04 be ee ee ff 
32 01 ff 33 01 0f 34 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:  28 01 08 21 43 65 87 09 21 43 f5 30 24 31 04 be ee ee ff 
32 01 ff 33 01 0f 34 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
@@ -54,18 +63,24 @@
   message 11: tested 13 truncations, 12 parse failures
   message 12: tested 211 truncations, 209 parse failures
   message 13: tested 45 truncations, 43 parse failures
+  message 14: tested 30 truncations, 29 parse failures
+  message 15: tested 46 truncations, 45 parse failures
+  message 16: tested 49 truncations, 48 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 7680 modifications, 1526 parse failures
+  message 15: tested 11776 modifications, 1526 parse failures
+  message 16: tested 12544 modifications, 1777 parse failures
diff --git a/tests/gsup/gsup_test.ok b/tests/gsup/gsup_test.ok
index 49a85ba..bd929b5 100644
--- a/tests/gsup/gsup_test.ok
+++ b/tests/gsup/gsup_test.ok
@@ -27,4 +27,10 @@
           Send Authentication Info Result with IK, CK, AUTN and RES (UMTS) OK
   Testing Send Authentication Info Request with AUTS and RAND (UMTS)
           Send Authentication Info Request with AUTS and RAND (UMTS) 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: 3
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