Index: /pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h	(revision 1318)
+++ /pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h	(revision 1319)
@@ -224,5 +224,6 @@
     pj_pool_t		*pool;			    /**< Dialog's pool.	    */
     pjsip_inv_state	 state;			    /**< Invite sess state. */
-    pj_bool_t		 cancelling;		    /**< CANCEL sent?	    */
+    pj_bool_t		 cancelling;		    /**< CANCEL requested   */
+    pj_bool_t		 pending_cancel;	    /**< Wait to send CANCEL*/
     pjsip_status_code	 cause;			    /**< Disconnect cause.  */
     pj_str_t		 cause_text;		    /**< Cause text.	    */
Index: /pjproject/trunk/pjsip/include/pjsip/sip_transaction.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_transaction.h	(revision 1318)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_transaction.h	(revision 1319)
@@ -298,4 +298,16 @@
 
 /**
+ * Cease retransmission on the UAC transaction. The UAC transaction is
+ * still considered running, and it will complete when either final
+ * response is received or the transaction times out.
+ *
+ * This operation normally is used for INVITE transaction only, when
+ * the transaction is cancelled before any provisional response has been
+ * received.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_stop_retransmit(pjsip_transaction *tsx);
+
+
+/**
  * Get the transaction instance in the incoming message. If the message
  * has a corresponding transaction, this function will return non NULL
Index: /pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 1318)
+++ /pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 1319)
@@ -1513,6 +1513,10 @@
 	    if (inv->invite_tsx->status_code < 100) {
 
-		pjsip_tsx_terminate(inv->invite_tsx, 487);
+		pjsip_tsx_stop_retransmit(inv->invite_tsx);
+		inv->cancelling = PJ_TRUE;
+		inv->pending_cancel = PJ_TRUE;
 		*p_tdata = NULL;
+		PJ_LOG(4, (inv->obj_name, "Stopping retransmission, "
+			   "delaying CANCEL"));
 		return PJ_SUCCESS;
 	    }
@@ -1926,4 +1930,14 @@
 
 	case PJSIP_TSX_STATE_PROCEEDING:
+	    if (inv->pending_cancel) {
+		pjsip_tx_data *cancel;
+
+		inv->pending_cancel = PJ_FALSE;
+
+		status = pjsip_inv_end_session(inv, 487, NULL, &cancel);
+		if (status == PJ_SUCCESS && cancel)
+		    status = pjsip_inv_send_msg(inv, cancel);
+	    }
+
 	    if (dlg->remote.info->tag.slen) {
 
Index: /pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 1318)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 1319)
@@ -1420,7 +1420,8 @@
     struct tsx_lock_data lck;
 
+    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);
+
     PJ_LOG(5,(tsx->obj_name, "Request to terminate transaction"));
 
-    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);
     PJ_ASSERT_RETURN(code >= 200, PJ_EINVAL);
 
@@ -1431,4 +1432,32 @@
     tsx_set_status_code(tsx, code, NULL);
     tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, NULL);
+    unlock_tsx(tsx, &lck);
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Cease retransmission on the UAC transaction. The UAC transaction is
+ * still considered running, and it will complete when either final
+ * response is received or the transaction times out.
+ */
+PJ_DEF(pj_status_t) pjsip_tsx_stop_retransmit(pjsip_transaction *tsx)
+{
+    struct tsx_lock_data lck;
+
+    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);
+    PJ_ASSERT_RETURN(tsx->role == PJSIP_ROLE_UAC &&
+		     tsx->method.id == PJSIP_INVITE_METHOD,
+		     PJ_EINVALIDOP);
+
+    PJ_LOG(5,(tsx->obj_name, "Request to stop retransmission"));
+
+    lock_tsx(tsx, &lck);
+    /* Cancel retransmission timer. */
+    if (tsx->retransmit_timer.id != 0) {
+	pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
+	tsx->retransmit_timer.id = 0;
+    }
     unlock_tsx(tsx, &lck);
 
