Index: /pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h	(revision 3776)
+++ /pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h	(revision 3777)
@@ -546,4 +546,23 @@
 
 /**
+ * Variant of #pjsip_inv_verify_request() which allows application not to
+ * specify the rdata (i.e. pass NULL as the rdata parameter) and specify
+ * the parsed SDP in the \a offer argument and a temporary pool in the
+ * \a tmp_pool argument.
+ * This is useful if application no longer has access to the rdata.
+ *
+ * @see pjsip_inv_verify_request()
+ */
+PJ_DECL(pj_status_t) pjsip_inv_verify_request3( pjsip_rx_data *rdata,
+                                                pj_pool_t *tmp_pool,
+						unsigned *options,
+						const pjmedia_sdp_session *offer,
+						const pjmedia_sdp_session *answer,
+						pjsip_dialog *dlg,
+						pjsip_endpoint *endpt,
+						pjsip_tx_data **tdata);
+
+
+/**
  * Create UAS invite session for the specified dialog in dlg. Application 
  * SHOULD call the verification function before calling this function, 
@@ -712,4 +731,19 @@
 
 /**
+ * Set local offer or answer depending on negotiator state (it may also
+ * create a negotiator if it doesn't exist yet).
+ *
+ * @param inv		The invite session.
+ * @param sdp		The SDP description which will be set as
+ *			an offer/answer to remote.
+ *
+ * @return		PJ_SUCCESS if local offer/answer can be accepted by
+ *			SDP negotiator.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_set_local_sdp(pjsip_inv_session *inv,
+					     const pjmedia_sdp_session *sdp );
+
+
+/**
  * Set local answer to respond to remote SDP offer, to be carried by 
  * subsequent response (or request).
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 3776)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 3777)
@@ -101,4 +101,14 @@
 #define PJSUA_MAX_CALL_MEDIA		PJMEDIA_MAX_SDP_MEDIA
 
+/* Call answer's list. */
+typedef struct call_answer
+{
+    PJ_DECL_LIST_MEMBER(struct call_answer);
+    pjsua_msg_data  *msg_data;      /**< Answer's headers list.       */
+    pj_str_t        *reason;        /**< Answer's reason phrase.      */
+    unsigned         code;          /**< Answer's status code.        */
+} call_answer;
+
+
 /** 
  * Structure to be attached to invite dialog. 
@@ -152,4 +162,7 @@
                 pjsua_msg_data  *msg_data;/**< Headers for outgoing INVITE. */
             } out_call;
+            struct {
+                call_answer      answers;/**< A list of call answers.       */
+            } inc_call;
         } call_var;
     } async_call;                      /**< Temporary storage for async
Index: /pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 3776)
+++ /pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 3777)
@@ -812,5 +812,6 @@
  * Verify incoming INVITE request.
  */
-PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata,
+PJ_DEF(pj_status_t) pjsip_inv_verify_request3(pjsip_rx_data *rdata,
+                                              pj_pool_t *tmp_pool,
 					      unsigned *options,
 					      const pjmedia_sdp_session *r_sdp,
@@ -820,9 +821,9 @@
 					      pjsip_tx_data **p_tdata)
 {
-    pjsip_msg *msg;
-    pjsip_allow_hdr *allow;
-    pjsip_supported_hdr *sup_hdr;
-    pjsip_require_hdr *req_hdr;
-    pjsip_contact_hdr *c_hdr;
+    pjsip_msg *msg = NULL;
+    pjsip_allow_hdr *allow = NULL;
+    pjsip_supported_hdr *sup_hdr = NULL;
+    pjsip_require_hdr *req_hdr = NULL;
+    pjsip_contact_hdr *c_hdr = NULL;
     int code = 200;
     unsigned rem_option = 0;
@@ -835,5 +836,5 @@
 
     /* Verify arguments. */
-    PJ_ASSERT_RETURN(rdata != NULL && options != NULL, PJ_EINVAL);
+    PJ_ASSERT_RETURN(tmp_pool != NULL && options != NULL, PJ_EINVAL);
 
     /* Normalize options */
@@ -845,11 +846,13 @@
 	*options |= PJSIP_INV_SUPPORT_ICE;
 
-    /* Get the message in rdata */
-    msg = rdata->msg_info.msg;
-
-    /* Must be INVITE request. */
-    PJ_ASSERT_RETURN(msg->type == PJSIP_REQUEST_MSG &&
-		     msg->line.req.method.id == PJSIP_INVITE_METHOD,
-		     PJ_EINVAL);
+    if (rdata) {
+        /* Get the message in rdata */
+        msg = rdata->msg_info.msg;
+    
+        /* Must be INVITE request. */
+        PJ_ASSERT_RETURN(msg && msg->type == PJSIP_REQUEST_MSG &&
+		         msg->line.req.method.id == PJSIP_INVITE_METHOD,
+		         PJ_EINVAL);
+    }
 
     /* If tdata is specified, then either dlg or endpt must be specified */
@@ -863,13 +866,15 @@
 
     /* Check the Contact header */
-    c_hdr = (pjsip_contact_hdr*)
-	    pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);
-    if (!c_hdr || !c_hdr->uri) {
-	/* Missing Contact header or Contact contains "*" */
+    if (msg) {
+        c_hdr = (pjsip_contact_hdr*)
+	        pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);
+    }
+    if (msg && (!c_hdr || !c_hdr->uri)) {
+        /* Missing Contact header or Contact contains "*" */
 	pjsip_warning_hdr *w;
 	pj_str_t warn_text;
 
 	warn_text = pj_str("Bad/missing Contact header");
-	w = pjsip_warning_hdr_create(rdata->tp_info.pool, 399,
+	w = pjsip_warning_hdr_create(tmp_pool, 399,
 				     pjsip_endpt_name(endpt),
 				     &warn_text);
@@ -886,5 +891,5 @@
      * only when the body hasn't been parsed before.
      */
-    if (r_sdp == NULL) {
+    if (r_sdp == NULL && rdata) {
 	sdp_info = pjsip_rdata_get_sdp_info(rdata);
     } else {
@@ -892,5 +897,5 @@
     }
 
-    if (r_sdp==NULL && msg->body) {
+    if (r_sdp==NULL && msg && msg->body) {
 
 	/* Check if body really contains SDP. */
@@ -904,5 +909,5 @@
 		pjsip_accept_hdr *acc;
 
-		acc = pjsip_accept_hdr_create(rdata->tp_info.pool);
+		acc = pjsip_accept_hdr_create(tmp_pool);
 		PJ_ASSERT_RETURN(acc, PJ_ENOMEM);
 		acc->values[acc->count++] = pj_str("application/sdp");
@@ -921,5 +926,5 @@
 		pjsip_warning_hdr *w;
 
-		w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool,
+		w = pjsip_warning_hdr_create_from_status(tmp_pool,
 							 pjsip_endpt_name(endpt),
 							 sdp_info->sdp_err);
@@ -946,9 +951,9 @@
 	    /* Create SDP negotiator */
 	    status = pjmedia_sdp_neg_create_w_remote_offer(
-			    rdata->tp_info.pool, l_sdp, r_sdp, &neg);
+			    tmp_pool, l_sdp, r_sdp, &neg);
 	    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
 	    /* Negotiate SDP */
-	    status = pjmedia_sdp_neg_negotiate(rdata->tp_info.pool, neg, 0);
+	    status = pjmedia_sdp_neg_negotiate(tmp_pool, neg, 0);
 	    if (status != PJ_SUCCESS) {
 
@@ -962,5 +967,5 @@
 		    /* Add Warning header. */
 		    w = pjsip_warning_hdr_create_from_status(
-					    rdata->tp_info.pool, 
+					    tmp_pool, 
 					    pjsip_endpt_name(endpt), status);
 		    PJ_ASSERT_RETURN(w, PJ_ENOMEM);
@@ -969,5 +974,5 @@
 
 		    /* Add Accept header to response */
-		    acc = pjsip_accept_hdr_create(rdata->tp_info.pool);
+		    acc = pjsip_accept_hdr_create(tmp_pool);
 		    PJ_ASSERT_RETURN(acc, PJ_ENOMEM);
 		    acc->values[acc->count++] = pj_str("application/sdp");
@@ -985,5 +990,8 @@
      * implicitly by sending this INVITE.
      */
-    allow = (pjsip_allow_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_ALLOW, NULL);
+    if (msg) {
+        allow = (pjsip_allow_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_ALLOW,
+                                                      NULL);
+    }
     if (allow) {
 	unsigned i;
@@ -1003,6 +1011,8 @@
 
     /* Check Supported header */
-    sup_hdr = (pjsip_supported_hdr*)
-	      pjsip_msg_find_hdr(msg, PJSIP_H_SUPPORTED, NULL);
+    if (msg) {
+        sup_hdr = (pjsip_supported_hdr*)
+	          pjsip_msg_find_hdr(msg, PJSIP_H_SUPPORTED, NULL);
+    }
     if (sup_hdr) {
 	unsigned i;
@@ -1022,6 +1032,8 @@
 
     /* Check Require header */
-    req_hdr = (pjsip_require_hdr*)
-	      pjsip_msg_find_hdr(msg, PJSIP_H_REQUIRE, NULL);
+    if (msg) {
+        req_hdr = (pjsip_require_hdr*)
+	          pjsip_msg_find_hdr(msg, PJSIP_H_REQUIRE, NULL);
+    }
     if (req_hdr) {
 	unsigned i;
@@ -1075,5 +1087,5 @@
 
 		/* Add Unsupported header. */
-		unsupp_hdr = pjsip_unsupported_hdr_create(rdata->tp_info.pool);
+		unsupp_hdr = pjsip_unsupported_hdr_create(tmp_pool);
 		PJ_ASSERT_RETURN(unsupp_hdr != NULL, PJ_ENOMEM);
 
@@ -1090,5 +1102,5 @@
 		if (h) {
 		    sup_hdr = (pjsip_supported_hdr*)
-			      pjsip_hdr_clone(rdata->tp_info.pool, h);
+			      pjsip_hdr_clone(tmp_pool, h);
 		    pj_list_push_back(&res_hdr_list, sup_hdr);
 		}
@@ -1102,8 +1114,8 @@
      * by peer.
      */
-    if ( ((*options & PJSIP_INV_REQUIRE_100REL)!=0 && 
+    if ( msg && (((*options & PJSIP_INV_REQUIRE_100REL)!=0 && 
 	  (rem_option & PJSIP_INV_SUPPORT_100REL)==0) ||
 	 ((*options & PJSIP_INV_REQUIRE_TIMER)!=0 && 
-	  (rem_option & PJSIP_INV_SUPPORT_TIMER)==0))
+	  (rem_option & PJSIP_INV_SUPPORT_TIMER)==0)))
     {
 	code = PJSIP_SC_EXTENSION_REQUIRED;
@@ -1114,5 +1126,5 @@
 
 	    /* Add Require header. */
-	    req_hdr = pjsip_require_hdr_create(rdata->tp_info.pool);
+	    req_hdr = pjsip_require_hdr_create(tmp_pool);
 	    PJ_ASSERT_RETURN(req_hdr != NULL, PJ_ENOMEM);
 
@@ -1130,5 +1142,5 @@
 	    if (h) {
 		sup_hdr = (pjsip_supported_hdr*)
-			  pjsip_hdr_clone(rdata->tp_info.pool, h);
+			  pjsip_hdr_clone(tmp_pool, h);
 		pj_list_push_back(&res_hdr_list, sup_hdr);
 	    }
@@ -1158,4 +1170,8 @@
 	const pjsip_hdr *h;
 
+        if (!rdata) {
+            return PJSIP_ERRNO_FROM_SIP_STATUS(code);
+        }
+
 	if (dlg) {
 	    status = pjsip_dlg_create_response(dlg, rdata, code, NULL, 
@@ -1199,4 +1215,21 @@
  * Verify incoming INVITE request.
  */
+PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata,
+					      unsigned *options,
+					      const pjmedia_sdp_session *r_sdp,
+					      const pjmedia_sdp_session *l_sdp,
+					      pjsip_dialog *dlg,
+					      pjsip_endpoint *endpt,
+					      pjsip_tx_data **p_tdata)
+{
+    return pjsip_inv_verify_request3(rdata, rdata->tp_info.pool,
+                                     options, r_sdp, l_sdp, dlg, 
+				     endpt, p_tdata);
+}
+
+
+/*
+ * Verify incoming INVITE request.
+ */
 PJ_DEF(pj_status_t) pjsip_inv_verify_request( pjsip_rx_data *rdata,
 					      unsigned *options,
@@ -1206,5 +1239,6 @@
 					      pjsip_tx_data **p_tdata)
 {
-    return pjsip_inv_verify_request2(rdata, options, NULL, l_sdp, dlg, 
+    return pjsip_inv_verify_request3(rdata, rdata->tp_info.pool,
+                                     options, NULL, l_sdp, dlg, 
 				     endpt, p_tdata);
 }
@@ -2023,4 +2057,41 @@
     pjsip_dlg_dec_lock(inv->dlg);
     pj_log_pop_indent();
+    return status;
+}
+
+
+/*
+ * Set local SDP offer/answer.
+ */
+PJ_DEF(pj_status_t) pjsip_inv_set_local_sdp(pjsip_inv_session *inv,
+					    const pjmedia_sdp_session *sdp )
+{
+    const pjmedia_sdp_session *offer;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(inv && sdp, PJ_EINVAL);
+
+    /* If we have remote SDP offer, set local answer to respond to the offer,
+     * otherwise we set/modify our local offer (and create an SDP negotiator
+     * if we don't have one yet).
+     */
+    if (inv->neg) {
+        pjmedia_sdp_neg_state neg_state = pjmedia_sdp_neg_get_state(inv->neg);
+
+        if ((neg_state == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER ||
+	     neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) &&
+            pjmedia_sdp_neg_get_neg_remote(inv->neg, &offer) == PJ_SUCCESS)
+        {
+            status = pjsip_inv_set_sdp_answer(inv, sdp);
+        }  else if (neg_state == PJMEDIA_SDP_NEG_STATE_DONE) {
+            status = pjmedia_sdp_neg_modify_local_offer(inv->pool,
+                                                        inv->neg, sdp);
+        } else
+            return PJMEDIA_SDPNEG_EINSTATE;
+    } else {
+	status = pjmedia_sdp_neg_create_w_local_offer(inv->pool, 
+						      sdp, &inv->neg);
+    }
+
     return status;
 }
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3776)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3777)
@@ -332,4 +332,5 @@
 */
 
+/* Outgoing call callback when media transport creation is completed. */
 static pj_status_t
 on_make_call_med_tp_complete(pjsua_call_id call_id,
@@ -612,4 +613,7 @@
     call->user_data = user_data;
     
+    /* Store variables required for the callback after the async
+     * media transport creation is completed.
+     */
     call->async_call.call_var.out_call.options = options;
     if (msg_data) {
@@ -686,4 +690,91 @@
 
 
+/* Incoming call callback when media transport creation is completed. */
+static pj_status_t
+on_incoming_call_med_tp_complete(pjsua_call_id call_id,
+                                 const pjsua_med_tp_state_info *info)
+{
+    pjsua_call *call = &pjsua_var.calls[call_id];
+    const pjmedia_sdp_session *offer=NULL;
+    pjmedia_sdp_session *answer;
+    pjsip_tx_data *response = NULL;
+    unsigned options = 0;
+    int sip_err_code = (info? info->sip_err_code: 0);
+    pj_status_t status = (info? info->status: PJ_SUCCESS);
+
+    PJSUA_LOCK();
+
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
+        goto on_return;
+    }
+    
+    /* Get remote SDP offer (if any). */
+    if (call->inv->neg)
+        pjmedia_sdp_neg_get_neg_remote(call->inv->neg, &offer);
+
+    status = pjsua_media_channel_create_sdp(call_id,
+                                            call->async_call.dlg->pool, 
+					    offer, &answer, &sip_err_code);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
+        goto on_return;
+    }
+
+    status = pjsip_inv_set_local_sdp(call->inv, answer);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Error setting local SDP", status);
+        sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
+        goto on_return;
+    }
+
+    /* Verify that we can handle the request. */
+    status = pjsip_inv_verify_request3(NULL,
+                                       call->inv->pool_prov, &options, offer,
+                                       answer, NULL, pjsua_var.endpt, &response);
+    if (status != PJ_SUCCESS) {
+	/*
+	 * No we can't handle the incoming INVITE request.
+	 */
+	goto on_return;
+    } 
+
+on_return:
+    if (status != PJ_SUCCESS) {
+        pjsip_tx_data *tdata;
+        pj_status_t status_;
+
+	status_ = pjsip_inv_end_session(call->inv, sip_err_code, NULL, &tdata);
+	if (status_ == PJ_SUCCESS && tdata)
+	    status_ = pjsip_inv_send_msg(call->inv, tdata);
+
+        pjsua_media_channel_deinit(call->index);
+    }
+
+    /* Set the callback to NULL to indicate that the async operation
+     * has completed.
+     */
+    call->med_ch_cb = NULL;
+
+    if (status == PJ_SUCCESS &&
+        !pj_list_empty(&call->async_call.call_var.inc_call.answers))
+    {
+        struct call_answer *answer, *next;
+        
+        answer = call->async_call.call_var.inc_call.answers.next;
+        while (answer != &call->async_call.call_var.inc_call.answers) {
+            next = answer->next;
+            pjsua_call_answer(call_id, answer->code, answer->reason,
+                              answer->msg_data);
+            pj_list_erase(answer);
+            answer = next;
+        }
+    }
+
+    PJSUA_UNLOCK();
+    return status;
+}
+
+
 /**
  * Handle incoming INVITE request.
@@ -704,5 +795,5 @@
     int call_id = -1;
     int sip_err_code;
-    pjmedia_sdp_session *offer=NULL, *answer;
+    pjmedia_sdp_session *offer=NULL;
     pj_status_t status;
 
@@ -865,28 +956,4 @@
     } else {
 	offer = NULL;
-    }
-
-    /* Init media channel */
-    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 
-				      call->secure_level, 
-				      rdata->tp_info.pool,
-				      offer,
-				      &sip_err_code, PJ_FALSE,
-                                      NULL);
-    if (status != PJ_SUCCESS) {
-	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
-	pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
-			    sip_err_code, NULL, NULL, NULL, NULL);
-	goto on_return;
-    }
-
-    /* Create answer */
-    status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool, 
-					    offer, &answer, &sip_err_code);
-    if (status != PJ_SUCCESS) {
-	pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
-	pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
-			    sip_err_code, NULL, NULL, NULL, NULL);
-	goto on_return;
     }
 
@@ -903,5 +970,5 @@
 	options |= PJSIP_INV_ALWAYS_USE_TIMER;
 
-    status = pjsip_inv_verify_request2(rdata, &options, offer, answer, NULL,
+    status = pjsip_inv_verify_request2(rdata, &options, offer, NULL, NULL,
 				       pjsua_var.endpt, &response);
     if (status != PJ_SUCCESS) {
@@ -923,8 +990,6 @@
 	}
 
-	pjsua_media_channel_deinit(call->index);
 	goto on_return;
     } 
-
 
     /* Get suitable Contact header */
@@ -939,5 +1004,4 @@
 	    pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
 					  NULL, NULL);
-	    pjsua_media_channel_deinit(call->index);
 	    goto on_return;
 	}
@@ -950,5 +1014,4 @@
 	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
 				      NULL, NULL);
