Index: /pjproject/trunk/pjsip/include/pjsip/sip_util.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_util.h	(revision 931)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_util.h	(revision 932)
@@ -427,4 +427,5 @@
  * @param timeout   Optional timeout for final response to be received, or -1 
  *		    if the transaction should not have a timeout restriction.
+ *		    The value is in miliseconds.
  * @param token	    Optional token to be associated with the transaction, and 
  *		    to be passed to the callback.
@@ -438,5 +439,5 @@
 PJ_DECL(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt,
 					       pjsip_tx_data *tdata,
-					       int timeout,
+					       pj_int32_t timeout,
 					       void *token,
 					       void (*cb)(void*,pjsip_event*));
Index: /pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c	(revision 931)
+++ /pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c	(revision 932)
@@ -39,4 +39,10 @@
 #define THIS_FILE		"sip_regc.c"
 
+/* Outgoing transaction timeout when server sends 100 but never replies
+ * with final response. Value is in MILISECONDS!
+ */
+#define REGC_TSX_TIMEOUT	33000
+
+
 /**
  * SIP client registration structure.
@@ -743,5 +749,6 @@
     regc->has_tsx = PJ_TRUE;
     ++regc->busy;
-    status = pjsip_endpt_send_request(regc->endpt, tdata, -1, regc, &tsx_callback);
+    status = pjsip_endpt_send_request(regc->endpt, tdata, REGC_TSX_TIMEOUT,
+				      regc, &tsx_callback);
     if (status!=PJ_SUCCESS) {
 	PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status));
Index: /pjproject/trunk/pjsip/src/pjsip/sip_util_statefull.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_util_statefull.c	(revision 931)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_util_statefull.c	(revision 932)
@@ -23,9 +23,14 @@
 #include <pjsip/sip_event.h>
 #include <pjsip/sip_errno.h>
+#include <pj/assert.h>
+#include <pj/log.h>
 #include <pj/pool.h>
-#include <pj/assert.h>
+#include <pj/string.h>
 
 struct tsx_data
 {
+    pj_time_val	    delay;
+    pj_timer_entry  timeout_timer;
+
     void *token;
     void (*cb)(void*, pjsip_event*);
@@ -67,4 +72,10 @@
 	return;
 
+    /* Cancel timer if any */
+    if (tsx_data->timeout_timer.id != 0) {
+	tsx_data->timeout_timer.id = 0;
+	pjsip_endpt_cancel_timer(tsx->endpt, &tsx_data->timeout_timer);
+    }
+
     /* Call the callback, if any, and prevent the callback to be called again
      * by clearing the transaction's module_data.
@@ -78,7 +89,30 @@
 
 
+static void mod_util_on_timeout(pj_timer_heap_t *th, pj_timer_entry *te)
+{
+    pjsip_transaction *tsx = (pjsip_transaction*) te->user_data;
+    struct tsx_data *tsx_data;
+
+    PJ_UNUSED_ARG(th);
+
+    tsx_data = tsx->mod_data[mod_stateful_util.id];
+    if (tsx_data == NULL) {
+	pj_assert(!"Shouldn't happen");
+	return;
+    }
+
+    tsx_data->timeout_timer.id = 0;
+
+    PJ_LOG(4,(tsx->obj_name, "Transaction timed out by user timer (%d.%d sec)",
+	      (int)tsx_data->delay.sec, (int)tsx_data->delay.msec));
+
+    /* Terminate the transaction. This will call mod_util_on_tsx_state() */
+    pjsip_tsx_terminate(tsx, PJSIP_SC_TSX_TIMEOUT);
+}
+
+
 PJ_DEF(pj_status_t) pjsip_endpt_send_request(  pjsip_endpoint *endpt,
 					       pjsip_tx_data *tdata,
-					       int timeout,
+					       pj_int32_t timeout,
 					       void *token,
 					       void (*cb)(void*,pjsip_event*))
@@ -100,14 +134,36 @@
     }
 
-    tsx_data = pj_pool_alloc(tsx->pool, sizeof(struct tsx_data));
+    tsx_data = pj_pool_zalloc(tsx->pool, sizeof(struct tsx_data));
     tsx_data->token = token;
     tsx_data->cb = cb;
+
+    if (timeout >= 0) {
+	tsx_data->delay.sec = 0;
+	tsx_data->delay.msec = timeout;
+	pj_time_val_normalize(&tsx_data->delay);
+
+	tsx_data->timeout_timer.id = PJ_TRUE;
+	tsx_data->timeout_timer.user_data = tsx;
+	tsx_data->timeout_timer.cb = &mod_util_on_timeout;
+	
+	status = pjsip_endpt_schedule_timer(endpt, &tsx_data->timeout_timer, 
+					    &tsx_data->delay);
+	if (status != PJ_SUCCESS) {
+	    pjsip_tsx_terminate(tsx, PJSIP_SC_INTERNAL_SERVER_ERROR);
+	    pjsip_tx_data_dec_ref(tdata);
+	    return status;
+	}
+    }
+
     tsx->mod_data[mod_stateful_util.id] = tsx_data;
 
-    PJ_TODO(IMPLEMENT_TIMEOUT_FOR_SEND_REQUEST);
-
     status = pjsip_tsx_send_msg(tsx, NULL);
-    if (status != PJ_SUCCESS)
-	pjsip_tx_data_dec_ref(tdata);
+    if (status != PJ_SUCCESS) {
+	if (tsx_data->timeout_timer.id != 0) {
+	    pjsip_endpt_cancel_timer(endpt, &tsx_data->timeout_timer);
+	    tsx_data->timeout_timer.id = PJ_FALSE;
+	}
+	pjsip_tx_data_dec_ref(tdata);
+    }
 
     return status;
