Index: pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 1813)
+++ pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 1814)
@@ -2884,4 +2884,58 @@
 
 /*
+ * Handle 408, 481, or any other responses that terminates dialog.
+ */
+static pj_bool_t handle_408_481_response(pjsip_inv_session *inv, 
+					 pjsip_event *e)
+{
+    /* RFC 3261 Section 12.2.1.2:
+     *  If the response for a request within a dialog is a 481
+     *  (Call/Transaction Does Not Exist) or a 408 (Request Timeout), the UAC
+     *  SHOULD terminate the dialog.  A UAC SHOULD also terminate a dialog if
+     *  no response at all is received for the request (the client
+     *  transaction would inform the TU about the timeout.)
+     * 
+     *  For INVITE initiated dialogs, terminating the dialog consists of
+     *  sending a BYE.
+     *
+     * Note:
+     *  according to X, this should terminate dialog usage only, not the 
+     *  dialog.
+     */
+    pjsip_transaction *tsx = e->body.tsx_state.tsx;
+
+    pj_assert(tsx->role == PJSIP_UAC_ROLE);
+
+    /* Note that 481 response to CANCEL does not terminate dialog usage,
+     * but only the transaction.
+     */
+    if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST &&
+	    tsx->method.id != PJSIP_CANCEL_METHOD) ||
+	tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT ||
+	tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||
+	tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR)
+    {
+	pjsip_tx_data *bye;
+	pj_status_t status;
+
+	inv_set_cause(inv, tsx->status_code, &tsx->status_text);
+	inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
+
+	/* Send BYE */
+	status = pjsip_dlg_create_request(inv->dlg, pjsip_get_bye_method(), 
+					  -1, &bye);
+	if (status == PJ_SUCCESS) {
+	    pjsip_inv_send_msg(inv, bye);
+	}
+
+	return PJ_TRUE; /* Handled */
+
+    } else {
+	return PJ_FALSE; /* Unhandled */
+    }
+}
+
+
+/*
  * State CONNECTING is after 2xx response to INVITE is sent/received.
  */
@@ -2994,5 +3048,6 @@
 	 * Handle response to outgoing UPDATE request.
 	 */
-	inv_handle_update_response(inv, e);
+	if (handle_408_481_response(inv, e) == PJ_FALSE)
+	    inv_handle_update_response(inv, e);
 
     } else if (tsx->role == PJSIP_ROLE_UAS &&
@@ -3006,20 +3061,6 @@
 
     } else if (tsx->role == PJSIP_ROLE_UAC) {
-	/*
-	 * Handle case when outgoing request is answered with 481 (Call/
-	 * Transaction Does Not Exist), 408, or when it's timed out. In these
-	 * cases, disconnect session (i.e. dialog usage only).
-	 * Note that 481 response to CANCEL does not terminate dialog usage,
-	 * but only the transaction.
-	 */
-	if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST &&
-		tsx->method.id != PJSIP_CANCEL_METHOD) ||
-	    tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT ||
-	    tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||
-	    tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR)
-	{
-	    inv_set_cause(inv, tsx->status_code, &tsx->status_text);
-	    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
-	}
+	
+	handle_408_481_response(inv, e);
     }
 
@@ -3250,4 +3291,9 @@
 	    inv_send_ack(inv, e);
 
+	} else if (handle_408_481_response(inv, e)) {
+
+	    /* Handle response that terminates dialog */
+	    /* Nothing to do (already handled) */
+
 	} else if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&
 		   (tsx->status_code==401 || tsx->status_code==407))
@@ -3267,14 +3313,4 @@
 	    status = pjsip_inv_send_msg( inv, tdata);
 
-	} else if (tsx->status_code==PJSIP_SC_CALL_TSX_DOES_NOT_EXIST ||
-		   tsx->status_code==PJSIP_SC_REQUEST_TIMEOUT ||
-		   tsx->status_code >= 700)
-	{
-	    /*
-	     * Handle responses that terminates dialog.
-	     */
-	    inv_set_cause(inv, tsx->status_code, &tsx->status_text);
-	    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
-
 	} else if (tsx->status_code >= 300 && tsx->status_code < 700) {
 
@@ -3305,5 +3341,6 @@
 	 * Handle response to outgoing UPDATE request.
 	 */
-	inv_handle_update_response(inv, e);
+	if (handle_408_481_response(inv, e) == PJ_FALSE)
+	    inv_handle_update_response(inv, e);
 
     } else if (tsx->role == PJSIP_ROLE_UAS &&
@@ -3318,19 +3355,7 @@
     } else if (tsx->role == PJSIP_ROLE_UAC) {
 	/*
-	 * Handle case when outgoing request is answered with 481 (Call/
-	 * Transaction Does Not Exist), 408, or when it's timed out. In these
-	 * cases, disconnect session (i.e. dialog usage only).
-	 * Note that 481 response to CANCEL does not terminate dialog usage,
-	 * but only the transaction.
-	 */
-	if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST &&
-		tsx->method.id != PJSIP_CANCEL_METHOD) ||
-	    tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT ||
-	    tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||
-	    tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR)
-	{
-	    inv_set_cause(inv, tsx->status_code, &tsx->status_text);
-	    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
-	}
+	 * Handle 408/481 response
+	 */
+	handle_408_481_response(inv, e);
     }
 
