<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/9658">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">libmsc/gsm_09_11.c: forward SS/USSD messages to HLR over GSUP<br><br>In order to be able to support external SS/USSD gateway, we should<br>not terminate the GSM 04.80 messages at OsmoMSC. Instead, we need<br>to follow the GSM TS 09.11 specification, and forward all messages<br>unhandled by OsmoMSC to OsmoHLR over GSUP protocol.<br><br>This change implements forwarding of MO SS/USSD messages. The<br>forwarding assumes transcoding between GSM 04.80 messages and<br>GSUP messages. The payload of Facility IE is carried 'as is'.<br><br>As a side-effect, this will disable the osmo-msc internal handler<br>implementing the "*#100#" for obtaining the subscribers own phone<br>number.  In order to re-gain this functionality, you will need a<br>modern osmo-hlr (Change-Id I1d09fab810a6bb9ab02904de72dbc9e8a414f9f9)<br>and the following line in your osmo-hlr.cfg:<br> hlr<br>  ussd route prefix *#100# internal own-msisdn<br><br>TTCN-3 test case: I01de73aced6057328a121577a5a83bc2615fb2d4<br>Change-Id: Ide5f7e350b537db80cd8326fc59c8bf2e01cb68c<br>---<br>M include/osmocom/msc/gsm_09_11.h<br>M src/libmsc/gsm_04_08.c<br>M src/libmsc/gsm_09_11.c<br>M tests/msc_vlr/msc_vlr_test_ss.c<br>M tests/msc_vlr/msc_vlr_test_ss.err<br>5 files changed, 225 insertions(+), 63 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/msc/gsm_09_11.h b/include/osmocom/msc/gsm_09_11.h</span><br><span>index 4e7a5b6..5e689fb 100644</span><br><span>--- a/include/osmocom/msc/gsm_09_11.h</span><br><span>+++ b/include/osmocom/msc/gsm_09_11.h</span><br><span>@@ -1,5 +1,7 @@</span><br><span> #pragma once</span><br><span> </span><br><span> #include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsup.h></span><br><span> </span><br><span> int gsm0911_rcv_nc_ss(struct gsm_subscriber_connection *conn, struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0911_gsup_handler(struct vlr_subscr *vsub, struct osmo_gsup_message *gsup);</span><br><span>diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c</span><br><span>index c10a701..19b0572 100644</span><br><span>--- a/src/libmsc/gsm_04_08.c</span><br><span>+++ b/src/libmsc/gsm_04_08.c</span><br><span>@@ -1702,7 +1702,13 @@</span><br><span>                             struct osmo_gsup_message *gsup_msg)</span><br><span> {</span><br><span>   switch (gsup_msg->message_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-    /* Nowhere to route for now */</span><br><span style="color: hsl(120, 100%, 40%);">+        /* GSM 09.11 code implementing SS/USSD */</span><br><span style="color: hsl(120, 100%, 40%);">+     case OSMO_GSUP_MSGT_PROC_SS_REQUEST:</span><br><span style="color: hsl(120, 100%, 40%);">+  case OSMO_GSUP_MSGT_PROC_SS_RESULT:</span><br><span style="color: hsl(120, 100%, 40%);">+   case OSMO_GSUP_MSGT_PROC_SS_ERROR:</span><br><span style="color: hsl(120, 100%, 40%);">+            DEBUGP(DMSC, "Routed to GSM 09.11 SS/USSD handler\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              return gsm0911_gsup_handler(vsub, gsup_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       default:</span><br><span>             LOGP(DMM, LOGL_ERROR, "No handler found for %s, dropping message...\n",</span><br><span>                    osmo_gsup_message_type_name(gsup_msg->message_type));</span><br><span>diff --git a/src/libmsc/gsm_09_11.c b/src/libmsc/gsm_09_11.c</span><br><span>index 799dfaa..219325e 100644</span><br><span>--- a/src/libmsc/gsm_09_11.c</span><br><span>+++ b/src/libmsc/gsm_09_11.c</span><br><span>@@ -1,6 +1,7 @@</span><br><span> /* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org></span><br><span>  * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org></span><br><span>  * (C) 2009 by Mike Haben <michael.haben@btinternet.com></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com></span><br><span>  *</span><br><span>  * All Rights Reserved</span><br><span>  *</span><br><span>@@ -26,9 +27,12 @@</span><br><span>  */</span><br><span> </span><br><span> #include <stdio.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdlib.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span> #include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/tlv.h></span><br><span> </span><br><span> #include <osmocom/msc/gsm_04_80.h></span><br><span> #include <osmocom/msc/gsm_subscriber.h></span><br><span>@@ -37,34 +41,21 @@</span><br><span> #include <osmocom/msc/vlr.h></span><br><span> #include <osmocom/msc/gsm_04_08.h></span><br><span> #include <osmocom/msc/transaction.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/msc/gsup_client.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/msc/msc_ifaces.h></span><br><span> </span><br><span> /* FIXME: choose a proper range */</span><br><span> static uint32_t new_callref = 0x20000001;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Declarations of USSD strings to be recognised */</span><br><span style="color: hsl(0, 100%, 40%);">-const char USSD_TEXT_OWN_NUMBER[] = "*#100#";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* A network-specific handler function */</span><br><span style="color: hsl(0, 100%, 40%);">-static int send_own_number(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                          uint8_t tid, uint8_t invoke_id)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     char *own_number = conn->vsub->msisdn;</span><br><span style="color: hsl(0, 100%, 40%);">-    char response_string[GSM_EXTENSION_LENGTH + 20];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        DEBUGP(DMM, "%s: MSISDN = %s\n", vlr_subscr_name(conn->vsub),</span><br><span style="color: hsl(0, 100%, 40%);">-             own_number);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Need trailing CR as EOT character */</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(response_string, sizeof(response_string), "Your extension is %s\r", own_number);</span><br><span style="color: hsl(0, 100%, 40%);">-     return gsm0480_send_ussd_response(conn, tid, invoke_id, response_string);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Entry point for call independent MO SS messages */</span><br><span> int gsm0911_rcv_nc_ss(struct gsm_subscriber_connection *conn, struct msgb *msg)</span><br><span> {</span><br><span>  struct gsm48_hdr *gh = msgb_l3(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_gsup_message gsup_msg;</span><br><span>   struct gsm_trans *trans;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct ss_request req;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct msgb *gsup_msgb;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t facility_ie_len;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t *facility_ie;</span><br><span>        uint8_t pdisc, tid;</span><br><span>  uint8_t msg_type;</span><br><span>    int rc;</span><br><span>@@ -116,47 +107,195 @@</span><br><span>             cm_service_request_concludes(conn, msg);</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   memset(&req, 0, sizeof(req));</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = gsm0480_decode_ss_request(gh, msgb_l3len(msg), &req);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-              LOGP(DMM, LOGL_ERROR, "SS/USSD message parsing error, "</span><br><span style="color: hsl(0, 100%, 40%);">-                       "rejecting request...\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            gsm0480_send_ussd_reject(conn, tid, -1,</span><br><span style="color: hsl(0, 100%, 40%);">-                 GSM_0480_PROBLEM_CODE_TAG_GENERAL,</span><br><span style="color: hsl(0, 100%, 40%);">-                      GSM_0480_GEN_PROB_CODE_UNRECOGNISED);</span><br><span style="color: hsl(0, 100%, 40%);">-           /* The GSM 04.80 API uses inverted codes (0 means error) */</span><br><span style="color: hsl(0, 100%, 40%);">-             return -EPROTO;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Attempt to extract Facility IE */</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = gsm0480_extract_ie_by_tag(gh, msgb_l3len(msg),</span><br><span style="color: hsl(120, 100%, 40%);">+           &facility_ie, &facility_ie_len, GSM0480_IE_FACILITY);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DMM, LOGL_ERROR, "GSM 04.80 message parsing error, "</span><br><span style="color: hsl(120, 100%, 40%);">+                   "couldn't extract Facility IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto error;</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* Interrogation or releaseComplete? */</span><br><span style="color: hsl(0, 100%, 40%);">- if (req.ussd_text[0] == '\0' || req.ussd_text[0] == 0xFF) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (req.ss_code > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       /* Assume interrogateSS or modification of it and reject */</span><br><span style="color: hsl(0, 100%, 40%);">-                     return gsm0480_send_ussd_return_error(conn, tid,</span><br><span style="color: hsl(0, 100%, 40%);">-                                req.invoke_id, GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION);</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Facility IE is optional for RELEASE COMPLETE */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (msg_type != GSM0480_MTYPE_RELEASE_COMPLETE) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!facility_ie || facility_ie_len < 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 LOGP(DMM, LOGL_ERROR, "GSM 04.80 message parsing error, "</span><br><span style="color: hsl(120, 100%, 40%);">+                           "missing mandatory Facility IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 rc = -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+                 goto error;</span><br><span>          }</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Still assuming a Release-Complete and returning */</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Compose a mew GSUP message */</span><br><span style="color: hsl(120, 100%, 40%);">+      memset(&gsup_msg, 0x00, sizeof(gsup_msg));</span><br><span style="color: hsl(120, 100%, 40%);">+        gsup_msg.message_type = OSMO_GSUP_MSGT_PROC_SS_REQUEST;</span><br><span style="color: hsl(120, 100%, 40%);">+       gsup_msg.session_id = trans->callref;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * Perform A-interface to GSUP-interface mapping,</span><br><span style="color: hsl(120, 100%, 40%);">+      * according to GSM TS 09.11, table 4.2.</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (msg_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+   case GSM0480_MTYPE_REGISTER:</span><br><span style="color: hsl(120, 100%, 40%);">+          gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_BEGIN;</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM0480_MTYPE_FACILITY:</span><br><span style="color: hsl(120, 100%, 40%);">+          gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_CONTINUE;</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM0480_MTYPE_RELEASE_COMPLETE:</span><br><span style="color: hsl(120, 100%, 40%);">+          gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Fill in the (optional) message payload */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (facility_ie) {</span><br><span style="color: hsl(120, 100%, 40%);">+            gsup_msg.ss_info_len = facility_ie_len;</span><br><span style="color: hsl(120, 100%, 40%);">+               gsup_msg.ss_info = facility_ie;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Fill in subscriber's IMSI */</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_STRLCPY_ARRAY(gsup_msg.imsi, conn->vsub->imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Allocate GSUP message buffer */</span><br><span style="color: hsl(120, 100%, 40%);">+    gsup_msgb = gsup_client_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!gsup_msgb) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DMM, LOGL_ERROR, "Couldn't allocate GSUP message\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              rc = -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+         goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Encode GSUP message */</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = osmo_gsup_encode(gsup_msgb, &gsup_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DMM, LOGL_ERROR, "Couldn't encode GSUP message\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Finally send */</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = gsup_client_send(conn->network->vlr->gsup_client, gsup_msgb);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DMM, LOGL_ERROR, "Couldn't send GSUP message\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Don't release connection, wait for response */</span><br><span style="color: hsl(120, 100%, 40%);">+ msc_subscr_conn_communicating(conn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+error:</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Abort transaction on DTAP-interface */</span><br><span style="color: hsl(120, 100%, 40%);">+     gsm0480_send_ussd_reject(conn, tid, -1,</span><br><span style="color: hsl(120, 100%, 40%);">+               GSM_0480_PROBLEM_CODE_TAG_GENERAL,</span><br><span style="color: hsl(120, 100%, 40%);">+            GSM_0480_GEN_PROB_CODE_UNRECOGNISED);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (trans)</span><br><span style="color: hsl(120, 100%, 40%);">+            trans_free(trans);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* TODO: abort transaction on GSUP interface if any */</span><br><span style="color: hsl(120, 100%, 40%);">+        return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0911_gsup_handler(struct vlr_subscr *vsub,</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct osmo_gsup_message *gsup_msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct vlr_instance *vlr;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gsm_network *net;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_trans *trans;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm48_hdr *gh;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *ss_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+  bool trans_end;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Associate logging messages with this subscriber */</span><br><span style="color: hsl(120, 100%, 40%);">+ log_set_context(LOG_CTX_VLR_SUBSCR, vsub);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Obtain pointer to vlr_instance */</span><br><span style="color: hsl(120, 100%, 40%);">+  vlr = vsub->vlr;</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(vlr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Obtain pointer to gsm_network */</span><br><span style="color: hsl(120, 100%, 40%);">+   net = (struct gsm_network *) vlr->user_ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(net);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Handle errors */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* FIXME: handle this error somehow! */</span><br><span>              return 0;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   msc_subscr_conn_communicating(conn);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req.ussd_text)) {</span><br><span style="color: hsl(0, 100%, 40%);">-               DEBUGP(DMM, "USSD: Own number requested\n");</span><br><span style="color: hsl(0, 100%, 40%);">-          rc = send_own_number(conn, tid, req.invoke_id);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                DEBUGP(DMM, "Unhandled USSD %s\n", req.ussd_text);</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = gsm0480_send_ussd_return_error(conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                       tid, req.invoke_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                     GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE);</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Attempt to find DTAP-transaction */</span><br><span style="color: hsl(120, 100%, 40%);">+        trans = trans_find_by_callref(net, gsup_msg->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!trans) {</span><br><span style="color: hsl(120, 100%, 40%);">+         /* FIXME: network-originated sessions are not supported yet */</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DMM, LOGL_ERROR, "Network-originated sessions "</span><br><span style="color: hsl(120, 100%, 40%);">+                        "are not supported, dropping request...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return -ENOTSUP;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /**</span><br><span style="color: hsl(0, 100%, 40%);">-      * TODO: as we only handle *#100# for now, and always</span><br><span style="color: hsl(0, 100%, 40%);">-    * respond with RELEASE COMPLETE, let's manually free</span><br><span style="color: hsl(0, 100%, 40%);">-        * the transaction here, until the external interface</span><br><span style="color: hsl(0, 100%, 40%);">-    * is implemented.</span><br><span style="color: hsl(0, 100%, 40%);">-       */</span><br><span style="color: hsl(0, 100%, 40%);">-     trans_free(trans);</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Allocate and prepare a new MT message */</span><br><span style="color: hsl(120, 100%, 40%);">+   ss_msg = gsm48_msgb_alloc_name("GSM 04.08 SS/USSD");</span><br><span style="color: hsl(120, 100%, 40%);">+        gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));</span><br><span style="color: hsl(120, 100%, 40%);">+     gh->proto_discr  = GSM48_PDISC_NC_SS;</span><br><span style="color: hsl(120, 100%, 40%);">+      gh->proto_discr |= trans->transaction_id << 4;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * Perform GSUP-interface to A-interface mapping,</span><br><span style="color: hsl(120, 100%, 40%);">+      * according to GSM TS 09.11, table 4.1.</span><br><span style="color: hsl(120, 100%, 40%);">+       *</span><br><span style="color: hsl(120, 100%, 40%);">+     * TODO: see (note 3), both CONTINUE and END may</span><br><span style="color: hsl(120, 100%, 40%);">+       * be also mapped to REGISTER if a new transaction</span><br><span style="color: hsl(120, 100%, 40%);">+     * has to be established.</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (gsup_msg->session_state) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_GSUP_SESSION_STATE_BEGIN:</span><br><span style="color: hsl(120, 100%, 40%);">+           gh->msg_type = GSM0480_MTYPE_REGISTER;</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case OSMO_GSUP_SESSION_STATE_CONTINUE:</span><br><span style="color: hsl(120, 100%, 40%);">+                gh->msg_type = GSM0480_MTYPE_FACILITY;</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case OSMO_GSUP_SESSION_STATE_END:</span><br><span style="color: hsl(120, 100%, 40%);">+             gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Missing or incorrect session state */</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_GSUP_SESSION_STATE_NONE:</span><br><span style="color: hsl(120, 100%, 40%);">+    default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DMM, LOGL_ERROR, "Unexpected session state %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      gsup_msg->session_state);</span><br><span style="color: hsl(120, 100%, 40%);">+          /* FIXME: send ERROR back to the HLR */</span><br><span style="color: hsl(120, 100%, 40%);">+               msgb_free(ss_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Facility IE is optional only for RELEASE COMPLETE */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (gh->msg_type != GSM0480_MTYPE_RELEASE_COMPLETE) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!gsup_msg->ss_info || gsup_msg->ss_info_len < 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       LOGP(DMM, LOGL_ERROR, "Missing mandatory Facility IE "</span><br><span style="color: hsl(120, 100%, 40%);">+                              "for mapped 0x%02x message\n", gh->msg_type);</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* FIXME: send ERROR back to the HLR */</span><br><span style="color: hsl(120, 100%, 40%);">+                       msgb_free(ss_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Append Facility IE if preset */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (gsup_msg->ss_info && gsup_msg->ss_info_len > 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Facility IE carries LV, others carry TLV */</span><br><span style="color: hsl(120, 100%, 40%);">+                if (gh->msg_type == GSM0480_MTYPE_FACILITY)</span><br><span style="color: hsl(120, 100%, 40%);">+                        msgb_lv_put(ss_msg, gsup_msg->ss_info_len, gsup_msg->ss_info);</span><br><span style="color: hsl(120, 100%, 40%);">+          else</span><br><span style="color: hsl(120, 100%, 40%);">+                  msgb_tlv_put(ss_msg, GSM0480_IE_FACILITY,</span><br><span style="color: hsl(120, 100%, 40%);">+                             gsup_msg->ss_info_len, gsup_msg->ss_info);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Should we release the transaction? */</span><br><span style="color: hsl(120, 100%, 40%);">+      trans_end = (gh->msg_type == GSM0480_MTYPE_RELEASE_COMPLETE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Sent to the MS, give ownership of ss_msg */</span><br><span style="color: hsl(120, 100%, 40%);">+        msc_tx_dtap(trans->conn, ss_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Release transaction if required */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (trans_end)</span><br><span style="color: hsl(120, 100%, 40%);">+                trans_free(trans);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return 0;</span><br><span> }</span><br><span>diff --git a/tests/msc_vlr/msc_vlr_test_ss.c b/tests/msc_vlr/msc_vlr_test_ss.c</span><br><span>index f3a1f68..f0652b0 100644</span><br><span>--- a/tests/msc_vlr/msc_vlr_test_ss.c</span><br><span>+++ b/tests/msc_vlr/msc_vlr_test_ss.c</span><br><span>@@ -94,11 +94,21 @@</span><br><span>        EXPECT_ACCEPTED(true);</span><br><span> </span><br><span>   /* MT: GSM 04.80 RELEASE COMPLETE with Facility IE */</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup_expect_tx("20" /* OSMO_GSUP_MSGT_PROC_SS_REQUEST */</span><br><span style="color: hsl(120, 100%, 40%);">+            "0108" "09710000004026f0" /* IMSI TLV */</span><br><span style="color: hsl(120, 100%, 40%);">+          "3004" "20000001" /* Session ID TLV */</span><br><span style="color: hsl(120, 100%, 40%);">+            "3101" "01" /* Session state: BEGIN */</span><br><span style="color: hsl(120, 100%, 40%);">+            "3515" FACILITY_IE_REQ);</span><br><span>   dtap_expect_tx("8b2a" "1c27" FACILITY_IE_RSP);</span><br><span>   expect_release_clear(via_ran);</span><br><span> </span><br><span>   /* MO: GSM 04.80 REGISTER with Facility IE and SS version IE */</span><br><span>      ms_sends_msg("0b7b" "1c15" FACILITY_IE_REQ "7f0100");</span><br><span style="color: hsl(120, 100%, 40%);">+   gsup_rx("20" /* OSMO_GSUP_MSGT_PROC_SS_REQUEST */</span><br><span style="color: hsl(120, 100%, 40%);">+           "0108" "09710000004026f0" /* IMSI TLV */</span><br><span style="color: hsl(120, 100%, 40%);">+          "3004" "20000001" /* Session ID TLV */</span><br><span style="color: hsl(120, 100%, 40%);">+            "3101" "03" /* Session state: END */</span><br><span style="color: hsl(120, 100%, 40%);">+              "3527" FACILITY_IE_RSP, NULL);</span><br><span>     VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");</span><br><span>  ASSERT_RELEASE_CLEAR(via_ran);</span><br><span> </span><br><span>diff --git a/tests/msc_vlr/msc_vlr_test_ss.err b/tests/msc_vlr/msc_vlr_test_ss.err</span><br><span>index c7f7711..fce5bb6 100644</span><br><span>--- a/tests/msc_vlr/msc_vlr_test_ss.err</span><br><span>+++ b/tests/msc_vlr/msc_vlr_test_ss.err</span><br><span>@@ -162,22 +162,27 @@</span><br><span> DREF MSISDN:46071: MSC conn use + trans_nc_ss == 3 (0x4a: dtap,cm_service,trans_nc_ss)</span><br><span> DMM MSISDN:46071: rx msg GSM0480_MTYPE_REGISTER: received_cm_service_request changes to false</span><br><span> DREF MSISDN:46071: MSC conn use - cm_service == 2 (0x42: dtap,trans_nc_ss)</span><br><span style="color: hsl(120, 100%, 40%);">+GSUP --> HLR: OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200000013101013515a11302010102013b300b04010f0406aa510c061b01</span><br><span> DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING</span><br><span> DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING</span><br><span style="color: hsl(0, 100%, 40%);">-DMM USSD: Own number requested</span><br><span style="color: hsl(0, 100%, 40%);">-DMM MSISDN:46071: MSISDN = 46071</span><br><span style="color: hsl(120, 100%, 40%);">+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x40: trans_nc_ss)</span><br><span style="color: hsl(120, 100%, 40%);">+<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200000013101033527a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d</span><br><span style="color: hsl(120, 100%, 40%);">+DVLR GSUP rx 61: 20010809710000004026f03004200000013101033527a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d</span><br><span style="color: hsl(120, 100%, 40%);">+DREF VLR subscr MSISDN:46071 usage increases to: 4</span><br><span style="color: hsl(120, 100%, 40%);">+DMSC Routed to GSM 09.11 SS/USSD handler</span><br><span> DMSC msc_tx 43 bytes to MSISDN:46071 via RAN_GERAN_A</span><br><span> - DTAP --RAN_GERAN_A--> MS: GSM0480_MTYPE_RELEASE_COMPLETE: 8b2a1c27a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d</span><br><span> - DTAP matches expected message</span><br><span style="color: hsl(0, 100%, 40%);">-DREF VLR subscr MSISDN:46071 usage decreases to: 2</span><br><span style="color: hsl(0, 100%, 40%);">-DREF MSISDN:46071: MSC conn use - trans_nc_ss == 1 (0x2: dtap)</span><br><span style="color: hsl(0, 100%, 40%);">-DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )</span><br><span style="color: hsl(120, 100%, 40%);">+DREF VLR subscr MSISDN:46071 usage decreases to: 3</span><br><span style="color: hsl(120, 100%, 40%);">+DREF MSISDN:46071: MSC conn use - trans_nc_ss == 0 (0x0: )</span><br><span> DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED</span><br><span> DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING</span><br><span> DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)</span><br><span style="color: hsl(0, 100%, 40%);">-DREF VLR subscr MSISDN:46071 usage increases to: 3</span><br><span style="color: hsl(0, 100%, 40%);">-DREF VLR subscr MSISDN:46071 usage decreases to: 2</span><br><span style="color: hsl(120, 100%, 40%);">+DREF VLR subscr MSISDN:46071 usage increases to: 4</span><br><span style="color: hsl(120, 100%, 40%);">+DREF VLR subscr MSISDN:46071 usage decreases to: 3</span><br><span> - BSSAP Clear --RAN_GERAN_A--> MS</span><br><span style="color: hsl(120, 100%, 40%);">+DREF VLR subscr MSISDN:46071 usage decreases to: 2</span><br><span style="color: hsl(120, 100%, 40%);">+<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns 0</span><br><span>   dtap_tx_confirmed == 1</span><br><span>   bssap_clear_sent == 1</span><br><span> - all requests serviced, conn has been released</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9658">change 9658</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/9658"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-msc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ide5f7e350b537db80cd8326fc59c8bf2e01cb68c </div>
<div style="display:none"> Gerrit-Change-Number: 9658 </div>
<div style="display:none"> Gerrit-PatchSet: 10 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Alexander Chemeris <Alexander.Chemeris@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>