Index: /pjproject/branches/split-3rd-party/Makefile
===================================================================
--- /pjproject/branches/split-3rd-party/Makefile	(revision 1209)
+++ /pjproject/branches/split-3rd-party/Makefile	(revision 1210)
@@ -57,2 +57,13 @@
 	done
 
+prefix = /usr/local
+install:
+	mkdir -p $(DESTDIR)$(prefix)/lib
+	cp -L $$(find . -name '*.a') $(DESTDIR)$(prefix)/lib
+	mkdir -p $(DESTDIR)$(prefix)/include
+	cp -RL $$(find  . -name include) $(DESTDIR)$(prefix)
+	cd $(DESTDIR)$(prefix)/lib && for i in $$(find . -name 'libpj*a'); do\
+		ln -s $$i $$(echo $$i | sed -e "s/-$(TARGET_NAME)//");\
+	done
+	mkdir -p $(DESTDIR)$(prefix)/lib/pkgconfig
+	sed -e "s!@PREFIX@!$(DESTDIR)$(prefix)!" libpj.pc.in > $(DESTDIR)/$(prefix)/lib/pkgconfig/libpj.pc
Index: /pjproject/branches/split-3rd-party/libpj.pc.in
===================================================================
--- /pjproject/branches/split-3rd-party/libpj.pc.in	(revision 1210)
+++ /pjproject/branches/split-3rd-party/libpj.pc.in	(revision 1210)
@@ -0,0 +1,12 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: libpj
+Description: Multimedia communication library
+Version: 0.5.10.3
+Libs: -L${libdir} -lpjsua -lpjsip -lpjmedia -lpjsip-ua -lpjsip-simple -lpjsip-ua -lpjmedia-codec -lpjlib-util -lpj
+Cflags: -I${includedir}
Index: /pjproject/branches/split-3rd-party/pjlib-util/src/pjlib-util/scanner.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjlib-util/src/pjlib-util/scanner.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjlib-util/src/pjlib-util/scanner.c	(revision 1210)
@@ -343,5 +343,7 @@
 				pj_str_t *out)
 {
-    pj_scan_get_quotes(scanner, (char*)&begin_quote, (char*)&end_quote, 1, out);
+    char beg = (char)begin_quote;
+    char end = (char)end_quote;
+    pj_scan_get_quotes(scanner, &beg, &end, 1, out);
 }
 
Index: /pjproject/branches/split-3rd-party/pjlib/include/pj/string.h
===================================================================
--- /pjproject/branches/split-3rd-party/pjlib/include/pj/string.h	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjlib/include/pj/string.h	(revision 1210)
@@ -519,4 +519,21 @@
 
 /**
+ * Convert strings to an unsigned long-integer value.
+ * This function stops reading the string input either when the number
+ * of characters has exceeded the length of the input or it has read 
+ * the first character it cannot recognize as part of a number, that is
+ * a character greater than or equal to base. 
+ *
+ * @param str	    The input string.
+ * @param endptr    Optional pointer to receive the remainder/unparsed
+ *		    portion of the input.
+ * @param base	    Number base to use.
+ *
+ * @return the unsigned integer number.
+ */
+PJ_DECL(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr,
+				   unsigned base);
+
+/**
  * Utility to convert unsigned integer to string. Note that the
  * string will be NULL terminated.
Index: /pjproject/branches/split-3rd-party/pjlib/src/pj/hash.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjlib/src/pj/hash.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjlib/src/pj/hash.c	(revision 1210)
@@ -134,4 +134,7 @@
     if (hval && *hval != 0) {
 	hash = *hval;
+	if (keylen==PJ_HASH_KEY_STRING) {
+	    keylen = pj_ansi_strlen((const char*)key);
+	}
     } else {
 	/* This slightly differs with pj_hash_calc() because we need 
Index: /pjproject/branches/split-3rd-party/pjlib/src/pj/string.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjlib/src/pj/string.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjlib/src/pj/string.c	(revision 1210)
@@ -18,4 +18,5 @@
  */
 #include <pj/string.h>
