<p>Vadim Yanitskiy has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/9555">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">libmsc/gsm_04_80.c: make the API abstract from ss_request struct<br><br>There is no need to pass a pointer to a ss_request struct when<br>calling the gsm0480_send_ussd_* functions, because they only<br>use both transaction ID and InvokeID from there, which may<br>be passed directly.<br><br>This change allows one to use this API without parsing the<br>whole GSM 04.80 message, or when parsing is failed. Moreover,<br>if InvokeID is not available, one can pass any incorrect,<br>(e.g. negative) value, so the universal NULL tag will be used.<br>Finally, setting a TI flag is also up to the caller.<br><br>Change-Id: I13d5abbfdcf8238ebaf0566c420f09cd9255b648<br>---<br>M include/osmocom/msc/gsm_04_80.h<br>M src/libmsc/gsm_04_80.c<br>M src/libmsc/gsm_09_11.c<br>3 files changed, 42 insertions(+), 24 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/55/9555/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/msc/gsm_04_80.h b/include/osmocom/msc/gsm_04_80.h</span><br><span>index fb057c8..3edb2fd 100644</span><br><span>--- a/include/osmocom/msc/gsm_04_80.h</span><br><span>+++ b/include/osmocom/msc/gsm_04_80.h</span><br><span>@@ -7,13 +7,13 @@</span><br><span> struct gsm_subscriber_connection;</span><br><span> </span><br><span> int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                            const char* response_text,</span><br><span style="color: hsl(0, 100%, 40%);">-                              const struct ss_request *req);</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint8_t transaction_id, uint8_t invoke_id,</span><br><span style="color: hsl(120, 100%, 40%);">+                            const char *response_text);</span><br><span> int gsm0480_send_ussd_return_error(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   const struct ss_request *req,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 uint8_t transaction_id, uint8_t invoke_id,</span><br><span>                                   uint8_t error_code);</span><br><span> int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                      const struct ss_request *req,</span><br><span style="color: hsl(120, 100%, 40%);">+                         uint8_t transaction_id, int invoke_id,</span><br><span>                       uint8_t error_tag, uint8_t error_code);</span><br><span> </span><br><span> int msc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level,</span><br><span>diff --git a/src/libmsc/gsm_04_80.c b/src/libmsc/gsm_04_80.c</span><br><span>index 8799fcb..36cc54f 100644</span><br><span>--- a/src/libmsc/gsm_04_80.c</span><br><span>+++ b/src/libmsc/gsm_04_80.c</span><br><span>@@ -59,10 +59,20 @@</span><br><span>   return data;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static inline unsigned char *msgb_push_NULL(struct msgb *msgb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t *data = msgb_push(msgb, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ data[0] = ASN1_NULL_TYPE_TAG;</span><br><span style="color: hsl(120, 100%, 40%);">+ data[1] = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  return data;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span> /* Send response to a mobile-originated ProcessUnstructuredSS-Request */</span><br><span> int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                            const char *response_text, const struct ss_request *req)</span><br><span style="color: hsl(120, 100%, 40%);">+                              uint8_t transaction_id, uint8_t invoke_id,</span><br><span style="color: hsl(120, 100%, 40%);">+                            const char *response_text)</span><br><span> {</span><br><span>       struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USSD RSP");</span><br><span>    struct gsm48_hdr *gh;</span><br><span>@@ -91,7 +101,7 @@</span><br><span>   msgb_wrap_with_TL(msg, GSM_0480_SEQUENCE_TAG);</span><br><span> </span><br><span>   /* Pre-pend the invoke ID */</span><br><span style="color: hsl(0, 100%, 40%);">-    msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id);</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, invoke_id);</span><br><span> </span><br><span>     /* Wrap this up as a Return Result component */</span><br><span>      msgb_wrap_with_TL(msg, GSM0480_CTYPE_RETURN_RESULT);</span><br><span>@@ -101,15 +111,15 @@</span><br><span> </span><br><span>     /* And finally pre-pend the L3 header */</span><br><span>     gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));</span><br><span style="color: hsl(0, 100%, 40%);">-  gh->proto_discr = GSM48_PDISC_NC_SS | req->transaction_id</span><br><span style="color: hsl(0, 100%, 40%);">-                                 | (1<<7);  /* TI direction = 1 */</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 |= transaction_id << 4;</span><br><span>     gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;</span><br><span> </span><br><span>        return msc_tx_dtap(conn, msg);</span><br><span> }</span><br><span> </span><br><span> int gsm0480_send_ussd_return_error(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-   const struct ss_request *req, uint8_t error_code)</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t transaction_id, uint8_t invoke_id, uint8_t error_code)</span><br><span> {</span><br><span>  struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USSD ERR");</span><br><span>    struct gsm48_hdr *gh;</span><br><span>@@ -118,7 +128,7 @@</span><br><span>  msgb_push_TLV1(msg, GSM_0480_ERROR_CODE_TAG, error_code);</span><br><span> </span><br><span>        /* Before it insert the invoke ID */</span><br><span style="color: hsl(0, 100%, 40%);">-    msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id);</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, invoke_id);</span><br><span> </span><br><span>     /* Wrap this up as a Reject component */</span><br><span>     msgb_wrap_with_TL(msg, GSM0480_CTYPE_RETURN_ERROR);</span><br><span>@@ -128,15 +138,15 @@</span><br><span> </span><br><span>      /* And finally pre-pend the L3 header */</span><br><span>     gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));</span><br><span style="color: hsl(0, 100%, 40%);">-  gh->proto_discr = GSM48_PDISC_NC_SS;</span><br><span style="color: hsl(0, 100%, 40%);">- gh->proto_discr |= req->transaction_id | (1<<7);  /* TI direction = 1 */</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 |= transaction_id << 4;</span><br><span>     gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;</span><br><span> </span><br><span>        return msc_tx_dtap(conn, msg);</span><br><span> }</span><br><span> </span><br><span> int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                      const struct ss_request *req,</span><br><span style="color: hsl(120, 100%, 40%);">+                         uint8_t transaction_id, int invoke_id,</span><br><span>                       uint8_t error_tag, uint8_t error_code)</span><br><span> {</span><br><span>     struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USSD REJ");</span><br><span>@@ -145,8 +155,14 @@</span><br><span>     /* First insert the problem code */</span><br><span>  msgb_push_TLV1(msg, error_tag, error_code);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* Before it insert the invoke ID */</span><br><span style="color: hsl(0, 100%, 40%);">-    msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id);</span><br><span style="color: hsl(120, 100%, 40%);">+  /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * If the Invoke ID is not available, Universal Null</span><br><span style="color: hsl(120, 100%, 40%);">+   * (table 3.9) with length = 0 shall be used.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (invoke_id < 0 || invoke_id > 255)</span><br><span style="color: hsl(120, 100%, 40%);">+           msgb_push_NULL(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  else</span><br><span style="color: hsl(120, 100%, 40%);">+          msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, invoke_id);</span><br><span> </span><br><span>     /* Wrap this up as a Reject component */</span><br><span>     msgb_wrap_with_TL(msg, GSM0480_CTYPE_REJECT);</span><br><span>@@ -156,8 +172,8 @@</span><br><span> </span><br><span>      /* And finally pre-pend the L3 header */</span><br><span>     gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));</span><br><span style="color: hsl(0, 100%, 40%);">-  gh->proto_discr = GSM48_PDISC_NC_SS;</span><br><span style="color: hsl(0, 100%, 40%);">- gh->proto_discr |= req->transaction_id | (1<<7);  /* TI direction = 1 */</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 |= transaction_id << 4;</span><br><span>     gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;</span><br><span> </span><br><span>        return msc_tx_dtap(conn, msg);</span><br><span>diff --git a/src/libmsc/gsm_09_11.c b/src/libmsc/gsm_09_11.c</span><br><span>index fc588f5..799dfaa 100644</span><br><span>--- a/src/libmsc/gsm_09_11.c</span><br><span>+++ b/src/libmsc/gsm_09_11.c</span><br><span>@@ -46,7 +46,7 @@</span><br><span> </span><br><span> /* A network-specific handler function */</span><br><span> static int send_own_number(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                     const struct ss_request *req)</span><br><span style="color: hsl(120, 100%, 40%);">+                         uint8_t tid, uint8_t invoke_id)</span><br><span> {</span><br><span>      char *own_number = conn->vsub->msisdn;</span><br><span>         char response_string[GSM_EXTENSION_LENGTH + 20];</span><br><span>@@ -56,7 +56,7 @@</span><br><span> </span><br><span>     /* Need trailing CR as EOT character */</span><br><span>      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, response_string, req);</span><br><span style="color: hsl(120, 100%, 40%);">+        return gsm0480_send_ussd_response(conn, tid, invoke_id, response_string);</span><br><span> }</span><br><span> </span><br><span> /* Entry point for call independent MO SS messages */</span><br><span>@@ -121,7 +121,8 @@</span><br><span>    if (!rc) {</span><br><span>           LOGP(DMM, LOGL_ERROR, "SS/USSD message parsing error, "</span><br><span>                    "rejecting request...\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            gsm0480_send_ussd_reject(conn, &req, GSM_0480_PROBLEM_CODE_TAG_GENERAL,</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>                   GSM_0480_GEN_PROB_CODE_UNRECOGNISED);</span><br><span>                /* The GSM 04.80 API uses inverted codes (0 means error) */</span><br><span>          return -EPROTO;</span><br><span>@@ -131,8 +132,8 @@</span><br><span>        if (req.ussd_text[0] == '\0' || req.ussd_text[0] == 0xFF) {</span><br><span>          if (req.ss_code > 0) {</span><br><span>                    /* Assume interrogateSS or modification of it and reject */</span><br><span style="color: hsl(0, 100%, 40%);">-                     return gsm0480_send_ussd_return_error(conn, &req,</span><br><span style="color: hsl(0, 100%, 40%);">-                           GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION);</span><br><span style="color: hsl(120, 100%, 40%);">+                       return gsm0480_send_ussd_return_error(conn, tid,</span><br><span style="color: hsl(120, 100%, 40%);">+                              req.invoke_id, GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION);</span><br><span>               }</span><br><span>            /* Still assuming a Release-Complete and returning */</span><br><span>                return 0;</span><br><span>@@ -141,10 +142,11 @@</span><br><span>    msc_subscr_conn_communicating(conn);</span><br><span>         if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req.ussd_text)) {</span><br><span>            DEBUGP(DMM, "USSD: Own number requested\n");</span><br><span style="color: hsl(0, 100%, 40%);">-          rc = send_own_number(conn, &req);</span><br><span style="color: hsl(120, 100%, 40%);">+         rc = send_own_number(conn, tid, req.invoke_id);</span><br><span>      } else {</span><br><span>             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, &req,</span><br><span style="color: hsl(120, 100%, 40%);">+           rc = gsm0480_send_ussd_return_error(conn,</span><br><span style="color: hsl(120, 100%, 40%);">+                     tid, req.invoke_id,</span><br><span>                  GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE);</span><br><span>     }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9555">change 9555</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/9555"/><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: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I13d5abbfdcf8238ebaf0566c420f09cd9255b648 </div>
<div style="display:none"> Gerrit-Change-Number: 9555 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>