-	pjsua_media_channel_deinit(call->index);
 	goto on_return;
     }
@@ -975,5 +1038,5 @@
 
     /* Create invite session: */
-    status = pjsip_inv_create_uas( dlg, rdata, answer, options, &inv);
+    status = pjsip_inv_create_uas( dlg, rdata, NULL, options, &inv);
     if (status != PJ_SUCCESS) {
 	pjsip_hdr hdr_list;
@@ -995,4 +1058,48 @@
     }
 
+    /* Create and attach pjsua_var data to the dialog: */
+    call->inv = inv;
+    dlg->mod_data[pjsua_var.mod.id] = call;
+    inv->mod_data[pjsua_var.mod.id] = call;
+
+    /* Store variables required for the callback after the async
+     * media transport creation is completed.
+     */
+    call->async_call.dlg = dlg;
+    pj_list_init(&call->async_call.call_var.inc_call.answers);
+
+    /* Init media channel */
+    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 
+				      call->secure_level, 
+				      rdata->tp_info.pool,
+				      offer,
+				      &sip_err_code, PJ_TRUE,
+                                      (pjsua_med_tp_state_cb)
+                                      &on_incoming_call_med_tp_complete);
+    if (status == PJ_SUCCESS) {
+        status = on_incoming_call_med_tp_complete(call_id, NULL);
+        if (status != PJ_SUCCESS) {
+            sip_err_code = PJSIP_SC_NOT_ACCEPTABLE;
+            pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
+	    goto on_return;
+        }
+    } else if (status != PJ_EPENDING) {
+	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
+	pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL);
+	goto on_return;
+    }
+
+    /* Create answer */
+/*  
+    status = pjsua_media_channel_create_sdp(call->index, rdata->tp_info.pool, 
+					    offer, &answer, &sip_err_code);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Error creating SDP answer", status);
+	pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
+			    sip_err_code, NULL, NULL, NULL, NULL);
+	goto on_return;
+    }
+*/
+
     /* Init Session Timers */
     status = pjsip_timer_init_session(inv, 
@@ -1013,5 +1120,5 @@
      * incoming INVITE! 
      */
-    if (pjsua_var.ua_cfg.nat_type_in_sdp &&
+    if (pjsua_var.ua_cfg.nat_type_in_sdp && inv->neg &&
 	pjmedia_sdp_neg_get_state(inv->neg) > PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 
     {
@@ -1063,10 +1170,4 @@
 	}
     }
-
-    /* Create and attach pjsua_var data to the dialog: */
-    call->inv = inv;
-
-    dlg->mod_data[pjsua_var.mod.id] = call;
-    inv->mod_data[pjsua_var.mod.id] = call;
 
     ++pjsua_var.call_cnt;
@@ -1637,4 +1738,33 @@
     if (status != PJ_SUCCESS)
 	goto on_return;
+
+    PJSUA_LOCK();
+    /* If media transport creation is not yet completed, we will answer
+     * the call in the media transport creation callback instead.
+     */
+    if (call->med_ch_cb) {
+        struct call_answer *answer;
+        
+        PJ_LOG(4,(THIS_FILE, "Pending answering call %d upon completion "
+                             "of media transport", call_id));
+
+        answer = PJ_POOL_ZALLOC_T(call->inv->pool_prov, struct call_answer);
+        answer->code = code;
+        if (reason) {
+            pj_strdup(call->inv->pool_prov, answer->reason, reason);
+        }
+        if (msg_data) {
+            answer->msg_data = pjsua_msg_data_clone(call->inv->pool_prov,
+                                                    msg_data);
+        }
+        pj_list_push_back(&call->async_call.call_var.inc_call.answers,
+                          answer);
+
+        PJSUA_UNLOCK();
+        if (dlg) pjsip_dlg_dec_lock(dlg);
+        pj_log_pop_indent();
+        return status;
+    }
+    PJSUA_UNLOCK();
 
     if (call->res_time.sec == 0)
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c	(revision 3776)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c	(revision 3777)
@@ -1657,5 +1657,4 @@
         call->med_ch_cb = cb;
         if (rem_sdp) {
-            /* TODO: change rem_sdp to non-const parameter. */
             call->async_call.rem_sdp =
                 pjmedia_sdp_session_clone(call->inv->pool_prov, rem_sdp);
@@ -2113,4 +2112,11 @@
     pjsua_call *call = &pjsua_var.calls[call_id];
     unsigned mi;
+
+    for (mi=0; mi<call->med_cnt; ++mi) {
+	pjsua_call_media *call_med = &call->media[mi];
+
+        if (call_med->tp_st == PJSUA_MED_TP_CREATING)
+            return PJ_EBUSY;
+    }
 
     PJ_LOG(4,(THIS_FILE, "Call %d: deinitializing media..", call_id));