+#include <pj/assert.h>
 #include <pj/pool.h>
 #include <pj/ctype.h>
@@ -84,4 +85,40 @@
 }
 
+PJ_DEF(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr,
+				  unsigned base)
+{
+    unsigned long value;
+    unsigned i;
+
+    PJ_CHECK_STACK();
+
+    value = 0;
+    if (base <= 10) {
+	for (i=0; i<(unsigned)str->slen; ++i) {
+	    unsigned c = (str->ptr[i] - '0');
+	    if (c >= base)
+		break;
+	    value = value * base + c;
+	}
+    } else if (base == 16) {
+	for (i=0; i<(unsigned)str->slen; ++i) {
+	    if (!pj_isxdigit(str->ptr[i]))
+		break;
+	    value = value * 16 + pj_hex_digit_to_val(str->ptr[i]);
+	}
+    } else {
+	pj_assert(!"Unsupported base");
+	i = 0;
+	value = 0xFFFFFFFFUL;
+    }
+
+    if (endptr) {
+	endptr->ptr = str->ptr + i;
+	endptr->slen = str->slen - i;
+    }
+
+    return value;
+}
+
 PJ_DEF(int) pj_utoa(unsigned long val, char *buf)
 {
Index: /pjproject/branches/split-3rd-party/pjlib/src/pjlib-test/string.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjlib/src/pjlib-test/string.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjlib/src/pjlib-test/string.c	(revision 1210)
@@ -49,4 +49,5 @@
  *  - pj_utoa()
  *  - pj_strtoul()
+ *  - pj_strtoul2()
  *  - pj_create_random_string()
  *  - ... and mode..
@@ -359,4 +360,30 @@
 	return -280;
 
+    /*
+     * pj_strtoul2()
+     */
+    s5 = pj_str("123456");
+
+    pj_strtoul2(&s5, NULL, 10);	/* Crash test */
+
+    if (pj_strtoul2(&s5, &s4, 10) != 123456UL)
+	return -290;
+    if (s4.slen != 0)
+	return -291;
+    if (pj_strtoul2(&s5, &s4, 16) != 0x123456UL)
+	return -292;
+
+    s5 = pj_str("0123ABCD");
+    if (pj_strtoul2(&s5, &s4, 10) != 123)
+	return -293;
+    if (s4.slen != 4)
+	return -294;
+    if (s4.ptr == NULL || *s4.ptr != 'A')
+	return -295;
+    if (pj_strtoul2(&s5, &s4, 16) != 0x123ABCDUL)
+	return -296;
+    if (s4.slen != 0)
+	return -297;
+
     /* 
      * pj_create_random_string() 
Index: /pjproject/branches/split-3rd-party/pjmedia/include/pjmedia/alaw_ulaw.h
===================================================================
--- /pjproject/branches/split-3rd-party/pjmedia/include/pjmedia/alaw_ulaw.h	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjmedia/include/pjmedia/alaw_ulaw.h	(revision 1210)
@@ -21,4 +21,6 @@
 
 #include <pjmedia/types.h>
+
+PJ_BEGIN_DECL
 
 #if defined(PJMEDIA_HAS_ALAW_ULAW_TABLE) && PJMEDIA_HAS_ALAW_ULAW_TABLE!=0
@@ -135,7 +137,7 @@
 PJ_DECL(unsigned char) pjmedia_ulaw2alaw(unsigned char uval);
 
-
 #endif
 
+PJ_END_DECL
 
 #endif	/* __PJMEDIA_ALAW_ULAW_H__ */
Index: /pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/alaw_ulaw.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/alaw_ulaw.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/alaw_ulaw.c	(revision 1210)
@@ -155,5 +155,5 @@
 PJ_DEF(int)
 pjmedia_alaw2linear(
-	unsigned char	a_val)
+	unsigned a_val)
 {
 	int		t;
Index: /pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/sdp.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/sdp.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/sdp.c	(revision 1210)
@@ -139,4 +139,8 @@
 {
     unsigned i;
+    unsigned c_pt = 0xFFFF;
+
+    if (c_fmt)
+	c_pt = pj_strtoul(c_fmt);
 
     for (i=0; i<count; ++i) {
@@ -144,7 +148,6 @@
 	    const pjmedia_sdp_attr *a = attr_array[i];
 	    if (c_fmt) {
-		if (a->value.slen > c_fmt->slen &&
-		    pj_strncmp(&a->value, c_fmt, c_fmt->slen)==0)
-		{
+		unsigned pt = (unsigned) pj_strtoul2(&a->value, NULL, 10);
+		if (pt == c_pt) {
 		    return (pjmedia_sdp_attr*)a;
 		}
Index: /pjproject/branches/split-3rd-party/pjnath/build/Makefile
===================================================================
--- /pjproject/branches/split-3rd-party/pjnath/build/Makefile	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjnath/build/Makefile	(revision 1210)
@@ -11,5 +11,4 @@
 PJLIB_UTIL_LIB:=../../pjlib-util/lib/libpjlib-util-$(TARGET_NAME)$(LIBEXT)
 PJNATH_LIB:=../../pjnath/lib/libpjnath-$(TARGET_NAME)$(LIBEXT)
-export PJNATH_LIB:=../lib/libpjnath-$(TARGET_NAME)$(LIBEXT)
 
 ###############################################################################
@@ -28,5 +27,5 @@
 
 ###############################################################################
-# Defines for building PJLIB-UTIL library
+# Defines for building PJNATH library
 #
 export PJNATH_SRCDIR = ../src/pjnath
@@ -46,4 +45,25 @@
 
 	
+###############################################################################
+# Defines for building test client application
+#
+export PJSTUN_CLIENT_SRCDIR = ../src/pjstun-client
+export PJSTUN_CLIENT_OBJS += client_main.o
+export PJSTUN_CLIENT_CFLAGS += $(_CFLAGS)
+export PJSTUN_CLIENT_LDFLAGS += $(_LDFLAGS)
+export PJSTUN_CLIENT_EXE:=../bin/pjstun-client-$(TARGET_NAME)$(HOST_EXE)
+
+###############################################################################
+# Defines for building test server application
+#
+export PJSTUN_SRV_TEST_SRCDIR = ../src/pjstun-srv-test
+export PJSTUN_SRV_TEST_OBJS += 	bind_usage.o server.o turn_usage.o usage.o \
+				main.o
+export PJSTUN_SRV_TEST_CFLAGS += $(_CFLAGS)
+export PJSTUN_SRV_TEST_LDFLAGS += $(_LDFLAGS)
+export PJSTUN_SRV_TEST_EXE:=../bin/pjstun-srv-test-$(TARGET_NAME)$(HOST_EXE)
+
+	
+	
 export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT 
 ###############################################################################
@@ -52,5 +72,5 @@
 # $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.
 #
-TARGETS := pjnath pjnath-test
+TARGETS := pjnath pjnath-test pjstun-client pjstun-srv-test
 
 all: $(TARGETS)
@@ -69,4 +89,10 @@
 pjnath-test: $(PJLIB_LIB) $(PJLIB_UTIL_LIB) $(PJNATH_LIB)
 	$(MAKE) -f $(RULES_MAK) APP=PJNATH_TEST app=pjnath-test $(PJNATH_TEST_EXE)
+
+pjstun-client: $(PJLIB_LIB) $(PJLIB_UTIL_LIB) $(PJNATH_LIB)
+	$(MAKE) -f $(RULES_MAK) APP=PJSTUN_CLIENT app=pjstun-client $(PJSTUN_CLIENT_EXE)
+
+pjstun-srv-test: $(PJLIB_LIB) $(PJLIB_UTIL_LIB) $(PJNATH_LIB)
+	$(MAKE) -f $(RULES_MAK) APP=PJSTUN_SRV_TEST app=pjstun-srv-test $(PJSTUN_SRV_TEST_EXE)
 
 .PHONY: ../lib/pjnath.ko
Index: /pjproject/branches/split-3rd-party/pjnath/src/pjnath/ice_session.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjnath/src/pjnath/ice_session.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjnath/src/pjnath/ice_session.c	(revision 1210)
@@ -550,5 +550,5 @@
     char tmp[128];
 
-    PJ_ASSERT_RETURN(ice && comp_id && local_pref &&
+    PJ_ASSERT_RETURN(ice && comp_id && 
 		     foundation && addr && base_addr && addr_len,
 		     PJ_EINVAL);
Index: /pjproject/branches/split-3rd-party/pjnath/src/pjnath/ice_strans.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjnath/src/pjnath/ice_strans.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjnath/src/pjnath/ice_strans.c	(revision 1210)
@@ -213,7 +213,21 @@
 {
     pj_ice_strans_cand *cand;
+    unsigned i;
 
     PJ_ASSERT_RETURN(ice_st && comp && addr, PJ_EINVAL);
     PJ_ASSERT_RETURN(comp->cand_cnt < PJ_ICE_ST_MAX_CAND, PJ_ETOOMANY);
+
+    /* Check that we don't have candidate with the same
+     * address.
+     */
+    for (i=0; i<comp->cand_cnt; ++i) {
+	if (pj_memcmp(addr, &comp->cand_list[i].addr, 
+		      sizeof(pj_sockaddr_in))==0)
+	{
+	    /* Duplicate */
+	    PJ_LOG(5,(ice_st->obj_name, "Duplicate candidate not added"));
+	    return PJ_SUCCESS;
+	}
+    }
 
     cand = &comp->cand_list[comp->cand_cnt];
@@ -226,5 +240,5 @@
     cand->local_pref = local_pref;
     pj_ice_calc_foundation(ice_st->pool, &cand->foundation, type, 
-			   (const pj_sockaddr*)addr);
+			   &comp->local_addr);
 
     if (set_default) 
Index: /pjproject/branches/split-3rd-party/pjnath/src/pjstun-client/client_main.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjnath/src/pjstun-client/client_main.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjnath/src/pjstun-client/client_main.c	(revision 1210)
@@ -67,5 +67,5 @@
 
 
-static my_perror(const char *title, pj_status_t status)
+static void my_perror(const char *title, pj_status_t status)
 {
     char errmsg[PJ_ERR_MSG_SIZE];
@@ -146,5 +146,5 @@
 	if (n > 0) {
 	    if (PJ_FD_ISSET(g.sock, &readset)) {
-		char buffer[512];
+		pj_uint8_t buffer[512];
 		pj_ssize_t len;
 		pj_sockaddr_in addr;
@@ -427,5 +427,5 @@
 				  &g.peer_addr, sizeof(g.peer_addr));
     pj_stun_msg_add_binary_attr(tdata->pool, tdata->msg,
-				PJ_STUN_ATTR_DATA, g.data, len);
+				PJ_STUN_ATTR_DATA, (pj_uint8_t*)g.data, len);
 
     rc = pj_stun_session_send_msg(g.sess, PJ_FALSE, 
@@ -521,5 +521,5 @@
     printf("Input peer address in IP:PORT format: ");
     fflush(stdout);
-    gets(addr);
+    fgets(addr, sizeof(addr), stdin);
 
     if (parse_addr(addr, &g.peer_addr) != PJ_SUCCESS) {
@@ -562,5 +562,5 @@
 	} else if (input[0]=='d' && input[1]=='t') {
 	    printf("Input data: ");
-	    gets(g.data);
+	    fgets(g.data, sizeof(g.data_buf), stdin);
 	    
 	} else if (input[0]=='p' && input[1]=='r') {
Index: /pjproject/branches/split-3rd-party/pjsip-apps/src/pjsua/pjsua_app.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjsip-apps/src/pjsua/pjsua_app.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjsip-apps/src/pjsua/pjsua_app.c	(revision 1210)
@@ -321,5 +321,5 @@
     int c;
     int option_index;
-    enum { OPT_CONFIG_FILE, OPT_LOG_FILE, OPT_LOG_LEVEL, OPT_APP_LOG_LEVEL, 
+    enum { OPT_CONFIG_FILE=127, OPT_LOG_FILE, OPT_LOG_LEVEL, OPT_APP_LOG_LEVEL, 
 	   OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO, 
 	   OPT_LOCAL_PORT, OPT_IP_ADDR, OPT_PROXY, OPT_OUTBOUND_PROXY, 
@@ -880,5 +880,5 @@
 	    PJ_LOG(1,(THIS_FILE, 
 		      "Argument \"%s\" is not valid. Use --help to see help",
-		      argv[pj_optind]));
+		      argv[pj_optind-1]));
 	    return -1;
 	}
Index: /pjproject/branches/split-3rd-party/pjsip/include/pjsip/sip_transaction.h
===================================================================
--- /pjproject/branches/split-3rd-party/pjsip/include/pjsip/sip_transaction.h	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjsip/include/pjsip/sip_transaction.h	(revision 1210)
@@ -75,19 +75,4 @@
 
 /**
- * Transaction timeout timer policy, to control the UAC transaction timeout
- * scheduling (see #pjsip_tsx_set_uac_timeout()).
- */
-typedef enum pjsip_tsx_timeout_policy
-{
-    PJSIP_TSX_IGNORE_100 = 1,	/**< To make the UAC transaction NOT to cancel
-				     the timeout timer when 100 response is 
-				     received.*/
-    PJSIP_TSX_IGNORE_1xx = 3	/**< To make the UAC transaction NOT to cancel
-				     the timeout timer when any 1xx responses 
-				     are received. */
-} pjsip_tsx_timeout_policy;
-
-
-/**
  * This structure describes SIP transaction object. The transaction object
  * is used to handle both UAS and UAC transaction.
@@ -146,7 +131,4 @@
     pj_timer_entry		timeout_timer;  /**< Timeout timer.         */
 
-    unsigned			msec_timeout;	/**< User set timeout.	    */
-    pjsip_tsx_timeout_policy	timeout_policy;	/**< Timeout policy.	    */
-
     /** Module specific data. */
     void		       *mod_data[PJSIP_MAX_MODULE];
@@ -249,45 +231,4 @@
 					     const pjsip_tpselector *sel);
 
-
-/**
- * Set the UAC absolute transaction timeout. Normally UAC transaction will
- * stop its timeout timer (timer B for INVITE and timer F for non-INVITE
- * transactions) after a provisional response is received.
- *
- * When this timer is set, the transaction's timer B and F will use this
- * value, and if the \a flag flag is set, the transaction will continue
- * the scheduling of the timeout timer even when provisional response has
- * been received.
- *
- * Note that this function MUST be called AFTER the transaction has been
- * created AND BEFORE any request is transmitted.
- *
- * @param tsx	    The client/UAC transaction.
- * @param msec_time The timeout value, in miliseconds. Currently this
- *		    value must be non-zero (value zero is reserved for
- *		    future use).
- * @param flag	    Option flags to control whether the transaction should
- *		    cancel the timeout timer on arrival of provisional
- *		    responses (which is yes according to RFC 3261).
- *		    The valid values are:
- *		    - PJSIP_TSX_IGNORE_100, to make the UAC transaction
- *		      NOT to cancel the timeout timer when 100 response
- *		      is received.
- *		    - PJSIP_TSX_IGNORE_1xx, to make the UAC transaction
- *		      NOT to cancel the timeout timer when any 1xx 
- *		      responses are received.
- *
- *		    Note that regardless of the values in the \a flag 
- *		    argument, the provisional response would still be
- *		    delivered to transaction user and it will still
- *		    affect the transaction state. The \a flag flag only
- *		    changes the behavior of the timeout timer of the
- *		    transaction.
- */
-PJ_DECL(pj_status_t) pjsip_tsx_set_uac_timeout(pjsip_transaction *tsx,
-					       unsigned msec_time,
-					       pjsip_tsx_timeout_policy flag);
-
-
 /**
  * Call this function to manually feed a message to the transaction.
Index: /pjproject/branches/split-3rd-party/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/branches/split-3rd-party/pjsip/include/pjsua-lib/pjsua.h	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjsip/include/pjsua-lib/pjsua.h	(revision 1210)
@@ -914,5 +914,6 @@
 
     /**
-     * Specify STUN server to be used.
+     * Specify STUN server to be used, in "HOST[:PORT]" format. If port is
+     * not specified, default port 3478 will be used.
      */
     pj_str_t	    stun_host;
Index: /pjproject/branches/split-3rd-party/pjsip/src/pjsip/sip_transaction.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjsip/src/pjsip/sip_transaction.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjsip/src/pjsip/sip_transaction.c	(revision 1210)
@@ -133,4 +133,6 @@
 static const pj_time_val t1_timer_val = { PJSIP_T1_TIMEOUT/1000, 
                                           PJSIP_T1_TIMEOUT%1000 };
+static const pj_time_val t2_timer_val = { PJSIP_T2_TIMEOUT/1000, 
+                                          PJSIP_T2_TIMEOUT%1000 };
 static const pj_time_val t4_timer_val = { PJSIP_T4_TIMEOUT/1000, 
                                           PJSIP_T4_TIMEOUT%1000 };
@@ -1397,21 +1399,4 @@
 
 /*
- * Set the UAC absolute transaction timeout.
- */
-PJ_DEF(pj_status_t) pjsip_tsx_set_uac_timeout(pjsip_transaction *tsx,
-					      unsigned msec_time,
-					      pjsip_tsx_timeout_policy policy)
-{
-    PJ_ASSERT_RETURN(tsx && tsx->role==PJSIP_ROLE_UAC &&
-		     tsx->state==PJSIP_TSX_STATE_NULL, PJ_EINVALIDOP);
-
-    tsx->msec_timeout = msec_time;
-    tsx->timeout_policy = policy;
-
-    return PJ_SUCCESS;
-}
-
-
-/*
  * Set transaction status code and reason.
  */
@@ -1810,7 +1795,11 @@
     pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0);
 
-    msec_time = (1 << (tsx->retransmit_count)) * PJSIP_T1_TIMEOUT;
+    if (tsx->role==PJSIP_ROLE_UAC && tsx->status_code >= 100)
+	msec_time = PJSIP_T2_TIMEOUT;
+    else
+	msec_time = (1 << (tsx->retransmit_count)) * PJSIP_T1_TIMEOUT;
 
     if (tsx->role == PJSIP_ROLE_UAC) {
+	pj_assert(tsx->status_code < 200);
 	/* Retransmission for non-INVITE transaction caps-off at T2 */
 	if (msec_time>PJSIP_T2_TIMEOUT && tsx->method.id!=PJSIP_INVITE_METHOD)
@@ -1914,20 +1903,8 @@
 
 	/* Start Timer B (or called timer F for non-INVITE) for transaction 
-	 * timeout. If user has configured the timeout value with 
-	 * pjsip_tsx_set_uac_timeout(), use the timeout value there.
+	 * timeout.
 	 */
-	if (tsx->msec_timeout > 0) {
-	    pj_time_val timeout;
-
-	    timeout.sec = tsx->msec_timeout / 1000;
-	    timeout.msec = tsx->msec_timeout % 1000;
-
-	    pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 
-					&timeout);
-
-	} else {
-	    pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 
-					&timeout_timer_val);
-	}
+	pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 
+				    &timeout_timer_val);
 
 	/* Start Timer A (or timer E) for retransmission only if unreliable 
@@ -2006,24 +1983,51 @@
 	    return PJSIP_ENOTRESPONSEMSG;
 
-	/* Cancel retransmission timer A. */
-	if (tsx->retransmit_timer._timer_id != -1) {
-	    pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
-	    tsx->retransmit_timer._timer_id = -1;
-	}
+	code = msg->line.status.code;
+
+	/* If the response is final, cancel both retransmission and timeout
+	 * timer.
+	 */
+	if (code >= 200) {
+	    if (tsx->retransmit_timer._timer_id != -1) {
+		pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
+		tsx->retransmit_timer._timer_id = -1;
+	    }
+
+	    if (tsx->timeout_timer._timer_id != -1) {
+		pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
+		tsx->timeout_timer._timer_id = -1;
+	    }
+
+	} else {
+	    /* Cancel retransmit timer (for non-INVITE transaction, the
+	     * retransmit timer will be rescheduled at T2.
+	     */
+	    if (tsx->retransmit_timer._timer_id != -1) {
+		pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
+		tsx->retransmit_timer._timer_id = -1;
+	    }
+
+	    /* For provisional response, only cancel retransmit when this
+	     * is an INVITE transaction. For non-INVITE, section 17.1.2.1
+	     * of RFC 3261 says that:
+	     *	- retransmit timer is set to T2
+	     *	- timeout timer F is not deleted.
+	     */
+	    if (tsx->method.id == PJSIP_INVITE_METHOD) {
+
+		/* Cancel timeout timer */
+		pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
+
+	    } else {
+		if (!tsx->is_reliable) {
+		    pjsip_endpt_schedule_timer(tsx->endpt, 
+					       &tsx->retransmit_timer,
+					       &t2_timer_val);
+		}
+	    }
+	}
+	 
 	tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);
 
-
-	/* Cancel timer B (transaction timeout) but look at the timeout policy
-	 * as set by pjsip_tsx_set_uac_timeout().
-	 */
-	code = msg->line.status.code;
-	if ((code==100 && tsx->timeout_policy==PJSIP_TSX_IGNORE_100) ||
-	    (code<200 && tsx->timeout_policy==PJSIP_TSX_IGNORE_1xx))
-	{
-	    /* Don't cancel the timeout timer */
-	}
-	else {
-	    pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
-	}
 
 	/* Discard retransmission message if it is not INVITE.
@@ -2368,5 +2372,15 @@
 
     } else {
-	tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
+	if (event->body.timer.entry == &tsx->retransmit_timer) {
+	    /* Retransmit message. */
+            pj_status_t status;
+
+            status = tsx_retransmit( tsx, 1 );
+	    
+	    return status;
+
+	} else {
+	    tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
+	}
     }
 
@@ -2407,4 +2421,10 @@
 					&timeout);
 
