<p>Keith Whyte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/10702">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">wip<br><br>Change-Id: I4e68bda2e7dc6842de1bbe2849097537ad84e8f6<br>---<br>M src/call.h<br>M src/mncc.c<br>M src/sip.c<br>3 files changed, 81 insertions(+), 7 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-sip-connector refs/changes/02/10702/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/call.h b/src/call.h</span><br><span>index 5a11f6c..eb9ef66 100644</span><br><span>--- a/src/call.h</span><br><span>+++ b/src/call.h</span><br><span>@@ -43,6 +43,7 @@</span><br><span>    struct call *call;</span><br><span> </span><br><span>       bool in_release;</span><br><span style="color: hsl(120, 100%, 40%);">+      int cause;</span><br><span> </span><br><span>       /**</span><br><span>   * RTP data</span><br><span>@@ -130,6 +131,7 @@</span><br><span>    int rsp_wanted;</span><br><span> </span><br><span>  struct mncc_connection *conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ int cause;</span><br><span> };</span><br><span> </span><br><span> extern struct llist_head g_call_list;</span><br><span>diff --git a/src/mncc.c b/src/mncc.c</span><br><span>index 2ecf8d0..9be010d 100644</span><br><span>--- a/src/mncc.c</span><br><span>+++ b/src/mncc.c</span><br><span>@@ -105,13 +105,19 @@</span><br><span> </span><br><span> static void mncc_fill_header(struct gsm_mncc *mncc, uint32_t msg_type, uint32_t callref)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     struct mncc_call_leg *mncc_leg;</span><br><span style="color: hsl(120, 100%, 40%);">+       mncc_leg = mncc_find_leg(callref);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         mncc->msg_type = msg_type;</span><br><span>        mncc->callref = callref;</span><br><span>  if (MNCC_DISC_REQ == msg_type || MNCC_REL_REQ == msg_type) {</span><br><span>                 mncc->fields |= MNCC_F_CAUSE;</span><br><span>             mncc->cause.coding = GSM48_CAUSE_CODING_GSM;</span><br><span>              mncc->cause.location = GSM48_CAUSE_LOC_PUN_S_LU;</span><br><span style="color: hsl(120, 100%, 40%);">+           mncc->cause.value = mncc_leg->base.cause;</span><br><span>      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> static void mncc_write(struct mncc_connection *conn, struct gsm_mncc *mncc, uint32_t callref)</span><br><span>@@ -134,6 +140,10 @@</span><br><span>         struct gsm_mncc mncc = { 0, };</span><br><span> </span><br><span>   mncc_fill_header(&mncc, msg_type, callref);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     LOGP(DMNCC, LOGL_DEBUG, "%s() message type: %s cause: %u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                         __func__, osmo_mncc_name(msg_type), mncc.cause.value);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    mncc_write(conn, &mncc, callref);</span><br><span> }</span><br><span> </span><br><span>@@ -260,7 +270,7 @@</span><br><span>         case MNCC_CC_PROCEEDING:</span><br><span>     case MNCC_CC_CONNECTED:</span><br><span>              LOGP(DMNCC, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                 "Releasing call in non-initial leg(%u)\n", leg->callref);</span><br><span style="color: hsl(120, 100%, 40%);">+                        "Releasing call in non-initial leg(%u) cause(%d)\n", leg->callref, leg->base.cause);</span><br><span>                 leg->base.in_release = true;</span><br><span>              start_cmd_timer(leg, MNCC_REL_IND);</span><br><span>          mncc_send(leg->conn, MNCC_DISC_REQ, leg->callref);</span><br><span>@@ -381,6 +391,7 @@</span><br><span> </span><br><span>   /* TODO.. now we can continue with the call */</span><br><span>       struct in_addr net = { .s_addr = htonl(leg->base.ip) };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         LOGP(DMNCC, LOGL_DEBUG,</span><br><span>              "RTP cnt leg(%u) ip(%s), port(%u) pt(%u) ptm(%u)\n",</span><br><span>               leg->callref, inet_ntoa(net), leg->base.port,</span><br><span>@@ -490,6 +501,7 @@</span><br><span>            return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      return leg;</span><br><span> }</span><br><span> </span><br><span>@@ -503,6 +515,8 @@</span><br><span>   if (!leg)</span><br><span>            return;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   LOGP(DMNCC, LOGL_DEBUG, "Rcvd MNCC_DISC_IND, Cause: %d\n", data->cause.value);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        LOGP(DMNCC,</span><br><span>          LOGL_DEBUG, "leg(%u) was disconnected. Releasing\n", data->callref);</span><br><span>    leg->base.in_release = true;</span><br><span>@@ -511,6 +525,7 @@</span><br><span> </span><br><span>    other_leg = call_leg_other(&leg->base);</span><br><span>       if (other_leg)</span><br><span style="color: hsl(120, 100%, 40%);">+                other_leg->cause = data->cause.value;</span><br><span>          other_leg->release_call(other_leg);</span><br><span> }</span><br><span> </span><br><span>@@ -520,15 +535,19 @@</span><br><span>      struct mncc_call_leg *leg;</span><br><span> </span><br><span>       leg = find_leg(conn, buf, rc, &data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  if (!leg)</span><br><span>            return;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   LOGP(DMNCC, LOGL_DEBUG, "Rcvd MNCC_REL_IND, Cause: %d\n", data->cause.value);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         if (leg->base.in_release)</span><br><span>                 stop_cmd_timer(leg, MNCC_REL_IND);</span><br><span>   else {</span><br><span>               struct call_leg *other_leg;</span><br><span>          other_leg = call_leg_other(&leg->base);</span><br><span>               if (other_leg)</span><br><span style="color: hsl(120, 100%, 40%);">+                        other_leg->cause = data->cause.value;</span><br><span>                  other_leg->release_call(other_leg);</span><br><span>       }</span><br><span>    LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was released.\n", data->callref);</span><br><span>diff --git a/src/sip.c b/src/sip.c</span><br><span>index 84d1f6e..141dc99 100644</span><br><span>--- a/src/sip.c</span><br><span>+++ b/src/sip.c</span><br><span>@@ -51,7 +51,7 @@</span><br><span>         if (status == 183)</span><br><span>           sdp_extract_sdp(leg, sip, false);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOGP(DSIP, LOGL_NOTICE, "leg(%p) is now rining.\n", leg);</span><br><span style="color: hsl(120, 100%, 40%);">+   LOGP(DSIP, LOGL_NOTICE, "leg(%p) is now ringing.\n", leg);</span><br><span>         other->ring_call(other);</span><br><span> }</span><br><span> </span><br><span>@@ -150,8 +150,8 @@</span><br><span> </span><br><span> void nua_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    LOGP(DSIP, LOGL_DEBUG, "SIP event(%u) status(%d) phrase(%s) %p\n",</span><br><span style="color: hsl(0, 100%, 40%);">-            event, status, phrase, hmagic);</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGP(DSIP, LOGL_DEBUG, "%s(): SIP event(%u) status(%d) phrase(%s) %p\n",</span><br><span style="color: hsl(120, 100%, 40%);">+            __func__, event, status, phrase, hmagic);</span><br><span> </span><br><span>        if (event == nua_r_invite) {</span><br><span>                 struct sip_call_leg *leg;</span><br><span>@@ -170,13 +170,29 @@</span><br><span>            else if (status >= 300) {</span><br><span>                         struct call_leg *other = call_leg_other(&leg->base);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                 LOGP(DSIP, LOGL_ERROR, "leg(%p) unknown err, releasing.\n", leg);</span><br><span style="color: hsl(120, 100%, 40%);">+                   LOGP(DSIP, LOGL_ERROR, "leg(%p) unknown error code (%d), releasing.\n", leg, status);</span><br><span>                      nua_cancel(leg->nua_handle, TAG_END());</span><br><span>                   nua_handle_destroy(leg->nua_handle);</span><br><span>                      call_leg_release(&leg->base);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                        if (other)</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (other) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          LOGP(DSIP, LOGL_ERROR, "Releasing other leg (%p) with status(%d)\n", other, status);</span><br><span style="color: hsl(120, 100%, 40%);">+                                switch (status) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                     case 404:</span><br><span style="color: hsl(120, 100%, 40%);">+                                             other->cause = GSM48_CC_CAUSE_UNASSIGNED_NR;</span><br><span style="color: hsl(120, 100%, 40%);">+                                               break;</span><br><span style="color: hsl(120, 100%, 40%);">+                                        case 502:</span><br><span style="color: hsl(120, 100%, 40%);">+                                     case 480:</span><br><span style="color: hsl(120, 100%, 40%);">+                                             other->cause = GSM48_CC_CAUSE_NO_ROUTE;</span><br><span style="color: hsl(120, 100%, 40%);">+                                            break;</span><br><span style="color: hsl(120, 100%, 40%);">+                                        case 486:</span><br><span style="color: hsl(120, 100%, 40%);">+                                             other->cause = GSM48_CC_CAUSE_USER_BUSY;</span><br><span style="color: hsl(120, 100%, 40%);">+                                           break;</span><br><span style="color: hsl(120, 100%, 40%);">+                                        default:</span><br><span style="color: hsl(120, 100%, 40%);">+                                              other->cause = GSM48_CC_CAUSE_NORM_CALL_CLEAR;</span><br><span style="color: hsl(120, 100%, 40%);">+                             }</span><br><span>                            other->release_call(other);</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span>            }</span><br><span>    } else if (event == nua_r_bye || event == nua_r_cancel) {</span><br><span>            /* our bye or hang up is answered */</span><br><span>@@ -214,13 +230,25 @@</span><br><span>                 call_leg_release(&leg->base);</span><br><span>                 if (other)</span><br><span>                   other->release_call(other);</span><br><span style="color: hsl(120, 100%, 40%);">+        } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DSIP, LOGL_ERROR, "Did nothing with event(%u) status(%d)\n", event, status);</span><br><span>  }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void copy_cause_phrase(int *to_cause, char **to_phrase,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    int from_cause, const char *from_phrase)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   *to_cause = from_cause;</span><br><span style="color: hsl(120, 100%, 40%);">+       *to_phrase = (char *)from_phrase;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> static void sip_release_call(struct call_leg *_leg)</span><br><span> {</span><br><span>         struct sip_call_leg *leg;</span><br><span style="color: hsl(120, 100%, 40%);">+     char reason[64];</span><br><span style="color: hsl(120, 100%, 40%);">+      char *sip_phrase;</span><br><span style="color: hsl(120, 100%, 40%);">+     char *reason_text;</span><br><span style="color: hsl(120, 100%, 40%);">+    int sip_cause;</span><br><span> </span><br><span>   OSMO_ASSERT(_leg->type == CALL_TYPE_SIP);</span><br><span>         leg = (struct sip_call_leg *) _leg;</span><br><span>@@ -231,6 +259,30 @@</span><br><span>    * and for a connected one bye. I don't see how sofia-sip is going</span><br><span>        * to help us here.</span><br><span>   */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DSIP, LOGL_DEBUG, "%s(): Release with MNCC cause(%d)\n", __func__, _leg->cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (_leg->cause) {</span><br><span style="color: hsl(120, 100%, 40%);">+             case GSM48_CC_CAUSE_NORM_CALL_CLEAR:</span><br><span style="color: hsl(120, 100%, 40%);">+                  copy_cause_phrase(&sip_cause, &sip_phrase, SIP_200_OK);</span><br><span style="color: hsl(120, 100%, 40%);">+                       reason_text = "Normal Call Clearing";</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case GSM48_CC_CAUSE_DEST_OOO:</span><br><span style="color: hsl(120, 100%, 40%);">+                 copy_cause_phrase(&sip_cause, &sip_phrase, SIP_502_BAD_GATEWAY);</span><br><span style="color: hsl(120, 100%, 40%);">+                      reason_text = "Destination out of Order";</span><br><span style="color: hsl(120, 100%, 40%);">+                   break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case GSM48_CC_CAUSE_USER_BUSY:</span><br><span style="color: hsl(120, 100%, 40%);">+                        copy_cause_phrase(&sip_cause, &sip_phrase, SIP_486_BUSY_HERE);</span><br><span style="color: hsl(120, 100%, 40%);">+                        reason_text = "User Busy";</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span style="color: hsl(120, 100%, 40%);">+                default:</span><br><span style="color: hsl(120, 100%, 40%);">+                      sip_cause = 502;</span><br><span style="color: hsl(120, 100%, 40%);">+                      sip_phrase = "";</span><br><span style="color: hsl(120, 100%, 40%);">+                    reason_text = "";</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%);">+   snprintf(reason, sizeof reason, "Q.850;cause=%u;text=\"%s\"", _leg->cause, reason_text);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    switch (leg->state) {</span><br><span>     case SIP_CC_INITIAL:</span><br><span>                 LOGP(DSIP, LOGL_NOTICE, "Canceling leg(%p) in int state\n", leg);</span><br><span>@@ -242,7 +294,8 @@</span><br><span>            if (leg->dir == SIP_DIR_MT)</span><br><span>                       nua_cancel(leg->nua_handle, TAG_END());</span><br><span>           else {</span><br><span style="color: hsl(0, 100%, 40%);">-                  nua_respond(leg->nua_handle, SIP_486_BUSY_HERE,</span><br><span style="color: hsl(120, 100%, 40%);">+                    nua_respond(leg->nua_handle, sip_cause, sip_phrase,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        SIPTAG_REASON_STR(reason),</span><br><span>                                   TAG_END());</span><br><span>                  nua_handle_destroy(leg->nua_handle);</span><br><span>                      call_leg_release(&leg->base);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10702">change 10702</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/10702"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-sip-connector </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I4e68bda2e7dc6842de1bbe2849097537ad84e8f6 </div>
<div style="display:none"> Gerrit-Change-Number: 10702 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Keith Whyte <keith@rhizomatica.org> </div>