Fixes #1595: Allow call hangup immediately after outgoing call



git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@4300 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index e97056a..d08b599 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -170,6 +170,7 @@
         union {
             struct {
                 pjsua_msg_data  *msg_data;/**< Headers for outgoing INVITE. */
+                pj_bool_t        hangup;  /**< Call is hangup?              */
             } out_call;
             struct {
                 call_answer      answers;/**< A list of call answers.       */
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 490561c..8fe7f5e 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -388,9 +388,16 @@
 	goto on_error;
     }
 
-    /* pjsua_media_channel_deinit() has been called. */
-    if (call->async_call.med_ch_deinit)
+    /* pjsua_media_channel_deinit() has been called or
+     * call has been hung up.
+     */
+    if (call->async_call.med_ch_deinit ||
+        call->async_call.call_var.out_call.hangup)
+    {
+        PJ_LOG(4,(THIS_FILE, "Call has been hung up or media channel has "
+                             "been deinitialized"));
         goto on_error;
+    }
 
     /* Create offer */
     status = pjsua_media_channel_create_sdp(call->index, dlg->pool, NULL,
@@ -487,6 +494,7 @@
     }
 
     /* Done. */
+    call->med_ch_cb = NULL;
 
     pjsip_dlg_dec_lock(dlg);
     PJSUA_UNLOCK();
@@ -514,6 +522,10 @@
 	pjsua_media_channel_deinit(call_id);
     }
 
+    call->med_ch_cb = NULL;
+
+    pjsua_check_snd_dev_idle();
+
     PJSUA_UNLOCK();
     return status;
 }
@@ -2145,6 +2157,25 @@
     if (status != PJ_SUCCESS)
 	goto on_return;
 
+    /* If media transport creation is not yet completed, we will hangup
+     * the call in the media transport creation callback instead.
+     */
+    if (call->med_ch_cb) {
+        PJ_LOG(4,(THIS_FILE, "Pending call %d hangup upon completion "
+                             "of media transport", call_id));
+        call->async_call.call_var.out_call.hangup = PJ_TRUE;
+        if (code == 0)
+            call->last_code = PJSIP_SC_REQUEST_TERMINATED;
+        else
+            call->last_code = code;
+        if (reason) {
+            pj_strncpy(&call->last_text, reason,
+		       sizeof(call->last_text_buf_));
+        }
+        
+        goto on_return;
+    }
+
     if (code==0) {
 	if (call->inv->state == PJSIP_INV_STATE_CONFIRMED)
 	    code = PJSIP_SC_OK;
diff --git a/pjsip/src/pjsua-lib/pjsua_dump.c b/pjsip/src/pjsua-lib/pjsua_dump.c
index 87201cc..1a78558 100644
--- a/pjsip/src/pjsua-lib/pjsua_dump.c
+++ b/pjsip/src/pjsua-lib/pjsua_dump.c
@@ -888,11 +888,12 @@
 {
     int len;
     pjsip_inv_session *inv = pjsua_var.calls[call_id].inv;
-    pjsip_dialog *dlg = inv->dlg;
+    pjsip_dialog *dlg;
     char userinfo[128];
 
     /* Dump invite sesion info. */
 
+    dlg = (inv? inv->dlg: pjsua_var.calls[call_id].async_call.dlg);
     len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));
     if (len < 0)
 	pj_ansi_strcpy(userinfo, "<--uri too long-->");
@@ -901,7 +902,8 @@
 
     len = pj_ansi_snprintf(buf, size, "%s[%s] %s",
 			   title,
-			   pjsip_inv_state_name(inv->state),
+                           pjsip_inv_state_name(inv? inv->state:
+                                                PJSIP_INV_STATE_DISCONNECTED),
 			   userinfo);
     if (len < 1 || len >= (int)size) {
 	pj_ansi_strcpy(buf, "<--uri too long-->");