+	    /* Cancel retransmission timer */
+	    if (tsx->retransmit_timer._timer_id != -1) {
+		pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
+		tsx->retransmit_timer._timer_id = -1;
+	    }
+
 	    /* Move state to Completed, inform TU. */
 	    tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
Index: /pjproject/branches/split-3rd-party/pjsip/src/pjsip/sip_util_statefull.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjsip/src/pjsip/sip_util_statefull.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjsip/src/pjsip/sip_util_statefull.c	(revision 1210)
@@ -95,4 +95,5 @@
     PJ_ASSERT_RETURN(mod_stateful_util.id != -1, PJ_EINVALIDOP);
 
+    PJ_UNUSED_ARG(timeout);
 
     status = pjsip_tsx_create_uac(&mod_stateful_util, tdata, &tsx);
@@ -105,9 +106,4 @@
     tsx_data->token = token;
     tsx_data->cb = cb;
-
-    if (timeout >= 0) {
-	status = pjsip_tsx_set_uac_timeout(tsx, timeout, PJSIP_TSX_IGNORE_1xx);
-	pj_assert(status == PJ_SUCCESS);
-    }
 
     tsx->mod_data[mod_stateful_util.id] = tsx_data;
Index: /pjproject/branches/split-3rd-party/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1210)
@@ -679,12 +679,32 @@
 	 */
 	if (pjsua_var.ua_cfg.stun_host.slen) {
+	    pj_str_t str_host, str_port;
+	    int port;
 	    pj_hostent he;
 
-	    pjsua_var.stun_status = pj_gethostbyname(&pjsua_var.ua_cfg.stun_host, &he);
+	    str_port.ptr = pj_strchr(&pjsua_var.ua_cfg.stun_host, ':');
+	    if (str_port.ptr != NULL) {
+		str_host.ptr = pjsua_var.ua_cfg.stun_host.ptr;
+		str_host.slen = (str_port.ptr - str_host.ptr);
+		str_port.ptr++;
+		str_port.slen = pjsua_var.ua_cfg.stun_host.slen - 
+				str_host.slen - 1;
+		port = (int)pj_strtoul(&str_port);
+		if (port < 1 || port > 65535) {
+		    pjsua_perror(THIS_FILE, "Invalid STUN server", PJ_EINVAL);
+		    pjsua_var.stun_status = PJ_EINVAL;
+		    return;
+		}
+	    } else {
+		str_host = pjsua_var.ua_cfg.stun_host;
+		port = 3478;
+	    }
+
+	    pjsua_var.stun_status = pj_gethostbyname(&str_host, &he);
 
 	    if (pjsua_var.stun_status == PJ_SUCCESS) {
 		pj_sockaddr_in_init(&pjsua_var.stun_srv.ipv4, NULL, 0);
 		pjsua_var.stun_srv.ipv4.sin_addr = *(pj_in_addr*)he.h_addr;
-		pjsua_var.stun_srv.ipv4.sin_port = pj_htons((pj_uint16_t)3478);
+		pjsua_var.stun_srv.ipv4.sin_port = pj_htons((pj_uint16_t)port);
 
 		PJ_LOG(3,(THIS_FILE, 
@@ -773,12 +793,33 @@
 	 */
 	else if (pjsua_var.ua_cfg.stun_host.slen) {
+	    pj_str_t str_host, str_port;
+	    int port;
 	    pj_hostent he;
 
-	    pjsua_var.stun_status = pj_gethostbyname(&pjsua_var.ua_cfg.stun_host, &he);
+	    str_port.ptr = pj_strchr(&pjsua_var.ua_cfg.stun_host, ':');
+	    if (str_port.ptr != NULL) {
+		str_host.ptr = pjsua_var.ua_cfg.stun_host.ptr;
+		str_host.slen = (str_port.ptr - str_host.ptr);
+		str_port.ptr++;
+		str_port.slen = pjsua_var.ua_cfg.stun_host.slen - 
+				str_host.slen - 1;
+		port = (int)pj_strtoul(&str_port);
+		if (port < 1 || port > 65535) {
+		    pjsua_perror(THIS_FILE, "Invalid STUN server", PJ_EINVAL);
+		    pjsua_var.stun_status = PJ_EINVAL;
+		    return pjsua_var.stun_status;
+		}
+	    } else {
+		str_host = pjsua_var.ua_cfg.stun_host;
+		port = 3478;
+	    }
+
+
+	    pjsua_var.stun_status = pj_gethostbyname(&str_host, &he);
 
 	    if (pjsua_var.stun_status == PJ_SUCCESS) {
 		pj_sockaddr_in_init(&pjsua_var.stun_srv.ipv4, NULL, 0);
 		pjsua_var.stun_srv.ipv4.sin_addr = *(pj_in_addr*)he.h_addr;
-		pjsua_var.stun_srv.ipv4.sin_port = pj_htons((pj_uint16_t)3478);
+		pjsua_var.stun_srv.ipv4.sin_port = pj_htons((pj_uint16_t)port);
 
 		PJ_LOG(3,(THIS_FILE, 
@@ -1056,6 +1097,6 @@
 	 */
 	status = pjstun_get_mapped_addr(&pjsua_var.cp.factory, 1, &sock,
-				         &stun_srv, 3478,
-					 &stun_srv, 3478,
+				         &stun_srv, pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port),
+					 &stun_srv, pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port),
 				         p_pub_addr);
 	if (status != PJ_SUCCESS) {
Index: /pjproject/branches/split-3rd-party/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- /pjproject/branches/split-3rd-party/pjsip/src/pjsua-lib/pjsua_media.c	(revision 1209)
+++ /pjproject/branches/split-3rd-party/pjsip/src/pjsua-lib/pjsua_media.c	(revision 1210)
@@ -290,6 +290,6 @@
 
 	    status=pjstun_get_mapped_addr(&pjsua_var.cp.factory, 2, sock,
-					   &stun_srv, 3478,
-					   &stun_srv, 3478,
+					   &stun_srv, pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port),
+					   &stun_srv, pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port),
 					   mapped_addr);
 	    if (status != PJ_SUCCESS) {
