Index: /pjproject/main/RELNOTES.txt
===================================================================
--- /pjproject/main/RELNOTES.txt	(revision 42)
+++ /pjproject/main/RELNOTES.txt	(revision 43)
@@ -1,2 +1,19 @@
+Version 0.3
+PJLIB
+	- Correct error reporting in the whole library. No more vague -1 errors!
+	- New super portable socket abstraction.
+	- Other headers were made super portable too.
+	- Ioqueue supports multiple pending operations in a single socket!
+	- No more floating point.
+	- Ported to new platforms:
+		- i386/linux kernel (!)
+		- Sparc/Solaris
+		- Alpha/Linux
+PJSIP
+	- Correct error reporting in the whole library. No more -1 errors!
+	- Rewrote event, now much more readable.
+	- Per object tracing.
+
+
 Version 0.2.9 - 2005/06/19
 Core:
Index: /pjproject/main/pjlib-util/include/pjlib-util/scanner.h
===================================================================
--- /pjproject/main/pjlib-util/include/pjlib-util/scanner.h	(revision 42)
+++ /pjproject/main/pjlib-util/include/pjlib-util/scanner.h	(revision 43)
@@ -1,8 +1,6 @@
 /* $Id$
- *
- */
-
-#ifndef __PJ_PARSER_H__
-#define __PJ_PARSER_H__
+ */
+#ifndef __PJ_SCANNER_H__
+#define __PJ_SCANNER_H__
 
 /**
@@ -20,13 +18,5 @@
  * @brief
  * Text scanning utility.
- */
-
-/**
- * @defgroup PJ_CHARSPEC Character Filter Specification
- * @ingroup PJ_SCAN
- * @brief
- * The type pj_char_spec is a specification of character set used in
- * scanner. Application can define multiple character specs, such as to
- * scan alpha numerics, numbers, tokens, etc.
+ *
  * @{
  */
@@ -34,98 +24,166 @@
 /**
  * This describes the type of individual character specification in
- * #pj_char_spec.
- */
-typedef pj_uint8_t pj_char_spec_element_t;
-
-/**
- * The character specification is implemented as array of boolean flags. Each
- * flag indicates the membership of the character in the spec. If the flag
- * at one position is non-zero, then the character at that position belongs
- * to the specification, and vice versa.
- */
-typedef pj_char_spec_element_t pj_char_spec[256];
-// Note: it's got to be 256 (not 128) to cater for extended character in input.
-
-/**
- * Initialize character spec.
- * @param cs the scanner character specification.
- */
-PJ_DECL(void) pj_cs_init( pj_char_spec cs);
-
-/**
- * Set the membership of the specified character to TRUE.
- * @param cs the scanner character specification.
- * @param c the character.
- */
-PJ_DECL(void) pj_cs_set( pj_char_spec cs, int c);
+ * #pj_cis_buf_t. Basicly the number of bits here
+ */
+#ifndef PJ_CIS_ELEM_TYPE
+#   define PJ_CIS_ELEM_TYPE pj_uint32_t
+#endif
+
+/**
+ * This describes the type of individual character specification in
+ * #pj_cis_buf_t.
+ */
+typedef PJ_CIS_ELEM_TYPE pj_cis_elem_t;
+
+/**
+ * Maximum number of input specification in a buffer.
+ * Effectively this means the number of bits in pj_cis_elem_t.
+ */
+#define PJ_CIS_MAX_INDEX   (sizeof(pj_cis_elem_t) << 3)
+
+/**
+ * The scanner input specification buffer.
+ */
+typedef struct pj_cis_buf_t
+{
+    pj_cis_elem_t    cis_buf[256];  /**< Must be 256 (not 128)! */
+    pj_cis_elem_t    use_mask;      /**< To keep used indexes.  */
+} pj_cis_buf_t;
+
+/**
+ * Character input specification.
+ */
+typedef struct pj_cis_t
+{
+    pj_cis_elem_t   *cis_buf;       /**< Pointer to buffer.     */
+    int              cis_id;        /**< Id.                    */
+} pj_cis_t;
+
+/**
+ * Initialize scanner input specification buffer.
+ *
+ * @param cs_buf    The scanner character specification.
+ */
+PJ_DECL(void) pj_cis_buf_init(pj_cis_buf_t *cs_buf);
+
+/**
+ * Create a new input specification.
+ *
+ * @param cs_buf    Specification buffer.
+ * @param cis       Character input specification to be initialized.
+ *
+ * @return          PJ_SUCCESS if new specification has been successfully
+ *                  created, or PJ_ETOOMANY if there are already too many
+ *                  specifications in the buffer.
+ */
+PJ_DECL(pj_status_t) pj_cis_init(pj_cis_buf_t *cs_buf, pj_cis_t *cis);
+
+/**
+ * Create a new input specification based on an existing specification.
+ *
+ * @param new_cis   The new specification to be initialized.
+ * @param existing  The existing specification, from which the input
+ *                  bitmask will be copied to the new specification.
+ *
+ * @return          PJ_SUCCESS if new specification has been successfully
+ *                  created, or PJ_ETOOMANY if there are already too many
+ *                  specifications in the buffer.
+ */
+PJ_DECL(pj_status_t) pj_cis_dup(pj_cis_t *new_cis, pj_cis_t *existing);
+
+/**
+ * Set the membership of the specified character.
+ * Note that this is a macro, and arguments may be evaluated more than once.
+ *
+ * @param cis       Pointer to character input specification.
+ * @param c         The character.
+ */
+#define PJ_CIS_SET(cis,c)   ((cis)->cis_buf[(c)] |= (1 << (cis)->cis_id))
+
+/**
+ * Remove the membership of the specified character.
+ * Note that this is a macro, and arguments may be evaluated more than once.
+ *
+ * @param cis       Pointer to character input specification.
+ * @param c         The character to be removed from the membership.
+ */
+#define PJ_CIS_CLR(cis,c)   ((cis)->cis_buf[c] &= ~(1 << (cis)->cis_id))
+
+/**
+ * Check the membership of the specified character.
+ * Note that this is a macro, and arguments may be evaluated more than once.
+ *
+ * @param cis       Pointer to character input specification.
+ * @param c         The character.
+ */
+#define PJ_CIS_ISSET(cis,c) ((cis)->cis_buf[c] & (1 << (cis)->cis_id))
 
 /**
  * Add the characters in the specified range '[cstart, cend)' to the 
  * specification (the last character itself ('cend') is not added).
- * @param cs the scanner character specification.
- * @param cstart the first character in the range.
- * @param cend the next character after the last character in the range.
- */
-PJ_DECL(void) pj_cs_add_range( pj_char_spec cs, int cstart, int cend);
+ *
+ * @param cis       The scanner character specification.
+ * @param cstart    The first character in the range.
+ * @param cend      The next character after the last character in the range.
+ */
+PJ_DECL(void) pj_cis_add_range( pj_cis_t *cis, int cstart, int cend);
 
 /**
  * Add alphabetic characters to the specification.
- * @param cs the scanner character specification.
- */
-PJ_DECL(void) pj_cs_add_alpha( pj_char_spec cs);
+ *
+ * @param cis       The scanner character specification.
+ */
+PJ_DECL(void) pj_cis_add_alpha( pj_cis_t *cis);
 
 /**
  * Add numeric characters to the specification.
- * @param cs the scanner character specification.
- */
-PJ_DECL(void) pj_cs_add_num( pj_char_spec cs);
+ *
+ * @param cis       The scanner character specification.
+ */
+PJ_DECL(void) pj_cis_add_num( pj_cis_t *cis);
 
 /**
  * Add the characters in the string to the specification.
- * @param cs the scanner character specification.
- * @param str the string.
- */
-PJ_DECL(void) pj_cs_add_str( pj_char_spec cs, const char *str);
+ *
+ * @param cis       The scanner character specification.
+ * @param str       The string.
+ */
+PJ_DECL(void) pj_cis_add_str( pj_cis_t *cis, const char *str);
 
 /**
  * Delete characters in the specified range from the specification.
- * @param cs the scanner character specification.
- * @param cstart the first character in the range.
- * @param cend the next character after the last character in the range.
- */
-PJ_DECL(void) pj_cs_del_range( pj_char_spec cs, int cstart, int cend);
+ *
+ * @param cis       The scanner character specification.
+ * @param cstart    The first character in the range.
+ * @param cend      The next character after the last character in the range.
+ */
+PJ_DECL(void) pj_cis_del_range( pj_cis_t *cis, int cstart, int cend);
 
 /**
  * Delete characters in the specified string from the specification.
- * @param cs the scanner character specification.
- * @param str the string.
- */
-PJ_DECL(void) pj_cs_del_str( pj_char_spec cs, const char *str);
+ *
+ * @param cis       The scanner character specification.
+ * @param str       The string.
+ */
+PJ_DECL(void) pj_cis_del_str( pj_cis_t *cis, const char *str);
 
 /**
  * Invert specification.
- * @param cs the scanner character specification.
- */
-PJ_DECL(void) pj_cs_invert( pj_char_spec cs );
+ *
+ * @param cis       The scanner character specification.
+ */
+PJ_DECL(void) pj_cis_invert( pj_cis_t *cis );
 
 /**
  * Check whether the specified character belongs to the specification.
- * @param cs the scanner character specification.
- * @param c the character to check for matching.
- */
-PJ_INLINE(int) pj_cs_match( const pj_char_spec cs, int c )
-{
-    return cs[c];
+ *
+ * @param cis       The scanner character specification.
+ * @param c         The character to check for matching.
+ */
+PJ_INLINE(int) pj_cis_match( const pj_cis_t *cis, int c )
+{
+    return PJ_CIS_ISSET(cis, c);
 }
 
-/**
- * @}
- */
-
-/**
- * @defgroup PJ_SCANNER Text Scanner
- * @ingroup PJ_SCAN
- * @{
- */
 
 /**
@@ -157,5 +215,6 @@
  * The callback function type to be called by the scanner when it encounters
  * syntax error.
- * @param scanner   The scanner instance that calls the callback .
+ *
+ * @param scanner       The scanner instance that calls the callback .
  */
 typedef void (*pj_syn_err_func_ptr)(struct pj_scanner *scanner);
@@ -245,5 +304,5 @@
  */
 PJ_DECL(int) pj_scan_peek( pj_scanner *scanner,
-			    const pj_char_spec spec, pj_str_t *out);
+			   const pj_cis_t *spec, pj_str_t *out);
 
 
@@ -262,5 +321,5 @@
  */
 PJ_DECL(int) pj_scan_peek_n( pj_scanner *scanner,
-			      pj_size_t len, pj_str_t *out);
+			     pj_size_t len, pj_str_t *out);
 
 
@@ -278,6 +337,6 @@
  */
 PJ_DECL(int) pj_scan_peek_until( pj_scanner *scanner,
-				  const pj_char_spec spec, 
-				  pj_str_t *out);
+				 const pj_cis_t *spec, 
+				 pj_str_t *out);
 
 
@@ -294,5 +353,5 @@
  */
 PJ_DECL(void) pj_scan_get( pj_scanner *scanner,
-			    const pj_char_spec spec, pj_str_t *out);
+			   const pj_cis_t *spec, pj_str_t *out);
 
 
@@ -318,5 +377,5 @@
  */
 PJ_DECL(void) pj_scan_get_n( pj_scanner *scanner,
-			      unsigned N, pj_str_t *out);
+			     unsigned N, pj_str_t *out);
 
 
@@ -326,5 +385,5 @@
  * @param scanner   The scanner.
  *
- * @return (unknown)
+ * @return The character.
  */
 PJ_DECL(int) pj_scan_get_char( pj_scanner *scanner );
@@ -349,5 +408,5 @@
  */
 PJ_DECL(void) pj_scan_get_until( pj_scanner *scanner,
-				  const pj_char_spec spec, pj_str_t *out);
+				 const pj_cis_t *spec, pj_str_t *out);
 
 
@@ -361,5 +420,5 @@
  */
 PJ_DECL(void) pj_scan_get_until_ch( pj_scanner *scanner, 
-				     int until_char, pj_str_t *out);
+				    int until_char, pj_str_t *out);
 
 
@@ -373,5 +432,5 @@
  */
 PJ_DECL(void) pj_scan_get_until_chr( pj_scanner *scanner,
-				      const char *until_spec, pj_str_t *out);
+				     const char *until_spec, pj_str_t *out);
 
 /** 
@@ -385,5 +444,5 @@
  */
 PJ_DECL(void) pj_scan_advance_n( pj_scanner *scanner,
-				  unsigned N, pj_bool_t skip);
+				 unsigned N, pj_bool_t skip);
 
 
@@ -446,11 +505,7 @@
  */
 
-#if PJ_FUNCTIONS_ARE_INLINED
-#  include "scanner_i.h"
+
+PJ_END_DECL
+
 #endif
 
-
-PJ_END_DECL
-
-#endif
-
Index: /pjproject/main/pjlib-util/src/pjlib-util/scanner.c
===================================================================
--- /pjproject/main/pjlib-util/src/pjlib-util/scanner.c	(revision 42)
+++ /pjproject/main/pjlib-util/src/pjlib-util/scanner.c	(revision 43)
@@ -5,4 +5,5 @@
 #include <pj/except.h>
 #include <pj/os.h>
+#include <pj/errno.h>
 
 #define PJ_SCAN_IS_SPACE(c)	((c)==' ' || (c)=='\t')
@@ -16,65 +17,97 @@
 }
 
-PJ_DEF(void) pj_cs_init( pj_char_spec cs)
-{
-    PJ_CHECK_STACK();
-    memset(cs, 0, sizeof(cs));
-}
-
-PJ_DEF(void) pj_cs_set( pj_char_spec cs, int c)
-{
-    PJ_CHECK_STACK();
-    cs[c] = 1;
-}
-
-PJ_DEF(void) pj_cs_add_range( pj_char_spec cs, int cstart, int cend)
-{
-    PJ_CHECK_STACK();
-    while (cstart != cend)
-	cs[cstart++] = 1;
-}
-
-PJ_DEF(void) pj_cs_add_alpha( pj_char_spec cs)
-{
-    pj_cs_add_range( cs, 'a', 'z'+1);
-    pj_cs_add_range( cs, 'A', 'Z'+1);
-}
-
-PJ_DEF(void) pj_cs_add_num( pj_char_spec cs)
-{
-    pj_cs_add_range( cs, '0', '9'+1);
-}
-
-PJ_DEF(void) pj_cs_add_str( pj_char_spec cs, const char *str)
-{
-    PJ_CHECK_STACK();
+PJ_DEF(void) pj_cis_buf_init( pj_cis_buf_t *cis_buf)
+{
+    pj_memset(cis_buf->cis_buf, 0, sizeof(cis_buf->cis_buf));
+    cis_buf->use_mask = 0;
+}
+
+PJ_DEF(pj_status_t) pj_cis_init(pj_cis_buf_t *cis_buf, pj_cis_t *cis)
+{
+    unsigned i;
+
+    cis->cis_buf = cis_buf->cis_buf;
+
+    for (i=0; i<PJ_CIS_MAX_INDEX; ++i) {
+        if ((cis_buf->use_mask & (1 << i)) == 0) {
+            cis->cis_index = i;
+            return PJ_SUCCESS;
+        }
+    }
+
+    cis->cis_index = PJ_CIS_MAX_INDEX;
+    return PJ_ETOOMANY;
+}
+
+PJ_DEF(pj_status_t) pj_cis_dup( pj_cis_t *new_cis, pj_cis_t *existing)
+{
+    pj_status_t status;
+    unsigned i;
+
+    status = pj_cis_init(existing->cis_buf, new_cis);
+    if (status != PJ_SUCCESS)
+        return status;
+
+    for (i=0; i<256; ++i) {
+        if (PJ_CIS_ISSET(existing, i))
+            PJ_CIS_SET(new_cis, i);
+        else
+            PJ_CIS_CLR(new_cis, i);
+    }
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(void) pj_cis_add_range(pj_cis_t *cis, int cstart, int cend)
+{
+    while (cstart != cend) {
+        PJ_CIS_SET(cis, cstart);
+	++cstart;
+    }
+}
+
+PJ_DEF(void) pj_cis_add_alpha(pj_cis_t *cis)
+{
+    pj_cis_add_range( cis, 'a', 'z'+1);
+    pj_cis_add_range( cis, 'A', 'Z'+1);
+}
+
+PJ_DEF(void) pj_cis_add_num(pj_cis_t *cis)
+{
+    pj_cis_add_range( cis, '0', '9'+1);
+}
+
+PJ_DEF(void) pj_cis_add_str( pj_cis_t *cis, const char *str)
+{
     while (*str) {
-        cs[(int)*str] = 1;
+        PJ_CIS_SET(cis, *str);
 	++str;
     }
 }
 
-PJ_DEF(void) pj_cs_del_range( pj_char_spec cs, int cstart, int cend)
-{
-    PJ_CHECK_STACK();
-    while (cstart != cend)
-	cs[cstart++] = 0;
-}
-
-PJ_DEF(void) pj_cs_del_str( pj_char_spec cs, const char *str)
-{
-    PJ_CHECK_STACK();
+PJ_DEF(void) pj_cis_del_range( pj_cis_t *cis, int cstart, int cend)
+{
+    while (cstart != cend) {
+        PJ_CIS_CLR(cis, cstart);
+        cstart++;
+    }
+}
+
+PJ_DEF(void) pj_cis_del_str( pj_cis_t *cis, const char *str)
+{
     while (*str) {
-        cs[(int)*str] = 0;
+        PJ_CIS_CLR(cis, *str);
 	++str;
     }
 }
 
-PJ_DEF(void) pj_cs_invert( pj_char_spec cs )
+PJ_DEF(void) pj_cis_invert( pj_cis_t *cis )
 {
     unsigned i;
-    PJ_CHECK_STACK();
-    for (i=0; i<sizeof(pj_char_spec)/sizeof(cs[0]); ++i) {
-	cs[i] = (pj_char_spec_element_t) !cs[i];
+    for (i=0; i<256; ++i) {
+	if (PJ_CIS_ISSET(cis,i))
+            PJ_CIS_CLR(cis,i);
+        else
+            PJ_CIS_SET(cis,i);
     }
 }
@@ -166,5 +199,5 @@
 
 PJ_DEF(int) pj_scan_peek( pj_scanner *scanner,
-			   const pj_char_spec spec, pj_str_t *out)
+			  const pj_cis_t *spec, pj_str_t *out)
 {
     register char *s = scanner->curptr;
@@ -178,5 +211,5 @@
     }
 
-    while (PJ_SCAN_CHECK_EOF(s) && pj_cs_match(spec, *s))
+    while (PJ_SCAN_CHECK_EOF(s) && pj_cis_match(spec, *s))
 	++s;
 
@@ -204,6 +237,6 @@
 
 PJ_DEF(int) pj_scan_peek_until( pj_scanner *scanner,
-				  const pj_char_spec spec, 
-				  pj_str_t *out)
+				const pj_cis_t *spec, 
+				pj_str_t *out)
 {
     register char *s = scanner->curptr;
@@ -217,5 +250,5 @@
     }
 
-    while (PJ_SCAN_CHECK_EOF(s) && !pj_cs_match( spec, *s))
+    while (PJ_SCAN_CHECK_EOF(s) && !pj_cis_match( spec, *s))
 	++s;
 
@@ -226,5 +259,5 @@
 
 PJ_DEF(void) pj_scan_get( pj_scanner *scanner,
-			   const pj_char_spec spec, pj_str_t *out)
+			  const pj_cis_t *spec, pj_str_t *out)
 {
     register char *s = scanner->curptr;
@@ -234,5 +267,5 @@
     PJ_CHECK_STACK();
 
-    if (pj_scan_is_eof(scanner) || !pj_cs_match(spec, *s)) {
+    if (pj_scan_is_eof(scanner) || !pj_cis_match(spec, *s)) {
 	pj_scan_syntax_err(scanner);
 	return;
@@ -241,5 +274,5 @@
     do {
 	++s;
-    } while (PJ_SCAN_CHECK_EOF(s) && pj_cs_match(spec, *s));
+    } while (PJ_SCAN_CHECK_EOF(s) && pj_cis_match(spec, *s));
 
     pj_strset3(out, scanner->curptr, s);
@@ -396,5 +429,5 @@
 
 PJ_DEF(void) pj_scan_get_until( pj_scanner *scanner,
-				 const pj_char_spec spec, pj_str_t *out)
+				const pj_cis_t *spec, pj_str_t *out)
 {
     register char *s = scanner->curptr;
@@ -409,5 +442,5 @@
     }
 
-    while (PJ_SCAN_CHECK_EOF(s) && !pj_cs_match(spec, *s)) {
+    while (PJ_SCAN_CHECK_EOF(s) && !pj_cis_match(spec, *s)) {
 	++s;
     }
@@ -425,5 +458,5 @@
 
 PJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner, 
-				    int until_char, pj_str_t *out)
+				   int until_char, pj_str_t *out)
 {
     register char *s = scanner->curptr;
Index: /pjproject/main/pjlib/build/pjlib.dsw
===================================================================
--- /pjproject/main/pjlib/build/pjlib.dsw	(revision 42)
+++ /pjproject/main/pjlib/build/pjlib.dsw	(revision 43)
@@ -24,4 +24,22 @@
 Package=<4>
 {{{
+}}}
+
+###############################################################################
+
+Project: "pjlib++_test"=".\pjlib++-test.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pjlib
+    End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name pjlib++
+    End Project Dependency
 }}}
 
@@ -58,22 +76,4 @@
 ###############################################################################
 
-Project: "pjlib++_test"=.\pjlib++-test.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name pjlib
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name pjlib++
-    End Project Dependency
-}}}
-
-###############################################################################
-
 Global:
 
Index: /pjproject/main/pjlib/include/pj++/file.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/file.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/file.hpp	(revision 43)
@@ -1,4 +1,4 @@
-/* $Id$ */
-
+/* $Id$ 
+ */
 #ifndef __PJPP_FILE_HPP__
 #define __PJPP_FILE_HPP__
Index: /pjproject/main/pjlib/include/pj++/hash.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/hash.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/hash.hpp	(revision 43)
@@ -1,6 +1,6 @@
 /* $Id$
  */
-#ifndef __PJPP_HASH_H__
-#define __PJPP_HASH_H__
+#ifndef __PJPP_HASH_HPP__
+#define __PJPP_HASH_HPP__
 
 #include <pj++/types.hpp>
@@ -136,4 +136,4 @@
 
 
-#endif	/* __PJPP_HASH_H__ */
+#endif	/* __PJPP_HASH_HPP__ */
 
Index: /pjproject/main/pjlib/include/pj++/list.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/list.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/list.hpp	(revision 43)
@@ -1,6 +1,6 @@
 /* $Id$
  */
-#ifndef __PJPP_LIST_H__
-#define __PJPP_LIST_H__
+#ifndef __PJPP_LIST_HPP__
+#define __PJPP_LIST_HPP__
 
 #include <pj/list.h>
@@ -308,3 +308,4 @@
 
 
-#endif	/* __PJPP_LIST_H__ */
+#endif	/* __PJPP_LIST_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj++/lock.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/lock.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/lock.hpp	(revision 43)
@@ -1,5 +1,6 @@
-/* $Id$ */
-#ifndef __PJPP_LOCK_H__
-#define __PJPP_LOCK_H__
+/* $Id$ 
+ */
+#ifndef __PJPP_LOCK_HPP__
+#define __PJPP_LOCK_HPP__
 
 #include <pj++/types.hpp>
@@ -128,4 +129,4 @@
 
 
-#endif	/* __PJPP_LOCK_H__ */
+#endif	/* __PJPP_LOCK_HPP__ */
 
Index: /pjproject/main/pjlib/include/pj++/os.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/os.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/os.hpp	(revision 43)
@@ -1,6 +1,6 @@
 /* $Id$
  */
-#ifndef __PJPP_OS_H__
-#define __PJPP_OS_H__
+#ifndef __PJPP_OS_HPP__
+#define __PJPP_OS_HPP__
 
 #include <pj/os.h>
@@ -785,3 +785,4 @@
 }
 
-#endif	/* __PJPP_OS_H__ */
+#endif	/* __PJPP_OS_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj++/pool.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/pool.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/pool.hpp	(revision 43)
@@ -1,6 +1,6 @@
 /* $Id$
  */
-#ifndef __PJPP_POOL_H__
-#define __PJPP_POOL_H__
+#ifndef __PJPP_POOL_HPP__
+#define __PJPP_POOL_HPP__
 
 #include <pj/pool.h>
@@ -251,3 +251,4 @@
 
 
-#endif	/* __PJPP_POOL_H__ */
+#endif	/* __PJPP_POOL_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj++/proactor.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/proactor.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/proactor.hpp	(revision 43)
@@ -1,6 +1,6 @@
 /* $Id$
  */
-#ifndef __PJPP_PROACTOR_H__
-#define __PJPP_PROACTOR_H__
+#ifndef __PJPP_PROACTOR_HPP__
+#define __PJPP_PROACTOR_HPP__
 
 #include <pj/ioqueue.h>
@@ -30,4 +30,5 @@
         : handler_(NULL)
     {
+	pj_ioqueue_op_key_init(this, sizeof(*this));
     }
 
@@ -38,5 +39,5 @@
         : handler_(handler)
     {
-        pj_memset(this, 0, sizeof(pj_ioqueue_op_key_t));
+	pj_ioqueue_op_key_init(this, sizeof(*this));
     }
 
@@ -498,3 +499,4 @@
 };
 
-#endif	/* __PJPP_PROACTOR_H__ */
+#endif	/* __PJPP_PROACTOR_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj++/scanner.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/scanner.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/scanner.hpp	(revision 43)
@@ -1,7 +1,6 @@
 /* $Id$
- *
  */
-#ifndef __PJPP_SCANNER_H__
-#define __PJPP_SCANNER_H__
+#ifndef __PJPP_SCANNER_HPP__
+#define __PJPP_SCANNER_HPP__
 
 #include <pjlib-util/scanner.h>
@@ -171,3 +170,4 @@
 };
 
-#endif	/* __PJPP_SCANNER_H__ */
+#endif	/* __PJPP_SCANNER_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj++/sock.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/sock.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/sock.hpp	(revision 43)
@@ -1,6 +1,6 @@
 /* $Id$
  */
-#ifndef __PJPP_SOCK_H__
-#define __PJPP_SOCK_H__
+#ifndef __PJPP_SOCK_HPP__
+#define __PJPP_SOCK_HPP__
 
 #include <pj/sock.h>
@@ -424,3 +424,4 @@
 
 
-#endif	/* __PJPP_SOCK_H__ */
+#endif	/* __PJPP_SOCK_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj++/string.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/string.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/string.hpp	(revision 43)
@@ -1,6 +1,6 @@
 /* $Id$
  */
-#ifndef __PJPP_STRING_H__
-#define __PJPP_STRING_H__
+#ifndef __PJPP_STRING_HPP__
+#define __PJPP_STRING_HPP__
 
 #include <pj/string.h>
@@ -406,3 +406,4 @@
 };
 
-#endif	/* __PJPP_STRING_H__ */
+#endif	/* __PJPP_STRING_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj++/timer.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/timer.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/timer.hpp	(revision 43)
@@ -1,6 +1,6 @@
 /* $Id$
  */
-#ifndef __PJPP_TIMER_H__
-#define __PJPP_TIMER_H__
+#ifndef __PJPP_TIMER_HPP__
+#define __PJPP_TIMER_HPP__
 
 #include <pj/timer.h>
@@ -178,3 +178,4 @@
 };
 
-#endif	/* __PJPP_TIMER_H__ */
+#endif	/* __PJPP_TIMER_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj++/tree.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/tree.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/tree.hpp	(revision 43)
@@ -1,7 +1,6 @@
 /* $Id$
- *
  */
-#ifndef __PJPP_TREE_H__
-#define __PJPP_TREE_H__
+#ifndef __PJPP_TREE_HPP__
+#define __PJPP_TREE_HPP__
 
 #include <pj/rbtree.h>
@@ -110,3 +109,4 @@
 };
 
-#endif	/* __PJPP_TREE_H__ */
+#endif	/* __PJPP_TREE_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj++/types.hpp
===================================================================
--- /pjproject/main/pjlib/include/pj++/types.hpp	(revision 42)
+++ /pjproject/main/pjlib/include/pj++/types.hpp	(revision 43)
@@ -1,7 +1,6 @@
 /* $Id$
- *
  */
-#ifndef __PJPP_TYPES_H__
-#define __PJPP_TYPES_H__
+#ifndef __PJPP_TYPES_HPP__
+#define __PJPP_TYPES_HPP__
 
 #include <pj/types.h>
@@ -142,3 +141,4 @@
 };
 
-#endif	/* __PJPP_TYPES_H__ */
+#endif	/* __PJPP_TYPES_HPP__ */
+
Index: /pjproject/main/pjlib/include/pj/compat/string.h
===================================================================
--- /pjproject/main/pjlib/include/pj/compat/string.h	(revision 42)
+++ /pjproject/main/pjlib/include/pj/compat/string.h	(revision 43)
@@ -41,3 +41,12 @@
 
 
+#define pj_native_strcmp        strcmp
+#define pj_native_strlen        strlen
+#define pj_native_strcpy        strcpy
+#define pj_native_strstr        strstr
+#define pj_native_strchr        strchr
+#define pj_native_strcasecmp    strcasecmp
+#define pj_native_strncasecmp   strncasecmp
+
+
 #endif	/* __PJ_COMPAT_STRING_H__ */
Index: /pjproject/main/pjlib/include/pj/config.h
===================================================================
--- /pjproject/main/pjlib/include/pj/config.h	(revision 42)
+++ /pjproject/main/pjlib/include/pj/config.h	(revision 43)
@@ -148,5 +148,5 @@
  */
 #ifndef PJ_LOG_MAX_LEVEL
-#  define PJ_LOG_MAX_LEVEL   4
+#  define PJ_LOG_MAX_LEVEL   5
 #endif
 
@@ -404,4 +404,11 @@
 #endif
 
+/**
+ * Function attributes to inform that the function may throw exception.
+ *
+ * @param x     The exception list, enclosed in parenthesis.
+ */
+#define __pj_throw__(x)
+
 
 /********************************************************************
Index: /pjproject/main/pjlib/include/pj/errno.h
===================================================================
--- /pjproject/main/pjlib/include/pj/errno.h	(revision 42)
+++ /pjproject/main/pjlib/include/pj/errno.h	(revision 43)
@@ -216,4 +216,9 @@
  */
 #define PJ_ECANCELLED	    (PJ_ERRNO_START_STATUS + 14)
+/**
+ * @hideinitializer
+ * Object already exists.
+ */
+#define PJ_EEXISTS          (PJ_ERRNO_START_STATUS + 14)
 
 /** @} */   /* pj_errnum */
Index: /pjproject/main/pjlib/include/pj/except.h
===================================================================
--- /pjproject/main/pjlib/include/pj/except.h	(revision 42)
+++ /pjproject/main/pjlib/include/pj/except.h	(revision 43)
@@ -184,4 +184,5 @@
 PJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id);
 
+
 /** @} */
 
Index: /pjproject/main/pjlib/include/pj/hash.h
===================================================================
--- /pjproject/main/pjlib/include/pj/hash.h	(revision 42)
+++ /pjproject/main/pjlib/include/pj/hash.h	(revision 43)
@@ -45,4 +45,19 @@
 				  const void *key, unsigned keylen);
 
+
+/**
+ * Convert the key to lowercase and calculate the hash value. The resulting
+ * string is stored in \c result.
+ *
+ * @param hval      The initial hash value, normally zero.
+ * @param result    Buffer to store the result, which must be enough to hold
+ *                  the string.
+ * @param key       The input key to be converted and calculated.
+ *
+ * @return          The hash value.
+ */
+PJ_DECL(pj_uint32_t) pj_hash_calc_tolower(pj_uint32_t hval,
+                                          char *result,
+                                          const pj_str_t *key);
 
 /**
Index: /pjproject/main/pjlib/include/pj/ioqueue.h
===================================================================
--- /pjproject/main/pjlib/include/pj/ioqueue.h	(revision 42)
+++ /pjproject/main/pjlib/include/pj/ioqueue.h	(revision 43)
@@ -342,7 +342,17 @@
 
 /**
+ * Initialize operation key.
+ *
+ * @param op_key    The operation key to be initialied.
+ * @param size	    The size of the operation key.
+ */
+PJ_DECL(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,
+				      pj_size_t size );
+
+/**
  * Check if operation is pending on the specified operation key.
- * The \c op_key must have been submitted as pending operation before,
- * or otherwise the result is undefined.
+ * The \c op_key must have been initialized with #pj_ioqueue_op_key_init() 
+ * or submitted as pending operation before, or otherwise the result 
+ * is undefined.
  *
  * @param key       The key.
Index: /pjproject/main/pjlib/include/pj/string.h
===================================================================
--- /pjproject/main/pjlib/include/pj/string.h	(revision 42)
+++ /pjproject/main/pjlib/include/pj/string.h	(revision 43)
@@ -13,4 +13,7 @@
 #include <pj/types.h>
 #include <pj/compat/string.h>
+#include <pj/compat/sprintf.h>
+#include <pj/compat/vsprintf.h>
+
 
 PJ_BEGIN_DECL
Index: /pjproject/main/pjlib/src/pj/errno.c
===================================================================
--- /pjproject/main/pjlib/src/pj/errno.c	(revision 42)
+++ /pjproject/main/pjlib/src/pj/errno.c	(revision 43)
@@ -31,5 +31,6 @@
     { PJ_ENOTSUP,	"Option/operation is not supported"},
     { PJ_EINVALIDOP,	"Invalid operation"},
-    { PJ_ECANCELLED,    "Operation cancelled"}
+    { PJ_ECANCELLED,    "Operation cancelled"},
+    { PJ_EEXISTS,       "Object already exists" }
 };
 
Index: /pjproject/main/pjlib/src/pj/hash.c
===================================================================
--- /pjproject/main/pjlib/src/pj/hash.c	(revision 42)
+++ /pjproject/main/pjlib/src/pj/hash.c	(revision 43)
@@ -50,4 +50,18 @@
     }
     return hash;
+}
+
+PJ_DEF(pj_uint32_t) pj_hash_calc_tolower( pj_uint32_t hval,
+                                          char *result,
+                                          const pj_str_t *key)
+{
+    long i;
+
+    for (i=0; i<key->slen; ++i) {
+	result[i] = (char)pj_tolower(key->ptr[i]);
+	hval = hval * PJ_HASH_MULTIPLIER + result[i];
+    }
+
+    return hval;
 }
 
Index: /pjproject/main/pjlib/src/pj/ioqueue_common_abs.c
===================================================================
--- /pjproject/main/pjlib/src/pj/ioqueue_common_abs.c	(revision 42)
+++ /pjproject/main/pjlib/src/pj/ioqueue_common_abs.c	(revision 43)
@@ -834,4 +834,12 @@
 #endif	/* PJ_HAS_TCP */
 
+
+PJ_DEF(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,
+				     pj_size_t size )
+{
+    pj_memset(op_key, 0, size);
+}
+
+
 /*
  * pj_ioqueue_is_pending()
Index: /pjproject/main/pjlib/src/pj/ioqueue_winnt.c
===================================================================
--- /pjproject/main/pjlib/src/pj/ioqueue_winnt.c	(revision 42)
+++ /pjproject/main/pjlib/src/pj/ioqueue_winnt.c	(revision 43)
@@ -893,4 +893,9 @@
 
 
+PJ_DEF(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,
+				     pj_size_t size )
+{
+    pj_memset(op_key, 0, size);
+}
 
 PJ_DEF(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key,
Index: project/main/pjsip/build/TODO.txt
===================================================================
--- /pjproject/main/pjsip/build/TODO.txt	(revision 42)
+++ 	(revision )
@@ -1,21 +1,0 @@
-- regc refresh automatically
-- if dialog CANCEL return 481, disconnect the dialog
-- presence implement callback from event_sub
-- presence supports multiple tuples!
-- implement event headers!
-
-Prio Task
- 10  General authentication framework in pjsua.
- 10  Start on SUBSCRIBE/NOTIFY framework.
- 10  Refactor pjsip_event
----
- 10  Concurrency in pool factory because endpt pool is shared by app.
-     Choices:
-	- another pool factory (thread safe) for app ==> waste memory.
-	- endpt pool is thread safe ==> slow
- 10  Sound in Linux
- 10  Support TCP
- 10  Per instance configuration:
-		- max number of tsxs
-		- max number of dialogs
-		- socket buffer size
Index: /pjproject/main/pjsip/build/pjsip_core.dsp
===================================================================
--- /pjproject/main/pjsip/build/pjsip_core.dsp	(revision 42)
+++ /pjproject/main/pjsip/build/pjsip_core.dsp	(revision 43)
@@ -33,14 +33,14 @@
 # PROP BASE Use_MFC 0
 # PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Output_Dir ".\output\pjsip-core-i386-win32-vc6-release"
+# PROP BASE Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-release"
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjsip_core_vc6_Release"
-# PROP Intermediate_Dir ".\output\pjsip_core_vc6_Release"
+# PROP Output_Dir ".\output\pjsip-core-i386-win32-vc6-release"
+# PROP Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-release"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /Zi /O2 /I "../src" /I "../../pjlib/src" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FR /FD /c
+# ADD CPP /nologo /MD /W4 /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
 # SUBTRACT CPP /YX
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -51,5 +51,5 @@
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjsip_core_vc6s.lib"
+# ADD LIB32 /nologo /out:"../lib/pjsip-core-i386-win32-vc6-release.lib"
 
 !ELSEIF  "$(CFG)" == "pjsip_core - Win32 Debug"
@@ -57,14 +57,14 @@
 # PROP BASE Use_MFC 0
 # PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Output_Dir ".\output\pjsip-core-i386-win32-vc6-debug"
+# PROP BASE Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-debug"
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjsip_core_vc6_Debug"
-# PROP Intermediate_Dir ".\output\pjsip_core_vc6_Debug"
+# PROP Output_Dir ".\output\pjsip-core-i386-win32-vc6-debug"
+# PROP Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-debug"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../src" /I "../../pjlib/src" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /FD /GZ /c
+# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c
 # SUBTRACT CPP /YX
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -75,5 +75,5 @@
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjsip_core_vc6sd.lib"
+# ADD LIB32 /nologo /out:"../lib/pjsip-core-i386-win32-vc6-debug.lib"
 
 !ENDIF 
@@ -136,73 +136,77 @@
 # Begin Source File
 
-SOURCE=..\src\pjsip_core.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\print.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_auth.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_auth_msg.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_auth_parser.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_endpoint.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_event.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_misc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_module.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_msg.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_parser.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_private.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_resolve.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_transaction.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_transport.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_types.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_uri.h
+SOURCE=..\include\pjsip_core.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\print_util.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_auth.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_auth_msg.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_auth_parser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_config.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_endpoint.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_errno.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_event.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_misc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_module.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_msg.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_parser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_private.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_resolve.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_transaction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_transport.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_types.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjsip\sip_uri.h
 # End Source File
 # End Group
@@ -212,5 +216,5 @@
 # Begin Source File
 
-SOURCE=..\src\pjsip\sip_msg_i.h
+SOURCE=..\include\pjsip\sip_msg_i.h
 # End Source File
 # End Group
Index: /pjproject/main/pjsip/build/pjsip_ua.dsp
===================================================================
--- /pjproject/main/pjsip/build/pjsip_ua.dsp	(revision 42)
+++ /pjproject/main/pjsip/build/pjsip_ua.dsp	(revision 43)
@@ -88,13 +88,17 @@
 # Begin Source File
 
-SOURCE=..\src\pjsip_mod_ua\sip_dialog.c
+SOURCE="..\src\pjsip-ua\sip_dialog.c"
 # End Source File
 # Begin Source File
 
-SOURCE=..\src\pjsip_mod_ua\sip_reg.c
+SOURCE="..\src\pjsip-ua\sip_reg.c"
 # End Source File
 # Begin Source File
 
-SOURCE=..\src\pjsip_mod_ua\sip_ua.c
+SOURCE="..\src\pjsip-ua\sip_ua.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjsip-ua\sip_ua_private.h"
 # End Source File
 # End Group
Index: project/main/pjsip/build/tounix
===================================================================
--- /pjproject/main/pjsip/build/tounix	(revision 42)
+++ 	(revision )
@@ -1,5 +1,0 @@
-#!/bin/sh
-name=`basename $1`
-cp $1 /tmp
-cat /tmp/$name | tr -d '\r' > $1
-rm -f /tmp/$name
Index: /pjproject/main/pjsip/include/pjsip/print_util.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/print_util.h	(revision 43)
+++ /pjproject/main/pjsip/include/pjsip/print_util.h	(revision 43)
@@ -0,0 +1,99 @@
+/* $Id$
+ */
+#ifndef __PJSIP_PRINT_H__
+#define __PJSIP_PRINT_H__
+
+#define copy_advance_check(buf,str)   \
+	do { \
+	    if ((str).slen+10 >= (endbuf-buf)) return -1;	\
+	    pj_memcpy(buf, (str).ptr, (str).slen); \
+	    buf += (str).slen; \
+	} while (0)
+
+/*
+static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, int len1, const pj_str_t *str2)
+{
+    if (str2->slen) {
+	int printed = len1+str2->slen;
+	if (printed+10 >= (endbuf-buf)) return NULL;
+	pj_memcpy(buf,str1,len1);
+	pj_memcpy(buf+len1, str2->ptr, str2->slen);
+	return buf + printed;
+    } else
+	return buf;
+}
+*/
+
+#define copy_advance_pair_check(buf,str1,len1,str2)   \
+	do { \
+	    if (str2.slen) { \
+		printed = len1+str2.slen; \
+		if (printed+10 >= (endbuf-buf)) return -1;	\
+		pj_memcpy(buf,str1,len1); \
+		pj_memcpy(buf+len1, str2.ptr, str2.slen); \
+		buf += printed; \
+	    } \
+	} while (0)
+/*
+#define copy_advance_pair(buf,str1,len1,str2)   \
+	do { \
+	    buf = imp_copy_advance_pair(buf, endbuf, str1, len1, &str2); \
+	    if (buf == NULL) return -1; \
+	} while (0)
+*/
+
+#define copy_advance_pair_quote_check(buf,str1,len1,str2,quotebegin,quoteend) \
+	do { \
+	    if (str2.slen) { \
+		printed = len1+str2.slen+2; \
+		if (printed+10 >= (endbuf-buf)) return -1;	\
+		pj_memcpy(buf,str1,len1); \
+		*(buf+len1)=quotebegin; \
+		pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \
+		*(buf+printed-1) = quoteend; \
+		buf += printed; \
+	    } \
+	} while (0)
+
+#define copy_advance_no_check(buf,str)   \
+	pj_memcpy(buf, (str).ptr, (str).slen); \
+	buf += (str).slen;
+
+#define copy_advance_pair_no_check(buf,str1,len1,str2)   \
+	if (str2.slen) { \
+	    pj_memcpy(buf,str1,len1); \
+	    pj_memcpy(buf+len1, str2.ptr, str2.slen); \
+	    buf += len1+str2.slen; \
+	}
+
+#define copy_advance 		copy_advance_check
+#define copy_advance_pair 	copy_advance_pair_check
+#define copy_advance_pair_quote	copy_advance_pair_quote_check
+
+#define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \
+	do {	\
+	    if (str2.slen && *str2.ptr!=quotebegin) \
+		copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \
+	    else \
+		copy_advance_pair(buf,str1,len1,str2); \
+	} while (0)
+
+/*
+ * Internal type declarations.
+ */
+typedef void* (*pjsip_hdr_clone_fptr)(pj_pool_t *, const void*);
+typedef int   (*pjsip_hdr_print_fptr)(void *hdr, char *buf, pj_size_t len);
+
+extern const pj_str_t pjsip_hdr_names[];
+
+PJ_INLINE(void) init_hdr(void *hptr, pjsip_hdr_e htype, void *vptr)
+{
+    pjsip_hdr *hdr = hptr;
+    hdr->type = htype;
+    hdr->name = hdr->sname = pjsip_hdr_names[htype];
+    hdr->vptr = vptr;
+    pj_list_init(hdr);
+}
+
+#endif	/* __PJSIP_PRINT_H__ */
+
Index: /pjproject/main/pjsip/include/pjsip/sip_auth.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_auth.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_auth.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_AUTH_SIP_AUTH_H__
@@ -61,5 +60,5 @@
 typedef struct pjsip_cached_auth_hdr
 {
-    PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth_hdr)
+    PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth_hdr);
 
     pjsip_method	     method;
@@ -81,5 +80,5 @@
 typedef struct pjsip_auth_session
 {
-    PJ_DECL_LIST_MEMBER(struct pjsip_auth_session)
+    PJ_DECL_LIST_MEMBER(struct pjsip_auth_session);
 
     pj_str_t			 realm;
Index: /pjproject/main/pjsip/include/pjsip/sip_auth_msg.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_auth_msg.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_auth_msg.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_AUTH_SIP_AUTH_MSG_H__
@@ -69,5 +68,5 @@
 struct pjsip_authorization_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_authorization_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_authorization_hdr);
     pj_str_t scheme;
     union
@@ -158,5 +157,5 @@
 struct pjsip_www_authenticate_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_www_authenticate_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_www_authenticate_hdr);
     pj_str_t	scheme;
     union
Index: /pjproject/main/pjsip/include/pjsip/sip_auth_parser.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_auth_parser.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_auth_parser.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_AUTH_SIP_AUTH_PARSER_H__
@@ -25,6 +24,8 @@
  * such as Authorization, WWW-Authenticate, Proxy-Authorizization, and 
  * Proxy-Authenticate headers.
+ *
+ * @return      PJ_SUCCESS or the appropriate status code.
  */
-PJ_DECL(void) pjsip_auth_init_parser();
+PJ_DECL(pj_status_t) pjsip_auth_init_parser(void);
 
 /**
Index: /pjproject/main/pjsip/include/pjsip/sip_config.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_config.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_config.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_CONFIG_H__
@@ -134,5 +133,4 @@
 
 #include <pj/config.h>
-#include <pj/compat.h>
 
 
Index: /pjproject/main/pjsip/include/pjsip/sip_endpoint.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_endpoint.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_endpoint.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_ENDPOINT_H__
@@ -29,5 +28,6 @@
  * all SIP objects in an application. It performs the following roles:
  *  - it manages the allocation/deallocation of memory pools for all objects.
- *  - it manages listeners and transports, and how they are used by transactions.
+ *  - it manages listeners and transports, and how they are used by 
+ *    transactions.
  *  - it owns transaction hash table.
  *  - it receives incoming messages from transport layer and automatically
@@ -35,5 +35,6 @@
  *  - it has a single instance of timer management (timer heap).
  *  - it manages modules, which is the primary means of extending the library.
- *  - it provides single polling function for all objects and distributes events.
+ *  - it provides single polling function for all objects and distributes 
+ *    events.
  *  - it provides SIP policy such as which outbound proxy to use for all
  *    outgoing SIP request messages.
@@ -50,12 +51,19 @@
 /**
  * Create an instance of SIP endpoint from the specified pool factory.
- * The pool factory reference then will be kept by the endpoint, so that future
- * memory allocations by SIP components will be taken from the same pool factory.
- *
- * @param pf	Pool factory that will be used for the lifetime of endpoint.
- *
- * @return the endpoint instance on success.
- */
-PJ_DECL(pjsip_endpoint*) pjsip_endpt_create(pj_pool_factory *pf);
+ * The pool factory reference then will be kept by the endpoint, so that 
+ * future memory allocations by SIP components will be taken from the same
+ * pool factory.
+ *
+ * @param pf	        Pool factory that will be used for the lifetime of 
+ *                      endpoint.
+ * @param name          Optional name to be specified for the endpoint.
+ *                      If this parameter is NULL, then the name will use
+ *                      local host name.
+ * @param endpt         Pointer to receive endpoint instance.
+ *
+ * @return              PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,
+                                        pjsip_endpoint **endpt);
 
 /**
@@ -67,4 +75,14 @@
  */
 PJ_DECL(void) pjsip_endpt_destroy(pjsip_endpoint *endpt);
+
+/**
+ * Get endpoint name.
+ *
+ * @param endpt         The SIP endpoint instance.
+ *
+ * @return              Endpoint name, as was registered during endpoint
+ *                      creation. The string is NULL terminated.
+ */
+PJ_DECL(const pj_str_t*) pjsip_endpt_name(const pjsip_endpoint *endpt);
 
 /**
@@ -155,7 +173,10 @@
  *
  * @param endpt	    The SIP endpoint.
- * @return	    The new transaction, or NULL on failure.
- */
-PJ_DECL(pjsip_transaction*) pjsip_endpt_create_tsx(pjsip_endpoint *endpt);
+ * @param p_tsx	    Pointer to receive the transaction.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_tsx(pjsip_endpoint *endpt,
+					    pjsip_transaction **p_tsx);
 
 /**
@@ -188,8 +209,11 @@
  * This function, like all other endpoint functions, is thread safe.
  *
- * @param endpt the endpoint.
- * @return new transmit data.
- */
-PJ_DECL(pjsip_tx_data*) pjsip_endpt_create_tdata( pjsip_endpoint *endpt );
+ * @param endpt	    The endpoint.
+ * @param p_tdata    Pointer to receive transmit data buffer.
+ *
+ * @return	    PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_tdata( pjsip_endpoint *endpt,
+					       pjsip_tx_data **p_tdata);
 
 /**
@@ -333,4 +357,22 @@
 
 /**
+ * Log an error.
+ */
+PJ_DECL(void) pjsip_endpt_log_error( pjsip_endpoint *endpt,
+				     const char *sender,
+                                     pj_status_t error_code,
+                                     const char *format,
+                                     ... );
+
+#define PJSIP_ENDPT_LOG_ERROR(expr)   \
+            pjsip_endpt_log_error expr
+
+#define PJSIP_ENDPT_TRACE(tracing,expr) \
+            do {                        \
+                if ((tracing))          \
+                    PJ_LOG(4,expr);     \
+            } while (0)
+
+/**
  * @}
  */
Index: /pjproject/main/pjsip/include/pjsip/sip_errno.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_errno.h	(revision 43)
+++ /pjproject/main/pjsip/include/pjsip/sip_errno.h	(revision 43)
@@ -0,0 +1,86 @@
+/* $Id$ 
+ */
+#ifndef __PJSIP_SIP_ERRNO_H__
+#define __PJSIP_SIP_ERRNO_H__
+
+#include <pj/errno.h>
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ */
+#define PJSIP_ERRNO_START       (PJ_ERRNO_START_USER+10000)
+
+/**
+ * Create error value from SIP status code.
+ * @param code      SIP status code.
+ * @return          Error code in pj_status_t namespace.
+ */
+#define PJSIP_ERRNO_FROM_SIP_STATUS(code)   (PJSIP_ERRNO_START+code)
+
+/**
+ * Get SIP status code from error value.
+ * If conversion to SIP status code is not available, a SIP status code
+ * 599 will be returned.
+ *
+ * @param status    Error code in pj_status_t namespace.
+ * @return          SIP status code.
+ */
+#define PJSIP_ERRNO_TO_SIP_STATUS(status)               \
+         ((status>=PJSIP_ERRNO_FROM_SIP_STATUS(100) &&  \
+           status<PJSIP_ERRNO_FROM_SIP_STATUS(999)) ?   \
+          status-PJSIP_ERRNO_FROM_SIP_STATUS(0) : 599)
+
+
+/**
+ * Start of PJSIP generated error code values.
+ */
+#define PJSIP_ERRNO_START_PJSIP (PJSIP_ERRNO_START + 10000)
+
+/**
+ * @hideinitializer
+ * Missing required header(s).
+ */
+#define PJSIP_EMISSINGHDR       (PJSIP_ERRNO_START_PJSIP + 1)
+/**
+ * @hideinitializer
+ * Unsupported URL scheme.
+ */
+#define PJSIP_EINVALIDSCHEME    (PJSIP_ERRNO_START_PJSIP + 2)
+/**
+ * @hideinitializer
+ * Transaction has just been destroyed.
+ */
+#define PJSIP_ETSXDESTROYED     (PJSIP_ERRNO_START_PJSIP + 3)
+/**
+ * @hideinitializer
+ * Buffer overflow. See also PJSIP_EMSGTOOLONG.
+ */
+#define PJSIP_EOVERFLOW         (PJSIP_ERRNO_START_PJSIP + 4)
+/**
+ * @hideinitializer
+ * Message not completely received.
+ */
+#define PJSIP_EPARTIALMSG       (PJSIP_ERRNO_START_PJSIP + 5)
+/**
+ * @hideinitializer
+ * Message too long. See also PJSIP_EOVERFLOW.
+ */
+#define PJSIP_EMSGTOOLONG	(PJSIP_ERRNO_START_PJSIP + 6)
+/**
+ * @hideinitializer
+ * Buffer is being sent, operation still pending.
+ */
+#define PJSIP_EPENDINGTX	(PJSIP_ERRNO_START_PJSIP + 7)
+/**
+ * @hideinitializer
+ * Unsupported transport type.
+ */
+#define PJSIP_EUNSUPTRANSPORT	(PJSIP_ERRNO_START_PJSIP + 8)
+/**
+ * @hideinitializer
+ * Invalid Via header in response (sent-by, etc).
+ */
+#define PJSIP_EINVALIDVIA	(PJSIP_ERRNO_START_PJSIP + 9)
+
+
+#endif	/* __PJSIP_SIP_ERRNO_H__ */
Index: /pjproject/main/pjsip/include/pjsip/sip_event.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_event.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_event.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_EVENT_H__
@@ -26,5 +25,5 @@
 {
     /** Unidentified event. */
-    PJSIP_EVENT_UNIDENTIFIED,
+    PJSIP_EVENT_UNKNOWN,
 
     /** Timer event, normally only used internally in transaction. */
@@ -41,8 +40,8 @@
 
     /** Transaction state changed event. */
-    PJSIP_EVENT_TSX_STATE_CHANGED,
+    PJSIP_EVENT_TSX_STATE,
 
     /** 2xx response received event. */
-    PJSIP_EVENT_RX_200_RESPONSE,
+    PJSIP_EVENT_RX_200_MSG,
 
     /** ACK request received event. */
@@ -56,5 +55,5 @@
 
     /** On before transmitting message. */
-    PJSIP_EVENT_BEFORE_TX,
+    PJSIP_EVENT_PRE_TX_MSG,
 
 } pjsip_event_id_e;
@@ -77,44 +76,206 @@
 {
     /** This is necessary so that we can put events as a list. */
-    PJ_DECL_LIST_MEMBER(struct pjsip_event)
+    PJ_DECL_LIST_MEMBER(struct pjsip_event);
 
     /** The event type, can be any value of \b pjsip_event_id_e.
-     *  @see pjsip_event_id_e
      */
     pjsip_event_id_e type;
 
-    /** This field determines what is the content of \b src (source data). 
-     */
-    pjsip_event_id_e src_type;
-
-    /** Source data, which content is dependent on \b src_type.
-     *  - if src_type==PJSIP_EVENT_RX_MSG, src.rdata is valid.
-     *  - if src_type==PJSIP_EVENT_TX_MSG, src.tdata is valid.
-     *  - if src_type==PJSIP_EVENT_TIMER, src.timer is valid.
+    /*
+     * The event body.
+     * By convention, the first member of each struct in the union must be
+     * the pointer which is relevant to the event.
      */
     union
     {
-	pjsip_rx_data	*rdata;
-	pjsip_tx_data	*tdata;
-	pj_timer_entry	*timer;
-	void		*data;
-	unsigned long	 udata;
-    } src;
-
-    /** The object that generates this event. */
-    union
-    {
-	pjsip_transaction  *tsx;
-	void		   *ptr;
-	unsigned long	    udata;
-    } obj;
-
-    /** Other data. */
-    union
-    {
-	long		    long_data;
-	void *		    ptr_data;
-    } data;
+        /** Timer event. */
+        struct
+        {
+            pj_timer_entry *entry;      /**< The timer entry.           */
+        } timer;
+
+        /** Transaction state has changed event. */
+        struct
+        {
+            union
+            {
+                pjsip_rx_data   *rdata; /**< The incoming message.      */
+                pjsip_tx_data   *tdata; /**< The outgoing message.      */
+                pj_timer_entry  *timer; /**< The timer.                 */
+                pj_status_t      status;/**< Transport error status.    */
+                void            *data;  /**< Generic data.              */
+            } src;
+            pjsip_transaction   *tsx;   /**< The transaction.           */
+            pjsip_event_id_e    type;   /**< Type of event source:      
+                                         *      - PJSIP_EVENT_TX_MSG
+                                         *      - PJSIP_EVENT_RX_MSG,
+                                         *      - PJSIP_EVENT_TRANSPORT_ERROR
+                                         *      - PJSIP_EVENT_TIMER
+                                         *      - PJSIP_EVENT_USER
+                                         */
+        } tsx_state;
+
+        /** Message transmission event. */
+        struct
+        {
+            pjsip_tx_data       *tdata; /**< The transmit data buffer.  */
+            pjsip_transaction   *tsx;   /**< The transaction.           */
+
+        } tx_msg;
+
+        /** Pre-transmission event. */
+        struct
+        {
+            pjsip_tx_data       *tdata; /**< Msg to be transmitted.     */
+            pjsip_transaction   *tsx;   /**< The transaction.           */
+            int                  retcnt;/**< Retransmission count.      */
+        } pre_tx_msg;
+
+        /** Transmission error event. */
+        struct
+        {
+            pjsip_tx_data       *tdata; /**< The transmit data.         */
+            pjsip_transaction   *tsx;   /**< The transaction.           */
+        } tx_error;
+
+        /** Message arrival event. */
+        struct
+        {
+            pjsip_rx_data       *rdata; /**< The receive data buffer.   */
+            pjsip_transaction   *tsx;   /**< The transaction.           */
+        } rx_msg;
+
+        /** Receipt of 200/INVITE response. */
+        struct
+        {
+            pjsip_rx_data       *rdata; /**< The 200 response msg.      */
+        } rx_200_msg;
+
+        /** Receipt of ACK message. */
+        struct
+        {
+            pjsip_rx_data       *rdata; /**< The ack message.           */
+        } rx_ack_msg;
+
+        /** Notification that endpoint has discarded a message. */
+        struct
+        {
+            pjsip_rx_data       *rdata; /**< The discarded message.     */
+            pj_status_t          reason;/**< The reason.                */
+        } discard_msg;
+
+        /** User event. */
+        struct
+        {
+            void                *user1; /**< User data 1.               */
+            void                *user2; /**< User data 2.               */
+            void                *user3; /**< User data 3.               */
+            void                *user4; /**< User data 4.               */
+        } user;
+
+    } body;
 };
+
+/**
+ * Init timer event.
+ */
+#define PJSIP_EVENT_INIT_TIMER(event,pentry)            \
+        do { \
+            (event).type = PJSIP_EVENT_TIMER;           \
+            (event).body.timer.entry = pentry;          \
+        } while (0)
+
+/**
+ * Init tsx state event.
+ */
+#define PJSIP_EVENT_INIT_TSX_STATE(event,ptsx,ptype,pdata)   \
+        do { \
+            (event).type = PJSIP_EVENT_TSX_STATE;           \
+            (event).body.tsx_state.tsx = ptsx;		    \
+            (event).body.tsx_state.type = ptype;            \
+            (event).body.tsx_state.src.data = pdata;        \
+        } while (0)
+
+/**
+ * Init tx msg event.
+ */
+#define PJSIP_EVENT_INIT_TX_MSG(event,ptsx,ptdata)	\
+        do { \
+            (event).type = PJSIP_EVENT_TX_MSG;          \
+            (event).body.tx_msg.tsx = ptsx;		\
+            (event).body.tx_msg.tdata = ptdata;		\
+        } while (0)
+
+/**
+ * Init rx msg event.
+ */
+#define PJSIP_EVENT_INIT_RX_MSG(event,ptsx,prdata)	\
+        do { \
+            (event).type = PJSIP_EVENT_RX_MSG;		\
+            (event).body.rx_msg.tsx = ptsx;		\
+            (event).body.rx_msg.rdata = prdata;		\
+        } while (0)
+
+/**
+ * Init transport error event.
+ */
+#define PJSIP_EVENT_INIT_TRANSPORT_ERROR(event,ptsx,ptdata)   \
+        do { \
+            (event).type = PJSIP_EVENT_TRANSPORT_ERROR; \
+            (event).body.tx_error.tsx = ptsx;		\
+            (event).body.tx_error.tdata = ptdata;	\
+        } while (0)
+
+/**
+ * Init rx 200/INVITE event.
+ */
+#define PJSIP_EVENT_INIT_RX_200_MSG(event,prdata)       \
+        do { \
+            (event).type = PJSIP_EVENT_RX_200_MSG;      \
+            (event).body.rx_200_msg.rdata = prdata;	\
+        } while (0)
+
+/**
+ * Init rx ack msg event.
+ */
+#define PJSIP_EVENT_INIT_RX_ACK_MSG(event,prdata)       \
+        do { \
+            (event).type = PJSIP_EVENT_RX_ACK_MSG;      \
+            (event).body.rx_ack_msg.rdata = prdata;	\
+        } while (0)
+
+/**
+ * Init discard msg event.
+ */
+#define PJSIP_EVENT_INIT_DISCARD_MSG(event,prdata,preason)  \
+        do { \
+            (event).type = PJSIP_EVENT_DISCARD_MSG;         \
+            (event).body.discard_msg.rdata = prdata;	    \
+            (event).body.discard_msg.reason = preason;	    \
+        } while (0)
+
+/**
+ * Init user event.
+ */
+#define PJSIP_EVENT_INIT_USER(event,u1,u2,u3,u4)    \
+        do { \
+            (event).type = PJSIP_EVENT_USER;        \
+            (event).body.user.user1 = (void*)u1;     \
+            (event).body.user.user2 = (void*)u2;     \
+            (event).body.user.user3 = (void*)u3;     \
+            (event).body.user.user4 = (void*)u4;     \
+        } while (0)
+
+/**
+ * Init pre tx msg event.
+ */
+#define PJSIP_EVENT_INIT_PRE_TX_MSG(event,ptsx,ptdata,pretcnt) \
+        do { \
+            (event).type = PJSIP_EVENT_PRE_TX_MSG;	\
+            (event).body.pre_tx_msg.tsx = ptsx;		\
+            (event).body.pre_tx_msg.tdata = ptdata;	\
+            (event).body.pre_tx_msg.retcnt = pretcnt;	\
+        } while (0)
+
 
 /**
Index: /pjproject/main/pjsip/include/pjsip/sip_misc.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_misc.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_misc.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_MISC_H__
@@ -31,16 +30,18 @@
  * @param cseq	    Optional CSeq (put -1 to generate random CSeq).
  * @param text	    Optional text body (put NULL to omit body).
+ * @param p_tdata   Pointer to receive the transmit data.
  *
- * @return	    The transmit data.
+ * @return	    PJ_SUCCESS, or the appropriate error code.
  */
-PJ_DECL(pjsip_tx_data*) pjsip_endpt_create_request( pjsip_endpoint *endpt, 
-						    const pjsip_method *method,
-						    const pj_str_t *target,
-						    const pj_str_t *from,
-						    const pj_str_t *to, 
-						    const pj_str_t *contact,
-						    const pj_str_t *call_id,
-						    int cseq, 
-						    const pj_str_t *text);
+PJ_DECL(pj_status_t) pjsip_endpt_create_request( pjsip_endpoint *endpt, 
+						 const pjsip_method *method,
+						 const pj_str_t *target,
+						 const pj_str_t *from,
+						 const pj_str_t *to, 
+						 const pj_str_t *contact,
+						 const pj_str_t *call_id,
+						 int cseq, 
+						 const pj_str_t *text,
+						 pjsip_tx_data **p_tdata);
 
 /**
@@ -59,8 +60,9 @@
  * @param cseq	    Optional CSeq (put -1 to generate random CSeq).
  * @param text	    Optional text body (put NULL to omit body).
+ * @param p_tdata   Pointer to receive the transmit data.
  *
- * @return	    The transmit data.
+ * @return	    PJ_SUCCESS, or the appropriate error code.
  */
-PJ_DECL(pjsip_tx_data*)
+PJ_DECL(pj_status_t)
 pjsip_endpt_create_request_from_hdr( pjsip_endpoint *endpt,
 				     const pjsip_method *method,
@@ -71,5 +73,6 @@
 				     const pjsip_cid_hdr *call_id,
 				     int cseq,
-				     const pj_str_t *text );
+				     const pj_str_t *text,
+				     pjsip_tx_data **p_tdata);
 
 /**
@@ -90,5 +93,5 @@
  *		    the completion of the transaction.
  *
- * @return	    Zero if transaction is started successfully.
+ * @return	    PJ_SUCCESS, or the appropriate error code.
  */
 PJ_DECL(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt,
@@ -108,10 +111,12 @@
  * @param rdata	    The request receive data.
  * @param code	    Status code to be put in the response.
+ * @param p_tdata   Pointer to receive the transmit data.
  *
- * @return	    Transmit data.
+ * @return	    PJ_SUCCESS, or the appropriate error code.
  */
-PJ_DECL(pjsip_tx_data*) pjsip_endpt_create_response(pjsip_endpoint *endpt,
-						    const pjsip_rx_data *rdata,
-						    int code);
+PJ_DECL(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt,
+						  const pjsip_rx_data *rdata,
+						  int code,
+						  pjsip_tx_data **p_tdata);
 
 /**
@@ -137,9 +142,11 @@
  * @param endpt	    The endpoint.
  * @param tdata	    The transmit buffer for the request being cancelled.
+ * @param p_tdata   Pointer to receive the transmit data.
  *
- * @return	    Cancel request.
+ * @return	    PJ_SUCCESS, or the appropriate error code.
  */
-PJ_DECL(pjsip_tx_data*) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
-						   pjsip_tx_data *tdata );
+PJ_DECL(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
+						pjsip_tx_data *tdata,
+						pjsip_tx_data **p_tdata);
 
 
@@ -160,5 +167,4 @@
 					     pjsip_host_port *addr);
 
-
 /**
  * @}
Index: /pjproject/main/pjsip/include/pjsip/sip_module.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_module.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_module.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_MODULE_H__
Index: /pjproject/main/pjsip/include/pjsip/sip_msg.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_msg.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_msg.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_MSG_H__
@@ -261,5 +260,5 @@
 #define PJSIP_DECL_HDR_MEMBER(hdr)   \
     /** List members. */	\
-    PJ_DECL_LIST_MEMBER(hdr)	\
+    PJ_DECL_LIST_MEMBER(hdr);	\
     /** Header type */		\
     pjsip_hdr_e	    type;	\
@@ -269,5 +268,5 @@
     pj_str_t	    sname;		\
     /** Virtual function table. */	\
-    pjsip_hdr_vptr *vptr;
+    pjsip_hdr_vptr *vptr
 
 
@@ -276,8 +275,8 @@
  * message. All header fields can be typecasted to this type.
  */
-typedef struct pjsip_hdr
-{
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_hdr)
-} pjsip_hdr;
+struct pjsip_hdr
+{
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_hdr);
+};
 
 
@@ -688,5 +687,5 @@
  *		value if the message is too large for the specified buffer.
  */
-PJ_DECL(int) pjsip_msg_print( pjsip_msg *msg, char *buf, pj_size_t size);
+PJ_DECL(pj_ssize_t) pjsip_msg_print(pjsip_msg *msg, char *buf, pj_size_t size);
 
 /**
@@ -708,5 +707,5 @@
 typedef struct pjsip_generic_string_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_string_hdr) /**< Standard header field. */
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_string_hdr); /**< Standard header field. */
     pj_str_t hvalue;				    /**< hvalue */
 } pjsip_generic_string_hdr;
@@ -757,5 +756,5 @@
 typedef struct pjsip_generic_int_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_int_hdr) /**< Standard header field. */
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_int_hdr); /**< Standard header field. */
     pj_int32_t ivalue;				    /**< ivalue */
 } pjsip_generic_int_hdr;
@@ -806,5 +805,5 @@
 typedef struct pjsip_generic_array_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_array_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_array_hdr);
     unsigned	count;					/**< Number of elements. */
     pj_str_t	values[PJSIP_GENERIC_ARRAY_MAX_COUNT];	/**< Elements.		 */
@@ -887,5 +886,5 @@
 typedef struct pjsip_cid_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_cid_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_cid_hdr);
     pj_str_t id;	    /**< Call-ID string. */
 } pjsip_cid_hdr;
@@ -918,5 +917,5 @@
 typedef struct pjsip_clen_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_clen_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_clen_hdr);
     int len;	/**< Content length. */
 } pjsip_clen_hdr;
@@ -946,5 +945,5 @@
 typedef struct pjsip_cseq_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_cseq_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_cseq_hdr);
     int		    cseq;	/**< CSeq number. */
     pjsip_method    method;	/**< CSeq method. */
@@ -978,5 +977,5 @@
 typedef struct pjsip_contact_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_contact_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_contact_hdr);
     int		    star;	    /**< The contact contains only a '*' character */
     pjsip_uri *uri;	    /**< URI in the contact. */
@@ -1011,5 +1010,5 @@
 typedef struct pjsip_ctype_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_ctype_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_ctype_hdr);
     pjsip_media_type media; /**< Media type. */
 } pjsip_ctype_hdr;
@@ -1062,5 +1061,5 @@
 typedef struct pjsip_fromto_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_fromto_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_fromto_hdr);
     pjsip_uri  *uri;	    /**< URI in From/To header. */
     pj_str_t	     tag;	    /**< Header "tag" parameter. */
@@ -1171,5 +1170,5 @@
 typedef struct pjsip_routing_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_routing_hdr)  /**< Generic header fields. */
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_routing_hdr);  /**< Generic header fields. */
     pjsip_name_addr  name_addr;	  /**< The URL in the Route/Record-Route header. */
     pj_str_t	     other_param; /** Other parameter. */
@@ -1328,5 +1327,5 @@
 typedef struct pjsip_via_hdr
 {
-    PJSIP_DECL_HDR_MEMBER(struct pjsip_via_hdr)
+    PJSIP_DECL_HDR_MEMBER(struct pjsip_via_hdr);
     pj_str_t	     transport;	    /**< Transport type. */
     pjsip_host_port  sent_by;	    /**< Host and optional port */
Index: /pjproject/main/pjsip/include/pjsip/sip_parser.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_parser.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_parser.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_PARSER_H__
@@ -11,5 +10,5 @@
 
 #include <pjsip/sip_types.h>
-#include <pj/scanner.h>
+#include <pjlib-util/scanner.h>
 #include <pj/list.h>
 
@@ -52,5 +51,5 @@
 typedef struct pjsip_parser_err_report
 {
-    PJ_DECL_LIST_MEMBER(struct pjsip_parser_err_report)
+    PJ_DECL_LIST_MEMBER(struct pjsip_parser_err_report);
     int		exception_code;	/**< Error exception (e.g. PJSIP_SYN_ERR_EXCEPTION) */
     int		line;		/**< Line number. */
@@ -58,4 +57,15 @@
     pj_str_t	hname;		/**< Header name, if any. */
 } pjsip_parser_err_report;
+
+
+/**
+ * Parsing context, the default argument for parsing functions.
+ */
+typedef struct pjsip_parse_ctx
+{
+    pj_scanner      *scanner;   /**< The scanner.       */
+    pj_pool_t       *pool;      /**< The pool.          */
+    pjsip_rx_data   *rdata;     /**< Optional rdata.    */
+} pjsip_parse_ctx;
 
 
@@ -77,5 +87,5 @@
  *        can be terminated when seeing EOF.
  */
-typedef void* (pjsip_parse_hdr_func)(pj_scanner *scanner, pj_pool_t *pool);
+typedef pjsip_hdr* (pjsip_parse_hdr_func)(pjsip_parse_ctx *context);
 
 /**
@@ -95,6 +105,5 @@
  * @param fptr		The pointer to function to parser the header.
  *
- * @return		zero if success.
- * @see pjsip_parse_hdr_func
+ * @return		PJ_SUCCESS if success, or the appropriate error code.
  */
 PJ_DECL(pj_status_t) pjsip_register_hdr_parser( const char *hname,
@@ -186,4 +195,25 @@
 
 /**
+ * Parse a packet buffer and build a rdata. The resulting message will be
+ * stored in \c msg field in the \c rdata. This behaves pretty much like
+ * #pjsip_parse_msg(), except that it will also initialize the header fields
+ * in the \c rdata.
+ *
+ * This function is normally called by the transport layer.
+ *
+ * @param buf           The input buffer
+ * @param buf		The input buffer, which size must be at least (size+1)
+ *			because the function will temporarily put NULL 
+ *			termination at the end of the buffer during parsing.
+ * @param size		The length of the string (not counting NULL terminator).
+ * @param rdata         The receive data buffer to store the message and
+ *                      its elements.
+ *
+ * @return              The message inside the rdata if successfull, or NULL.
+ */
+PJ_DECL(pjsip_msg *) pjsip_parse_rdata( char *buf, pj_size_t size,
+                                        pjsip_rx_data *rdata );
+
+/**
  * Check incoming packet to see if a (probably) valid SIP message has been 
  * received.
@@ -194,8 +224,10 @@
  *			the size of the SIP message (including body, if any).
  *
- * @return		PJ_TRUE (1) if a message is found.
- */
-PJ_DECL(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size, 
-				   pj_bool_t is_datagram, pj_size_t *msg_size);
+ * @return		PJ_SUCCESS if a message is found, or an error code.
+ */
+PJ_DECL(pj_status_t) pjsip_find_msg(const char *buf, 
+                                    pj_size_t size, 
+				    pj_bool_t is_datagram, 
+                                    pj_size_t *msg_size);
 
 /**
@@ -248,5 +280,5 @@
  */
 extern
-pj_char_spec	pjsip_HOST_SPEC,	    /* For scanning host part. */
+pj_cis_t	pjsip_HOST_SPEC,	    /* For scanning host part. */
 		pjsip_DIGIT_SPEC,	    /* Decimal digits */
 		pjsip_ALPHA_SPEC,	    /* Alpha (A-Z, a-z) */
Index: /pjproject/main/pjsip/include/pjsip/sip_private.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_private.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_private.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_PRIVATE_H__
@@ -27,7 +26,9 @@
  * @param cb Callback to be called to receive messages from transport.
  */
-PJ_DECL(pjsip_transport_mgr*) pjsip_transport_mgr_create( pj_pool_t *pool,
-							  pjsip_endpoint *endpt,
-							  void (*cb)(pjsip_endpoint *,pjsip_rx_data *));
+PJ_DECL(pj_status_t) pjsip_transport_mgr_create( pj_pool_t *pool,
+						 pjsip_endpoint *endpt,
+						 void (*cb)(pjsip_endpoint *,
+							    pjsip_rx_data *),
+						 pjsip_transport_mgr **);
 
 
@@ -36,5 +37,5 @@
  * @param mgr Transport manager to be destroyed.
  */
-PJ_DECL(void) pjsip_transport_mgr_destroy( pjsip_transport_mgr *mgr );
+PJ_DECL(pj_status_t) pjsip_transport_mgr_destroy( pjsip_transport_mgr *mgr );
 
 /**
Index: /pjproject/main/pjsip/include/pjsip/sip_resolve.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_resolve.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_resolve.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_RESOLVE_H__
Index: /pjproject/main/pjsip/include/pjsip/sip_transaction.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_transaction.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_transaction.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_TRANSACTION_H__
@@ -12,6 +11,4 @@
 #include <pjsip/sip_msg.h>
 #include <pjsip/sip_resolve.h>
-//#include <pjsip/sip_config.h>
-//#include <pjsip/sip_endpoint.h>
 #include <pj/timer.h>
 
@@ -24,4 +21,5 @@
  */
 
+/* Forward decl. */
 struct pjsip_transaction;
 
@@ -62,31 +60,54 @@
 struct pjsip_transaction
 {
-    pj_pool_t		       *pool;
-    pjsip_endpoint	       *endpt;
-    char			obj_name[PJ_MAX_OBJ_NAME];
-    pjsip_role_e		role;
-    int				status_code;
-    pjsip_tsx_state_e		state;
-    int (*state_handler)(struct pjsip_transaction *, pjsip_event *);
-
-    pj_mutex_t		       *mutex;
-    pjsip_method		method;
-    int				cseq;
-    pj_str_t			transaction_key;
-    pj_str_t			branch;
-
-    pjsip_tsx_transport_state_e	transport_state;
-    pjsip_host_port		dest_name;
-    int				current_addr;
-    pjsip_server_addresses	remote_addr;
-    pjsip_transport_t	       *transport;
-
-    pjsip_tx_data	       *last_tx;
-    int				has_unsent_msg;
-    int				handle_ack;
-    int				retransmit_count;
-
-    pj_timer_entry		retransmit_timer;
-    pj_timer_entry		timeout_timer;
+    /*
+     * Administrivia
+     */
+    pj_pool_t		       *pool;           /**< Pool owned by the tsx. */
+    pjsip_endpoint	       *endpt;          /**< Endpoint instance.     */
+    pj_mutex_t		       *mutex;          /**< Mutex for this tsx.    */
+    char			obj_name[PJ_MAX_OBJ_NAME];  /**< Tsx name.  */
+    int                         tracing;        /**< Tracing enabled?       */
+
+    /*
+     * Transaction identification.
+     */
+    pjsip_role_e		role;           /**< Role (UAS or UAC)      */
+    pjsip_method		method;         /**< The method.            */
+    int				cseq;           /**< The CSeq               */
+    pj_str_t			transaction_key;/**< hash table key.        */
+    pj_str_t			branch;         /**< The branch Id.         */
+
+    /*
+     * State and status.
+     */
+    int				status_code;    /**< Last status code seen. */
+    pjsip_tsx_state_e		state;          /**< State.                 */
+    int				handle_ack;     /**< Should we handle ACK?  */
+
+    /** Handler according to current state. */
+    pj_status_t (*state_handler)(struct pjsip_transaction *, pjsip_event *);
+
+    /*
+     * Transport.
+     */
+    pjsip_tsx_transport_state_e	transport_state;/**< Transport's state.     */
+    pjsip_host_port		dest_name;      /**< Destination address.   */
+    pjsip_server_addresses	remote_addr;    /**< Addresses resolved.    */
+    int				current_addr;   /**< Address currently used. */
+
+    pjsip_transport_t	       *transport;      /**< Transport to use.      */
+
+    /*
+     * Messages and timer.
+     */
+    pjsip_tx_data	       *last_tx;        /**< Msg kept for retrans.  */
+    int				has_unsent_msg; /**< Non-zero if tsx need to 
+                                                     transmit msg once resolver
+                                                     completes.             */
+    int				retransmit_count;/**< Retransmission count. */
+    pj_timer_entry		retransmit_timer;/**< Retransmit timer.     */
+    pj_timer_entry		timeout_timer;  /**< Timeout timer.         */
+
+    /** Module specific data. */
     void		       *module_data[PJSIP_MAX_MODULE];
 };
@@ -94,8 +115,24 @@
 
 /** 
- * Init transaction as UAC.
- * @param tsx the transaction.
- * @param tdata the transmit data.
- * @return PJ_SUCCESS if successfull.
+ * Init transaction as UAC from the specified transmit data (\c tdata).
+ * The transmit data must have a valid \c Request-Line and \c CSeq header.
+ * If \c Route headers are present, it will be used to calculate remote
+ * destination.
+ *
+ * If \c Via header does not exist, it will be created along with a unique
+ * \c branch parameter. If it exists and contains branch parameter, then
+ * the \c branch parameter will be used as is as the transaction key.
+ *
+ * The \c Route headers in the transmit data, if present, are used to 
+ * calculate remote destination.
+ *
+ * At the end of the function, the transaction will start resolving the
+ * addresses of remote server to contact. Transport will be acquired as soon
+ * as the resolving job completes.
+ *
+ * @param tsx       The transaction.
+ * @param tdata     The transmit data.
+ *
+ * @return          PJ_SUCCESS if successfull.
  */
 PJ_DECL(pj_status_t) pjsip_tsx_init_uac( pjsip_transaction *tsx, 
@@ -104,6 +141,8 @@
 /**
  * Init transaction as UAS.
- * @param tsx the transaction to be initialized.
- * @param rdata the received incoming request.
+ *
+ * @param tsx       The transaction to be initialized.
+ * @param rdata     The received incoming request.
+ *
  * @return PJ_SUCCESS if successfull.
  */
@@ -113,6 +152,7 @@
 /**
  * Process incoming message for this transaction.
- * @param tsx the transaction.
- * @param rdata the incoming message.
+ *
+ * @param tsx       The transaction.
+ * @param rdata     The incoming message.
  */
 PJ_DECL(void) pjsip_tsx_on_rx_msg( pjsip_transaction *tsx,
@@ -121,6 +161,7 @@
 /**
  * Transmit message with this transaction.
- * @param tsx the transaction.
- * @param tdata the outgoing message.
+ *
+ * @param tsx       The transaction.
+ * @param tdata     The outgoing message.
  */
 PJ_DECL(void) pjsip_tsx_on_tx_msg( pjsip_transaction *tsx,
@@ -135,6 +176,7 @@
  * transaction will comply with RFC-3261, i.e. it will set itself to 
  * TERMINATED state when it receives 2xx/INVITE.
- * @param tsx The transaction.
- * @param tdata The ACK request.
+ *
+ * @param tsx       The transaction.
+ * @param tdata     The ACK request.
  */
 PJ_DECL(void) pjsip_tsx_on_tx_ack( pjsip_transaction *tsx,
@@ -142,7 +184,8 @@
 
 /**
- * Forcely terminate transaction.
- * @param tsx the transaction.
- * @param code the status code to report.
+ * Force terminate transaction.
+ *
+ * @param tsx       The transaction.
+ * @param code      The status code to report.
  */
 PJ_DECL(void) pjsip_tsx_terminate( pjsip_transaction *tsx,
@@ -152,15 +195,19 @@
  * Create transaction key, which is used to match incoming requests 
  * or response (retransmissions) against transactions.
- * @param pool The pool
- * @param key Output key.
- * @param role The role of the transaction.
- * @param method The method to be put as a key. 
- * @param rdata The received data to calculate.
- */
-PJ_DECL(void) pjsip_tsx_create_key( pj_pool_t *pool,
-				    pj_str_t *key,
-				    pjsip_role_e role,
-				    const pjsip_method *method,
-				    const pjsip_rx_data *rdata );
+ *
+ * @param pool      The pool
+ * @param key       Output key.
+ * @param role      The role of the transaction.
+ * @param method    The method to be put as a key. 
+ * @param rdata     The received data to calculate.
+ *
+ * @return          PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_create_key( pj_pool_t *pool,
+				           pj_str_t *key,
+				           pjsip_role_e role,
+				           const pjsip_method *method,
+				           const pjsip_rx_data *rdata );
+
 
 /**
@@ -184,5 +231,5 @@
 
 /* Thread Local Storage ID for transaction lock (initialized by endpoint) */
-extern int pjsip_tsx_lock_tls_id;
+extern long pjsip_tsx_lock_tls_id;
 
 PJ_END_DECL
Index: /pjproject/main/pjsip/include/pjsip/sip_transport.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_transport.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_transport.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_TRANSPORT_H__
@@ -14,4 +13,5 @@
 #include <pj/sock.h>
 #include <pj/list.h>
+#include <pj/ioqueue.h>
 
 PJ_BEGIN_DECL
@@ -37,8 +37,11 @@
 struct pjsip_rx_data
 {
-    PJ_DECL_LIST_MEMBER(struct pjsip_rx_data)
+    //PJ_DECL_LIST_MEMBER(struct pjsip_rx_data);
 
     /** Memory pool for this buffer. */
     pj_pool_t		*pool;
+
+    /** Ioqueue op key. */
+    pj_ioqueue_op_key_t	 op_key;
 
     /** Time when the message was received. */
@@ -74,13 +77,7 @@
     pjsip_from_hdr	*from;
 
-    /** The tag in the From header as found in the message. */
-    pj_str_t		 from_tag;
-
     /** The To header as found in the message. */
     pjsip_to_hdr	*to;
 
-    /** The To tag header as found in the message. */
-    pj_str_t		 to_tag;
-
     /** The topmost Via header as found in the message. */
     pjsip_via_hdr	*via;
@@ -88,4 +85,22 @@
     /** The CSeq header as found in the message. */
     pjsip_cseq_hdr	*cseq;
+
+    /** Max forwards header. */
+    pjsip_max_forwards_hdr *max_fwd;
+
+    /** The first route header. */
+    pjsip_route_hdr     *route;
+
+    /** The first record-route header. */
+    pjsip_rr_hdr        *record_route;
+
+    /** Content-type header. */
+    pjsip_ctype_hdr     *ctype;
+
+    /** Content-length header. */
+    pjsip_clen_hdr      *clen;
+
+    /** The first Require header. */
+    pjsip_require_hdr   *require;
 
     /** The list of error generated by the parser when parsing this message. */
@@ -110,5 +125,5 @@
 struct pjsip_tx_data
 {
-    PJ_DECL_LIST_MEMBER(struct pjsip_tx_data)
+    PJ_DECL_LIST_MEMBER(struct pjsip_tx_data);
 
     /** Memory pool for this buffer. */
@@ -127,4 +142,7 @@
     /** The transport manager for this buffer. */
     pjsip_transport_mgr *mgr;
+
+    /** Ioqueue asynchronous operation key. */
+    pj_ioqueue_op_key_t	 op_key;
 
     /** The message in this buffer. */
@@ -357,11 +375,13 @@
  * @param tdata		The outgoing message buffer.
  * @param addr		The remote address.
- *
- * @return		The number of bytes sent, or zero if the connection 
- *			has closed, or -1 on error.
- */
-PJ_DECL(int) pjsip_transport_send_msg( pjsip_transport_t *tr, 
-				       pjsip_tx_data *tdata,
-				       const pj_sockaddr_in *addr);
+ * @param sent          If not null, it will be filled up with the length of
+ *                      data sent.
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_transport_send_msg( pjsip_transport_t *tr, 
+					       pjsip_tx_data *tdata,
+					       const pj_sockaddr_in *addr,
+					       pj_ssize_t *sent);
 
 
@@ -387,5 +407,6 @@
  * @return		The transmit buffer data, or NULL on error.
  */
-pjsip_tx_data* pjsip_tx_data_create( pjsip_transport_mgr *mgr );
+pj_status_t pjsip_tx_data_create( pjsip_transport_mgr *mgr,
+                                  pjsip_tx_data **tdata );
 
 
Index: /pjproject/main/pjsip/include/pjsip/sip_types.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_types.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_types.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_TYPES_H__
@@ -74,4 +73,9 @@
 
 /**
+ * Forward declaration for header field (sip_msg.h).
+ */
+typedef struct pjsip_hdr pjsip_hdr;
+
+/**
  * Forward declaration for URI (sip_uri.h).
  */
@@ -135,4 +139,23 @@
 
 
+/**
+ * Convert exception ID into pj_status_t status.
+ *
+ * @param exception_id  Exception Id.
+ *
+ * @return              Error code for the specified exception Id.
+ */
+PJ_DECL(pj_status_t) pjsip_exception_to_status(int exception_id);
+
+/**
+ * Return standard pj_status_t status from current exception.
+ */
+#define PJSIP_RETURN_EXCEPTION() pjsip_exception_to_status(PJ_GET_EXCEPTION())
+
+/**
+ * Attributes to inform that the function may throw exceptions.
+ */
+#define PJSIP_THROW_SPEC(list)
+
 #endif	/* __PJSIP_SIP_TYPES_H__ */
 
Index: /pjproject/main/pjsip/include/pjsip/sip_uri.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip/sip_uri.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip/sip_uri.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_SIP_URI_H__
Index: /pjproject/main/pjsip/include/pjsip_core.h
===================================================================
--- /pjproject/main/pjsip/include/pjsip_core.h	(revision 42)
+++ /pjproject/main/pjsip/include/pjsip_core.h	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #ifndef __PJSIP_CORE_H__
Index: project/main/pjsip/src/pjsip/print.h
===================================================================
--- /pjproject/main/pjsip/src/pjsip/print.h	(revision 42)
+++ 	(revision )
@@ -1,100 +1,0 @@
-/* $Id$
- *
- */
-#ifndef __PJSIP_PRINT_H__
-#define __PJSIP_PRINT_H__
-
-#define copy_advance_check(buf,str)   \
-	do { \
-	    if ((str).slen+10 >= (endbuf-buf)) return -1;	\
-	    pj_memcpy(buf, (str).ptr, (str).slen); \
-	    buf += (str).slen; \
-	} while (0)
-
-/*
-static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, int len1, const pj_str_t *str2)
-{
-    if (str2->slen) {
-	int printed = len1+str2->slen;
-	if (printed+10 >= (endbuf-buf)) return NULL;
-	pj_memcpy(buf,str1,len1);
-	pj_memcpy(buf+len1, str2->ptr, str2->slen);
-	return buf + printed;
-    } else
-	return buf;
-}
-*/
-
-#define copy_advance_pair_check(buf,str1,len1,str2)   \
-	do { \
-	    if (str2.slen) { \
-		printed = len1+str2.slen; \
-		if (printed+10 >= (endbuf-buf)) return -1;	\
-		pj_memcpy(buf,str1,len1); \
-		pj_memcpy(buf+len1, str2.ptr, str2.slen); \
-		buf += printed; \
-	    } \
-	} while (0)
-/*
-#define copy_advance_pair(buf,str1,len1,str2)   \
-	do { \
-	    buf = imp_copy_advance_pair(buf, endbuf, str1, len1, &str2); \
-	    if (buf == NULL) return -1; \
-	} while (0)
-*/
-
-#define copy_advance_pair_quote_check(buf,str1,len1,str2,quotebegin,quoteend) \
-	do { \
-	    if (str2.slen) { \
-		printed = len1+str2.slen+2; \
-		if (printed+10 >= (endbuf-buf)) return -1;	\
-		pj_memcpy(buf,str1,len1); \
-		*(buf+len1)=quotebegin; \
-		pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \
-		*(buf+printed-1) = quoteend; \
-		buf += printed; \
-	    } \
-	} while (0)
-
-#define copy_advance_no_check(buf,str)   \
-	pj_memcpy(buf, (str).ptr, (str).slen); \
-	buf += (str).slen;
-
-#define copy_advance_pair_no_check(buf,str1,len1,str2)   \
-	if (str2.slen) { \
-	    pj_memcpy(buf,str1,len1); \
-	    pj_memcpy(buf+len1, str2.ptr, str2.slen); \
-	    buf += len1+str2.slen; \
-	}
-
-#define copy_advance 		copy_advance_check
-#define copy_advance_pair 	copy_advance_pair_check
-#define copy_advance_pair_quote	copy_advance_pair_quote_check
-
-#define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \
-	do {	\
-	    if (str2.slen && *str2.ptr!=quotebegin) \
-		copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \
-	    else \
-		copy_advance_pair(buf,str1,len1,str2); \
-	} while (0)
-
-/*
- * Internal type declarations.
- */
-typedef void* (*pjsip_hdr_clone_fptr)(pj_pool_t *, const void*);
-typedef int   (*pjsip_hdr_print_fptr)(void *hdr, char *buf, pj_size_t len);
-
-extern const pj_str_t pjsip_hdr_names[];
-
-PJ_INLINE(void) init_hdr(void *hptr, pjsip_hdr_e htype, void *vptr)
-{
-    pjsip_hdr *hdr = hptr;
-    hdr->type = htype;
-    hdr->name = hdr->sname = pjsip_hdr_names[htype];
-    hdr->vptr = vptr;
-    pj_list_init(hdr);
-}
-
-#endif	/* __PJSIP_PRINT_H__ */
-
Index: /pjproject/main/pjsip/src/pjsip/sip_auth.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_auth.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_auth.c	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_auth.h>
@@ -6,9 +5,11 @@
 #include <pjsip/sip_transport.h>
 #include <pjsip/sip_endpoint.h>
-#include <pj/md5.h>
+#include <pjlib-util/md5.h>
 #include <pj/log.h>
 #include <pj/string.h>
 #include <pj/pool.h>
 #include <pj/guid.h>
+#include <pj/assert.h>
+#include <pj/ctype.h>
 
 /* Length of digest string. */
@@ -147,5 +148,5 @@
     p = qop.ptr;
     while (*p) {
-	*p = (char)tolower(*p);
+	*p = (char)pj_tolower(*p);
 	++p;
     }
@@ -218,5 +219,5 @@
 	cred->qop = pjsip_AUTH_STR;
 	cred->nc.ptr = pj_pool_alloc(pool, 16);
-	sprintf(cred->nc.ptr, "%06u", nc);
+	pj_snprintf(cred->nc.ptr, 16, "%06u", nc);
 
 	if (cnonce && cnonce->slen) {
@@ -485,5 +486,5 @@
 {
     unsigned i;
-    PJ_UNUSED_ARG(scheme)
+    PJ_UNUSED_ARG(scheme);
     for (i=0; i<count; ++i) {
 	if (pj_stricmp(&cred[i].realm, realm) == 0)
@@ -716,5 +717,5 @@
     pjsip_via_hdr *via;
 
-    PJ_UNUSED_ARG(endpt)
+    PJ_UNUSED_ARG(endpt);
 
     pj_assert(rdata->msg->type == PJSIP_RESPONSE_MSG);
Index: /pjproject/main/pjsip/src/pjsip/sip_auth_msg.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_auth_msg.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_auth_msg.c	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_auth_msg.h>
@@ -7,5 +6,6 @@
 #include <pj/list.h>
 #include <pj/string.h>
-#include <pjsip/print.h>
+#include <pj/assert.h>
+#include <pjsip/print_util.h>
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -68,7 +68,7 @@
 static int print_pgp_credential(pjsip_pgp_credential *cred, char *buf, pj_size_t size)
 {
-    PJ_UNUSED_ARG(cred)
-    PJ_UNUSED_ARG(buf)
-    PJ_UNUSED_ARG(size)
+    PJ_UNUSED_ARG(cred);
+    PJ_UNUSED_ARG(buf);
+    PJ_UNUSED_ARG(size);
     return -1;
 }
@@ -213,7 +213,7 @@
 			        char *buf, pj_size_t size)
 {
-    PJ_UNUSED_ARG(chal)
-    PJ_UNUSED_ARG(buf)
-    PJ_UNUSED_ARG(size)
+    PJ_UNUSED_ARG(chal);
+    PJ_UNUSED_ARG(buf);
+    PJ_UNUSED_ARG(size);
     return -1;
 }
Index: /pjproject/main/pjsip/src/pjsip/sip_auth_parser.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_auth_parser.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_auth_parser.c	(revision 43)
@@ -1,20 +1,24 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_auth_parser.h>
 #include <pjsip/sip_auth_msg.h>
 #include <pjsip/sip_parser.h>
+#include <pj/assert.h>
 #include <pj/string.h>
 #include <pj/except.h>
 
-static pjsip_authorization_hdr*	      parse_hdr_authorization( pj_scanner *scanner, pj_pool_t *pool);
-static pjsip_proxy_authorization_hdr* parse_hdr_proxy_authorization( pj_scanner *scanner, pj_pool_t *pool);
-static pjsip_www_authenticate_hdr*    parse_hdr_www_authenticate( pj_scanner *scanner, pj_pool_t *pool);
-static pjsip_proxy_authenticate_hdr*  parse_hdr_proxy_authenticate( pj_scanner *scanner, pj_pool_t *pool);
-
-static void parse_digest_credential( pj_scanner *scanner, pj_pool_t *pool, pjsip_digest_credential *cred);
-static void parse_pgp_credential( pj_scanner *scanner, pj_pool_t *pool, pjsip_pgp_credential *cred);
-static void parse_digest_challenge( pj_scanner *scanner, pj_pool_t *pool, pjsip_digest_challenge *chal);
-static void parse_pgp_challenge( pj_scanner *scanner, pj_pool_t *pool, pjsip_pgp_challenge *chal);
+static pjsip_hdr* parse_hdr_authorization       ( pjsip_parse_ctx *ctx );
+static pjsip_hdr* parse_hdr_proxy_authorization ( pjsip_parse_ctx *ctx );
+static pjsip_hdr* parse_hdr_www_authenticate    ( pjsip_parse_ctx *ctx );
+static pjsip_hdr* parse_hdr_proxy_authenticate  ( pjsip_parse_ctx *ctx );
+
+static void parse_digest_credential ( pj_scanner *scanner, pj_pool_t *pool, 
+                                      pjsip_digest_credential *cred);
+static void parse_pgp_credential    ( pj_scanner *scanner, pj_pool_t *pool, 
+                                      pjsip_pgp_credential *cred);
+static void parse_digest_challenge  ( pj_scanner *scanner, pj_pool_t *pool, 
+                                      pjsip_digest_challenge *chal);
+static void parse_pgp_challenge     ( pj_scanner *scanner, pj_pool_t *pool,
+                                      pjsip_pgp_challenge *chal);
 
 const pj_str_t	pjsip_USERNAME_STR =	    { "username", 8 },
@@ -44,10 +48,11 @@
 
 
-static void parse_digest_credential( pj_scanner *scanner, pj_pool_t *pool, pjsip_digest_credential *cred)
+static void parse_digest_credential( pj_scanner *scanner, pj_pool_t *pool, 
+                                     pjsip_digest_credential *cred)
 {
     for (;;) {
 	pj_str_t name, value;
 
-	pjsip_parse_param_imp(scanner, &name, &value, PJSIP_PARSE_REMOVE_QUOTE);
+	pjsip_parse_param_imp(scanner, &name, &value,PJSIP_PARSE_REMOVE_QUOTE);
 
 	if (!pj_stricmp(&name, &pjsip_USERNAME_STR)) {
@@ -82,9 +87,9 @@
 
 	} else {
-	    pjsip_concat_param_imp(&cred->other_param, pool, &name, &value, ',');
+	    pjsip_concat_param_imp(&cred->other_param,pool,&name,&value, ',');
 	}
 
 	/* Eat comma */
-	if (!pj_scan_is_eof(scanner) && *scanner->current == ',')
+	if (!pj_scan_is_eof(scanner) && *scanner->curptr == ',')
 	    pj_scan_get_char(scanner);
 	else
@@ -93,19 +98,21 @@
 }
 
-static void parse_pgp_credential( pj_scanner *scanner, pj_pool_t *pool, pjsip_pgp_credential *cred)
-{
-    PJ_UNUSED_ARG(scanner)
-    PJ_UNUSED_ARG(pool)
-    PJ_UNUSED_ARG(cred)
+static void parse_pgp_credential( pj_scanner *scanner, pj_pool_t *pool, 
+                                  pjsip_pgp_credential *cred)
+{
+    PJ_UNUSED_ARG(scanner);
+    PJ_UNUSED_ARG(pool);
+    PJ_UNUSED_ARG(cred);
 
     PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 }
 
-static void parse_digest_challenge( pj_scanner *scanner, pj_pool_t *pool, pjsip_digest_challenge *chal)
+static void parse_digest_challenge( pj_scanner *scanner, pj_pool_t *pool, 
+                                    pjsip_digest_challenge *chal)
 {
     for (;;) {
 	pj_str_t name, value;
 
-	pjsip_parse_param_imp(scanner, &name, &value, PJSIP_PARSE_REMOVE_QUOTE);
+	pjsip_parse_param_imp(scanner, &name, &value,PJSIP_PARSE_REMOVE_QUOTE);
 
 	if (!pj_stricmp(&name, &pjsip_REALM_STR)) {
@@ -122,6 +129,9 @@
 
 	} else if (!pj_stricmp(&name, &pjsip_STALE_STR)) {
-	    if (!pj_stricmp(&value, &pjsip_TRUE_STR) || !pj_stricmp(&value, &pjsip_QUOTED_TRUE_STR))
+	    if (!pj_stricmp(&value, &pjsip_TRUE_STR) || 
+                !pj_stricmp(&value, &pjsip_QUOTED_TRUE_STR))
+            {
 		chal->stale = 1;
+            }
 
 	} else if (!pj_stricmp(&name, &pjsip_ALGORITHM_STR)) {
@@ -133,9 +143,10 @@
 
 	} else {
-	    pjsip_concat_param_imp(&chal->other_param, pool, &name, &value, ',');
+	    pjsip_concat_param_imp(&chal->other_param, pool, 
+                                   &name, &value, ',');
 	}
 
 	/* Eat comma */
-	if (!pj_scan_is_eof(scanner) && *scanner->current == ',')
+	if (!pj_scan_is_eof(scanner) && *scanner->curptr == ',')
 	    pj_scan_get_char(scanner);
 	else
@@ -144,22 +155,23 @@
 }
 
-static void parse_pgp_challenge( pj_scanner *scanner, pj_pool_t *pool, pjsip_pgp_challenge *chal)
-{
-    PJ_UNUSED_ARG(scanner)
-    PJ_UNUSED_ARG(pool)
-    PJ_UNUSED_ARG(chal)
+static void parse_pgp_challenge( pj_scanner *scanner, pj_pool_t *pool, 
+                                 pjsip_pgp_challenge *chal)
+{
+    PJ_UNUSED_ARG(scanner);
+    PJ_UNUSED_ARG(pool);
+    PJ_UNUSED_ARG(chal);
 
     PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 }
 
-static void int_parse_hdr_authorization( pj_scanner *scanner, pj_pool_t *pool, 
+static void int_parse_hdr_authorization( pj_scanner *scanner, pj_pool_t *pool,
 					 pjsip_authorization_hdr *hdr)
 {
-    if (*scanner->current == '"') {
+    if (*scanner->curptr == '"') {
 	pj_scan_get_quote(scanner, '"', '"', &hdr->scheme);
 	hdr->scheme.ptr++;
 	hdr->scheme.slen -= 2;
     } else {
-	pj_scan_get(scanner, pjsip_TOKEN_SPEC, &hdr->scheme);
+	pj_scan_get(scanner, &pjsip_TOKEN_SPEC, &hdr->scheme);
     }
 
@@ -182,10 +194,10 @@
 					pjsip_www_authenticate_hdr *hdr)
 {
-    if (*scanner->current == '"') {
+    if (*scanner->curptr == '"') {
 	pj_scan_get_quote(scanner, '"', '"', &hdr->scheme);
 	hdr->scheme.ptr++;
 	hdr->scheme.slen -= 2;
     } else {
-	pj_scan_get(scanner, pjsip_TOKEN_SPEC, &hdr->scheme);
+	pj_scan_get(scanner, &pjsip_TOKEN_SPEC, &hdr->scheme);
     }
 
@@ -206,39 +218,54 @@
 
 
-static pjsip_authorization_hdr *parse_hdr_authorization( pj_scanner *scanner, pj_pool_t *pool)
-{
-    pjsip_authorization_hdr *hdr = pjsip_authorization_hdr_create(pool);
-    int_parse_hdr_authorization(scanner, pool, hdr);
-    return hdr;
-}
-
-static pjsip_proxy_authorization_hdr *parse_hdr_proxy_authorization( pj_scanner *scanner, pj_pool_t *pool)
-{
-    pjsip_proxy_authorization_hdr *hdr = pjsip_proxy_authorization_hdr_create(pool);
-    int_parse_hdr_authorization(scanner, pool, hdr);
-    return hdr;
-}
-
-static pjsip_www_authenticate_hdr *parse_hdr_www_authenticate( pj_scanner *scanner, pj_pool_t *pool)
-{
-    pjsip_www_authenticate_hdr *hdr = pjsip_www_authenticate_hdr_create(pool);
-    int_parse_hdr_authenticate(scanner, pool, hdr);
-    return hdr;
-}
-
-static pjsip_proxy_authenticate_hdr *parse_hdr_proxy_authenticate( pj_scanner *scanner, pj_pool_t *pool)
-{
-    pjsip_proxy_authenticate_hdr *hdr = pjsip_proxy_authenticate_hdr_create(pool);
-    int_parse_hdr_authenticate(scanner, pool, hdr);
-    return hdr;
-}
-
-
-PJ_DEF(void) pjsip_auth_init_parser()
-{
-    pjsip_register_hdr_parser( "Authorization", NULL, (pjsip_parse_hdr_func*) &parse_hdr_authorization);
-    pjsip_register_hdr_parser( "Proxy-Authorization", NULL, (pjsip_parse_hdr_func*) &parse_hdr_proxy_authorization);
-    pjsip_register_hdr_parser( "WWW-Authenticate", NULL, (pjsip_parse_hdr_func*) &parse_hdr_www_authenticate);
-    pjsip_register_hdr_parser( "Proxy-Authenticate", NULL, (pjsip_parse_hdr_func*) &parse_hdr_proxy_authenticate);
+static pjsip_hdr* parse_hdr_authorization( pjsip_parse_ctx *ctx )
+{
+    pjsip_authorization_hdr *hdr = pjsip_authorization_hdr_create(ctx->pool);
+    int_parse_hdr_authorization(ctx->scanner, ctx->pool, hdr);
+    return (pjsip_hdr*)hdr;
+}
+
+static pjsip_hdr* parse_hdr_proxy_authorization( pjsip_parse_ctx *ctx )
+{
+    pjsip_proxy_authorization_hdr *hdr = 
+        pjsip_proxy_authorization_hdr_create(ctx->pool);
+    int_parse_hdr_authorization(ctx->scanner, ctx->pool, hdr);
+    return (pjsip_hdr*)hdr;
+}
+
+static pjsip_hdr* parse_hdr_www_authenticate( pjsip_parse_ctx *ctx )
+{
+    pjsip_www_authenticate_hdr *hdr = 
+        pjsip_www_authenticate_hdr_create(ctx->pool);
+    int_parse_hdr_authenticate(ctx->scanner, ctx->pool, hdr);
+    return (pjsip_hdr*)hdr;
+}
+
+static pjsip_hdr* parse_hdr_proxy_authenticate( pjsip_parse_ctx *ctx )
+{
+    pjsip_proxy_authenticate_hdr *hdr = 
+        pjsip_proxy_authenticate_hdr_create(ctx->pool);
+    int_parse_hdr_authenticate(ctx->scanner, ctx->pool, hdr);
+    return (pjsip_hdr*)hdr;
+}
+
+
+PJ_DEF(pj_status_t) pjsip_auth_init_parser()
+{
+    pj_status_t status;
+
+    status = pjsip_register_hdr_parser( "Authorization", NULL, 
+                                        &parse_hdr_authorization);
+    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+    status = pjsip_register_hdr_parser( "Proxy-Authorization", NULL, 
+                                        &parse_hdr_proxy_authorization);
+    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+    status = pjsip_register_hdr_parser( "WWW-Authenticate", NULL, 
+                                        &parse_hdr_www_authenticate);
+    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+    status = pjsip_register_hdr_parser( "Proxy-Authenticate", NULL, 
+                                        &parse_hdr_proxy_authenticate);
+    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+
+    return PJ_SUCCESS;
 }
 
Index: /pjproject/main/pjsip/src/pjsip/sip_endpoint.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_endpoint.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_endpoint.c	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_endpoint.h>
@@ -9,4 +8,5 @@
 #include <pjsip/sip_module.h>
 #include <pjsip/sip_misc.h>
+#include <pjsip/sip_errno.h>
 #include <pj/except.h>
 #include <pj/log.h>
@@ -15,8 +15,10 @@
 #include <pj/pool.h>
 #include <pj/hash.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
 
 
 #define PJSIP_EX_NO_MEMORY  PJ_NO_MEMORY_EXCEPTION
-#define LOG_THIS	    "endpoint..."
+#define THIS_FILE	    "endpoint"
 
 #define MAX_METHODS   32
@@ -85,5 +87,6 @@
  * Defined in sip_transaction.c
  */
-pjsip_transaction * pjsip_tsx_create( pj_pool_t *pool, pjsip_endpoint *endpt);
+pj_status_t pjsip_tsx_create( pj_pool_t *pool, pjsip_endpoint *endpt,
+                              pjsip_transaction **tsx );
 
 /*
@@ -95,6 +98,6 @@
 static void pool_callback( pj_pool_t *pool, pj_size_t size )
 {
-    PJ_UNUSED_ARG(pool)
-    PJ_UNUSED_ARG(size)
+    PJ_UNUSED_ARG(pool);
+    PJ_UNUSED_ARG(size);
 
     PJ_THROW(PJSIP_EX_NO_MEMORY);
@@ -112,5 +115,5 @@
     extern pjsip_module aux_tsx_module;
 
-    PJ_LOG(5, (LOG_THIS, "init_modules()"));
+    PJ_LOG(5, (THIS_FILE, "init_modules()"));
 
     /* Load static modules. */
@@ -165,5 +168,5 @@
 		    endpt->methods[endpt->method_cnt++] = mod->methods[j];
 		} else {
-		    PJ_LOG(1,(LOG_THIS, "Too many methods"));
+		    PJ_LOG(1,(THIS_FILE, "Too many methods"));
 		    return -1;
 		}
@@ -201,5 +204,5 @@
 				      pjsip_transaction *tsx)
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_destroy_tsx(%s)", tsx->obj_name));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_destroy_tsx(%s)", tsx->obj_name));
 
     pj_assert(tsx->state == PJSIP_TSX_STATE_DESTROYED);
@@ -227,5 +230,5 @@
     pj_pool_release(tsx->pool);
 
-    PJ_LOG(4, (LOG_THIS, "tsx%p destroyed", tsx));
+    PJ_LOG(4, (THIS_FILE, "tsx%p destroyed", tsx));
 }
 
@@ -248,9 +251,9 @@
 
     /* Destroy transaction if it is terminated. */
-    if (evt->type == PJSIP_EVENT_TSX_STATE_CHANGED && 
-	evt->obj.tsx->state == PJSIP_TSX_STATE_DESTROYED) 
+    if (evt->type == PJSIP_EVENT_TSX_STATE && 
+	evt->body.tsx_state.tsx->state == PJSIP_TSX_STATE_DESTROYED) 
     {
 	/* No need to lock mutex. Mutex is locked inside the destroy function */
-	pjsip_endpt_destroy_tsx( endpt, evt->obj.tsx );
+	pjsip_endpt_destroy_tsx( endpt, evt->body.tsx_state.tsx );
     }
 }
@@ -262,4 +265,5 @@
 void pjsip_endpt_send_tsx_event( pjsip_endpoint *endpt, pjsip_event *evt )
 {
+    // Need to protect this with try/catch?
     endpt_do_event(endpt, evt);
 }
@@ -302,5 +306,5 @@
 	if (!hdr) {
 	    pj_mutex_unlock(endpt->mutex);
-	    PJ_LOG(4,(LOG_THIS, "Invalid URL %s in proxy URL", dup));
+	    PJ_LOG(4,(THIS_FILE, "Invalid URL %s in proxy URL", dup));
 	    return -1;
 	}
@@ -328,5 +332,6 @@
  * Initialize endpoint.
  */
-PJ_DEF(pjsip_endpoint*) pjsip_endpt_create(pj_pool_factory *pf)
+PJ_DEF(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,
+                                       pjsip_endpoint **p_endpt)
 {
     pj_status_t status;
@@ -335,5 +340,7 @@
     pjsip_max_forwards_hdr *mf_hdr;
 
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_create()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create()"));
+
+    *p_endpt = NULL;
 
     /* Create pool */
@@ -342,5 +349,5 @@
 			  &pool_callback);
     if (!pool)
-	return NULL;
+	return PJ_ENOMEM;
 
     /* Create endpoint. */
@@ -350,14 +357,13 @@
 
     /* Create mutex for the events, etc. */
-    endpt->mutex = pj_mutex_create( endpt->pool, "ept%p", 0 );
-    if (!endpt->mutex) {
-	PJ_LOG(4, (LOG_THIS, "pjsip_endpt_init(): error creating endpoint mutex"));
+    status = pj_mutex_create_recursive( endpt->pool, "ept%p", &endpt->mutex );
+    if (status != PJ_SUCCESS) {
 	goto on_error;
     }
 
     /* Create mutex for the transaction table. */
-    endpt->tsx_table_mutex = pj_mutex_create( endpt->pool, "mtbl%p", 0);
-    if (!endpt->tsx_table_mutex) {
-	PJ_LOG(4, (LOG_THIS, "pjsip_endpt_init(): error creating endpoint mutex(2)"));
+    status = pj_mutex_create_recursive( endpt->pool, "mtbl%p", 
+                                        &endpt->tsx_table_mutex);
+    if (status != PJ_SUCCESS) {
 	goto on_error;
     }
@@ -366,21 +372,21 @@
     endpt->tsx_table = pj_hash_create( endpt->pool, PJSIP_MAX_TSX_COUNT );
     if (!endpt->tsx_table) {
-	PJ_LOG(4, (LOG_THIS, "pjsip_endpt_init(): error creating tsx hash table"));
+	status = PJ_ENOMEM;
 	goto on_error;
     }
 
     /* Create timer heap to manage all timers within this endpoint. */
-    endpt->timer_heap = pj_timer_heap_create( endpt->pool, PJSIP_MAX_TIMER_COUNT, 0);
-    if (!endpt->timer_heap) {
-	PJ_LOG(4, (LOG_THIS, "pjsip_endpt_init(): error creating timer heap"));
+    status = pj_timer_heap_create( endpt->pool, PJSIP_MAX_TIMER_COUNT, 
+                                   &endpt->timer_heap);
+    if (status != PJ_SUCCESS) {
 	goto on_error;
     }
 
     /* Create transport manager. */
-    endpt->transport_mgr = pjsip_transport_mgr_create( endpt->pool,
-						       endpt,
-						       &endpt_transport_callback);
-    if (!endpt->transport_mgr) {
-	PJ_LOG(4, (LOG_THIS, "pjsip_endpt_init(): error creating transport mgr"));
+    status = pjsip_transport_mgr_create( endpt->pool,
+					 endpt,
+					 &endpt_transport_callback,
+					 &endpt->transport_mgr);
+    if (status != PJ_SUCCESS) {
 	goto on_error;
     }
@@ -389,12 +395,11 @@
     endpt->resolver = pjsip_resolver_create(endpt->pool);
     if (!endpt->resolver) {
-	PJ_LOG(4, (LOG_THIS, "pjsip_endpt_init(): error creating resolver"));
+	PJ_LOG(4, (THIS_FILE, "pjsip_endpt_init(): error creating resolver"));
 	goto on_error;
     }
 
     /* Initialize TLS ID for transaction lock. */
-    pjsip_tsx_lock_tls_id = pj_thread_local_alloc();
-    if (pjsip_tsx_lock_tls_id == -1) {
-	PJ_LOG(4, (LOG_THIS, "pjsip_endpt_init(): error allocating TLS"));
+    status = pj_thread_local_alloc(&pjsip_tsx_lock_tls_id);
+    if (status != PJ_SUCCESS) {
 	goto on_error;
     }
@@ -415,10 +420,11 @@
     status = init_modules(endpt);
     if (status != PJ_SUCCESS) {
-	PJ_LOG(4, (LOG_THIS, "pjsip_endpt_init(): error in init_modules()"));
-	return NULL;
+	PJ_LOG(4, (THIS_FILE, "pjsip_endpt_init(): error in init_modules()"));
+	return status;
     }
 
     /* Done. */
-    return endpt;
+    *p_endpt = endpt;
+    return status;
 
 on_error:
@@ -437,6 +443,6 @@
     pj_pool_release( endpt->pool );
 
-    PJ_LOG(4, (LOG_THIS, "pjsip_endpt_init() failed"));
-    return NULL;
+    PJ_LOG(4, (THIS_FILE, "pjsip_endpt_init() failed"));
+    return status;
 }
 
@@ -446,5 +452,5 @@
 PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt)
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_destroy()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_destroy()"));
 
     /* Shutdown and destroy all transports. */
@@ -471,5 +477,5 @@
     pj_pool_t *pool;
 
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_create_pool()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_pool()"));
 
     /* Lock endpoint mutex. */
@@ -484,7 +490,7 @@
 
     if (pool) {
-	PJ_LOG(5, (LOG_THIS, "   pool %s created", pj_pool_getobjname(pool)));
+	PJ_LOG(5, (THIS_FILE, "   pool %s created", pj_pool_getobjname(pool)));
     } else {
-	PJ_LOG(4, (LOG_THIS, "Unable to create pool %s!", pool_name));
+	PJ_LOG(4, (THIS_FILE, "Unable to create pool %s!", pool_name));
     }
 
@@ -498,5 +504,5 @@
 PJ_DEF(void) pjsip_endpt_destroy_pool( pjsip_endpoint *endpt, pj_pool_t *pool )
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_destroy_pool(%s)", pj_pool_getobjname(pool)));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_destroy_pool(%s)", pj_pool_getobjname(pool)));
 
     pj_mutex_lock(endpt->mutex);
@@ -514,5 +520,5 @@
     int i;
 
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_handle_events()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_handle_events()"));
 
     /* Poll the timer. The timer heap has its own mutex for better 
@@ -544,5 +550,5 @@
 						const pj_time_val *delay )
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)",
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)",
 			 entry, delay->sec, delay->msec));
     return pj_timer_heap_schedule( endpt->timer_heap, entry, delay );
@@ -555,5 +561,5 @@
 				       pj_timer_entry *entry )
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_cancel_timer(entry=%p)", entry));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_cancel_timer(entry=%p)", entry));
     pj_timer_heap_cancel( endpt->timer_heap, entry );
 }
@@ -564,10 +570,12 @@
  * register it to the hash table.
  */
-PJ_DEF(pjsip_transaction*) pjsip_endpt_create_tsx(pjsip_endpoint *endpt)
+PJ_DEF(pj_status_t) pjsip_endpt_create_tsx(pjsip_endpoint *endpt,
+					   pjsip_transaction **p_tsx)
 {
     pj_pool_t *pool;
-    pjsip_transaction *tsx;
-
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_create_tsx()"));
+
+    PJ_ASSERT_RETURN(endpt && p_tsx, PJ_EINVAL);
+
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_tsx()"));
 
     /* Request one pool for the transaction. Mutex is locked there. */
@@ -575,13 +583,9 @@
 				      PJSIP_POOL_LEN_TSX, PJSIP_POOL_INC_TSX);
     if (pool == NULL) {
-	PJ_LOG(2, (LOG_THIS, "failed to create transaction (no pool)"));
-	return NULL;
+	return PJ_ENOMEM;
     }
 
     /* Create the transaction. */
-    tsx = pjsip_tsx_create(pool, endpt);
-
-    /* Return */
-    return tsx;
+    return pjsip_tsx_create(pool, endpt, p_tsx);
 }
 
@@ -595,5 +599,5 @@
 				       pjsip_transaction *tsx)
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_register_tsx(%s)", tsx->obj_name));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_register_tsx(%s)", tsx->obj_name));
 
     pj_assert(tsx->transaction_key.slen != 0);
@@ -619,5 +623,5 @@
     pjsip_transaction *tsx;
 
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_find_tsx()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_find_tsx()"));
 
     /* Start lock mutex in the endpoint. */
@@ -659,5 +663,5 @@
     pj_bool_t a_new_transaction_just_been_created = PJ_FALSE;
 
-    PJ_LOG(5, (LOG_THIS, "endpt_transport_callback(rdata=%p)", rdata));
+    PJ_LOG(5, (THIS_FILE, "endpt_transport_callback(rdata=%p)", rdata));
 
     /* For response, check that the value in Via sent-by match the transport.
@@ -676,8 +680,8 @@
 	}
 	addr = pjsip_transport_get_addr_name(rdata->transport);
-	addr_addr = pj_sockaddr_get_str_addr(addr);
+	addr_addr = pj_inet_ntoa(addr->sin_addr);
 	if (pj_strcmp2(&rdata->via->sent_by.host, addr_addr) != 0)
 	    mismatch = PJ_TRUE;
-	else if (port != pj_sockaddr_get_port(addr)) {
+	else if (port != pj_ntohs(addr->sin_port)) {
 	    /* Port or address mismatch, we should discard response */
 	    /* But we saw one implementation (we don't want to name it to 
@@ -687,8 +691,8 @@
 	     * both the port in sent-by and rport. We try to be lenient here!
 	     */
-	    if (rdata->via->rport_param != pj_sockaddr_get_port(addr))
+	    if (rdata->via->rport_param != pj_sockaddr_in_get_port(addr))
 		mismatch = PJ_TRUE;
 	    else {
-		PJ_LOG(4,(LOG_THIS, "Response %p has mismatch port in sent-by"
+		PJ_LOG(4,(THIS_FILE, "Response %p has mismatch port in sent-by"
 				    " but the rport parameter is correct",
 				    rdata));
@@ -699,11 +703,5 @@
 	    pjsip_event e;
 
-	    PJ_LOG(3, (LOG_THIS, "Response %p discarded: sent-by mismatch",
-				 rdata));
-
-	    e.type = PJSIP_EVENT_DISCARD_MSG;
-	    e.src_type = PJSIP_EVENT_RX_MSG;
-	    e.src.rdata = rdata;
-	    e.obj.ptr = NULL;
+	    PJSIP_EVENT_INIT_DISCARD_MSG(e, rdata, PJSIP_EINVALIDVIA);
 	    endpt_do_event( endpt, &e );
 	    return;
@@ -715,5 +713,5 @@
 
     /* Find the transaction for the received message. */
-    PJ_LOG(5, (LOG_THIS, "finding tsx with key=%.*s", 
+    PJ_LOG(5, (THIS_FILE, "finding tsx with key=%.*s", 
 			 rdata->key.slen, rdata->key.ptr));
 
@@ -748,8 +746,5 @@
 		pj_assert(0);
 
-		e.type = PJSIP_EVENT_RX_200_RESPONSE;
-		e.src_type = PJSIP_EVENT_RX_MSG;
-		e.src.rdata = rdata;
-		e.obj.ptr = NULL;
+		PJSIP_EVENT_INIT_RX_200_MSG(e, rdata);
 		endpt_do_event( endpt, &e );
 
@@ -758,11 +753,6 @@
 		pjsip_event e;
 
-		PJ_LOG(3, (LOG_THIS, "Response %p discarded: transaction not found",
-			   rdata));
-
-		e.type = PJSIP_EVENT_DISCARD_MSG;
-		e.src_type = PJSIP_EVENT_RX_MSG;
-		e.src.rdata = rdata;
-		e.obj.ptr = NULL;
+		PJSIP_EVENT_INIT_DISCARD_MSG(e, rdata, 
+		    PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_CALL_TSX_DOES_NOT_EXIST));
 		endpt_do_event( endpt, &e );
 	    }
@@ -772,8 +762,14 @@
 	 */
 	} else if (rdata->msg->line.req.method.id != PJSIP_ACK_METHOD) {
+
+	    pj_status_t status;
+
 	    /* Create transaction, mutex is locked there. */
-	    tsx = pjsip_endpt_create_tsx(endpt);
-	    if (!tsx)
+	    status = pjsip_endpt_create_tsx(endpt, &tsx);
+	    if (status != PJ_SUCCESS) {
+		PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status,
+				       "Unable to create transaction"));
 		return;
+	    }
 
 	    /* Initialize transaction as UAS. */
@@ -803,8 +799,5 @@
 	pjsip_event event;
 
-	event.type = PJSIP_EVENT_RX_ACK_MSG;
-	event.src_type = PJSIP_EVENT_RX_MSG;
-	event.src.rdata = rdata;
-	event.obj.ptr = NULL;
+	PJSIP_EVENT_INIT_RX_ACK_MSG(event,rdata);
 	endpt_do_event( endpt, &event );
     }
@@ -835,11 +828,21 @@
 	     */
 	    pjsip_tx_data *tdata;
+	    pj_status_t status;
 	    
 	    if (tsx->method.id == PJSIP_OPTIONS_METHOD) {
-		tdata = pjsip_endpt_create_response(endpt, rdata, 200);
+		status = pjsip_endpt_create_response(endpt, rdata, 200, 
+						     &tdata);
 	    } else {
-		tdata = pjsip_endpt_create_response(endpt, rdata, 
-						    PJSIP_SC_METHOD_NOT_ALLOWED);
-	    }
+		status = pjsip_endpt_create_response(endpt, rdata, 
+						     PJSIP_SC_METHOD_NOT_ALLOWED,
+						     &tdata);
+	    }
+
+	    if (status != PJ_SUCCESS) {
+		PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status,
+				       "Unable to create response"));
+		return;
+	    }
+
 	    if (endpt->allow_hdr) {
 		pjsip_msg_add_hdr( tdata->msg, 
@@ -856,5 +859,13 @@
 	     */
 	    pjsip_tx_data *tdata;
-	    tdata = pjsip_endpt_create_response(endpt, rdata, 500);
+	    pj_status_t status;
+
+	    status = pjsip_endpt_create_response(endpt, rdata, 500, &tdata);
+	    if (status != PJ_SUCCESS) {
+		PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status,
+				       "Unable to create response"));
+		return;
+	    }
+
 	    pjsip_tsx_on_tx_msg(tsx, tdata);
 	}
@@ -865,8 +876,9 @@
  * Create transmit data buffer.
  */
-PJ_DEF(pjsip_tx_data*) pjsip_endpt_create_tdata( pjsip_endpoint *endpt )
-{
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_create_tdata()"));
-    return pjsip_tx_data_create(endpt->transport_mgr);
+PJ_DEF(pj_status_t) pjsip_endpt_create_tdata(  pjsip_endpoint *endpt,
+					       pjsip_tx_data **p_tdata)
+{
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_tdata()"));
+    return pjsip_tx_data_create(endpt->transport_mgr, p_tdata);
 }
 
@@ -880,5 +892,5 @@
 				  pjsip_resolver_callback *cb)
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_resolve()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_resolve()"));
     pjsip_resolve( endpt->resolver, pool, target, token, cb);
 }
@@ -894,5 +906,5 @@
 					pjsip_transport_completion_callback *cb)
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_get_transport()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_get_transport()"));
     pjsip_transport_get( endpt->transport_mgr, pool, type,
 			 remote, token, cb);
@@ -905,5 +917,5 @@
 						 const pj_sockaddr_in *addr_name)
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_create_listener()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_listener()"));
     return pjsip_create_listener( endpt->transport_mgr, type, addr, addr_name );
 }
@@ -913,5 +925,5 @@
 						     const pj_sockaddr_in *addr_name)
 {
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_create_udp_listener()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_udp_listener()"));
     return pjsip_create_udp_listener( endpt->transport_mgr, sock, addr_name );
 }
@@ -924,10 +936,10 @@
     pj_hash_iterator_t *itr;
 
-    PJ_LOG(5, (LOG_THIS, "pjsip_endpt_dump()"));
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_dump()"));
 
     /* Lock mutex. */
     pj_mutex_lock(endpt->mutex);
 
-    PJ_LOG(3, (LOG_THIS, "Dumping endpoint %p:", endpt));
+    PJ_LOG(3, (THIS_FILE, "Dumping endpoint %p:", endpt));
     
     /* Dumping pool factory. */
@@ -935,5 +947,5 @@
 
     /* Pool health. */
-    PJ_LOG(3, (LOG_THIS," Endpoint pool capacity=%u, used_size=%u",
+    PJ_LOG(3, (THIS_FILE," Endpoint pool capacity=%u, used_size=%u",
 	       pj_pool_get_capacity(endpt->pool),
 	       pj_pool_get_used_size(endpt->pool)));
@@ -941,5 +953,5 @@
     /* Transaction tables. */
     count = pj_hash_count(endpt->tsx_table);
-    PJ_LOG(3, (LOG_THIS, " Number of transactions: %u", count));
+    PJ_LOG(3, (THIS_FILE, " Number of transactions: %u", count));
 
     if (count && detail) {
@@ -948,5 +960,5 @@
 	pj_time_val now;
 
-	PJ_LOG(3, (LOG_THIS, " Dumping transaction tables:"));
+	PJ_LOG(3, (THIS_FILE, " Dumping transaction tables:"));
 
 	pj_gettimeofday(&now);
@@ -975,5 +987,5 @@
 	    }
 
-	    PJ_LOG(3, (LOG_THIS, "  %s %s %10.*s %.9u %s t=%ds", 
+	    PJ_LOG(3, (THIS_FILE, "  %s %s %10.*s %.9u %s t=%ds", 
 		       tsx->obj_name, role, 
 		       tsx->method.name.slen, tsx->method.name.ptr,
@@ -992,5 +1004,5 @@
     itr = pjsip_transport_first( endpt->transport_mgr, &itr_val );
     if (itr) {
-	PJ_LOG(3, (LOG_THIS, " Dumping transports:"));
+	PJ_LOG(3, (THIS_FILE, " Dumping transports:"));
 
 	do {
@@ -1002,12 +1014,12 @@
 	    t = pjsip_transport_this(endpt->transport_mgr, itr);
 	    addr = pjsip_transport_get_local_addr(t);
-	    strcpy(src_addr, pj_sockaddr_get_str_addr(addr));
-	    src_port = pj_sockaddr_get_port(addr);
+	    pj_native_strcpy(src_addr, pj_inet_ntoa(addr->sin_addr));
+	    src_port = pj_ntohs(addr->sin_port);
 
 	    addr = pjsip_transport_get_remote_addr(t);
-	    strcpy(dst_addr, pj_sockaddr_get_str_addr(addr));
-	    dst_port = pj_sockaddr_get_port(addr);
-
-	    PJ_LOG(3, (LOG_THIS, "  %s %s %s:%d --> %s:%d (refcnt=%d)", 
+	    pj_native_strcpy(dst_addr, pj_inet_ntoa(addr->sin_addr));
+	    dst_port = pj_ntohs(addr->sin_port);
+
+	    PJ_LOG(3, (THIS_FILE, "  %s %s %s:%d --> %s:%d (refcnt=%d)", 
 		       pjsip_transport_get_type_name(t),
 		       pjsip_transport_get_obj_name(t),
@@ -1021,5 +1033,5 @@
 
     /* Timer. */
-    PJ_LOG(3,(LOG_THIS, " Timer heap has %u entries", 
+    PJ_LOG(3,(THIS_FILE, " Timer heap has %u entries", 
 			pj_timer_heap_count(endpt->timer_heap)));
 
@@ -1027,5 +1039,5 @@
     pj_mutex_unlock(endpt->mutex);
 #else
-    PJ_LOG(3,(LOG_THIS, "pjsip_end_dump: can't dump because it's disabled."));
+    PJ_LOG(3,(THIS_FILE, "pjsip_end_dump: can't dump because it's disabled."));
 #endif
 }
Index: /pjproject/main/pjsip/src/pjsip/sip_misc.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_misc.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_misc.c	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_misc.h>
@@ -14,6 +13,9 @@
 #include <pj/pool.h>
 #include <pj/except.h>
-
-#define LOG_THIS    "endpoint..."
+#include <pj/rand.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+
+#define THIS_FILE    "endpoint"
 
 static const char *event_str[] = 
@@ -45,6 +47,6 @@
 				 struct pjsip_module *mod, pj_uint32_t id )
 {
-    PJ_UNUSED_ARG(endpt)
-    PJ_UNUSED_ARG(mod)
+    PJ_UNUSED_ARG(endpt);
+    PJ_UNUSED_ARG(mod);
 
     aux_mod_id = id;
@@ -54,11 +56,14 @@
 static void aux_tsx_handler( struct pjsip_module *mod, pjsip_event *event )
 {
-    pjsip_transaction *tsx = event->obj.tsx;
+    pjsip_transaction *tsx;
     struct aux_tsx_data *tsx_data;
 
-    PJ_UNUSED_ARG(mod)
-
-    if (event->type != PJSIP_EVENT_TSX_STATE_CHANGED)
+    PJ_UNUSED_ARG(mod);
+
+    if (event->type != PJSIP_EVENT_TSX_STATE)
 	return;
+
+    pj_assert(event->body.tsx_state.tsx != NULL);
+    tsx = event->body.tsx_state.tsx;
     if (tsx == NULL)
 	return;
@@ -101,6 +106,7 @@
     pjsip_transaction *tsx;
     struct aux_tsx_data *tsx_data;
-
-    tsx = pjsip_endpt_create_tsx(endpt);
+    pj_status_t status;
+
+    status = pjsip_endpt_create_tsx(endpt, &tsx);
     if (!tsx) {
 	pjsip_tx_data_dec_ref(tdata);
@@ -135,5 +141,6 @@
  * this function.
  */
-static void init_request_throw( pjsip_tx_data *tdata, 
+static void init_request_throw( pjsip_endpoint *endpt,
+                                pjsip_tx_data *tdata, 
 				pjsip_method *method,
 				pjsip_uri *param_target,
@@ -147,4 +154,5 @@
     pjsip_msg *msg;
     pjsip_msg_body *body;
+    const pjsip_hdr *endpt_hdr;
 
     /* Create the message. */
@@ -154,4 +162,12 @@
     pj_memcpy(&msg->line.req.method, method, sizeof(*method));
     msg->line.req.uri = param_target;
+
+    /* Add additional request headers from endpoint. */
+    endpt_hdr = pjsip_endpt_get_request_headers(endpt)->next;
+    while (endpt_hdr != pjsip_endpt_get_request_headers(endpt)) {
+	pjsip_hdr *hdr = pjsip_hdr_shallow_clone(tdata->pool, endpt_hdr);
+	pjsip_msg_add_hdr( tdata->msg, hdr );
+	endpt_hdr = endpt_hdr->next;
+    }
 
     /* Add From header. */
@@ -190,13 +206,14 @@
  * Create arbitrary request.
  */
-PJ_DEF(pjsip_tx_data*) pjsip_endpt_create_request(  pjsip_endpoint *endpt, 
-						    const pjsip_method *method,
-						    const pj_str_t *param_target,
-						    const pj_str_t *param_from,
-						    const pj_str_t *param_to, 
-						    const pj_str_t *param_contact,
-						    const pj_str_t *param_call_id,
-						    int param_cseq, 
-						    const pj_str_t *param_text)
+PJ_DEF(pj_status_t) pjsip_endpt_create_request(  pjsip_endpoint *endpt, 
+						 const pjsip_method *method,
+						 const pj_str_t *param_target,
+						 const pj_str_t *param_from,
+						 const pj_str_t *param_to, 
+						 const pj_str_t *param_contact,
+						 const pj_str_t *param_call_id,
+						 int param_cseq, 
+						 const pj_str_t *param_text,
+						 pjsip_tx_data **p_tdata)
 {
     pjsip_uri *target;
@@ -208,11 +225,12 @@
     pjsip_cid_hdr *call_id;
     pj_str_t tmp;
+    pj_status_t status;
     PJ_USE_EXCEPTION;
 
-    PJ_LOG(5,(LOG_THIS, "Entering pjsip_endpt_create_request()"));
-
-    tdata = pjsip_endpt_create_tdata(endpt);
-    if (!tdata)
-	return NULL;
+    PJ_LOG(5,(THIS_FILE, "Entering pjsip_endpt_create_request()"));
+
+    status = pjsip_endpt_create_tdata(endpt, &tdata);
+    if (status != PJ_SUCCESS)
+	return status;
 
     /* Init reference counter to 1. */
@@ -224,5 +242,5 @@
 	target = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, 0);
 	if (target == NULL) {
-	    PJ_LOG(4,(LOG_THIS, "Error creating request: invalid target %s", 
+	    PJ_LOG(4,(THIS_FILE, "Error creating request: invalid target %s", 
 		      tmp.ptr));
 	    goto on_error;
@@ -235,5 +253,5 @@
 				     PJSIP_PARSE_URI_AS_NAMEADDR);
 	if (from->uri == NULL) {
-	    PJ_LOG(4,(LOG_THIS, "Error creating request: invalid 'From' URI '%s'",
+	    PJ_LOG(4,(THIS_FILE, "Error creating request: invalid 'From' URI '%s'",
 				tmp.ptr));
 	    goto on_error;
@@ -247,5 +265,5 @@
 				   PJSIP_PARSE_URI_AS_NAMEADDR);
 	if (to->uri == NULL) {
-	    PJ_LOG(4,(LOG_THIS, "Error creating request: invalid 'To' URI '%s'",
+	    PJ_LOG(4,(THIS_FILE, "Error creating request: invalid 'To' URI '%s'",
 				tmp.ptr));
 	    goto on_error;
@@ -259,5 +277,5 @@
 					    PJSIP_PARSE_URI_AS_NAMEADDR);
 	    if (contact->uri == NULL) {
-		PJ_LOG(4,(LOG_THIS, 
+		PJ_LOG(4,(THIS_FILE, 
 			  "Error creating request: invalid 'Contact' URI '%s'",
 			  tmp.ptr));
@@ -286,15 +304,14 @@
 
 	/* Create the request. */
-	init_request_throw( tdata, &cseq->method, target, from, to, contact, 
-			    call_id, cseq, param_text);
+	init_request_throw( endpt, tdata, &cseq->method, target, from, to, 
+                            contact, call_id, cseq, param_text);
     }
     PJ_DEFAULT {
-	PJ_LOG(4,(LOG_THIS, "Caught exception %d when creating request", 
-			    PJ_GET_EXCEPTION()));
+	status = PJ_ENOMEM;
 	goto on_error;
     }
     PJ_END
 
-    PJ_LOG(4,(LOG_THIS, "Request %s (%d %.*s) created.", 
+    PJ_LOG(4,(THIS_FILE, "Request %s (%d %.*s) created.", 
 		        tdata->obj_name, 
 			cseq->cseq, 
@@ -302,12 +319,13 @@
 			cseq->method.name.ptr));
 
-    return tdata;
+    *p_tdata = tdata;
+    return PJ_SUCCESS;
 
 on_error:
     pjsip_tx_data_dec_ref(tdata);
-    return NULL;
-}
-
-PJ_DEF(pjsip_tx_data*)
+    return status;
+}
+
+PJ_DEF(pj_status_t)
 pjsip_endpt_create_request_from_hdr( pjsip_endpoint *endpt,
 				     const pjsip_method *method,
@@ -318,5 +336,6 @@
 				     const pjsip_cid_hdr *param_call_id,
 				     int param_cseq,
-				     const pj_str_t *param_text )
+				     const pj_str_t *param_text,
+				     pjsip_tx_data **p_tdata)
 {
     pjsip_uri *target;
@@ -327,11 +346,12 @@
     pjsip_cid_hdr *call_id;
     pjsip_cseq_hdr *cseq = NULL; /* The NULL because warning in VC6 */
+    pj_status_t status;
     PJ_USE_EXCEPTION;
 
-    PJ_LOG(5,(LOG_THIS, "Entering pjsip_endpt_create_request_from_hdr()"));
-
-    tdata = pjsip_endpt_create_tdata(endpt);
-    if (!tdata)
-	return NULL;
+    PJ_LOG(5,(THIS_FILE, "Entering pjsip_endpt_create_request_from_hdr()"));
+
+    status = pjsip_endpt_create_tdata(endpt, &tdata);
+    if (status != PJ_SUCCESS)
+	return status;
 
     pjsip_tx_data_add_ref(tdata);
@@ -355,24 +375,25 @@
 	pjsip_method_copy(tdata->pool, &cseq->method, method);
 
-	init_request_throw(tdata, &cseq->method, target, from, to, contact, 
-			   call_id, cseq, param_text);
+	init_request_throw(endpt, tdata, &cseq->method, target, from, to, 
+                           contact, call_id, cseq, param_text);
     }
     PJ_DEFAULT {
-	PJ_LOG(4,(LOG_THIS, "Caught exception %d when creating request", 
-			    PJ_GET_EXCEPTION()));
+	status = PJ_ENOMEM;
 	goto on_error;
     }
     PJ_END;
 
-    PJ_LOG(4,(LOG_THIS, "Request %s (%d %.*s) created.", 
+    PJ_LOG(4,(THIS_FILE, "Request %s (%d %.*s) created.", 
 			tdata->obj_name, 
 			cseq->cseq, 
 			cseq->method.name.slen,
 			cseq->method.name.ptr));
-    return tdata;
+
+    *p_tdata = tdata;
+    return PJ_SUCCESS;
 
 on_error:
     pjsip_tx_data_dec_ref(tdata);
-    return NULL;
+    return status;
 }
 
@@ -380,7 +401,8 @@
  * Construct a minimal response message for the received request.
  */
-PJ_DEF(pjsip_tx_data*) pjsip_endpt_create_response( pjsip_endpoint *endpt,
-						    const pjsip_rx_data *rdata,
-						    int code)
+PJ_DEF(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt,
+						 const pjsip_rx_data *rdata,
+						 int code,
+						 pjsip_tx_data **p_tdata)
 {
     pjsip_tx_data *tdata;
@@ -389,4 +411,5 @@
     pjsip_via_hdr *via;
     pjsip_rr_hdr *rr;
+    pj_status_t status;
 
     /* rdata must be a request message. */
@@ -395,11 +418,11 @@
 
     /* Log this action. */
-    PJ_LOG(5,(LOG_THIS, "pjsip_endpt_create_response(rdata=%p, code=%d)", 
+    PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_response(rdata=%p, code=%d)", 
 		         rdata, code));
 
     /* Create a new transmit buffer. */
-    tdata = pjsip_endpt_create_tdata( endpt );
-    if (!tdata)
-	return NULL;
+    status = pjsip_endpt_create_tdata( endpt, &tdata);
+    if (status != PJ_SUCCESS)
+	return status;
 
     /* Create new response message. */
@@ -452,5 +475,6 @@
 
     /* All done. */
-    return tdata;
+    *p_tdata = tdata;
+    return PJ_SUCCESS;
 }
 
@@ -479,5 +503,5 @@
 
     /* Log this action. */
-    PJ_LOG(5,(LOG_THIS, "pjsip_endpt_create_ack(rdata=%p)", rdata));
+    PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_ack(rdata=%p)", rdata));
 
     /* Create new request message. */
@@ -503,5 +527,5 @@
     to = (pjsip_to_hdr*)pjsip_msg_find_remove_hdr( invite_msg, 
 						   PJSIP_H_TO, NULL);
-    pj_strdup(tdata->pool, &to->tag, &rdata->to_tag);
+    pj_strdup(tdata->pool, &to->tag, &rdata->to->tag);
     pjsip_msg_add_hdr( ack_msg, (pjsip_hdr*)to );
 
@@ -543,6 +567,7 @@
  * chapter 9.1 of RFC3261.
  */
-PJ_DEF(pjsip_tx_data*) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
-						  pjsip_tx_data *req_tdata )
+PJ_DEF(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
+					       pjsip_tx_data *req_tdata,
+					       pjsip_tx_data **p_tdata)
 {
     pjsip_msg *req_msg;	/* the original request. */
@@ -552,7 +577,8 @@
     pjsip_cseq_hdr *req_cseq, *cseq;
     pjsip_uri *req_uri;
+    pj_status_t status;
 
     /* Log this action. */
-    PJ_LOG(5,(LOG_THIS, "pjsip_endpt_create_cancel(tdata=%p)", req_tdata));
+    PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_cancel(tdata=%p)", req_tdata));
 
     /* Get the original request. */
@@ -560,11 +586,12 @@
 
     /* The transmit buffer must INVITE request. */
-    pj_assert(req_msg->type == PJSIP_REQUEST_MSG &&
-	      req_msg->line.req.method.id == PJSIP_INVITE_METHOD );
+    PJ_ASSERT_RETURN(req_msg->type == PJSIP_REQUEST_MSG &&
+		     req_msg->line.req.method.id == PJSIP_INVITE_METHOD,
+		     PJ_EINVAL);
 
     /* Create new transmit buffer. */
-    cancel_tdata = pjsip_endpt_create_tdata( endpt );
-    if (!cancel_tdata) {
-	return NULL;
+    status = pjsip_endpt_create_tdata( endpt, &cancel_tdata);
+    if (status != PJ_SUCCESS) {
+	return status;
     }
 
@@ -624,5 +651,6 @@
      * Return the transmit buffer containing the CANCEL request.
      */
-    return cancel_tdata;
+    *p_tdata = cancel_tdata;
+    return PJ_SUCCESS;
 }
 
@@ -651,6 +679,6 @@
 	remote_addr = pjsip_transport_get_remote_addr(req_transport);
 	pj_strdup2(pool, &send_addr->host, 
-		   pj_sockaddr_get_str_addr(remote_addr));
-	send_addr->port = pj_sockaddr_get_port(remote_addr);
+		   pj_inet_ntoa(remote_addr->sin_addr));
+	send_addr->port = pj_sockaddr_in_get_port(remote_addr);
 
     } else {
Index: /pjproject/main/pjsip/src/pjsip/sip_msg.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_msg.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_msg.c	(revision 43)
@@ -1,7 +1,6 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_msg.h>
-#include <pjsip/print.h>
+#include <pjsip/print_util.h>
 #include <pj/string.h>
 #include <pj/pool.h>
@@ -265,5 +264,5 @@
 }
 
-PJ_DEF(int) pjsip_msg_print( pjsip_msg *msg, char *buf, pj_size_t size)
+PJ_DEF(pj_ssize_t) pjsip_msg_print( pjsip_msg *msg, char *buf, pj_size_t size)
 {
     char *p=buf, *end=buf+size;
Index: /pjproject/main/pjsip/src/pjsip/sip_parser.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_parser.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_parser.c	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_parser.h>
@@ -6,5 +5,7 @@
 #include <pjsip/sip_msg.h>
 #include <pjsip/sip_auth_parser.h>
-#include <pj/scanner.h>
+#include <pjsip/sip_errno.h>
+#include <pjsip/sip_transport.h>        /* rdata structure */
+#include <pjlib-util/scanner.h>
 #include <pj/except.h>
 #include <pj/log.h>
@@ -13,5 +14,6 @@
 #include <pj/pool.h>
 #include <pj/string.h>
-#include <ctype.h>	/* tolower() */
+#include <pj/ctype.h>
+#include <pj/assert.h>
 
 #define RESERVED    ";/?:@&=+$,"
@@ -20,5 +22,6 @@
 #define USER	    "&=+$,;?/"
 #define PASS	    "&=+$,"
-#define TOKEN	    "-.!%*_=`'~+"   /* '+' is because of application/pidf+xml in Content-Type! */
+#define TOKEN	    "-.!%*_=`'~+"   /* '+' is because of application/pidf+xml
+                                     * in Content-Type! */
 #define HOST	    "_-."
 #define HEX_DIGIT   "abcdefABCDEF"
@@ -46,33 +49,39 @@
  * Global vars (also extern).
  */
-const pj_str_t  pjsip_USER_STR = { "user", 4};
-const pj_str_t  pjsip_METHOD_STR = { "method", 6};
+const pj_str_t  pjsip_USER_STR      = { "user", 4};
+const pj_str_t  pjsip_METHOD_STR    = { "method", 6};
 const pj_str_t  pjsip_TRANSPORT_STR = { "transport", 9};
-const pj_str_t  pjsip_MADDR_STR = { "maddr", 5 };
-const pj_str_t  pjsip_LR_STR = { "lr", 2 };
-const pj_str_t  pjsip_SIP_STR = { "sip", 3 };
-const pj_str_t  pjsip_SIPS_STR = { "sips", 4 };
-const pj_str_t  pjsip_TEL_STR = { "tel", 3 };
-const pj_str_t  pjsip_BRANCH_STR = { "branch", 6 };
-const pj_str_t  pjsip_TTL_STR = { "ttl", 3 };
-const pj_str_t  pjsip_PNAME_STR = { "received", 8 };
-const pj_str_t  pjsip_Q_STR = { "q", 1 };
-const pj_str_t  pjsip_EXPIRES_STR = { "expires", 7 };
-const pj_str_t  pjsip_TAG_STR = { "tag", 3 };
-const pj_str_t  pjsip_RPORT_STR = { "rport", 5};
-
-pj_char_spec	pjsip_HOST_SPEC,	    /* For scanning host part. */
-		pjsip_DIGIT_SPEC,	    /* Decimal digits */
-		pjsip_ALPHA_SPEC,	    /* Alpha (A-Z, a-z) */
-		pjsip_ALNUM_SPEC,	    /* Decimal + Alpha. */
-		pjsip_TOKEN_SPEC,	    /* Token. */
-		pjsip_HEX_SPEC,		    /* Hexadecimal digits. */
-		pjsip_PARAM_CHAR_SPEC,	    /* For scanning pname (or pvalue when it's not quoted.) */
-		pjsip_PROBE_USER_HOST_SPEC, /* Hostname characters. */
-		pjsip_PASSWD_SPEC,	    /* Password. */
-		pjsip_USER_SPEC,	    /* User */
-		pjsip_ARRAY_ELEMENTS,	    /* Array separator. */
-		pjsip_NEWLINE_OR_EOF_SPEC,  /* For eating up header.*/
-		pjsip_DISPLAY_SCAN_SPEC;    /* Used when searching for display name in URL. */
+const pj_str_t  pjsip_MADDR_STR     = { "maddr", 5 };
+const pj_str_t  pjsip_LR_STR        = { "lr", 2 };
+const pj_str_t  pjsip_SIP_STR       = { "sip", 3 };
+const pj_str_t  pjsip_SIPS_STR      = { "sips", 4 };
+const pj_str_t  pjsip_TEL_STR       = { "tel", 3 };
+const pj_str_t  pjsip_BRANCH_STR    = { "branch", 6 };
+const pj_str_t  pjsip_TTL_STR       = { "ttl", 3 };
+const pj_str_t  pjsip_PNAME_STR     = { "received", 8 };
+const pj_str_t  pjsip_Q_STR         = { "q", 1 };
+const pj_str_t  pjsip_EXPIRES_STR   = { "expires", 7 };
+const pj_str_t  pjsip_TAG_STR       = { "tag", 3 };
+const pj_str_t  pjsip_RPORT_STR     = { "rport", 5};
+
+/* Character Input Specification buffer. */
+static pj_cis_buf_t cis_buf;
+
+/* Character Input Specifications. */
+pj_cis_t    pjsip_HOST_SPEC,	        /* For scanning host part. */
+	    pjsip_DIGIT_SPEC,	        /* Decimal digits */
+	    pjsip_ALPHA_SPEC,	        /* Alpha (A-Z, a-z) */
+	    pjsip_ALNUM_SPEC,	        /* Decimal + Alpha. */
+	    pjsip_TOKEN_SPEC,	        /* Token. */
+	    pjsip_HEX_SPEC,	        /* Hexadecimal digits. */
+	    pjsip_PARAM_CHAR_SPEC,      /* For scanning pname (or pvalue when
+                                         * it's not quoted.) */
+	    pjsip_PROBE_USER_HOST_SPEC, /* Hostname characters. */
+	    pjsip_PASSWD_SPEC,	        /* Password. */
+	    pjsip_USER_SPEC,	        /* User */
+	    pjsip_ARRAY_ELEMENTS,       /* Array separator. */
+	    pjsip_NEWLINE_OR_EOF_SPEC,  /* For eating up header.*/
+	    pjsip_DISPLAY_SCAN_SPEC;    /* Used when searching for display name
+                                         * in URL. */
 
 
@@ -80,73 +89,56 @@
  * Forward decl.
  */
-static pjsip_msg *	  int_parse_msg( pj_scanner *scanner, 
-					 pj_pool_t *pool, 
-					 pjsip_parser_err_report *err_list);
-static void		  int_parse_param( pj_scanner *scanner, 
-					   pj_str_t *pname, 
-					   pj_str_t *pvalue);
-static void		  int_parse_req_line( pj_scanner *scanner, 
-					      pj_pool_t *pool,
-					      pjsip_request_line *req_line);
-static int		  int_is_next_user( pj_scanner *scanner);
-static void		  int_parse_status_line( pj_scanner *scanner, 
-						 pjsip_status_line *line);
-static void		  int_parse_user_pass( pj_scanner *scanner, 
-					       pj_str_t *user, 
-					       pj_str_t *pass);
-static void		  int_parse_uri_host_port( pj_scanner *scanner, 
-						   pj_str_t *p_host, 
-						   int *p_port);
-static pjsip_uri *	  int_parse_uri_or_name_addr( pj_scanner *scanner, 
-					    pj_pool_t *pool, unsigned option);
-static pjsip_url *	  int_parse_sip_url( pj_scanner *scanner, 
-					     pj_pool_t *pool,
-					     pj_bool_t parse_params);
-static pjsip_name_addr*	  int_parse_name_addr( pj_scanner *scanner, 
-					       pj_pool_t *pool );
-static void		  parse_hdr_end( pj_scanner *scanner );
-static pjsip_accept_hdr*  parse_hdr_accept( pj_scanner *scanner, 
-					    pj_pool_t *pool);
-static pjsip_allow_hdr*   parse_hdr_allow( pj_scanner *scanner, 
-					   pj_pool_t *pool);
-static pjsip_cid_hdr*	  parse_hdr_call_id( pj_scanner *scanner, 
-					     pj_pool_t *pool);
-static pjsip_contact_hdr* parse_hdr_contact( pj_scanner *scanner, 
-					     pj_pool_t *pool);
-static pjsip_clen_hdr*    parse_hdr_content_length( pj_scanner *scanner, 
-						    pj_pool_t *pool);
-static pjsip_ctype_hdr*   parse_hdr_content_type( pj_scanner *scanner, 
-						  pj_pool_t *pool);
-static pjsip_cseq_hdr*    parse_hdr_cseq( pj_scanner *scanner, 
-					  pj_pool_t *pool);
-static pjsip_expires_hdr* parse_hdr_expires( pj_scanner *scanner, 
-					  pj_pool_t *pool);
-static pjsip_from_hdr*    parse_hdr_from( pj_scanner *scanner, 
-					  pj_pool_t *pool);
-static pjsip_max_forwards_hdr*  parse_hdr_max_forwards( pj_scanner *scanner, 
-				        pj_pool_t *pool);
-static pjsip_min_expires_hdr*  parse_hdr_min_expires( pj_scanner *scanner, 
-				        pj_pool_t *pool);
-static pjsip_rr_hdr*      parse_hdr_rr( pj_scanner *scanner, 
-				        pj_pool_t *pool);
-static pjsip_route_hdr*   parse_hdr_route( pj_scanner *scanner, 
-					   pj_pool_t *pool);
-static pjsip_require_hdr* parse_hdr_require( pj_scanner *scanner, 
-				        pj_pool_t *pool);
-static pjsip_retry_after_hdr* parse_hdr_retry_after( pj_scanner *scanner, 
-				        pj_pool_t *pool);
-static pjsip_supported_hdr* parse_hdr_supported( pj_scanner *scanner, 
-				        pj_pool_t *pool);
-static pjsip_to_hdr*	  parse_hdr_to( pj_scanner *scanner, 
-				        pj_pool_t *pool);
-static pjsip_unsupported_hdr* parse_hdr_unsupported( pj_scanner *scanner, 
-				        pj_pool_t *pool);
-static pjsip_via_hdr*	  parse_hdr_via( pj_scanner *scanner, 
-					 pj_pool_t *pool);
-static pjsip_generic_string_hdr* parse_hdr_generic_string( pj_scanner *scanner, 
-					     pj_pool_t *pool);
+static pjsip_msg *  int_parse_msg( pjsip_parse_ctx *ctx, 
+				   pjsip_parser_err_report *err_list);
+static void	    int_parse_param( pj_scanner *scanner, 
+				     pj_str_t *pname, 
+				     pj_str_t *pvalue);
+static void         int_parse_req_line( pj_scanner *scanner, 
+					pj_pool_t *pool,
+					pjsip_request_line *req_line);
+static int          int_is_next_user( pj_scanner *scanner);
+static void	    int_parse_status_line( pj_scanner *scanner, 
+					   pjsip_status_line *line);
+static void	    int_parse_user_pass( pj_scanner *scanner, 
+					 pj_str_t *user, 
+					 pj_str_t *pass);
+static void	    int_parse_uri_host_port( pj_scanner *scanner, 
+					     pj_str_t *p_host, 
+					     int *p_port);
+static pjsip_uri *  int_parse_uri_or_name_addr( pj_scanner *scanner, 
+					        pj_pool_t *pool, 
+                                                unsigned option);
+static pjsip_url *  int_parse_sip_url( pj_scanner *scanner, 
+				       pj_pool_t *pool,
+				       pj_bool_t parse_params);
+static pjsip_name_addr *
+                    int_parse_name_addr( pj_scanner *scanner, 
+					 pj_pool_t *pool );
+static void	    parse_hdr_end( pj_scanner *scanner );
+
+static pjsip_hdr*   parse_hdr_accept( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_allow( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_call_id( pjsip_parse_ctx *ctx);
+static pjsip_hdr*   parse_hdr_contact( pjsip_parse_ctx *ctx);
+static pjsip_hdr*   parse_hdr_content_len( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_content_type( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_cseq( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_expires( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_from( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_max_forwards( pjsip_parse_ctx *ctx);
+static pjsip_hdr*   parse_hdr_min_expires( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_rr( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_route( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_require( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_retry_after( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_supported( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_to( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_unsupported( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_via( pjsip_parse_ctx *ctx );
+static pjsip_hdr*   parse_hdr_generic_string( pjsip_parse_ctx *ctx);
 
 /* Convert non NULL terminated string to integer. */
-static unsigned long pj_strtoul_mindigit(const pj_str_t *str, unsigned mindig)
+static unsigned long pj_strtoul_mindigit(const pj_str_t *str, 
+                                         unsigned mindig)
 {
     unsigned long value;
@@ -164,12 +156,11 @@
 
 /* Case insensitive comparison */
-#define parser_stricmp(str1, str2)  \
-	    (str1.slen != str2.slen ? -1 : \
-		!(memcmp(str1.ptr, str2.ptr, str1.slen)==0 || stricmp(str1.ptr, str2.ptr)==0))
+#define parser_stricmp(str1, str2)  pj_stricmp(&str1, &str2)
+
 
 /* Syntax error handler for parser. */
 static void on_syntax_error(pj_scanner *scanner)
 {
-    PJ_UNUSED_ARG(scanner)
+    PJ_UNUSED_ARG(scanner);
     PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 }
@@ -177,5 +168,6 @@
 /* Concatenate unrecognized params into single string. */
 void pjsip_concat_param_imp( pj_str_t *param, pj_pool_t *pool, 
-			     const pj_str_t *pname, const pj_str_t *pvalue, int sepchar)
+			     const pj_str_t *pname, const pj_str_t *pvalue, 
+                             int sepchar)
 {
     char *new_param, *p;
@@ -214,73 +206,142 @@
 
 /* Initialize static properties of the parser. */
-static void init_parser()
+static pj_status_t init_parser()
 {
     static int initialized;
+    pj_status_t status;
 
     if (initialized)
-	return;
+	return PJ_SUCCESS;
 
     initialized = 1;
 
-    pj_cs_add_num( pjsip_DIGIT_SPEC );
-    pj_cs_add_alpha( pjsip_ALPHA_SPEC );
+    pj_cis_buf_init(&cis_buf);
+
+    status = pj_cis_init(&cis_buf, &pjsip_DIGIT_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_num(&pjsip_DIGIT_SPEC);
     
-    pj_cs_add_alpha( pjsip_ALNUM_SPEC );
-    pj_cs_add_num( pjsip_ALNUM_SPEC );
-
-    pj_cs_add_str(pjsip_NEWLINE_OR_EOF_SPEC, "\r\n");
+    status = pj_cis_init(&cis_buf, &pjsip_ALPHA_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_alpha( &pjsip_ALPHA_SPEC );
+    
+    status = pj_cis_init(&cis_buf, &pjsip_ALNUM_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_alpha( &pjsip_ALNUM_SPEC );
+    pj_cis_add_num( &pjsip_ALNUM_SPEC );
+
+    status = pj_cis_init(&cis_buf, &pjsip_NEWLINE_OR_EOF_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str(&pjsip_NEWLINE_OR_EOF_SPEC, "\r\n");
     //pj_cs_set(pjsip_NEWLINE_OR_EOF_SPEC, 0);
 
-    pj_cs_add_str( pjsip_ARRAY_ELEMENTS, ",\r\n");
-
-    pj_memcpy(pjsip_TOKEN_SPEC, pjsip_ALNUM_SPEC, sizeof(pj_char_spec));
-    pj_cs_add_str( pjsip_TOKEN_SPEC, TOKEN);
-
-    pj_memcpy(pjsip_HOST_SPEC, pjsip_ALNUM_SPEC, sizeof(pj_char_spec));
-    pj_cs_add_str( pjsip_HOST_SPEC, HOST);
-
-    pj_memcpy(pjsip_HEX_SPEC, pjsip_DIGIT_SPEC, sizeof(pj_char_spec));
-    pj_cs_add_str( pjsip_HEX_SPEC, HEX_DIGIT);
-
-    pj_memcpy(pjsip_PARAM_CHAR_SPEC, pjsip_ALNUM_SPEC, sizeof(pj_char_spec));
-    pj_cs_add_str( pjsip_PARAM_CHAR_SPEC, PARAM_CHAR);
-
-    pj_memcpy(pjsip_USER_SPEC, pjsip_ALNUM_SPEC, sizeof(pj_char_spec));
-    pj_cs_add_str( pjsip_USER_SPEC, MARK ESCAPED USER );
-
-    pj_memcpy(pjsip_PASSWD_SPEC, pjsip_ALNUM_SPEC, sizeof(pj_char_spec));
-    pj_cs_add_str( pjsip_PASSWD_SPEC, MARK ESCAPED PASS);
-
-    pj_cs_add_str( pjsip_PROBE_USER_HOST_SPEC, "@ \n>");
-    pj_cs_invert( pjsip_PROBE_USER_HOST_SPEC );
-
-    pj_cs_add_str( pjsip_DISPLAY_SCAN_SPEC, ":\r\n<");
-
-    pjsip_register_hdr_parser( "Accept", NULL, (pjsip_parse_hdr_func*) &parse_hdr_accept);
-    pjsip_register_hdr_parser( "Allow", NULL, (pjsip_parse_hdr_func*) &parse_hdr_allow);
-    pjsip_register_hdr_parser( "Call-ID", NULL, (pjsip_parse_hdr_func*) &parse_hdr_call_id);
-    pjsip_register_hdr_parser( "Contact", "m", (pjsip_parse_hdr_func*) &parse_hdr_contact);
-    pjsip_register_hdr_parser( "Content-Length", NULL, (pjsip_parse_hdr_func*) &parse_hdr_content_length);
-    pjsip_register_hdr_parser( "Content-Type", NULL, (pjsip_parse_hdr_func*) &parse_hdr_content_type);
-    pjsip_register_hdr_parser( "CSeq", NULL, (pjsip_parse_hdr_func*) &parse_hdr_cseq);
-    pjsip_register_hdr_parser( "Expires", NULL, (pjsip_parse_hdr_func*) &parse_hdr_expires);
-    pjsip_register_hdr_parser( "From", "f", (pjsip_parse_hdr_func*) &parse_hdr_from);
-    pjsip_register_hdr_parser( "Max-Forwards", NULL, (pjsip_parse_hdr_func*) &parse_hdr_max_forwards);
-    pjsip_register_hdr_parser( "Min-Expires", NULL, (pjsip_parse_hdr_func*) &parse_hdr_min_expires);
-    pjsip_register_hdr_parser( "Record-Route", NULL, (pjsip_parse_hdr_func*) &parse_hdr_rr);
-    pjsip_register_hdr_parser( "Route", NULL, (pjsip_parse_hdr_func*) &parse_hdr_route);
-    pjsip_register_hdr_parser( "Require", NULL, (pjsip_parse_hdr_func*) &parse_hdr_require);
-    pjsip_register_hdr_parser( "Retry-After", NULL, (pjsip_parse_hdr_func*) &parse_hdr_retry_after);
-    pjsip_register_hdr_parser( "Supported", "k", (pjsip_parse_hdr_func*) &parse_hdr_supported);
-    pjsip_register_hdr_parser( "To", "t", (pjsip_parse_hdr_func*) &parse_hdr_to);
-    pjsip_register_hdr_parser( "Unsupported", NULL, (pjsip_parse_hdr_func*) &parse_hdr_unsupported);
-    pjsip_register_hdr_parser( "Via", NULL, (pjsip_parse_hdr_func*) &parse_hdr_via);
+    status = pj_cis_init(&cis_buf, &pjsip_ARRAY_ELEMENTS);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str( &pjsip_ARRAY_ELEMENTS, ",\r\n");
+
+    status = pj_cis_dup(&pjsip_TOKEN_SPEC, &pjsip_ALNUM_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str( &pjsip_TOKEN_SPEC, TOKEN);
+
+    status = pj_cis_dup(&pjsip_HOST_SPEC, &pjsip_ALNUM_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str( &pjsip_HOST_SPEC, HOST);
+
+    status = pj_cis_dup(&pjsip_HEX_SPEC, &pjsip_DIGIT_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str( &pjsip_HEX_SPEC, HEX_DIGIT);
+
+    status = pj_cis_dup(&pjsip_PARAM_CHAR_SPEC, &pjsip_ALNUM_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str(&pjsip_PARAM_CHAR_SPEC, PARAM_CHAR);
+
+    status = pj_cis_dup(&pjsip_USER_SPEC, &pjsip_ALNUM_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str( &pjsip_USER_SPEC, MARK ESCAPED USER );
+
+    status = pj_cis_dup(&pjsip_PASSWD_SPEC, &pjsip_ALNUM_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str( &pjsip_PASSWD_SPEC, MARK ESCAPED PASS);
+
+    status = pj_cis_init(&cis_buf, &pjsip_PROBE_USER_HOST_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str( &pjsip_PROBE_USER_HOST_SPEC, "@ \n>");
+    pj_cis_invert( &pjsip_PROBE_USER_HOST_SPEC );
+
+    status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SCAN_SPEC);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+    pj_cis_add_str( &pjsip_DISPLAY_SCAN_SPEC, ":\r\n<");
+
+    status = pjsip_register_hdr_parser( "Accept", NULL, &parse_hdr_accept);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Allow", NULL, &parse_hdr_allow);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Call-ID", NULL, &parse_hdr_call_id);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Contact", "m", &parse_hdr_contact);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Content-Length", NULL, 
+                                        &parse_hdr_content_len);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Content-Type", NULL, 
+                                        &parse_hdr_content_type);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "CSeq", NULL, &parse_hdr_cseq);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Expires", NULL, &parse_hdr_expires);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "From", "f", &parse_hdr_from);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Max-Forwards", NULL, 
+                                        &parse_hdr_max_forwards);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Min-Expires", NULL, 
+                                        &parse_hdr_min_expires);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Record-Route", NULL, &parse_hdr_rr);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Route", NULL, &parse_hdr_route);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Require", NULL, &parse_hdr_require);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Retry-After", NULL, 
+                                        &parse_hdr_retry_after);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Supported", "k", 
+                                        &parse_hdr_supported);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "To", "t", &parse_hdr_to);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Unsupported", NULL, 
+                                        &parse_hdr_unsupported);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    status = pjsip_register_hdr_parser( "Via", NULL, &parse_hdr_via);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
     /* Register auth parser. */
-    pjsip_auth_init_parser();
-
-}
-
-static void init_sip_parser()
+    status = pjsip_auth_init_parser();
+
+    return status;
+}
+
+static void init_sip_parser(void)
 {
     if (!parser_is_initialized) {
@@ -318,9 +379,10 @@
 
     /* Equal length and equal hash. compare the strings. */
-    return strcmp(r1->hname, name);
+    return pj_native_strcmp(r1->hname, name);
 }
 
 /* Register one handler for one header name. */
-static int int_register_parser( const char *name, pjsip_parse_hdr_func *fptr )
+static pj_status_t int_register_parser( const char *name, 
+                                        pjsip_parse_hdr_func *fptr )
 {
     unsigned	pos;
@@ -329,5 +391,5 @@
 
     if (handler_count >= PJ_ARRAY_SIZE(handler)) {
-	return -1;
+	return PJ_ETOOMANY;
     }
 
@@ -336,9 +398,9 @@
     rec.hname_len = strlen(name);
     if (rec.hname_len >= sizeof(rec.hname)) {
-	return -1;
+	return PJ_ENAMETOOLONG;
     }
     /* Name is copied in lowercase. */
     for (i=0; i<rec.hname_len; ++i) {
-	rec.hname[i] = (char)tolower(name[i]);
+	rec.hname[i] = (char)pj_tolower(name[i]);
     }
     rec.hname[i] = '\0';
@@ -349,8 +411,9 @@
     for (pos=0; pos < handler_count; ++pos) {
 	int d;
-	d = compare_handler(&handler[pos], rec.hname, rec.hname_len, rec.hname_hash);
+	d = compare_handler(&handler[pos], rec.hname, rec.hname_len, 
+                            rec.hname_hash);
 	if (d == 0) {
 	    pj_assert(0);
-	    return -1;
+	    return PJ_EEXISTS;
 	}
 	if (d > 0) {
@@ -361,5 +424,6 @@
     /* Shift handlers. */
     if (pos != handler_count) {
-	pj_memmove( &handler[pos+1], &handler[pos], (handler_count-pos)*sizeof(handler_rec));
+	pj_memmove( &handler[pos+1], &handler[pos], 
+                    (handler_count-pos)*sizeof(handler_rec));
     }
     /* Add new handler. */
@@ -367,5 +431,5 @@
     ++handler_count;
 
-    return 0;
+    return PJ_SUCCESS;
 }
 
@@ -377,11 +441,16 @@
 					       pjsip_parse_hdr_func *fptr)
 {
-    if (int_register_parser(hname, fptr)) {
-	return -1;
-    }
-    if (hshortname && int_register_parser(hshortname, fptr)) {
-	return -1;
-    }
-    return 0;
+    pj_status_t status;
+
+    status = int_register_parser(hname, fptr);
+    if (status != PJ_SUCCESS) {
+	return status;
+    }
+    if (hshortname) {
+        status = int_register_parser(hshortname, fptr);
+        if (status != PJ_SUCCESS) 
+	    return status;
+    }
+    return PJ_SUCCESS;
 }
 
@@ -393,15 +462,16 @@
     pj_uint32_t  hash;
     int		 comp;
-    unsigned	 i, n;
+    unsigned	 n;
+
+    if (hname->slen >= PJSIP_MAX_HNAME_LEN) {
+        pj_assert(!"Header name is too long!");
+        return NULL;
+    }
 
     /* Calculate hash value while converting the header to lowercase. 
      * Don't assume that 'hname' is NULL terminated.
      */
-    hash = 0;
-    for (i=0; i<(unsigned)hname->slen; ++i) {
-	hname_copy[i] = (char)tolower(hname->ptr[i]);
-	hash = hash * PJ_HASH_MULTIPLIER + hname_copy[i];
-    }
-    hname_copy[i] = '\0';
+    hash = pj_hash_calc_tolower(0, hname_copy, hname);
+    hname_copy[hname->slen] = '\0';
 
     /* Binary search for the handler. */
@@ -429,17 +499,24 @@
 
 /* Public function to parse SIP message. */
-PJ_DEF(pjsip_msg*) pjsip_parse_msg( pj_pool_t *pool, char *buf, pj_size_t size,
+PJ_DEF(pjsip_msg*) pjsip_parse_msg( pj_pool_t *pool, 
+                                    char *buf, pj_size_t size,
 				    pjsip_parser_err_report *err_list)
 {
     pjsip_msg *msg = NULL;
     pj_scanner scanner;
+    pjsip_parse_ctx context;
     PJ_USE_EXCEPTION;
 
     init_sip_parser();
 
-    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, &on_syntax_error);
+    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, 
+                 &on_syntax_error);
+
+    context.scanner = &scanner;
+    context.pool = pool;
+    context.rdata = NULL;
 
     PJ_TRY {
-	msg = int_parse_msg(&scanner, pool, err_list);
+	msg = int_parse_msg(&context, err_list);
     } 
     PJ_DEFAULT {
@@ -450,4 +527,33 @@
     pj_scan_fini(&scanner);
     return msg;
+}
+
+/* Public function to parse as rdata.*/
+PJ_DEF(pjsip_msg *) pjsip_parse_rdata( char *buf, pj_size_t size,
+                                       pjsip_rx_data *rdata )
+{
+    pj_scanner scanner;
+    pjsip_parse_ctx context;
+    PJ_USE_EXCEPTION;
+
+    init_sip_parser();
+
+    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, 
+                 &on_syntax_error);
+
+    context.scanner = &scanner;
+    context.pool = rdata->pool;
+    context.rdata = rdata;
+
+    PJ_TRY {
+	rdata->msg = int_parse_msg(&context, &rdata->parse_err);
+    } 
+    PJ_DEFAULT {
+	rdata->msg = NULL;
+    }
+    PJ_END
+
+    pj_scan_fini(&scanner);
+    return rdata->msg;
 }
 
@@ -467,11 +573,11 @@
     /* For datagram, the whole datagram IS the message. */
     if (is_datagram) {
-	return PJ_TRUE;
+	return PJ_SUCCESS;
     }
 
 
     /* Find the end of header area by finding an empty line. */
-    if ((pos = strstr(buf, "\n\r\n")) == NULL) {
-	return PJ_FALSE;
+    if ((pos = pj_native_strstr(buf, "\n\r\n")) == NULL) {
+	return PJSIP_EPARTIALMSG;
     }
 
@@ -480,9 +586,11 @@
 
     /* Find "Content-Length" header the hard way. */
-    line = strchr(buf, '\n');
+    line = pj_native_strchr(buf, '\n');
     while (line && line < hdr_end-14) {
 	++line;
-	if ( ((*line=='C' || *line=='c') && strncasecmp(line, "Content-Length", 14) == 0) ||
-	     ((*line=='l' || *line=='L') && (*(line+1)==' ' || *(line+1)=='\t' || *(line+1)==':')))
+	if ( ((*line=='C' || *line=='c') && 
+              pj_native_strncasecmp(line, "Content-Length", 14) == 0) ||
+	     ((*line=='l' || *line=='L') && 
+              (*(line+1)==' ' || *(line+1)=='\t' || *(line+1)==':')))
 	{
 	    /* Try to parse the header. */
@@ -510,5 +618,5 @@
 
 		/* Get number */
-		pj_scan_get(&scanner, pjsip_DIGIT_SPEC, &str_clen);
+		pj_scan_get(&scanner, &pjsip_DIGIT_SPEC, &str_clen);
 
 		/* Get newline. */
@@ -528,22 +636,20 @@
 
 	/* Go to next line. */
-	line = strchr(line, '\n');
+	line = pj_native_strchr(line, '\n');
     }
 
     /* Found Content-Length? */
     if (content_length == -1) {
-	PJ_LOG(4, ("sipparser", "pjsip_find_msg: incoming TCP packet has missing "
-			     "Content-Length header, treated as incomplete."));
-	return PJ_FALSE;
+	return PJSIP_EMISSINGHDR;
     }
 
     /* Enough packet received? */
     *msg_size = (body_start - buf) + content_length;
-    return (*msg_size) <= size;
+    return (*msg_size) <= size ? PJ_SUCCESS : PJSIP_EPARTIALMSG;
 #else
-    PJ_UNUSED_ARG(buf)
-    PJ_UNUSED_ARG(is_datagram)
+    PJ_UNUSED_ARG(buf);
+    PJ_UNUSED_ARG(is_datagram);
     *msg_size = size;
-    return 1;
+    return PJ_SUCCESS;
 #endif
 }
@@ -558,8 +664,5 @@
     pjsip_uri *uri = NULL;
 
-    if (!parser_is_initialized) {
-	init_parser();
-	parser_is_initialized = 1;
-    }
+    init_sip_parser();
 
     pj_scan_init(&scanner, buf, size, 0, &on_syntax_error);
@@ -572,5 +675,7 @@
 
     /* Must have exhausted all inputs. */
-    if (pj_scan_is_eof(&scanner) || *scanner.current=='\r' || *scanner.current=='\n') {
+    if (pj_scan_is_eof(&scanner) || *scanner.curptr=='\r' || 
+                       *scanner.curptr=='\n') 
+    {
 	/* Success. */
 	pj_scan_fini(&scanner);
@@ -587,5 +692,6 @@
  * actual body is laid.
  */
-static int generic_print_body (pjsip_msg_body *msg_body, char *buf, pj_size_t size)
+static int generic_print_body (pjsip_msg_body *msg_body, 
+                               char *buf, pj_size_t size)
 {
     pjsip_msg_body *body = msg_body;
@@ -598,5 +704,5 @@
 
 /* Internal function to parse SIP message */
-static pjsip_msg *int_parse_msg( pj_scanner *scanner, pj_pool_t *pool, 
+static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
 				 pjsip_parser_err_report *err_list)
 {
@@ -605,10 +711,12 @@
     pjsip_msg *msg;
     pjsip_ctype_hdr *ctype_hdr = NULL;
+    pj_scanner *scanner = ctx->scanner;
+    pj_pool_t *pool = ctx->pool;
 
     /* Skip leading newlines. */
-    ch = *scanner->current;
+    ch = *scanner->curptr;
     while (ch=='\r' || ch=='\n') {
 	pj_scan_get_char(scanner);
-	ch = *scanner->current;
+	ch = *scanner->curptr;
     }
 
@@ -631,5 +739,5 @@
 
 	/* Get hname. */
-	pj_scan_get( scanner, pjsip_TOKEN_SPEC, &hname);
+	pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname);
 	ch = pj_scan_get_char( scanner );
 	if (ch != ':') {
@@ -646,10 +754,9 @@
 	     */
 	    if (handler) {
-		hdr = (*handler)(scanner, pool);
+		hdr = (*handler)(ctx);
 	    } else {
-		pjsip_generic_string_hdr *ghdr = parse_hdr_generic_string(scanner, pool);
-		ghdr->type = PJSIP_H_OTHER;
-		ghdr->name = ghdr->sname = hname;
-		hdr = (pjsip_hdr*)ghdr;
+		hdr = parse_hdr_generic_string(ctx);
+		hdr->type = PJSIP_H_OTHER;
+		hdr->name = hdr->sname = hname;
 	    }
 
@@ -669,6 +776,7 @@
 	    hdr = NULL;
 
-	    PJ_LOG(4,("sipparser", "Syntax error in line %d col %d (hname=%.*s)",
-		      scanner->line, scanner->col, hname.slen, hname.ptr));
+	    //PJ_LOG(4,("sipparser", 
+            //          "Syntax error in line %d col %d (hname=%.*s)",
+	    //	      scanner->line, scanner->col, hname.slen, hname.ptr));
 
 	    if (err_list) {
@@ -685,5 +793,5 @@
 
 	    if (!pj_scan_is_eof(scanner)) {
-		pj_scan_get_until(scanner, pjsip_NEWLINE_OR_EOF_SPEC, &token);
+		pj_scan_get_until(scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &token);
 		parse_hdr_end(scanner);
 	    }
@@ -703,21 +811,21 @@
 	/* Parse until EOF or an empty line is found. */
     } while (!pj_scan_is_eof(scanner) && 
-	      *scanner->current != '\r' && *scanner->current != '\n');
+	      *scanner->curptr != '\r' && *scanner->curptr != '\n');
 
     /* If empty line is found, eat it. */
     if (!pj_scan_is_eof(scanner)) {
-	if (*scanner->current=='\r' || *scanner->current=='\n') {
+	if (*scanner->curptr=='\r' || *scanner->curptr=='\n') {
 	    pj_scan_get_newline(scanner);
 	}
     }
 
-    /* If we have Content-Type header, treat the rest of the message as body. */
+    /* If we have Content-Type header, treat the rest of the message as body.*/
     if (ctype_hdr) {
 	pjsip_msg_body *body = pj_pool_alloc(pool, sizeof(pjsip_msg_body));
-	pj_strdup (pool, &body->content_type.type, &ctype_hdr->media.type);
-	pj_strdup (pool, &body->content_type.subtype, &ctype_hdr->media.subtype);
-	pj_strdup (pool, &body->content_type.param, &ctype_hdr->media.param);
-	body->data = scanner->current;
-	body->len = scanner->end - scanner->current;
+	pj_strdup(pool, &body->content_type.type, &ctype_hdr->media.type);
+	pj_strdup(pool, &body->content_type.subtype, &ctype_hdr->media.subtype);
+	pj_strdup(pool, &body->content_type.param, &ctype_hdr->media.param);
+	body->data = scanner->curptr;
+	body->len = scanner->end - scanner->curptr;
 	body->print_body = &generic_print_body;
 
@@ -734,11 +842,11 @@
 {
     /* pname */
-    pj_scan_get(scanner, pjsip_PARAM_CHAR_SPEC, pname);
+    pj_scan_get(scanner, &pjsip_PARAM_CHAR_SPEC, pname);
 
     /* pvalue, if any */
-    if (*scanner->current == '=') {
+    if (*scanner->curptr == '=') {
 	pj_scan_get_char(scanner);
 	/* pvalue can be a quoted string. */
-	if (*scanner->current == '"') {
+	if (*scanner->curptr == '"') {
 	    pj_scan_get_quote( scanner, '"', '"', pvalue);
 	    if (option & PJSIP_PARSE_REMOVE_QUOTE) {
@@ -747,5 +855,5 @@
 	    }
 	} else {
-	    pj_scan_get(scanner, pjsip_PARAM_CHAR_SPEC, pvalue);
+	    pj_scan_get(scanner, &pjsip_PARAM_CHAR_SPEC, pvalue);
 	}
     } else {
@@ -770,9 +878,9 @@
 				     pj_str_t *host, int *p_port)
 {
-    pj_scan_get( scanner, pjsip_HOST_SPEC, host);
-    if (*scanner->current == ':') {
+    pj_scan_get( scanner, &pjsip_HOST_SPEC, host);
+    if (*scanner->curptr == ':') {
 	pj_str_t port;
 	pj_scan_get_char(scanner);
-	pj_scan_get(scanner, pjsip_DIGIT_SPEC, &port);
+	pj_scan_get(scanner, &pjsip_DIGIT_SPEC, &port);
 	*p_port = pj_strtoul(&port);
     } else {
@@ -790,5 +898,5 @@
      * must be a username.
      */
-    if (pj_scan_peek( scanner, pjsip_PROBE_USER_HOST_SPEC, &dummy) == '@')
+    if (pj_scan_peek( scanner, &pjsip_PROBE_USER_HOST_SPEC, &dummy) == '@')
 	is_user = 1;
     else
@@ -802,8 +910,8 @@
 				 pj_str_t *user, pj_str_t *pass)
 {
-    pj_scan_get( scanner, pjsip_USER_SPEC, user);
-    if ( *scanner->current == ':') {
+    pj_scan_get( scanner, &pjsip_USER_SPEC, user);
+    if ( *scanner->curptr == ':') {
 	pj_scan_get_char( scanner );
-	pj_scan_get( scanner, pjsip_PASSWD_SPEC, pass);
+	pj_scan_get( scanner, &pjsip_PASSWD_SPEC, pass);
     } else {
 	pass->ptr = NULL;
@@ -816,11 +924,11 @@
 
 /* Parse all types of URI. */
-static pjsip_uri *int_parse_uri_or_name_addr(pj_scanner *scanner, pj_pool_t *pool,
-						  unsigned option)
+static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *pool,
+					      unsigned opt)
 {
     pjsip_uri *uri;
     int is_name_addr = 0;
 
-    if (*scanner->current=='"' || *scanner->current=='<') {
+    if (*scanner->curptr=='"' || *scanner->curptr=='<') {
 	uri = (pjsip_uri*)int_parse_name_addr( scanner, pool );
 	is_name_addr = 1;
@@ -831,12 +939,15 @@
 
 	pj_scan_save_state( scanner, &backtrack);
-	pj_scan_get( scanner, pjsip_TOKEN_SPEC, &scheme);
+	pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &scheme);
 	colon = pj_scan_get_char( scanner );
 	pj_scan_restore_state( scanner, &backtrack);
 
-	if (colon==':' && (parser_stricmp(scheme, pjsip_SIP_STR)==0 || parser_stricmp(scheme, pjsip_SIPS_STR)==0)) 
+	if (colon==':' && 
+            (parser_stricmp(scheme, pjsip_SIP_STR)==0 || 
+             parser_stricmp(scheme, pjsip_SIPS_STR)==0)) 
 	{
-	    uri = (pjsip_uri*)int_parse_sip_url( scanner, pool, 
-					(option & PJSIP_PARSE_URI_IN_FROM_TO_HDR) == 0 );
+	    uri = (pjsip_uri*)
+                int_parse_sip_url( scanner, pool, 
+				   (opt & PJSIP_PARSE_URI_IN_FROM_TO_HDR)== 0);
 
 	} else if (colon==':' && parser_stricmp( scheme, pjsip_TEL_STR)==0) {
@@ -853,5 +964,5 @@
 
     /* Should we return the URI object as name address? */
-    if (option & PJSIP_PARSE_URI_AS_NAMEADDR) {
+    if (opt & PJSIP_PARSE_URI_AS_NAMEADDR) {
 	if (is_name_addr == 0) {
 	    pjsip_name_addr *name_addr;
@@ -871,5 +982,5 @@
 				pj_bool_t parse_params)
 {
-    if (*scanner->current=='"' || *scanner->current=='<') {
+    if (*scanner->curptr=='"' || *scanner->curptr=='<') {
 	return (pjsip_uri*)int_parse_name_addr( scanner, pool );
     } else {
@@ -878,12 +989,13 @@
 
 	/* Get scheme. */
-	colon = pj_scan_peek(scanner, pjsip_TOKEN_SPEC, &scheme);
+	colon = pj_scan_peek(scanner, &pjsip_TOKEN_SPEC, &scheme);
 	if (colon != ':') {
 	    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 	}
 
-	if ((parser_stricmp(scheme, pjsip_SIP_STR)==0 || parser_stricmp(scheme, pjsip_SIPS_STR)==0)) 
+	if ((parser_stricmp(scheme, pjsip_SIP_STR)==0 || 
+            parser_stricmp(scheme, pjsip_SIPS_STR)==0)) 
 	{
-	    return (pjsip_uri*)int_parse_sip_url( scanner, pool, parse_params );
+	    return (pjsip_uri*)int_parse_sip_url( scanner, pool, parse_params);
 
 	} else if (parser_stricmp(scheme, pjsip_TEL_STR)==0) {
@@ -909,5 +1021,5 @@
     scanner->skip_ws = 0;
 
-    pj_scan_get(scanner, pjsip_TOKEN_SPEC, &scheme);
+    pj_scan_get(scanner, &pjsip_TOKEN_SPEC, &scheme);
     colon = pj_scan_get_char(scanner);
     if (colon != ':') {
@@ -938,5 +1050,5 @@
 
     /* Get URL parameters. */
-    while ( parse_params && *scanner->current == ';' ) {
+    while ( parse_params && *scanner->curptr == ';' ) {
 	pj_str_t pname, pvalue;
 
@@ -949,5 +1061,5 @@
 	    url->method_param = pvalue;
 
-	} else if (!parser_stricmp(pname, pjsip_TRANSPORT_STR) && pvalue.slen) {
+	} else if (!parser_stricmp(pname,pjsip_TRANSPORT_STR) && pvalue.slen) {
 	    url->transport_param = pvalue;
 
@@ -967,6 +1079,7 @@
 
     /* Get header params. */
-    if (parse_params && *scanner->current == '?') {
-	pj_scan_get_until(scanner, pjsip_NEWLINE_OR_EOF_SPEC, &url->header_param);
+    if (parse_params && *scanner->curptr == '?') {
+	pj_scan_get_until(scanner, &pjsip_NEWLINE_OR_EOF_SPEC, 
+                          &url->header_param);
     }
 
@@ -985,8 +1098,8 @@
     name_addr = pjsip_name_addr_create(pool);
 
-    if (*scanner->current == '"') {
+    if (*scanner->curptr == '"') {
 	pj_scan_get_quote( scanner, '"', '"', &name_addr->display);
 
-    } else if (*scanner->current != '<') {
+    } else if (*scanner->curptr != '<') {
 	int next;
 	pj_str_t dummy;
@@ -997,5 +1110,5 @@
 	 * will be parser later.
 	 */
-	next = pj_scan_peek_until(scanner, pjsip_DISPLAY_SCAN_SPEC, &dummy);
+	next = pj_scan_peek_until(scanner, &pjsip_DISPLAY_SCAN_SPEC, &dummy);
 	if (next == '<') {
 	    /* Ok, this is what we're looking for, a display name. */
@@ -1009,5 +1122,5 @@
 
     /* Get the SIP-URL */
-    has_bracket = (*scanner->current == '<');
+    has_bracket = (*scanner->curptr == '<');
     if (has_bracket)
 	pj_scan_get_char(scanner);
@@ -1026,5 +1139,5 @@
     pj_str_t token;
 
-    pj_scan_get( scanner, pjsip_TOKEN_SPEC, &token);
+    pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &token);
     pjsip_method_init_np( &req_line->method, &token);
 
@@ -1046,7 +1159,8 @@
     pj_scan_advance_n( scanner, 7, 1);
 
-    pj_scan_get( scanner, pjsip_DIGIT_SPEC, &token);
+    pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &token);
     status_line->code = pj_strtoul(&token);
-    pj_scan_get_until( scanner, pjsip_NEWLINE_OR_EOF_SPEC, &status_line->reason);
+    pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, 
+                       &status_line->reason);
     pj_scan_get_newline( scanner );
 }
@@ -1057,5 +1171,5 @@
     if (pj_scan_is_eof(scanner)) {
 	;   /* Do nothing. */
-    } else if (*scanner->current == '&') {
+    } else if (*scanner->curptr == '&') {
 	pj_scan_get_char(scanner);
     } else {
@@ -1074,10 +1188,11 @@
 				     pj_scanner *scanner)
 {
-    pj_scan_get_until( scanner, pjsip_ARRAY_ELEMENTS, &hdr->values[0]);
+    pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS, &hdr->values[0]);
     hdr->count++;
 
-    while (*scanner->current == ',') {
+    while (*scanner->curptr == ',') {
 	pj_scan_get_char(scanner);
-	pj_scan_get_until( scanner, pjsip_ARRAY_ELEMENTS, &hdr->values[hdr->count]);
+	pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS, 
+                           &hdr->values[hdr->count]);
 	hdr->count++;
     }
@@ -1089,5 +1204,5 @@
 				      pj_scanner *scanner )
 {
-    pj_scan_get_until( scanner, pjsip_NEWLINE_OR_EOF_SPEC, &hdr->hvalue);
+    pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->hvalue);
     parse_hdr_end(scanner);
 }
@@ -1098,5 +1213,5 @@
 {
     pj_str_t tmp;
-    pj_scan_get_until( scanner, pjsip_NEWLINE_OR_EOF_SPEC, &tmp);
+    pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &tmp);
     hdr->ivalue = pj_strtoul(&tmp);
     parse_hdr_end(scanner);
@@ -1105,29 +1220,30 @@
 
 /* Parse Accept header. */
-static pjsip_accept_hdr* parse_hdr_accept( pj_scanner *scanner, 
-					    pj_pool_t *pool)
-{
-    pjsip_accept_hdr *accept = pjsip_accept_hdr_create(pool);
-    parse_generic_array_hdr(accept, scanner);
-    return accept;
+static pjsip_hdr* parse_hdr_accept(pjsip_parse_ctx *ctx)
+{
+    pjsip_accept_hdr *accept = pjsip_accept_hdr_create(ctx->pool);
+    parse_generic_array_hdr(accept, ctx->scanner);
+    return (pjsip_hdr*)accept;
 }
 
 /* Parse Allow header. */
-static pjsip_allow_hdr*   parse_hdr_allow( pj_scanner *scanner, 
-					   pj_pool_t *pool)
-{
-    pjsip_allow_hdr *allow = pjsip_allow_hdr_create(pool);
-    parse_generic_array_hdr(allow, scanner);
-    return allow;
+static pjsip_hdr* parse_hdr_allow(pjsip_parse_ctx *ctx)
+{
+    pjsip_allow_hdr *allow = pjsip_allow_hdr_create(ctx->pool);
+    parse_generic_array_hdr(allow, ctx->scanner);
+    return (pjsip_hdr*)allow;
 }
 
 /* Parse Call-ID header. */
-static pjsip_cid_hdr* parse_hdr_call_id( pj_scanner *scanner, 
-					  pj_pool_t *pool)
-{
-    pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(pool);
-    pj_scan_get_until( scanner, pjsip_NEWLINE_OR_EOF_SPEC, &hdr->id);
-    parse_hdr_end(scanner);
-    return hdr;
+static pjsip_hdr* parse_hdr_call_id(pjsip_parse_ctx *ctx)
+{
+    pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(ctx->pool);
+    pj_scan_get_until( ctx->scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->id);
+    parse_hdr_end(ctx->scanner);
+
+    if (ctx->rdata)
+        ctx->rdata->call_id = hdr->id;
+
+    return (pjsip_hdr*)hdr;
 }
 
@@ -1137,5 +1253,5 @@
 				     pj_pool_t *pool)
 {
-    while ( *scanner->current == ';' ) {
+    while ( *scanner->curptr == ';' ) {
 	pj_str_t pname, pvalue;
 
@@ -1160,11 +1276,11 @@
 
 /* Parse Contact header. */
-PJ_DEF(pjsip_contact_hdr*) parse_hdr_contact( pj_scanner *scanner, 
-					      pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_contact( pjsip_parse_ctx *ctx )
 {
     pjsip_contact_hdr *first = NULL;
+    pj_scanner *scanner = ctx->scanner;
     
     do {
-	pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(pool);
+	pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(ctx->pool);
 	if (first == NULL)
 	    first = hdr;
@@ -1172,5 +1288,5 @@
 	    pj_list_insert_before(first, hdr);
 
-	if (*scanner->current == '*') {
+	if (*scanner->curptr == '*') {
 	    pj_scan_get_char(scanner);
 	    hdr->star = 1;
@@ -1178,10 +1294,11 @@
 	} else {
 	    hdr->star = 0;
-	    hdr->uri = int_parse_uri_or_name_addr(scanner, pool, PJSIP_PARSE_URI_AS_NAMEADDR);
-
-	    int_parse_contact_param(hdr, scanner, pool);
-	}
-
-	if (*scanner->current != ',')
+	    hdr->uri = int_parse_uri_or_name_addr(scanner, ctx->pool, 
+                                                  PJSIP_PARSE_URI_AS_NAMEADDR);
+
+	    int_parse_contact_param(hdr, scanner, ctx->pool);
+	}
+
+	if (*scanner->curptr != ',')
 	    break;
 
@@ -1191,70 +1308,80 @@
 
     parse_hdr_end(scanner);
-    return first;
+
+    return (pjsip_hdr*)first;
 }
 
 /* Parse Content-Length header. */
-PJ_DEF(pjsip_clen_hdr*) parse_hdr_content_length( pj_scanner *scanner, 
-					          pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_content_len( pjsip_parse_ctx *ctx )
 {
     pj_str_t digit;
     pjsip_clen_hdr *hdr;
 
-    hdr = pjsip_clen_hdr_create(pool);
-    pj_scan_get(scanner, pjsip_DIGIT_SPEC, &digit);
+    hdr = pjsip_clen_hdr_create(ctx->pool);
+    pj_scan_get(ctx->scanner, &pjsip_DIGIT_SPEC, &digit);
     hdr->len = pj_strtoul(&digit);
-    parse_hdr_end(scanner);
-    return hdr;
+    parse_hdr_end(ctx->scanner);
+
+    if (ctx->rdata)
+        ctx->rdata->clen = hdr;
+
+    return (pjsip_hdr*)hdr;
 }
 
 /* Parse Content-Type header. */
-PJ_DEF(pjsip_ctype_hdr*) parse_hdr_content_type( pj_scanner *scanner, 
-					         pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_content_type( pjsip_parse_ctx *ctx )
 {
     pjsip_ctype_hdr *hdr;
-
-    hdr = pjsip_ctype_hdr_create(pool);
+    pj_scanner *scanner = ctx->scanner;
+
+    hdr = pjsip_ctype_hdr_create(ctx->pool);
     
     /* Parse media type and subtype. */
-    pj_scan_get(scanner, pjsip_TOKEN_SPEC, &hdr->media.type);
+    pj_scan_get(scanner, &pjsip_TOKEN_SPEC, &hdr->media.type);
     pj_scan_get_char(scanner);
-    pj_scan_get(scanner, pjsip_TOKEN_SPEC, &hdr->media.subtype);
+    pj_scan_get(scanner, &pjsip_TOKEN_SPEC, &hdr->media.subtype);
 
     /* Parse media parameters */
-    while (*scanner->current == ';') {
+    while (*scanner->curptr == ';') {
 	pj_str_t pname, pvalue;
 	int_parse_param(scanner, &pname, &pvalue);
-	concat_param(&hdr->media.param, pool, &pname, &pvalue);
-    }
-
-    parse_hdr_end(scanner);
-    return hdr;
+	concat_param(&hdr->media.param, ctx->pool, &pname, &pvalue);
+    }
+
+    parse_hdr_end(ctx->scanner);
+
+    if (ctx->rdata)
+        ctx->rdata->ctype = hdr;
+
+    return (pjsip_hdr*)hdr;
 }
 
 /* Parse CSeq header. */
-PJ_DEF(pjsip_cseq_hdr*) parse_hdr_cseq( pj_scanner *scanner, 
-				        pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_cseq( pjsip_parse_ctx *ctx )
 {
     pj_str_t cseq, method;
     pjsip_cseq_hdr *hdr;
 
-    hdr = pjsip_cseq_hdr_create(pool);
-    pj_scan_get( scanner, pjsip_DIGIT_SPEC, &cseq);
+    hdr = pjsip_cseq_hdr_create(ctx->pool);
+    pj_scan_get( ctx->scanner, &pjsip_DIGIT_SPEC, &cseq);
     hdr->cseq = pj_strtoul(&cseq);
 
-    pj_scan_get( scanner, pjsip_TOKEN_SPEC, &method);
+    pj_scan_get( ctx->scanner, &pjsip_TOKEN_SPEC, &method);
     pjsip_method_init_np(&hdr->method, &method);
 
-    parse_hdr_end( scanner );
-    return hdr;
+    parse_hdr_end( ctx->scanner );
+
+    if (ctx->rdata)
+        ctx->rdata->cseq = hdr;
+
+    return (pjsip_hdr*)hdr;
 }
 
 /* Parse Expires header. */
-static pjsip_expires_hdr* parse_hdr_expires(pj_scanner *scanner, 
-					    pj_pool_t *pool)
-{
-    pjsip_expires_hdr *hdr = pjsip_expires_hdr_create(pool);
-    parse_generic_int_hdr(hdr, scanner);
-    return hdr;
+static pjsip_hdr* parse_hdr_expires(pjsip_parse_ctx *ctx)
+{
+    pjsip_expires_hdr *hdr = pjsip_expires_hdr_create(ctx->pool);
+    parse_generic_int_hdr(hdr, ctx->scanner);
+    return (pjsip_hdr*)hdr;
 }
 
@@ -1268,5 +1395,5 @@
 					  PJSIP_PARSE_URI_IN_FROM_TO_HDR);
 
-    while ( *scanner->current == ';' ) {
+    while ( *scanner->curptr == ';' ) {
 	pj_str_t pname, pvalue;
 
@@ -1285,57 +1412,62 @@
 
 /* Parse From: header. */
-PJ_DEF(pjsip_from_hdr*) parse_hdr_from( pj_scanner *scanner, 
-				        pj_pool_t *pool)
-{
-    pjsip_from_hdr *hdr = pjsip_from_hdr_create(pool);
-    parse_hdr_fromto(scanner, pool, hdr);
-    return hdr;
+static pjsip_hdr* parse_hdr_from( pjsip_parse_ctx *ctx )
+{
+    pjsip_from_hdr *hdr = pjsip_from_hdr_create(ctx->pool);
+    parse_hdr_fromto(ctx->scanner, ctx->pool, hdr);
+    if (ctx->rdata)
+        ctx->rdata->from = hdr;
+
+    return (pjsip_hdr*)hdr;
 }
 
 /* Parse Require: header. */
-static pjsip_require_hdr* parse_hdr_require( pj_scanner *scanner, 
-					     pj_pool_t *pool)
-{
-    pjsip_require_hdr *hdr = pjsip_require_hdr_create(pool);
-    parse_generic_array_hdr(hdr, scanner);
-    return hdr;
+static pjsip_hdr* parse_hdr_require( pjsip_parse_ctx *ctx )
+{
+    pjsip_require_hdr *hdr = pjsip_require_hdr_create(ctx->pool);
+    parse_generic_array_hdr(hdr, ctx->scanner);
+
+    if (ctx->rdata && ctx->rdata->require == NULL)
+        ctx->rdata->require = hdr;
+
+    return (pjsip_hdr*)hdr;
 }
 
 /* Parse Retry-After: header. */
-static pjsip_retry_after_hdr* parse_hdr_retry_after(pj_scanner *scanner, 
-						    pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_retry_after(pjsip_parse_ctx *ctx)
 {
     pjsip_retry_after_hdr *hdr;
-    hdr = pjsip_retry_after_hdr_create(pool);
-    parse_generic_int_hdr(hdr, scanner);
-    return hdr;
+    hdr = pjsip_retry_after_hdr_create(ctx->pool);
+    parse_generic_int_hdr(hdr, ctx->scanner);
+    return (pjsip_hdr*)hdr;
 }
 
 /* Parse Supported: header. */
-static pjsip_supported_hdr* parse_hdr_supported(pj_scanner *scanner, 
-						pj_pool_t *pool)
-{
-    pjsip_supported_hdr *hdr = pjsip_supported_hdr_create(pool);
-    parse_generic_array_hdr(hdr, scanner);
-    return hdr;
+static pjsip_hdr* parse_hdr_supported(pjsip_parse_ctx *ctx)
+{
+    pjsip_supported_hdr *hdr = pjsip_supported_hdr_create(ctx->pool);
+    parse_generic_array_hdr(hdr, ctx->scanner);
+    return (pjsip_hdr*)hdr;
 }
 
 
 /* Parse To: header. */
-PJ_DEF(pjsip_to_hdr*) parse_hdr_to( pj_scanner *scanner, 
-				    pj_pool_t *pool)
-{
-    pjsip_to_hdr *hdr = pjsip_to_hdr_create(pool);
-    parse_hdr_fromto(scanner, pool, hdr);
-    return hdr;
+static pjsip_hdr* parse_hdr_to( pjsip_parse_ctx *ctx )
+{
+    pjsip_to_hdr *hdr = pjsip_to_hdr_create(ctx->pool);
+    parse_hdr_fromto(ctx->scanner, ctx->pool, hdr);
+
+    if (ctx->rdata)
+        ctx->rdata->to = hdr;
+
+    return (pjsip_hdr*)hdr;
 }
 
 /* Parse Unsupported: header. */
-static pjsip_unsupported_hdr* parse_hdr_unsupported(pj_scanner *scanner, 
-						    pj_pool_t *pool)
-{
-    pjsip_unsupported_hdr *hdr = pjsip_unsupported_hdr_create(pool);
-    parse_generic_array_hdr(hdr, scanner);
-    return hdr;
+static pjsip_hdr* parse_hdr_unsupported(pjsip_parse_ctx *ctx)
+{
+    pjsip_unsupported_hdr *hdr = pjsip_unsupported_hdr_create(ctx->pool);
+    parse_generic_array_hdr(hdr, ctx->scanner);
+    return (pjsip_hdr*)hdr;
 }
 
@@ -1344,5 +1476,5 @@
 				 pj_pool_t *pool)
 {
-    while ( *scanner->current == ';' ) {
+    while ( *scanner->curptr == ';' ) {
 	pj_str_t pname, pvalue;
 
@@ -1374,21 +1506,23 @@
 
 /* Parse Max-Forwards header. */
-static pjsip_max_forwards_hdr* parse_hdr_max_forwards( pj_scanner *scanner, 
-						       pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_max_forwards( pjsip_parse_ctx *ctx )
 {
     pjsip_max_forwards_hdr *hdr;
-    hdr = pjsip_max_forwards_hdr_create(pool);
-    parse_generic_int_hdr(hdr, scanner);
-    return hdr;
+    hdr = pjsip_max_forwards_hdr_create(ctx->pool);
+    parse_generic_int_hdr(hdr, ctx->scanner);
+
+    if (ctx->rdata)
+        ctx->rdata->max_fwd = hdr;
+
+    return (pjsip_hdr*)hdr;
 }
 
 /* Parse Min-Expires header. */
-static pjsip_min_expires_hdr*  parse_hdr_min_expires(pj_scanner *scanner, 
-						     pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_min_expires(pjsip_parse_ctx *ctx)
 {
     pjsip_min_expires_hdr *hdr;
-    hdr = pjsip_min_expires_hdr_create(pool);
-    parse_generic_int_hdr(hdr, scanner);
-    return hdr;
+    hdr = pjsip_min_expires_hdr_create(ctx->pool);
+    parse_generic_int_hdr(hdr, ctx->scanner);
+    return (pjsip_hdr*)hdr;
 }
 
@@ -1401,16 +1535,18 @@
 
     pj_memcpy(&hdr->name_addr, temp, sizeof(*temp));
-    if (*scanner->current == ';') {
-	pj_scan_get_until(scanner, pjsip_NEWLINE_OR_EOF_SPEC, &hdr->other_param);
+    if (*scanner->curptr == ';') {
+	pj_scan_get_until(scanner, &pjsip_NEWLINE_OR_EOF_SPEC, 
+                          &hdr->other_param);
     }
 }
 
 /* Parse Record-Route header. */
-PJ_DEF(pjsip_rr_hdr*) parse_hdr_rr( pj_scanner *scanner, pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_rr( pjsip_parse_ctx *ctx)
 {
     pjsip_rr_hdr *first = NULL;
+    pj_scanner *scanner = ctx->scanner;
 
     do {
-	pjsip_rr_hdr *hdr = pjsip_rr_hdr_create(pool);
+	pjsip_rr_hdr *hdr = pjsip_rr_hdr_create(ctx->pool);
 	if (!first) {
 	    first = hdr;
@@ -1418,6 +1554,6 @@
 	    pj_list_insert_before(first, hdr);
 	}
-	parse_hdr_rr_route(scanner, pool, hdr);
-	if (*scanner->current == ',') {
+	parse_hdr_rr_route(scanner, ctx->pool, hdr);
+	if (*scanner->curptr == ',') {
 	    pj_scan_get_char(scanner);
 	} else {
@@ -1426,15 +1562,19 @@
     } while (1);
     parse_hdr_end(scanner);
-    return first;
+
+    if (ctx->rdata && ctx->rdata->record_route==NULL)
+        ctx->rdata->record_route = first;
+
+    return (pjsip_hdr*)first;
 }
 
 /* Parse Route: header. */
-PJ_DEF(pjsip_route_hdr*) parse_hdr_route( pj_scanner *scanner, 
-					  pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_route( pjsip_parse_ctx *ctx )
 {
     pjsip_route_hdr *first = NULL;
+    pj_scanner *scanner = ctx->scanner;
 
     do {
-	pjsip_route_hdr *hdr = pjsip_route_hdr_create(pool);
+	pjsip_route_hdr *hdr = pjsip_route_hdr_create(ctx->pool);
 	if (!first) {
 	    first = hdr;
@@ -1442,6 +1582,6 @@
 	    pj_list_insert_before(first, hdr);
 	}
-	parse_hdr_rr_route(scanner, pool, hdr);
-	if (*scanner->current == ',') {
+	parse_hdr_rr_route(scanner, ctx->pool, hdr);
+	if (*scanner->curptr == ',') {
 	    pj_scan_get_char(scanner);
 	} else {
@@ -1450,14 +1590,19 @@
     } while (1);
     parse_hdr_end(scanner);
-    return first;
+
+    if (ctx->rdata && ctx->rdata->route==NULL)
+        ctx->rdata->route = first;
+
+    return (pjsip_hdr*)first;
 }
 
 /* Parse Via: header. */
-PJ_DEF(pjsip_via_hdr*) parse_hdr_via( pj_scanner *scanner, pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_via( pjsip_parse_ctx *ctx )
 {
     pjsip_via_hdr *first = NULL;
+    pj_scanner *scanner = ctx->scanner;
 
     do {
-	pjsip_via_hdr *hdr = pjsip_via_hdr_create(pool);
+	pjsip_via_hdr *hdr = pjsip_via_hdr_create(ctx->pool);
 	if (!first)
 	    first = hdr;
@@ -1470,11 +1615,11 @@
 	pj_scan_advance_n( scanner, 8, 1);
 
-	pj_scan_get( scanner, pjsip_TOKEN_SPEC, &hdr->transport);
-	pj_scan_get( scanner, pjsip_HOST_SPEC, &hdr->sent_by.host);
-
-	if (*scanner->current==':') {
+	pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hdr->transport);
+	pj_scan_get( scanner, &pjsip_HOST_SPEC, &hdr->sent_by.host);
+
+	if (*scanner->curptr==':') {
 	    pj_str_t digit;
 	    pj_scan_get_char(scanner);
-	    pj_scan_get(scanner, pjsip_DIGIT_SPEC, &digit);
+	    pj_scan_get(scanner, &pjsip_DIGIT_SPEC, &digit);
 	    hdr->sent_by.port = pj_strtoul(&digit);
 	} else {
@@ -1482,7 +1627,7 @@
 	}
 	
-	int_parse_via_param(hdr, scanner, pool);
-
-	if (*scanner->current == '(') {
+	int_parse_via_param(hdr, scanner, ctx->pool);
+
+	if (*scanner->curptr == '(') {
 	    pj_scan_get_char(scanner);
 	    pj_scan_get_until_ch( scanner, ')', &hdr->comment);
@@ -1490,5 +1635,5 @@
 	}
 
-	if (*scanner->current != ',')
+	if (*scanner->curptr != ',')
 	    break;
 
@@ -1498,16 +1643,19 @@
 
     parse_hdr_end(scanner);
-    return first;
+
+    if (ctx->rdata && ctx->rdata->via == NULL)
+        ctx->rdata->via = first;
+
+    return (pjsip_hdr*)first;
 }
 
 /* Parse generic header. */
-PJ_DEF(pjsip_generic_string_hdr*) parse_hdr_generic_string( pj_scanner *scanner, 
-						pj_pool_t *pool)
+static pjsip_hdr* parse_hdr_generic_string( pjsip_parse_ctx *ctx )
 {
     pjsip_generic_string_hdr *hdr;
 
-    hdr = pjsip_generic_string_hdr_create(pool, NULL);
-    parse_generic_string_hdr(hdr, scanner);
-    return hdr;
+    hdr = pjsip_generic_string_hdr_create(ctx->pool, NULL);
+    parse_generic_string_hdr(hdr, ctx->scanner);
+    return (pjsip_hdr*)hdr;
 
 }
@@ -1519,20 +1667,25 @@
     pj_scanner scanner;
     pjsip_hdr *hdr = NULL;
+    pjsip_parse_ctx context;
     PJ_USE_EXCEPTION;
 
     init_sip_parser();
 
-    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, &on_syntax_error);
+    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, 
+                 &on_syntax_error);
+
+    context.scanner = &scanner;
+    context.pool = pool;
+    context.rdata = NULL;
 
     PJ_TRY {
 	pjsip_parse_hdr_func *handler = find_handler(hname);
 	if (handler) {
-	    hdr = (*handler)(&scanner, pool);
+	    hdr = (*handler)(&context);
 	} else {
-	    pjsip_generic_string_hdr *ghdr = parse_hdr_generic_string(&scanner, pool);
-	    ghdr->type = PJSIP_H_OTHER;
-	    pj_strdup(pool, &ghdr->name, hname);
-	    ghdr->sname = ghdr->name;
-	    hdr = (pjsip_hdr*)ghdr;
+	    hdr = parse_hdr_generic_string(&context);
+	    hdr->type = PJSIP_H_OTHER;
+	    pj_strdup(pool, &hdr->name, hname);
+	    hdr->sname = hdr->name;
 	}
 
@@ -1544,5 +1697,5 @@
 
     if (parsed_len) {
-	*parsed_len = (scanner.current - scanner.begin);
+	*parsed_len = (scanner.curptr - scanner.begin);
     }
 
Index: /pjproject/main/pjsip/src/pjsip/sip_resolve.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_resolve.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_resolve.c	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 
@@ -6,5 +5,6 @@
 #include <pjsip/sip_transport.h>
 #include <pj/pool.h>
-#include <ctype.h>
+#include <pj/ctype.h>
+#include <pj/assert.h>
 
 struct pjsip_resolver_t
@@ -22,5 +22,5 @@
 PJ_DEF(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver)
 {
-    PJ_UNUSED_ARG(resolver)
+    PJ_UNUSED_ARG(resolver);
 }
 
@@ -31,5 +31,5 @@
 
     while (p != end) {
-	if (isdigit(*p) || *p=='.') {
+	if (pj_isdigit(*p) || *p=='.') {
 	    ++p;
 	} else {
@@ -51,6 +51,6 @@
     pjsip_transport_type_e type = target->type;
 
-    PJ_UNUSED_ARG(resolver)
-    PJ_UNUSED_ARG(pool)
+    PJ_UNUSED_ARG(resolver);
+    PJ_UNUSED_ARG(pool);
 
     /* We only do synchronous resolving at this moment. */
@@ -95,7 +95,9 @@
     /* Resolve hostname. */
     if (!is_ip_addr) {
-	status = pj_sockaddr_init(&svr_addr.entry[0].addr, &target->host, target->port);
+	status = pj_sockaddr_in_init(&svr_addr.entry[0].addr, &target->host, 
+				     (pj_uint16_t)target->port);
     } else {
-	status = pj_sockaddr_init(&svr_addr.entry[0].addr, &target->host, target->port);
+	status = pj_sockaddr_in_init(&svr_addr.entry[0].addr, &target->host, 
+				     (pj_uint16_t)target->port);
 	pj_assert(status == PJ_SUCCESS);
     }
Index: /pjproject/main/pjsip/src/pjsip/sip_transaction.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_transaction.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_transaction.c	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_transaction.h>
@@ -8,4 +7,5 @@
 #include <pjsip/sip_event.h>
 #include <pjsip/sip_endpoint.h>
+#include <pjsip/sip_errno.h>
 #include <pj/log.h>
 #include <pj/string.h>
@@ -13,7 +13,8 @@
 #include <pj/guid.h>
 #include <pj/pool.h>
+#include <pj/assert.h>
 
 /* Thread Local Storage ID for transaction lock (initialized by endpoint) */
-int pjsip_tsx_lock_tls_id;
+long pjsip_tsx_lock_tls_id;
 
 /* State names */
@@ -44,8 +45,12 @@
 } tsx_lock_data;
 
+
 /* Timer timeout value constants */
-static const pj_time_val t1_timer_val = { PJSIP_T1_TIMEOUT/1000, PJSIP_T1_TIMEOUT%1000 };
-static const pj_time_val t4_timer_val = { PJSIP_T4_TIMEOUT/1000, PJSIP_T4_TIMEOUT%1000 };
-static const pj_time_val td_timer_val = { PJSIP_TD_TIMEOUT/1000, PJSIP_TD_TIMEOUT%1000 };
+static const pj_time_val t1_timer_val = { PJSIP_T1_TIMEOUT/1000, 
+                                          PJSIP_T1_TIMEOUT%1000 };
+static const pj_time_val t4_timer_val = { PJSIP_T4_TIMEOUT/1000, 
+                                          PJSIP_T4_TIMEOUT%1000 };
+static const pj_time_val td_timer_val = { PJSIP_TD_TIMEOUT/1000, 
+                                          PJSIP_TD_TIMEOUT%1000 };
 static const pj_time_val timeout_timer_val = { (64*PJSIP_T1_TIMEOUT)/1000,
 					       (64*PJSIP_T1_TIMEOUT)%1000 };
@@ -59,33 +64,37 @@
 
 /* Function Prototypes */
-static int  pjsip_tsx_on_state_null( pjsip_transaction *tsx, 
-				     pjsip_event *event);
-static int  pjsip_tsx_on_state_calling( pjsip_transaction *tsx, 
-				        pjsip_event *event);
-static int  pjsip_tsx_on_state_trying( pjsip_transaction *tsx, 
-				       pjsip_event *event);
-static int  pjsip_tsx_on_state_proceeding_uas( pjsip_transaction *tsx, 
-					       pjsip_event *event);
-static int  pjsip_tsx_on_state_proceeding_uac( pjsip_transaction *tsx, 
-					       pjsip_event *event);
-static int  pjsip_tsx_on_state_completed_uas( pjsip_transaction *tsx, 
-					      pjsip_event *event);
-static int  pjsip_tsx_on_state_completed_uac( pjsip_transaction *tsx, 
-					      pjsip_event *event);
-static int  pjsip_tsx_on_state_confirmed( pjsip_transaction *tsx, 
-					  pjsip_event *event);
-static int  pjsip_tsx_on_state_terminated( pjsip_transaction *tsx, 
-					   pjsip_event *event);
-static int  pjsip_tsx_on_state_destroyed( pjsip_transaction *tsx, 
-					  pjsip_event *event);
-static void tsx_timer_callback( pj_timer_heap_t *theap, 
-			        pj_timer_entry *entry);
-static int  tsx_send_msg( pjsip_transaction *tsx, pjsip_tx_data *tdata);
-static void lock_tsx( pjsip_transaction *tsx, struct tsx_lock_data *lck );
-static pj_status_t unlock_tsx( pjsip_transaction *tsx, struct tsx_lock_data *lck );
+static pj_status_t pjsip_tsx_on_state_null(     pjsip_transaction *tsx, 
+				                pjsip_event *event);
+static pj_status_t pjsip_tsx_on_state_calling(  pjsip_transaction *tsx, 
+				                pjsip_event *event);
+static pj_status_t pjsip_tsx_on_state_trying(   pjsip_transaction *tsx, 
+				                pjsip_event *event);
+static pj_status_t pjsip_tsx_on_state_proceeding_uas( pjsip_transaction *tsx, 
+					        pjsip_event *event);
+static pj_status_t pjsip_tsx_on_state_proceeding_uac( pjsip_transaction *tsx,
+					        pjsip_event *event);
+static pj_status_t pjsip_tsx_on_state_completed_uas( pjsip_transaction *tsx, 
+					        pjsip_event *event);
+static pj_status_t pjsip_tsx_on_state_completed_uac( pjsip_transaction *tsx,
+					        pjsip_event *event);
+static pj_status_t pjsip_tsx_on_state_confirmed(pjsip_transaction *tsx, 
+					        pjsip_event *event);
+static pj_status_t pjsip_tsx_on_state_terminated(pjsip_transaction *tsx, 
+					        pjsip_event *event);
+static pj_status_t pjsip_tsx_on_state_destroyed(pjsip_transaction *tsx, 
+					        pjsip_event *event);
+
+static void         tsx_timer_callback( pj_timer_heap_t *theap, 
+			                pj_timer_entry *entry);
+static int          tsx_send_msg( pjsip_transaction *tsx, 
+                                  pjsip_tx_data *tdata);
+static void         lock_tsx( pjsip_transaction *tsx, struct 
+                               tsx_lock_data *lck );
+static pj_status_t  unlock_tsx( pjsip_transaction *tsx, 
+                               struct tsx_lock_data *lck );
 
 /* State handlers for UAC, indexed by state */
-static int  (*tsx_state_handler_uac[PJSIP_TSX_STATE_MAX])(pjsip_transaction *tsx,
-							  pjsip_event *event ) = 
+static int  (*tsx_state_handler_uac[PJSIP_TSX_STATE_MAX])(pjsip_transaction *,
+							  pjsip_event *) = 
 {
     &pjsip_tsx_on_state_null,
@@ -100,6 +109,6 @@
 
 /* State handlers for UAS */
-static int  (*tsx_state_handler_uas[PJSIP_TSX_STATE_MAX])(pjsip_transaction *tsx, 
-							  pjsip_event *event ) = 
+static int  (*tsx_state_handler_uas[PJSIP_TSX_STATE_MAX])(pjsip_transaction *, 
+							  pjsip_event *) = 
 {
     &pjsip_tsx_on_state_null,
@@ -154,9 +163,9 @@
  * components. Additional comparison is needed to fully match a transaction.
  */
-void create_tsx_key_2543( pj_pool_t *pool,
-			  pj_str_t *str,
-			  pjsip_role_e role,
-			  const pjsip_method *method,
-			  const pjsip_rx_data *rdata )
+static pj_status_t create_tsx_key_2543( pj_pool_t *pool,
+			                pj_str_t *str,
+			                pjsip_role_e role,
+			                const pjsip_method *method,
+			                const pjsip_rx_data *rdata )
 {
 #define SEPARATOR   '$'
@@ -167,15 +176,20 @@
     pj_str_t *host;
 
+    PJ_ASSERT_RETURN(pool && str && method && rdata, PJ_EINVAL);
+    PJ_ASSERT_RETURN(rdata->msg, PJ_EINVAL);
+    PJ_ASSERT_RETURN(rdata->via, PJSIP_EMISSINGHDR);
+    PJ_ASSERT_RETURN(rdata->cseq, PJSIP_EMISSINGHDR);
+    PJ_ASSERT_RETURN(rdata->from, PJSIP_EMISSINGHDR);
+
     host = &rdata->via->sent_by.host;
     req_uri = (pjsip_uri*)rdata->msg->line.req.uri;
 
     /* Calculate length required. */
-    len_required = PJSIP_MAX_URL_SIZE +	    /* URI */
-		   9 +			    /* CSeq number */
-		   rdata->from_tag.slen +   /* From tag. */
+    len_required = 9 +			    /* CSeq number */
+		   rdata->from->tag.slen +   /* From tag. */
 		   rdata->call_id.slen +    /* Call-ID */
 		   host->slen +		    /* Via host. */
 		   9 +			    /* Via port. */
-		   32;			    /* Separator+Allowance. */
+		   16;			    /* Separator+Allowance. */
     key = p = pj_pool_alloc(pool, len_required);
     end = p + len_required;
@@ -224,7 +238,4 @@
      * request retransmissions will contain the same port.
      */
-    if ((end-p) < host->slen + 12) {
-	goto on_error;
-    }
     pj_memcpy(p, host->ptr, host->slen);
     p += host->slen;
@@ -241,12 +252,5 @@
     str->slen = p-key;
 
-    return;
-
-on_error:
-    PJ_LOG(2,("tsx........", "Not enough buffer (%d) for transaction key",
-	      len_required));
-    pj_assert(0);
-    str->ptr = NULL;
-    str->slen = 0;
+    return PJ_SUCCESS;
 }
 
@@ -254,11 +258,13 @@
  * Create transaction key for RFC3161 compliant system.
  */
-void create_tsx_key_3261( pj_pool_t *pool,
-			  pj_str_t *key,
-			  pjsip_role_e role,
-			  const pjsip_method *method,
-			  const pj_str_t *branch )
+static pj_status_t create_tsx_key_3261( pj_pool_t *pool,
+		                        pj_str_t *key,
+		                        pjsip_role_e role,
+		                        const pjsip_method *method,
+		                        const pj_str_t *branch)
 {
     char *p;
+
+    PJ_ASSERT_RETURN(pool && key && method && branch, PJ_EINVAL);
 
     p = key->ptr = pj_pool_alloc(pool, branch->slen + method->name.slen + 4 );
@@ -281,4 +287,6 @@
     /* Set length */
     key->slen = p - key->ptr;
+
+    return PJ_SUCCESS;
 }
 
@@ -287,10 +295,12 @@
  * in the transaction hash table.
  */
-PJ_DEF(void) pjsip_tsx_create_key( pj_pool_t *pool, pj_str_t *key, 
-				   pjsip_role_e role, 
-				   const pjsip_method *method, 
-				   const pjsip_rx_data *rdata )
-{
-    pj_str_t rfc3261_branch = {PJSIP_RFC3261_BRANCH_ID, PJSIP_RFC3261_BRANCH_LEN};
+PJ_DEF(pj_status_t) pjsip_tsx_create_key( pj_pool_t *pool, pj_str_t *key, 
+				          pjsip_role_e role, 
+				          const pjsip_method *method, 
+				          const pjsip_rx_data *rdata)
+{
+    pj_str_t rfc3261_branch = {PJSIP_RFC3261_BRANCH_ID, 
+                               PJSIP_RFC3261_BRANCH_LEN};
+
 
     /* Get the branch parameter in the top-most Via.
@@ -301,15 +311,16 @@
     const pj_str_t *branch = &rdata->via->branch_param;
 
-    if (pj_strncmp(branch, &rfc3261_branch, PJSIP_RFC3261_BRANCH_LEN) == 0) {
+    if (pj_strncmp(branch,&rfc3261_branch,PJSIP_RFC3261_BRANCH_LEN)==0) {
 
 	/* Create transaction key. */
-	create_tsx_key_3261(pool, key, role, method, branch);
+	return create_tsx_key_3261(pool, key, role, method, branch);
 
     } else {
-	/* Create the key for the message. This key will be matched up with the
-	 * transaction key. For RFC2563 transactions, the transaction key
-	 * was created by the same function, so it will match the message.
+	/* Create the key for the message. This key will be matched up 
+         * with the transaction key. For RFC2563 transactions, the 
+         * transaction key was created by the same function, so it will 
+         * match the message.
 	 */
-	create_tsx_key_2543( pool, key, role, method, rdata );
+	return create_tsx_key_2543( pool, key, role, method, rdata );
     }
 }
@@ -319,8 +330,10 @@
  * Create new transaction.
  */
-PJ_DEF(pjsip_transaction *) pjsip_tsx_create(pj_pool_t *pool,
-					     pjsip_endpoint *endpt)
+pj_status_t pjsip_tsx_create( pj_pool_t *pool,
+			      pjsip_endpoint *endpt,
+                              pjsip_transaction **p_tsx)
 {
     pjsip_transaction *tsx;
+    pj_status_t status;
 
     tsx = pj_pool_calloc(pool, 1, sizeof(pjsip_transaction));
@@ -336,11 +349,12 @@
     tsx->timeout_timer.user_data = tsx;
     tsx->timeout_timer.cb = &tsx_timer_callback;
-    sprintf(tsx->obj_name, "tsx%p", tsx);
-    tsx->mutex = pj_mutex_create(pool, "mtsx%p", 0);
-    if (!tsx->mutex) {
-	return NULL;
-    }
-
-    return tsx;
+    pj_sprintf(tsx->obj_name, "tsx%p", tsx);
+    status = pj_mutex_create_recursive(pool, "mtsx%p", &tsx->mutex);
+    if (status != PJ_SUCCESS) {
+	return status;
+    }
+
+    *p_tsx = tsx;
+    return PJ_SUCCESS;
 }
 
@@ -353,5 +367,6 @@
 
     pj_mutex_lock(tsx->mutex);
-    prev_data = (struct tsx_lock_data *) pj_thread_local_get(pjsip_tsx_lock_tls_id);
+    prev_data = (struct tsx_lock_data *) 
+                    pj_thread_local_get(pjsip_tsx_lock_tls_id);
     lck->prev = prev_data;
     lck->tsx = tsx;
@@ -368,5 +383,6 @@
  * will be set to zero.
  */
-static pj_status_t unlock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck)
+static pj_status_t unlock_tsx( pjsip_transaction *tsx, 
+                               struct tsx_lock_data *lck)
 {
     pj_assert( (void*)pj_thread_local_get(pjsip_tsx_lock_tls_id) == lck);
@@ -376,5 +392,5 @@
 	pj_mutex_unlock(tsx->mutex);
 
-    return lck->is_alive ? 0 : -1;
+    return lck->is_alive ? PJ_SUCCESS : PJSIP_ETSXDESTROYED;
 }
 
@@ -384,11 +400,12 @@
 static void tsx_set_state( pjsip_transaction *tsx,
 			   pjsip_tsx_state_e state,
-			   const pjsip_event *event )
+			   pjsip_event_id_e event_src_type,
+                           void *event_src )
 {
     pjsip_event e;
 
-    PJ_LOG(4, (tsx->obj_name, "STATE %s-->%s, ev=%s (src:%s)", 
-	       state_str[tsx->state], state_str[state], pjsip_event_str(event->type),
-	       pjsip_event_str(event->src_type)));
+    PJ_LOG(4, (tsx->obj_name, "STATE %s-->%s, cause = %s",
+	       state_str[tsx->state], state_str[state], 
+               pjsip_event_str(event_src_type)));
 
     /* Change state. */
@@ -403,7 +420,5 @@
 
     /* Inform TU */
-    pj_memcpy(&e, event, sizeof(*event));
-    e.type = PJSIP_EVENT_TSX_STATE_CHANGED;
-    e.obj.tsx = tsx;
+    PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src);
     pjsip_endpt_send_tsx_event( tsx->endpt, &e  );
 
@@ -414,5 +429,7 @@
 
 	/* Decrement transport reference counter. */
-	if (tsx->transport && tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL) {
+	if (tsx->transport && 
+            tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL) 
+        {
 	    pjsip_transport_dec_ref( tsx->transport );
 	    tsx->transport = NULL;
@@ -484,5 +501,6 @@
 	while (last_route_hdr->next != (void*)&tdata->msg->hdr) {
 	    pjsip_route_hdr *hdr;
-	    hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, last_route_hdr->next);
+	    hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, 
+                                     last_route_hdr->next);
 	    if (!hdr)
 		break;
@@ -564,5 +582,6 @@
 	pj_strdup(tdata->pool, &send_addr->host, &url->host);
         send_addr->port = url->port;
-	send_addr->type = pjsip_transport_get_type_from_name(&url->transport_param);
+	send_addr->type = 
+            pjsip_transport_get_type_from_name(&url->transport_param);
 
     } else if (PJSIP_URI_SCHEME_IS_SIP(target_uri)) {
@@ -571,5 +590,6 @@
 	pj_strdup(tdata->pool, &send_addr->host, &url->host);
 	send_addr->port = url->port;
-	send_addr->type = pjsip_transport_get_type_from_name(&url->transport_param);
+	send_addr->type = 
+            pjsip_transport_get_type_from_name(&url->transport_param);
 #if PJ_HAS_TCP
 	if (send_addr->type == PJSIP_TRANSPORT_TCP || 
@@ -580,7 +600,6 @@
 #endif
     } else {
-	PJ_LOG(2, (tsx->obj_name, "Unable to lookup destination address for "
-				  "non SIP-URL"));   
-	return -1;
+        pj_assert(!"Unsupported URI scheme!");
+	return PJSIP_EINVALIDSCHEME;
     }
 
@@ -599,5 +618,5 @@
 
     /* Success. */
-    return 0;  
+    return PJ_SUCCESS;  
 }
 
@@ -625,5 +644,5 @@
 				  addr, tsx->dest_name.port));
     } else {
-	PJ_LOG(3, (tsx->obj_name, "%s unable to connect to %s:%d, status=%d", 
+	PJ_LOG(4, (tsx->obj_name, "%s unable to connect to %s:%d, status=%d", 
 				  pjsip_transport_get_type_name(tr),
 				  addr, tsx->dest_name.port, status));
@@ -634,13 +653,9 @@
 
     if (status != PJ_SUCCESS) {
-	pjsip_event event;
-	
-	event.type = PJSIP_EVENT_TRANSPORT_ERROR;
-	event.src_type = PJSIP_EVENT_TX_MSG;
-	event.src.tdata = tsx->last_tx;
-
 	tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL;
 	tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR;
-	tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, &event);
+
+	tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED,
+                      PJSIP_EVENT_TRANSPORT_ERROR, (void*)status);
 
 	/* Unlock transaction. */
@@ -649,6 +664,6 @@
     }
 
-    /* See if transaction has already been terminated. If so, schedule to destroy
-     * the transaction.
+    /* See if transaction has already been terminated. 
+     * If so, schedule to destroy the transaction.
      */
     if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
@@ -691,13 +706,8 @@
 
     if (status != PJ_SUCCESS || addr->count == 0) {
-	pjsip_event event;
-	
-	event.type = PJSIP_EVENT_TRANSPORT_ERROR;
-	event.src_type = PJSIP_EVENT_TX_MSG;
-	event.src.tdata = tsx->last_tx;
-
 	lock_tsx(tsx, &lck);
 	tsx->status_code = PJSIP_SC_TSX_RESOLVE_ERROR;
-	tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, &event);
+	tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, 
+                      PJSIP_EVENT_TRANSPORT_ERROR, (void*)status);
 	unlock_tsx(tsx, &lck);
 	return;
@@ -712,6 +722,6 @@
     /* Create/find the transport for the remote address. */
     PJ_LOG(5,(tsx->obj_name, "tsx getting transport for %s:%d",
-			     pj_sockaddr_get_str_addr(&addr->entry[0].addr),
-			     pj_sockaddr_get_port(&addr->entry[0].addr)));
+			     pj_inet_ntoa(addr->entry[0].addr.sin_addr),
+			     pj_ntohs(addr->entry[0].addr.sin_port)));
 
     tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_CONNECTING;
@@ -739,6 +749,6 @@
     pjsip_cseq_hdr *cseq;
     pjsip_via_hdr *via;
+    pj_status_t status;
     struct tsx_lock_data lck;
-    const pjsip_hdr *endpt_hdr;
 
     PJ_LOG(4,(tsx->obj_name, "initializing tsx as UAC (tdata=%p)", tdata));
@@ -756,5 +766,5 @@
     pjsip_method_copy( tsx->pool, &tsx->method, &msg->line.req.method);
 
-    /* Generate branch parameter if it doesn't exist. */
+    /* Generate Via header if it doesn't exist. */
     via = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, NULL);
     if (via == NULL) {
@@ -772,21 +782,21 @@
 	tmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN;
 	pj_generate_unique_string( &tmp );
-    }
-
-    /* Copy branch parameter. */
-    tsx->branch = via->branch_param;
-
-    /* Add additional request headers from endpoint. */
-    endpt_hdr = pjsip_endpt_get_request_headers(tsx->endpt)->next;
-    while (endpt_hdr != pjsip_endpt_get_request_headers(tsx->endpt)) {
-	pjsip_hdr *hdr = pjsip_hdr_shallow_clone(tdata->pool, endpt_hdr);
-	pjsip_msg_add_hdr( tdata->msg, hdr );
-	endpt_hdr = endpt_hdr->next;
-    }
+
+        /* Save branch parameter. */
+        tsx->branch = via->branch_param;
+    } else {
+        /* Copy branch parameter. */
+        pj_strdup(tsx->pool, &tsx->branch, &via->branch_param);
+    }
+
 
     /* Generate transaction key. */
-    create_tsx_key_3261( tsx->pool, &tsx->transaction_key,
-			 PJSIP_ROLE_UAC, &tsx->method, 
-			 &via->branch_param);
+    status = create_tsx_key_3261( tsx->pool, &tsx->transaction_key,
+			          PJSIP_ROLE_UAC, &tsx->method, 
+			          &via->branch_param);
+    if (status != PJ_SUCCESS) {
+        unlock_tsx(tsx, &lck);
+        return status;
+    }
 
     PJ_LOG(6, (tsx->obj_name, "tsx_key=%.*s", tsx->transaction_key.slen,
@@ -796,6 +806,7 @@
     cseq = pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL);
     if (!cseq) {
-	PJ_LOG(4,(tsx->obj_name, "CSeq header not present in outgoing message!"));
-	return -1;
+	pj_assert(!"CSeq header not present in outgoing message!");
+        unlock_tsx(tsx, &lck);
+	return PJSIP_EMISSINGHDR;
     }
     tsx->cseq = cseq->cseq;
@@ -806,20 +817,15 @@
      */
     tsx->state = PJSIP_TSX_STATE_NULL;
-    tsx->state_handler = pjsip_tsx_on_state_null;
+    tsx->state_handler = &pjsip_tsx_on_state_null;
 
     /* Get destination name from the message. */
-    if (tsx_process_route(tsx, tdata, &tsx->dest_name) != 0) {
-	pjsip_event event;
-	PJ_LOG(3,(tsx->obj_name, "Error: unable to get destination address for request"));
-	
-	event.type = PJSIP_EVENT_TRANSPORT_ERROR;
-	event.src_type = PJSIP_EVENT_TX_MSG;
-	event.src.tdata = tsx->last_tx;
-
+    status = tsx_process_route(tsx, tdata, &tsx->dest_name);
+    if (status != PJ_SUCCESS) {
 	tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL;
 	tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR;
-	tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, &event);
+	tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, 
+                      PJSIP_EVENT_TRANSPORT_ERROR, (void*)status);
 	unlock_tsx(tsx, &lck);
-	return -1;
+	return status;
     }
 
@@ -859,4 +865,5 @@
     pj_str_t *branch;
     pjsip_cseq_hdr *cseq;
+    pj_status_t status;
     struct tsx_lock_data lck;
 
@@ -878,6 +885,10 @@
      * create transaction key.
      */
-    pjsip_tsx_create_key(tsx->pool, &tsx->transaction_key, PJSIP_ROLE_UAS, 
-			 &tsx->method, rdata);
+    status = pjsip_tsx_create_key(tsx->pool, &tsx->transaction_key, 
+                                  PJSIP_ROLE_UAS, &tsx->method, rdata);
+    if (status != PJ_SUCCESS) {
+        unlock_tsx(tsx, &lck);
+        return status;
+    }
 
     /* Duplicate branch parameter for transaction. */
@@ -914,5 +925,6 @@
 	tsx->current_addr = 0;
 	tsx->remote_addr.count = 1;
-	tsx->remote_addr.entry[0].type = pjsip_transport_get_type(tsx->transport);
+	tsx->remote_addr.entry[0].type = 
+		pjsip_transport_get_type(tsx->transport);
 	pj_memcpy(&tsx->remote_addr.entry[0].addr, 
 		  &rdata->addr, rdata->addr_len);
@@ -924,15 +936,8 @@
 					 rdata->via, &tsx->dest_name);
 	if (status != PJ_SUCCESS) {
-	    pjsip_event event;
-	    PJ_LOG(2,(tsx->obj_name, "Unable to get destination address "
-				     "for response"));
-	    
-	    event.type = PJSIP_EVENT_TRANSPORT_ERROR;
-	    event.src_type = PJSIP_EVENT_TX_MSG;
-	    event.src.tdata = tsx->last_tx;
-
 	    tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL;
 	    tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR;
-	    tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, &event);
+	    tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, 
+                          PJSIP_EVENT_TRANSPORT_ERROR, (void*)status);
 	    unlock_tsx(tsx, &lck);
 	    return status;
@@ -944,5 +949,6 @@
 	 */
 	PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d",
-				 tsx->dest_name.host.slen, tsx->dest_name.host.ptr,
+				 tsx->dest_name.host.slen, 
+				 tsx->dest_name.host.ptr,
 				 tsx->dest_name.port));
 
@@ -976,9 +982,12 @@
 
     PJ_LOG(5,(tsx->obj_name, "got timer event (%s timer)", 
-	     (entry->id == TSX_TIMER_RETRANSMISSION ? "Retransmit" : "Timeout")));
-
-    event.type = event.src_type = PJSIP_EVENT_TIMER;
-    event.src.timer = (entry->id == TSX_TIMER_RETRANSMISSION ? 
-	&tsx->retransmit_timer : &tsx->timeout_timer);
+	     (entry->id==TSX_TIMER_RETRANSMISSION ? "Retransmit" : "Timeout")));
+
+
+    if (entry->id == TSX_TIMER_RETRANSMISSION) {
+        PJSIP_EVENT_INIT_TIMER(event, &tsx->retransmit_timer);
+    } else {
+        PJSIP_EVENT_INIT_TIMER(event, &tsx->timeout_timer);
+    }
 
     /* Dispatch event to transaction. */
@@ -1000,8 +1009,9 @@
     pjsip_msg *msg;
     pjsip_host_port dest_addr;
-    pjsip_event event;
     pjsip_via_hdr *via;
     struct tsx_lock_data lck;
-
+    pj_status_t status = PJ_SUCCESS;
+
+    /* Lock tsx. */
     lock_tsx(tsx, &lck);
 
@@ -1024,6 +1034,6 @@
 
     /* Get destination name from the message. */
-    if (tsx_process_route(tsx, tdata, &dest_addr) != 0){
-	PJ_LOG(2,(tsx->obj_name, "Unable to get destination address for request"));
+    status = tsx_process_route(tsx, tdata, &dest_addr);
+    if (status != 0){
 	goto on_error;
     }
@@ -1089,8 +1099,7 @@
      */
     tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR;
-    event.type = PJSIP_EVENT_TRANSPORT_ERROR;
-    event.src_type = PJSIP_EVENT_TX_MSG;
-    event.src.tdata = tdata;
-    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, &event);
+
+    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                   PJSIP_EVENT_TRANSPORT_ERROR, (void*)status);
 
     unlock_tsx(tsx, &lck);
@@ -1106,17 +1115,14 @@
     pjsip_event event;
     struct tsx_lock_data lck;
-
-    PJ_LOG(5,(tsx->obj_name, "on transmit msg (tdata=%p)", tdata));
-
-    event.type = event.src_type = PJSIP_EVENT_TX_MSG;
-    event.src.tdata = tdata;
-
-    PJ_LOG(5,(tsx->obj_name, "on state %s (ev=%s, src=%s, data=%p)", 
-	      state_str[tsx->state], pjsip_event_str(event.type), 
-	      pjsip_event_str(event.src_type), event.src.data));
+    pj_status_t status;
+
+    PJ_LOG(5,(tsx->obj_name, "Request to transmit msg on state %s (tdata=%p)",
+                             state_str[tsx->state], tdata));
+
+    PJSIP_EVENT_INIT_TX_MSG(event, tsx, tdata);
 
     /* Dispatch to transaction. */
     lock_tsx(tsx, &lck);
-    (*tsx->state_handler)(tsx, &event);
+    status = (*tsx->state_handler)(tsx, &event);
     unlock_tsx(tsx, &lck);
 }
@@ -1131,15 +1137,14 @@
     pjsip_event event;
     struct tsx_lock_data lck;
-
-    event.type = event.src_type = PJSIP_EVENT_RX_MSG;
-    event.src.rdata = rdata;
-
-    PJ_LOG(5,(tsx->obj_name, "on state %s (ev=%s, src=%s, data=%p)", 
-	      state_str[tsx->state], pjsip_event_str(event.type), 
-	      pjsip_event_str(event.src_type), event.src.data));
+    pj_status_t status;
+
+    PJ_LOG(5,(tsx->obj_name, "Incoming msg on state %s (rdata=%p)", 
+	      state_str[tsx->state], rdata));
+
+    PJSIP_EVENT_INIT_RX_MSG(event, tsx, rdata);
 
     /* Dispatch to transaction. */
     lock_tsx(tsx, &lck);
-    (*tsx->state_handler)(tsx, &event);
+    status = (*tsx->state_handler)(tsx, &event);
     unlock_tsx(tsx, &lck);
 }
@@ -1150,15 +1155,10 @@
 PJ_DEF(void) pjsip_tsx_terminate( pjsip_transaction *tsx, int code )
 {
-    pjsip_event event;
     struct tsx_lock_data lck;
 
     lock_tsx(tsx, &lck);
-
     tsx->status_code = code;
-    event.type = PJSIP_EVENT_USER;
-    event.src_type = PJSIP_EVENT_USER;
-    event.src.data = 0;
-    event.obj.tsx = tsx;
-    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, &event);
+    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                   PJSIP_EVENT_USER, NULL);
 
     unlock_tsx(tsx, &lck);
@@ -1170,12 +1170,13 @@
  * transmitted when transport connection completion callback is called.
  */
-static int tsx_send_msg( pjsip_transaction *tsx, pjsip_tx_data *tdata)
-{
-    pjsip_event event;
+static pj_status_t tsx_send_msg( pjsip_transaction *tsx, 
+                                 pjsip_tx_data *tdata)
+{
+    pj_status_t status = PJ_SUCCESS;
 
     PJ_LOG(5,(tsx->obj_name, "sending msg (tdata=%p)", tdata));
 
     if (tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL) {
-	int sent;
+	pj_ssize_t sent;
 	pjsip_event before_tx_event;
 
@@ -1200,23 +1201,20 @@
 			pjsip_transport_get_type_name(tsx->transport));
 		pj_strdup2(tdata->pool, &via->sent_by.host, 
-			pj_sockaddr_get_str_addr(addr_name));
-		via->sent_by.port = pj_sockaddr_get_port(addr_name);
+			   pj_inet_ntoa(addr_name->sin_addr));
+		via->sent_by.port = pj_ntohs(addr_name->sin_port);
 	    }
 	}
 
 	/* Notify everybody we're about to send message. */
-	before_tx_event.type = PJSIP_EVENT_BEFORE_TX;
-	before_tx_event.src_type = PJSIP_EVENT_TX_MSG;
-	before_tx_event.obj.tsx = tsx;
-	before_tx_event.src.tdata = tdata;
-	before_tx_event.data.long_data = tsx->retransmit_count;
-	pjsip_endpt_send_tsx_event( tsx->endpt, &before_tx_event  );
+        PJSIP_EVENT_INIT_PRE_TX_MSG(before_tx_event, tsx, tdata, 
+                                    tsx->retransmit_count);
+	pjsip_endpt_send_tsx_event( tsx->endpt, &before_tx_event );
 
 	tsx->has_unsent_msg = 0;
-	sent = pjsip_transport_send_msg(
-		tsx->transport, tdata,
-		&tsx->remote_addr.entry[tsx->current_addr].addr
-		);
-	if (sent < 1) {
+	status = pjsip_transport_send_msg(
+		        tsx->transport, tdata,
+		        &tsx->remote_addr.entry[tsx->current_addr].addr,
+                        &sent);
+	if (status != PJ_SUCCESS) {
 	    goto on_error;
 	}
@@ -1229,9 +1227,7 @@
 on_error:
     tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR;
-    event.type = PJSIP_EVENT_TRANSPORT_ERROR;
-    event.src_type = PJSIP_EVENT_TX_MSG;
-    event.src.tdata = tdata;
-    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, &event);
-    return -1;
+    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                   PJSIP_EVENT_TRANSPORT_ERROR, (void*)status);
+    return status;
 }
 
@@ -1242,4 +1238,6 @@
 					 int should_restart_timer)
 {
+    pj_status_t status;
+
     PJ_LOG(4,(tsx->obj_name, "retransmiting (tdata=%p, count=%d, restart?=%d)", 
 	      tsx->last_tx, tsx->retransmit_count, should_restart_timer));
@@ -1249,6 +1247,7 @@
     ++tsx->retransmit_count;
 
-    if (tsx_send_msg( tsx, tsx->last_tx) != 0) {
-	return -1;
+    status = tsx_send_msg( tsx, tsx->last_tx);
+    if (status != PJ_SUCCESS) {
+	return status;
     }
     
@@ -1258,10 +1257,11 @@
 	int msec_time = (1 << (tsx->retransmit_count)) * PJSIP_T1_TIMEOUT;
 
-	if (tsx->method.id != PJSIP_INVITE_METHOD && msec_time > PJSIP_T2_TIMEOUT) 
+	if (tsx->method.id!=PJSIP_INVITE_METHOD && msec_time>PJSIP_T2_TIMEOUT) 
 	    msec_time = PJSIP_T2_TIMEOUT;
 
 	timeout.sec = msec_time / 1000;
 	timeout.msec = msec_time % 1000;
-	pjsip_endpt_schedule_timer( tsx->endpt, &tsx->retransmit_timer, &timeout);
+	pjsip_endpt_schedule_timer( tsx->endpt, &tsx->retransmit_timer, 
+				    &timeout);
     }
 
@@ -1272,6 +1272,9 @@
  * Handler for events in state Null.
  */
-static int  pjsip_tsx_on_state_null( pjsip_transaction *tsx, pjsip_event *event )
-{
+static pj_status_t pjsip_tsx_on_state_null( pjsip_transaction *tsx, 
+                                            pjsip_event *event )
+{
+    pj_status_t status;
+
     pj_assert( tsx->state == PJSIP_TSX_STATE_NULL);
     pj_assert( tsx->last_tx == NULL );
@@ -1282,8 +1285,9 @@
 	/* Set state to Trying. */
 	pj_assert(event->type == PJSIP_EVENT_RX_MSG);
-	tsx_set_state( tsx, PJSIP_TSX_STATE_TRYING, event);
+	tsx_set_state( tsx, PJSIP_TSX_STATE_TRYING, 
+                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 
     } else {
-	pjsip_tx_data *tdata = event->src.tdata;
+	pjsip_tx_data *tdata = event->body.tx_msg.tdata;
 
 	/* Save the message for retransmission. */
@@ -1292,6 +1296,7 @@
 
 	/* Send the message. */
-	if (tsx_send_msg( tsx, tdata) != 0) {
-	    return -1;
+        status = tsx_send_msg( tsx, tdata);
+	if (status != PJ_SUCCESS) {
+	    return status;
 	}
 
@@ -1299,5 +1304,6 @@
 	 * timeout.
 	 */
-	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 
@@ -1307,10 +1313,12 @@
 	    PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) 
 	{
-	    pjsip_endpt_schedule_timer(tsx->endpt, &tsx->retransmit_timer, &t1_timer_val);
+	    pjsip_endpt_schedule_timer(tsx->endpt, &tsx->retransmit_timer, 
+                                       &t1_timer_val);
 	    tsx->retransmit_count = 0;
 	}
 
 	/* Move state. */
-	tsx_set_state( tsx, PJSIP_TSX_STATE_CALLING, event);
+	tsx_set_state( tsx, PJSIP_TSX_STATE_CALLING, 
+                       PJSIP_EVENT_TX_MSG, tdata);
     }
 
@@ -1322,6 +1330,6 @@
  * is received.
  */
-static int  pjsip_tsx_on_state_calling( pjsip_transaction *tsx, 
-				        pjsip_event *event)
+static pj_status_t pjsip_tsx_on_state_calling( pjsip_transaction *tsx, 
+				               pjsip_event *event )
 {
     pj_assert(tsx->state == PJSIP_TSX_STATE_CALLING);
@@ -1329,14 +1337,16 @@
 
     if (event->type == PJSIP_EVENT_TIMER && 
-	event->src.timer == &tsx->retransmit_timer) 
+	event->body.timer.entry == &tsx->retransmit_timer) 
     {
+        pj_status_t status;
 
 	/* Retransmit the request. */
-	if (pjsip_tsx_retransmit( tsx, 1 ) != 0) {
-	    return -1;
+        status = pjsip_tsx_retransmit( tsx, 1 );
+	if (status != PJ_SUCCESS) {
+	    return status;
 	}
 
     } else if (event->type == PJSIP_EVENT_TIMER && 
-	      event->src.timer == &tsx->timeout_timer) 
+	       event->body.timer.entry == &tsx->timeout_timer) 
     {
 
@@ -1350,8 +1360,9 @@
 
 	/* Inform TU. */
-	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, event );
+	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                       PJSIP_EVENT_TIMER, &tsx->timeout_timer);
 
 	/* Transaction is destroyed */
-	return -1;
+	return PJSIP_ETSXDESTROYED;
 
     } else if (event->type == PJSIP_EVENT_RX_MSG) {
@@ -1370,5 +1381,5 @@
 	 */
 	/* Keep last_tx for authorization. */
-	code = event->src.rdata->msg->line.status.code;
+	code = event->body.rx_msg.rdata->msg->line.status.code;
 	if (tsx->method.id != PJSIP_INVITE_METHOD && code!=401 && code!=407) {
 	    pjsip_tx_data_dec_ref(tsx->last_tx);
@@ -1381,4 +1392,5 @@
     } else {
 	pj_assert(0);
+        return PJ_EBUG;
     }
 
@@ -1392,7 +1404,8 @@
  *	 non-INVITE client transaction (bug in RFC?).
  */
-static int  pjsip_tsx_on_state_trying( pjsip_transaction *tsx, pjsip_event *event)
-{
-    int result;
+static pj_status_t pjsip_tsx_on_state_trying( pjsip_transaction *tsx, 
+                                              pjsip_event *event)
+{
+    pj_status_t status;
 
     pj_assert(tsx->state == PJSIP_TSX_STATE_TRYING);
@@ -1415,12 +1428,13 @@
      * "Proceeding" state.
      */
-    result = pjsip_tsx_on_state_proceeding_uas( tsx, event);
+    status = pjsip_tsx_on_state_proceeding_uas( tsx, event);
 
     /* Inform the TU of the state transision if state is still State_Trying */
-    if (result==0 && tsx->state == PJSIP_TSX_STATE_TRYING) {
-	tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, event);
-    }
-
-    return result;
+    if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TRYING) {
+	tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 
+                       PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata);
+    }
+
+    return status;
 }
 
@@ -1429,5 +1443,6 @@
  * This state happens after the TU sends provisional response.
  */
-static int pjsip_tsx_on_state_proceeding_uas( pjsip_transaction *tsx, pjsip_event *event)
+static pj_status_t pjsip_tsx_on_state_proceeding_uas( pjsip_transaction *tsx,
+                                                      pjsip_event *event)
 {
     pj_assert(tsx->state == PJSIP_TSX_STATE_PROCEEDING || 
@@ -1440,11 +1455,15 @@
     if (event->type == PJSIP_EVENT_RX_MSG) {
 
+        pj_status_t status;
+
 	/* Send last response. */
-	if (pjsip_tsx_retransmit( tsx, 0 ) != 0) {
-	    return -1;
+        status = pjsip_tsx_retransmit( tsx, 0 );
+	if (status != PJ_SUCCESS) {
+	    return status;
 	}
 	
     } else if (event->type == PJSIP_EVENT_TX_MSG ) {
-	pjsip_tx_data *tdata = event->src.tdata;
+	pjsip_tx_data *tdata = event->body.tx_msg.tdata;
+        pj_status_t status;
 
 	/* The TU sends response message to the request. Save this message so
@@ -1472,6 +1491,7 @@
 
 	/* Send the message. */
-	if (tsx_send_msg(tsx, tdata) != 0) {
-	    return -1;
+        status = tsx_send_msg(tsx, tdata);
+	if (status != PJ_SUCCESS) {
+	    return status;
 	}
 
@@ -1486,5 +1506,6 @@
 		pjsip_tx_data_add_ref( tdata );
 	    }
-	    tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, event);
+	    tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 
+                           PJSIP_EVENT_TX_MSG, tdata );
 
 	} else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) {
@@ -1492,11 +1513,12 @@
 	    if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_ack==0) {
 
-		/* 2xx class message is not saved, because retransmission is handled
-		 * by the TU.
+		/* 2xx class message is not saved, because retransmission 
+                 * is handled by TU.
 		 */
-		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, event);
+		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                               PJSIP_EVENT_TX_MSG, tdata );
 
 		/* Transaction is destroyed. */
-		return -1;
+		return PJSIP_ETSXDESTROYED;
 
 	    } else {
@@ -1505,5 +1527,6 @@
 		if (tsx->method.id == PJSIP_INVITE_METHOD) {
 		    tsx->retransmit_count = 0;
-		    pjsip_endpt_schedule_timer( tsx->endpt, &tsx->retransmit_timer, 
+		    pjsip_endpt_schedule_timer( tsx->endpt, 
+                                                &tsx->retransmit_timer, 
 						&t1_timer_val);
 		}
@@ -1526,13 +1549,17 @@
 		}
 
-		pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &timeout);
+		pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 
+                                            &timeout);
 
 		/* Set state to "Completed" */
-		tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, event);
+		tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
+                               PJSIP_EVENT_TX_MSG, tdata );
 	    }
 
 	} else if (tsx->status_code >= 300) {
 
-	    /* 3xx-6xx class message causes transaction to move to "Completed" state. */
+	    /* 3xx-6xx class message causes transaction to move to 
+             * "Completed" state. 
+             */
 	    if (tsx->last_tx != tdata) {
 		tsx->last_tx = tdata;
@@ -1541,5 +1568,6 @@
 
 	    /* Start timer H for transaction termination */
-	    pjsip_endpt_schedule_timer(tsx->endpt,&tsx->timeout_timer,&timeout_timer_val);
+	    pjsip_endpt_schedule_timer(tsx->endpt,&tsx->timeout_timer,
+                                       &timeout_timer_val);
 
 	    /* For INVITE, if unreliable transport is used, retransmission 
@@ -1547,8 +1575,10 @@
 	     */
 	    if (PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) {
-		pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, NULL);
+		pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ,
+                                                           NULL);
 		if (cseq->method.id == PJSIP_INVITE_METHOD) {
 		    tsx->retransmit_count = 0;
-		    pjsip_endpt_schedule_timer(tsx->endpt, &tsx->retransmit_timer, 
+		    pjsip_endpt_schedule_timer(tsx->endpt, 
+                                               &tsx->retransmit_timer, 
 					       &t1_timer_val);
 		}
@@ -1556,5 +1586,6 @@
 
 	    /* Inform TU */
-	    tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, event);
+	    tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
+                           PJSIP_EVENT_TX_MSG, tdata );
 
 	} else {
@@ -1564,6 +1595,7 @@
 
     } else if (event->type == PJSIP_EVENT_TIMER && 
-	       event->src.timer == &tsx->retransmit_timer) {
+	       event->body.timer.entry == &tsx->retransmit_timer) {
 	/* Retransmission timer elapsed. */
+        pj_status_t status;
 
 	/* Must have last response to retransmit. */
@@ -1571,10 +1603,11 @@
 
 	/* Retransmit the last response. */
-	if (pjsip_tsx_retransmit( tsx, 1 ) != 0) {
-	    return -1;
+        status = pjsip_tsx_retransmit( tsx, 1 );
+	if (status != PJ_SUCCESS) {
+	    return status;
 	}
 
     } else if (event->type == PJSIP_EVENT_TIMER && 
-	       event->src.timer == &tsx->timeout_timer) {
+	       event->body.timer.entry == &tsx->timeout_timer) {
 
 	/* Timeout timer. should not happen? */
@@ -1583,13 +1616,15 @@
 	tsx->status_code = PJSIP_SC_TSX_TIMEOUT;
 
-	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, event);
-
-	return -1;
+	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                       PJSIP_EVENT_TIMER, &tsx->timeout_timer);
+
+	return PJ_EBUG;
 
     } else {
 	pj_assert(0);
-    }
-
-    return 0;
+        return PJ_EBUG;
+    }
+
+    return PJ_SUCCESS;
 }
 
@@ -1599,5 +1634,6 @@
  * UAS.
  */
-static int pjsip_tsx_on_state_proceeding_uac( pjsip_transaction *tsx, pjsip_event *event)
+static pj_status_t pjsip_tsx_on_state_proceeding_uac(pjsip_transaction *tsx, 
+                                                     pjsip_event *event)
 {
 
@@ -1611,8 +1647,8 @@
 	pj_assert(event->type == PJSIP_EVENT_RX_MSG);
 	if (event->type != PJSIP_EVENT_RX_MSG) {
-	    return 0;
-	}
-
-	tsx->status_code = event->src.rdata->msg->line.status.code;
+	    return PJ_EINVALIDOP;
+	}
+
+	tsx->status_code = event->body.rx_msg.rdata->msg->line.status.code;
     } else {
 	tsx->status_code = PJSIP_SC_TSX_TIMEOUT;
@@ -1622,5 +1658,6 @@
 
 	/* Inform the message to TU. */
-	tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, event);
+	tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 
+                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 
     } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code,200)) {
@@ -1633,6 +1670,7 @@
 	 */
 	if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_ack == 0) {
-	    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, event);
-	    return -1;
+	    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
+	    return PJSIP_ETSXDESTROYED;
 
 	} else {
@@ -1650,12 +1688,15 @@
 		timeout.sec = timeout.msec = 0;
 	    }
-	    pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &timeout);
+	    pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 
+					&timeout);
 
 	    /* Move state to Completed, inform TU. */
-	    tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, event);
+	    tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
+                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 	}
 
     } else if (tsx->status_code >= 300 && tsx->status_code <= 699) {
 	pj_time_val timeout;
+        pj_status_t status;
 
 	/* Stop timer B. */
@@ -1664,7 +1705,9 @@
 	/* Generate and send ACK for INVITE. */
 	if (tsx->method.id == PJSIP_INVITE_METHOD) {
-	    pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx, event->src.rdata );
-	    if (tsx_send_msg( tsx, tsx->last_tx) != 0) {
-		return -1;
+	    pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx, 
+                                    event->body.rx_msg.rdata );
+            status = tsx_send_msg( tsx, tsx->last_tx);
+	    if (status != PJ_SUCCESS) {
+		return status;
 	    }
 	}
@@ -1683,9 +1726,11 @@
 
 	/* Inform TU. */
-	tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, event);
+	tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
+                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 
     } else {
 	// Shouldn't happen because there's no timer for this state.
 	pj_assert(0);
+        return PJ_EBUG;
     }
 
@@ -1696,16 +1741,20 @@
  * Handler for events in Completed state for UAS
  */
-static int pjsip_tsx_on_state_completed_uas( pjsip_transaction *tsx, pjsip_event *event)
+static pj_status_t pjsip_tsx_on_state_completed_uas( pjsip_transaction *tsx, 
+                                                     pjsip_event *event)
 {
     pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED);
 
     if (event->type == PJSIP_EVENT_RX_MSG) {
-	pjsip_msg *msg = event->src.rdata->msg;
+	pjsip_msg *msg = event->body.rx_msg.rdata->msg;
 	pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, NULL );
 
 	/* On receive request retransmission, retransmit last response. */
 	if (cseq->method.id != PJSIP_ACK_METHOD) {
-	    if (pjsip_tsx_retransmit( tsx, 0 ) != 0) {
-		return -1;
+            pj_status_t status;
+
+            status = pjsip_tsx_retransmit( tsx, 0 );
+	    if (status != PJ_SUCCESS) {
+		return status;
 	    }
 
@@ -1718,16 +1767,21 @@
 	    /* Start timer I in T4 interval (transaction termination). */
 	    pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer );
-	    pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &t4_timer_val);
+	    pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 
+					&t4_timer_val);
 
 	    /* Move state to "Confirmed" */
-	    tsx_set_state( tsx, PJSIP_TSX_STATE_CONFIRMED, event);
+	    tsx_set_state( tsx, PJSIP_TSX_STATE_CONFIRMED, 
+                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 	}	
 
     } else if (event->type == PJSIP_EVENT_TIMER) {
 
-	if (event->src.timer == &tsx->retransmit_timer) {
+	if (event->body.timer.entry == &tsx->retransmit_timer) {
 	    /* Retransmit message. */
-	    if (pjsip_tsx_retransmit( tsx, 1 ) != 0) {
-		return -1;
+            pj_status_t status;
+
+            status = pjsip_tsx_retransmit( tsx, 1 );
+	    if (status != PJ_SUCCESS) {
+		return status;
 	    }
 
@@ -1741,12 +1795,14 @@
 		tsx->status_code = PJSIP_SC_TSX_TIMEOUT;
 
-		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, event);
-
-		return -1;
+		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                               PJSIP_EVENT_TIMER, &tsx->timeout_timer );
+
+		return PJSIP_ETSXDESTROYED;
 
 	    } else {
 		/* Transaction terminated, it can now be deleted. */
-		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, event);
-		return -1;
+		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                               PJSIP_EVENT_TIMER, &tsx->timeout_timer );
+		return PJSIP_ETSXDESTROYED;
 	    }
 	}
@@ -1754,5 +1810,5 @@
     } else {
 	/* Ignore request to transmit. */
-	pj_assert(event->src.tdata == tsx->last_tx);
+	pj_assert(event->body.tx_msg.tdata == tsx->last_tx);
     }
 
@@ -1763,5 +1819,6 @@
  * Handler for events in Completed state for UAC transaction.
  */
-static int pjsip_tsx_on_state_completed_uac( pjsip_transaction *tsx, pjsip_event *event)
+static pj_status_t pjsip_tsx_on_state_completed_uac( pjsip_transaction *tsx,
+                                                     pjsip_event *event)
 {
     pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED);
@@ -1769,11 +1826,12 @@
     if (event->type == PJSIP_EVENT_TIMER) {
 	/* Must be the timeout timer. */
-	pj_assert(event->src.timer == &tsx->timeout_timer);
+	pj_assert(event->body.timer.entry == &tsx->timeout_timer);
 
 	/* Move to Terminated state. */
-	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, event);
+	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                       PJSIP_EVENT_TIMER, event->body.timer.entry );
 
 	/* Transaction has been destroyed. */
-	return -1;
+	return PJSIP_ETSXDESTROYED;
 
     } else if (event->type == PJSIP_EVENT_RX_MSG) {
@@ -1782,11 +1840,14 @@
 	     * TU doesn't need to be informed.
 	     */
-	    pjsip_msg *msg = event->src.rdata->msg;
+	    pjsip_msg *msg = event->body.rx_msg.rdata->msg;
 	    pj_assert(msg->type == PJSIP_RESPONSE_MSG);
 	    if (msg->type==PJSIP_RESPONSE_MSG &&
 		msg->line.status.code >= 200)
 	    {
-		if (pjsip_tsx_retransmit( tsx, 0 ) != 0) {
-		    return -1;
+                pj_status_t status;
+
+                status = pjsip_tsx_retransmit( tsx, 0 );
+		if (status != PJ_SUCCESS) {
+		    return status;
 		}
 	    } else {
@@ -1799,10 +1860,12 @@
     } else if (tsx->method.id == PJSIP_INVITE_METHOD &&
 	       event->type == PJSIP_EVENT_TX_MSG &&
-	       event->src.tdata->msg->line.req.method.id == PJSIP_ACK_METHOD) {
+	       event->body.tx_msg.tdata->msg->line.req.method.id==PJSIP_ACK_METHOD) {
+
+        pj_status_t status;
 
 	/* Set last transmitted message. */
-	if (tsx->last_tx != event->src.tdata) {
+	if (tsx->last_tx != event->body.tx_msg.tdata) {
 	    pjsip_tx_data_dec_ref( tsx->last_tx );
-	    tsx->last_tx = event->src.tdata;
+	    tsx->last_tx = event->body.tx_msg.tdata;
 	    pjsip_tx_data_add_ref( tsx->last_tx );
 	}
@@ -1811,14 +1874,18 @@
 	 * Must notify now, so app has chance to put SDP in outgoing ACK msg.
 	 */
-	tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, event );
+	tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
+                       PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata );
 
 	/* Send msg */
-	tsx_send_msg(tsx, event->src.tdata);
+	status = tsx_send_msg(tsx, event->body.tx_msg.tdata);
+        if (status != PJ_SUCCESS)
+            return status;
 
     } else {
 	pj_assert(0);
-    }
-
-    return 0;
+        return PJ_EBUG;
+    }
+
+    return PJ_SUCCESS;
 }
 
@@ -1826,5 +1893,6 @@
  * Handler for events in state Confirmed.
  */
-static int pjsip_tsx_on_state_confirmed( pjsip_transaction *tsx, pjsip_event *event)
+static pj_status_t pjsip_tsx_on_state_confirmed( pjsip_transaction *tsx,
+                                                 pjsip_event *event)
 {
     pj_assert(tsx->state == PJSIP_TSX_STATE_CONFIRMED);
@@ -1836,23 +1904,34 @@
     /* Absorb any ACK received. */
     if (event->type == PJSIP_EVENT_RX_MSG) {
+
+        pjsip_method_e method_id = 
+            event->body.rx_msg.rdata->msg->line.req.method.id;
+
 	/* Must be a request message. */
-	pj_assert(event->src.rdata->msg->type == PJSIP_REQUEST_MSG);
+	pj_assert(event->body.rx_msg.rdata->msg->type == PJSIP_REQUEST_MSG);
 
 	/* Must be an ACK request or a late INVITE retransmission. */
-	pj_assert(event->src.rdata->msg->line.req.method.id == PJSIP_ACK_METHOD ||
-		  event->src.rdata->msg->line.req.method.id == PJSIP_INVITE_METHOD);
+	pj_assert(method_id == PJSIP_ACK_METHOD ||
+		  method_id == PJSIP_INVITE_METHOD);
+
+        /* Just so that compiler won't complain about unused vars when
+         * building release code.
+         */
+        PJ_UNUSED_ARG(method_id);
 
     } else if (event->type == PJSIP_EVENT_TIMER) {
 	/* Must be from timeout_timer_. */
-	pj_assert(event->src.timer == &tsx->timeout_timer);
+	pj_assert(event->body.timer.entry == &tsx->timeout_timer);
 
 	/* Move to Terminated state. */
-	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, event);
+	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
+                       PJSIP_EVENT_TIMER, &tsx->timeout_timer );
 
 	/* Transaction has been destroyed. */
-	return -1;
+	return PJSIP_ETSXDESTROYED;
 
     } else {
 	pj_assert(0);
+        return PJ_EBUG;
     }
 
@@ -1863,12 +1942,14 @@
  * Handler for events in state Terminated.
  */
-static int pjsip_tsx_on_state_terminated( pjsip_transaction *tsx, pjsip_event *event)
+static pj_status_t pjsip_tsx_on_state_terminated( pjsip_transaction *tsx,
+                                                  pjsip_event *event)
 {
     pj_assert(tsx->state == PJSIP_TSX_STATE_TERMINATED);
 
-    PJ_UNUSED_ARG(event)
+    PJ_UNUSED_ARG(event);
 
     /* Destroy this transaction */
-    tsx_set_state(tsx, PJSIP_TSX_STATE_DESTROYED, event);
+    tsx_set_state(tsx, PJSIP_TSX_STATE_DESTROYED, 
+                  event->type, event->body.user.user1 );
 
     return PJ_SUCCESS;
@@ -1876,8 +1957,9 @@
 
 
-static int pjsip_tsx_on_state_destroyed( pjsip_transaction *tsx, pjsip_event *event)
-{
-    PJ_UNUSED_ARG(tsx)
-    PJ_UNUSED_ARG(event)
+static pj_status_t pjsip_tsx_on_state_destroyed(pjsip_transaction *tsx,
+                                                pjsip_event *event)
+{
+    PJ_UNUSED_ARG(tsx);
+    PJ_UNUSED_ARG(event);
     return PJ_SUCCESS;
 }
Index: /pjproject/main/pjsip/src/pjsip/sip_transport.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_transport.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_transport.c	(revision 43)
@@ -1,4 +1,3 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_transport.h>
@@ -7,4 +6,5 @@
 #include <pjsip/sip_msg.h>
 #include <pjsip/sip_private.h>
+#include <pjsip/sip_errno.h>
 #include <pj/os.h>
 #include <pj/log.h>
@@ -13,4 +13,5 @@
 #include <pj/string.h>
 #include <pj/pool.h>
+#include <pj/assert.h>
 
 #define MGR_IDLE_CHECK_INTERVAL	30
@@ -45,5 +46,5 @@
      *  listener list. 
      */
-    PJ_DECL_LIST_MEMBER(struct pjsip_transport_t)
+    PJ_DECL_LIST_MEMBER(struct pjsip_transport_t);
 
     /** Transport's pool. */
@@ -67,4 +68,7 @@
     /** I/O Queue key */
     pj_ioqueue_key_t	*key;
+
+    /** Accept key. */
+    pj_ioqueue_op_key_t	 accept_op;
 
     /** Receive data buffer */
@@ -116,4 +120,6 @@
     pj_ioqueue_t    *ioqueue;
     pj_time_val	     next_idle_check;
+    pj_size_t        send_buf_size;
+    pj_size_t        recv_buf_size;
     void           (*message_callback)(pjsip_endpoint*, pjsip_rx_data *rdata);
 };
@@ -145,5 +151,5 @@
 struct transport_callback
 {
-    PJ_DECL_LIST_MEMBER(struct transport_callback)
+    PJ_DECL_LIST_MEMBER(struct transport_callback);
 
     /** User defined token to be passed to the callback. */
@@ -174,8 +180,16 @@
 };
 
-static void on_ioqueue_read(pj_ioqueue_key_t *key, pj_ssize_t bytes_read);
-static void on_ioqueue_write(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent);
-static void on_ioqueue_accept(pj_ioqueue_key_t *key, int status);
-static void on_ioqueue_connect(pj_ioqueue_key_t *key, int status);
+static void on_ioqueue_read(pj_ioqueue_key_t *key, 
+                            pj_ioqueue_op_key_t *op_key, 
+                            pj_ssize_t bytes_read);
+static void on_ioqueue_write(pj_ioqueue_key_t *key, 
+                             pj_ioqueue_op_key_t *op_key, 
+                             pj_ssize_t bytes_sent);
+static void on_ioqueue_accept(pj_ioqueue_key_t *key, 
+                              pj_ioqueue_op_key_t *op_key, 
+			      pj_sock_t newsock,
+                              int status);
+static void on_ioqueue_connect(pj_ioqueue_key_t *key, 
+                               int status);
 
 static pj_ioqueue_callback ioqueue_transport_callback = 
@@ -195,9 +209,9 @@
     key->type = (pj_uint8_t)tr->type;
     key->zero = 0;
-    key->addr = pj_sockaddr_get_addr(&tr->remote_addr);
-    key->port = pj_sockaddr_get_port(&tr->remote_addr);
+    key->addr = pj_sockaddr_in_get_addr(&tr->remote_addr).s_addr;
+    key->port = pj_sockaddr_in_get_port(&tr->remote_addr);
     /*
     if (key->port == 0) {
-	key->port = pj_sockaddr_get_port(&tr->local_addr);
+	key->port = pj_sockaddr_in_get_port(&tr->local_addr);
     }
     */
@@ -213,6 +227,6 @@
     key->type = (pj_uint8_t)type;
     key->zero = 0;
-    key->addr = pj_sockaddr_get_addr(addr);
-    key->port = pj_sockaddr_get_port(addr);
+    key->addr = pj_sockaddr_in_get_addr(addr).s_addr;
+    key->port = pj_sockaddr_in_get_port(addr);
 }
 #endif
@@ -221,5 +235,5 @@
 			  const pj_sockaddr_in *addr)
 {
-    PJ_UNUSED_ARG(addr)
+    PJ_UNUSED_ARG(addr);
 
     /* This is to detect alignment problems. */
@@ -237,5 +251,5 @@
 	pj_sockaddr_in addr;
 	pj_sockaddr_set_str_addr(&addr, &localaddr);
-	key->addr = pj_sockaddr_get_addr(&addr);
+	key->addr = pj_sockaddr_in_get_addr(&addr);
     }
 #endif
@@ -298,10 +312,14 @@
  * Create new transmit buffer.
  */
-pjsip_tx_data* pjsip_tx_data_create( pjsip_transport_mgr *mgr )
+pj_status_t pjsip_tx_data_create( pjsip_transport_mgr *mgr,
+                                  pjsip_tx_data **p_tdata )
 {
     pj_pool_t *pool;
     pjsip_tx_data *tdata;
+    pj_status_t status;
 
     PJ_LOG(5, ("", "pjsip_tx_data_create"));
+
+    PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL);
 
     pool = pjsip_endpt_create_pool( mgr->endpt, "ptdt%p",
@@ -309,18 +327,19 @@
 				    PJSIP_POOL_INC_TDATA );
     if (!pool) {
-	return NULL;
+	return PJ_ENOMEM;
     }
     tdata = pj_pool_calloc(pool, 1, sizeof(pjsip_tx_data));
     tdata->pool = pool;
     tdata->mgr = mgr;
-    sprintf(tdata->obj_name,"txd%p", tdata);
-
-    tdata->ref_cnt = pj_atomic_create(tdata->pool, 0);
-    if (!tdata->ref_cnt) {
+    pj_sprintf(tdata->obj_name,"txd%p", tdata);
+
+    status = pj_atomic_create(tdata->pool, 0, &tdata->ref_cnt);
+    if (status != PJ_SUCCESS) {
 	pjsip_endpt_destroy_pool( mgr->endpt, tdata->pool );
-	return NULL;
+	return status;
     }
     
-    return tdata;
+    *p_tdata = tdata;
+    return PJ_SUCCESS;
 }
 
@@ -340,5 +359,5 @@
 {
     pj_assert( pj_atomic_get(tdata->ref_cnt) > 0);
-    if (pj_atomic_dec(tdata->ref_cnt) <= 0) {
+    if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) {
 	PJ_LOG(6,(tdata->obj_name, "destroying txdata"));
 	pj_atomic_destroy( tdata->ref_cnt );
@@ -376,5 +395,5 @@
     } else 
 #else
-    PJ_UNUSED_ARG(flag)
+    PJ_UNUSED_ARG(flag);
 #endif
     {
@@ -453,5 +472,5 @@
 {
     pj_assert(tr->ref_cnt > 0);
-    if (pj_atomic_dec(tr->ref_cnt) == 0) {
+    if (pj_atomic_dec_and_get(tr->ref_cnt) == 0) {
 	pj_gettimeofday(&tr->close_time);
 	tr->close_time.sec += PJSIP_TRANSPORT_CLOSE_TIMEOUT;
@@ -462,6 +481,7 @@
  * Open the underlying transport.
  */
-static pj_sock_t create_socket( pjsip_transport_type_e type,
-				pj_sockaddr_in *local )
+static pj_status_t create_socket( pjsip_transport_type_e type,
+				  pj_sockaddr_in *local,
+                                  pj_sock_t *p_sock)
 {
     int sock_family;
@@ -469,4 +489,5 @@
     int sock_proto;
     int len;
+    pj_status_t status;
     pj_sock_t sock;
 
@@ -484,15 +505,11 @@
 #endif
     } else {
-	PJ_LOG(2,("", "create_socket: unsupported transport type %s",
-		  get_type_name(type)));
-	return PJ_INVALID_SOCKET;
+	return PJ_EINVAL;
     }
 
     /* Create socket. */
-    sock = pj_sock_socket( sock_family, sock_type, sock_proto, PJ_SOCK_ASYNC);
-    if (sock == PJ_INVALID_SOCKET) {
-	PJ_PERROR((THIS_FILE, "%s socket()", get_type_name(type)));
-	return PJ_INVALID_SOCKET;
-    }
+    status = pj_sock_socket( sock_family, sock_type, sock_proto, &sock);
+    if (status != PJ_SUCCESS)
+	return status;
 
     /* Bind the socket to the requested address, or if no address is
@@ -501,11 +518,8 @@
     if (/*local->sin_addr.s_addr != 0 &&*/ local->sin_port != 0) {
 	/* Bind to the requested address. */
-	if (pj_sock_bind(sock, local, sizeof(*local)) != 0) {
-	    PJ_PERROR((THIS_FILE, "bind() to %s %s:%d",
-				  get_type_name(type),
-				  pj_sockaddr_get_str_addr(local),
-				  pj_sockaddr_get_port(local)));
+        status = pj_sock_bind(sock, local, sizeof(*local));
+	if (status != PJ_SUCCESS) {
 	    pj_sock_close(sock);
-	    return PJ_INVALID_SOCKET;
+	    return status;
 	}
     } else if (type == PJSIP_TRANSPORT_UDP) {
@@ -517,20 +531,21 @@
 	pj_memset(local, 0, sizeof(*local));
 	local->sin_family = PJ_AF_INET;
-	if (pj_sock_bind(sock, local, sizeof(*local)) != 0) {
-	    PJ_PERROR((THIS_FILE, "bind() to %s 0.0.0.0:0", get_type_name(type)));
+        status = pj_sock_bind(sock, local, sizeof(*local));
+	if (status != PJ_SUCCESS) {
 	    pj_sock_close(sock);
-	    return PJ_INVALID_SOCKET;
+	    return status;
 	}
 
 	/* Get the local address. */
 	len = sizeof(pj_sockaddr_in);
-	if (pj_sock_getsockname(sock, local, &len)) {
-	    PJ_PERROR((THIS_FILE, "getsockname()"));
+        status = pj_sock_getsockname(sock, local, &len);
+	if (status != PJ_SUCCESS) {
 	    pj_sock_close(sock);
-	    return -1;
-	}
-    }
-
-    return sock;
+	    return status;
+	}
+    }
+
+    *p_sock = sock;
+    return PJ_SUCCESS;
 }
 
@@ -548,12 +563,14 @@
  * Create a new transport object.
  */
-static pjsip_transport_t* create_transport( pjsip_transport_mgr *mgr,
-					    pjsip_transport_type_e type,
-					    pj_sock_t sock_hnd,
-					    const pj_sockaddr_in *local_addr,
-					    const pj_sockaddr_in *addr_name)
+static pj_status_t create_transport( pjsip_transport_mgr *mgr,
+				     pjsip_transport_type_e type,
+				     pj_sock_t sock_hnd,
+				     const pj_sockaddr_in *local_addr,
+				     const pj_sockaddr_in *addr_name,
+				     pjsip_transport_t **p_transport )
 {
     pj_pool_t *tr_pool=NULL, *rdata_pool=NULL;
     pjsip_transport_t *tr = NULL;
+    pj_status_t status;
 
     /* Allocate pool for transport from endpoint. */
@@ -563,4 +580,5 @@
 				       PJSIP_POOL_INC_TRANSPORT );
     if (!tr_pool) {
+	status = PJ_ENOMEM;
 	goto on_error;
     }
@@ -572,4 +590,5 @@
 					     PJSIP_POOL_INC_RDATA );
     if (!rdata_pool) {
+	status = PJ_ENOMEM;
 	goto on_error;
     }
@@ -583,5 +602,5 @@
     pj_memcpy(&tr->local_addr, local_addr, sizeof(pj_sockaddr_in));
     pj_list_init(&tr->cb_list);
-    sprintf(tr->obj_name, transport_get_name_format(type), tr);
+    pj_sprintf(tr->obj_name, transport_get_name_format(type), tr);
 
     if (type != PJSIP_TRANSPORT_UDP) {
@@ -596,8 +615,7 @@
 
     /* Create atomic */
-    tr->ref_cnt = pj_atomic_create(tr_pool, 0);
-    if (!tr->ref_cnt) {
+    status = pj_atomic_create(tr_pool, 0, &tr->ref_cnt);
+    if (status != PJ_SUCCESS)
 	goto on_error;
-    }
     
     /* Init rdata in the transport. */
@@ -608,20 +626,18 @@
     
     /* Init transport mutex. */
-    tr->tr_mutex = pj_mutex_create(tr_pool, "mtr%p", 0);
-    if (!tr->tr_mutex) {
-	PJ_PERROR((tr->obj_name, "pj_mutex_create()"));
+    status = pj_mutex_create_recursive(tr_pool, "mtr%p", &tr->tr_mutex);
+    if (status != PJ_SUCCESS)
 	goto on_error;
-    }
 
     /* Register to I/O Queue */
-    tr->key = pj_ioqueue_register(tr_pool, mgr->ioqueue, 
-				  (pj_oshandle_t)tr->sock, tr,
-				  &ioqueue_transport_callback);
-    if (tr->key == NULL) {
-	PJ_PERROR((tr->obj_name, "pj_ioqueue_register()"));
+    status = pj_ioqueue_register_sock( tr_pool, mgr->ioqueue, 
+				       tr->sock, tr,
+				       &ioqueue_transport_callback,
+				       &tr->key);
+    if (status != PJ_SUCCESS)
 	goto on_error;
-    }
-
-    return tr;
+
+    *p_transport = tr;
+    return PJ_SUCCESS;
 
 on_error:
@@ -635,5 +651,5 @@
 	pjsip_endpt_destroy_pool(mgr->endpt, rdata_pool);
     }
-    return NULL;
+    return status;
 }
 
@@ -641,10 +657,10 @@
  * Destroy transport.
  */
-static void destroy_transport( pjsip_transport_mgr *mgr, pjsip_transport_t *tr )
+static void destroy_transport( pjsip_transport_mgr *mgr, pjsip_transport_t *tr)
 {
     transport_key hash_key;
 
     /* Remove from I/O queue. */
-    pj_ioqueue_unregister( mgr->ioqueue, tr->key );
+    pj_ioqueue_unregister( tr->key );
 
     /* Remove from hash table */
@@ -669,10 +685,16 @@
 
 
-static int transport_send_msg( pjsip_transport_t *tr, pjsip_tx_data *tdata,
-			       const pj_sockaddr_in *addr)
+static pj_status_t transport_send_msg( pjsip_transport_t *tr, 
+				       pjsip_tx_data *tdata,
+				       const pj_sockaddr_in *addr, 
+				       pj_ssize_t *p_sent)
 {
     const char *buf = tdata->buf.start;
-    int sent;
-    int len;
+    pj_ssize_t size;
+    pj_status_t status;
+
+    /* Can only send if tdata is not being sent! */
+    if (pj_ioqueue_is_pending(tr->key, &tdata->op_key))
+	return PJSIP_EPENDINGTX;
 
     /* Allocate buffer if necessary. */
@@ -685,20 +707,17 @@
     /* Print the message if it's not printed */
     if (tdata->buf.cur <= tdata->buf.start) {
-	len = pjsip_msg_print(tdata->msg, tdata->buf.start, 
-			      tdata->buf.end - tdata->buf.start);
-	if (len < 1) {
-	    return len;
-	}
-	tdata->buf.cur += len;
-	tdata->buf.cur[len] = '\0';
-    }
-
-    /* BUG BUG BUG */
-    /* MUST CHECK THAT THE SOCKET IS READY TO SEND (IOQueue)! */
-    PJ_TODO(BUG_BUG_BUG___SENDING_DATAGRAM_WHILE_SOCKET_IS_PENDING__)
+	size = pjsip_msg_print( tdata->msg, tdata->buf.start, 
+			        tdata->buf.end - tdata->buf.start);
+	if (size < 0) {
+	    return PJSIP_EMSGTOOLONG;
+	}
+	pj_assert(size != 0);
+	tdata->buf.cur += size;
+	tdata->buf.cur[size] = '\0';
+    }
 
     /* Send the message. */
     buf = tdata->buf.start;
-    len = tdata->buf.cur - tdata->buf.start;
+    size = tdata->buf.cur - tdata->buf.start;
 
     if (tr->type == PJSIP_TRANSPORT_UDP) {
@@ -707,10 +726,10 @@
 		  "%s"
 		  "------------ end msg -------------",
-		  pj_sockaddr_get_str_addr(addr), 
-		  pj_sockaddr_get_port(addr),
-		  len, buf));
-
-	sent = pj_ioqueue_sendto( tr->mgr->ioqueue, tr->key,
-				  buf, len, addr, sizeof(*addr));
+		  pj_inet_ntoa(addr->sin_addr), 
+		  pj_sockaddr_in_get_port(addr),
+		  size, buf));
+
+	status = pj_ioqueue_sendto( tr->key, &tdata->op_key,
+				    buf, &size, 0, addr, sizeof(*addr));
     } 
 #if PJ_HAS_TCP
@@ -720,22 +739,17 @@
 		  "%s"
 		  "------------ end msg -------------",
-		  len, buf));
-
-	sent = pj_ioqueue_write (tr->mgr->ioqueue, tr->key, buf, len);
+		  size, buf));
+
+	status = pj_ioqueue_send(tr->key, &tdata->op_key, buf, &size, 0);
     }
 #else
     else {
-	pj_assert(0);
-	sent = -1;
+	pj_assert(!"Unsupported transport");
+	status = PJSIP_EUNSUPTRANSPORT;
     }
 #endif
 
-    if (sent == len || sent == PJ_IOQUEUE_PENDING) {
-	return len;
-    }
-
-    /* On error, clear the flag. */
-    PJ_PERROR((tr->obj_name, tr->type == PJSIP_TRANSPORT_UDP ? "pj_ioqueue_sendto()" : "pj_ioqueue_write()"));
-    return -1;
+    *p_sent = size;
+    return status;
 }
 
@@ -744,14 +758,12 @@
  * in the outgoing data.
  */
-PJ_DEF(int) pjsip_transport_send_msg( pjsip_transport_t *tr, 
-				      pjsip_tx_data *tdata,
-				      const pj_sockaddr_in *addr)
-{
-    int sent;
-
+PJ_DEF(pj_status_t) pjsip_transport_send_msg( pjsip_transport_t *tr,
+					      pjsip_tx_data *tdata,
+					      const pj_sockaddr_in *addr,
+					      pj_ssize_t *sent)
+{
     PJ_LOG(5, (tr->obj_name, "pjsip_transport_send_msg(tdata=%s)", tdata->obj_name));
 
-    sent = transport_send_msg(tr, tdata, addr );
-    return sent;
+    return transport_send_msg(tr, tdata, addr, sent );
 }
 
@@ -761,10 +773,12 @@
  * Create a new transport manager.
  */
-PJ_DEF(pjsip_transport_mgr*) 
-pjsip_transport_mgr_create( pj_pool_t *pool,
-			    pjsip_endpoint * endpt,
-			    void (*cb)(pjsip_endpoint*,pjsip_rx_data *) )
+PJ_DEF(pj_status_t) pjsip_transport_mgr_create( pj_pool_t *pool,
+						pjsip_endpoint * endpt,
+						void (*cb)(pjsip_endpoint*,
+							   pjsip_rx_data *),
+						pjsip_transport_mgr **p_mgr)
 {
     pjsip_transport_mgr *mgr;
+    pj_status_t status;
 
     PJ_LOG(5, (LOG_TRANSPORT_MGR, "pjsip_transport_mgr_create()"));
@@ -773,24 +787,25 @@
     mgr->endpt = endpt;
     mgr->message_callback = cb;
-    
+    mgr->send_buf_size = DEFAULT_SO_SNDBUF;
+    mgr->recv_buf_size = DEFAULT_SO_RCVBUF;
+
     mgr->transport_table = pj_hash_create(pool, MGR_HASH_TABLE_SIZE);
     if (!mgr->transport_table) {
-	PJ_LOG(3, (LOG_TRANSPORT_MGR, "error creating transport manager hash table"));
-	return NULL;
-    }
-    mgr->ioqueue = pj_ioqueue_create(pool, PJSIP_MAX_TRANSPORTS);
-    if (!mgr->ioqueue) {
-	PJ_LOG(3, (LOG_TRANSPORT_MGR, "error creating IO queue"));
-	return NULL;
-    }
-    mgr->mutex = pj_mutex_create(pool, "tmgr%p", 0);
-    if (!mgr->mutex) {
-	PJ_LOG(3, (LOG_TRANSPORT_MGR, "error creating mutex"));
+	return PJ_ENOMEM;
+    }
+    status = pj_ioqueue_create(pool, PJSIP_MAX_TRANSPORTS, &mgr->ioqueue);
+    if (status != PJ_SUCCESS) {
+	return status;
+    }
+    status = pj_mutex_create_recursive(pool, "tmgr%p", &mgr->mutex);
+    if (status != PJ_SUCCESS) {
 	pj_ioqueue_destroy(mgr->ioqueue);
-	return NULL;
+	return status;
     }
     pj_gettimeofday(&mgr->next_idle_check);
     mgr->next_idle_check.sec += MGR_IDLE_CHECK_INTERVAL;
-    return mgr;
+
+    *p_mgr = mgr;
+    return status;
 }
 
@@ -798,5 +813,5 @@
  * Destroy transport manager.
  */
-PJ_DEF(void) pjsip_transport_mgr_destroy( pjsip_transport_mgr *mgr )
+PJ_DEF(pj_status_t) pjsip_transport_mgr_destroy( pjsip_transport_mgr *mgr )
 {
     pj_hash_iterator_t itr_val;
@@ -824,4 +839,6 @@
 
     pj_mutex_unlock(mgr->mutex);
+
+    return PJ_SUCCESS;
 }
 
@@ -837,59 +854,78 @@
     pjsip_transport_t *tr;
     struct transport_key *hash_key;
-    int opt_val;
-
-    opt_val = DEFAULT_SO_SNDBUF;
-    if (pj_sock_setsockopt( sock_hnd, SOL_SOCKET, SO_SNDBUF, &opt_val, sizeof(opt_val)) != PJ_SUCCESS) {
-	PJ_LOG(3, (LOG_TRANSPORT_MGR, "create listener: error setting SNDBUF to %d", DEFAULT_SO_SNDBUF));
-	// Just ignore the error.
-    }
-
-    opt_val = DEFAULT_SO_RCVBUF;
-    if (pj_sock_setsockopt( sock_hnd, SOL_SOCKET, SO_RCVBUF, &opt_val, sizeof(opt_val)) != PJ_SUCCESS) {
-	PJ_LOG(3, (LOG_TRANSPORT_MGR, "create listener: error setting RCVBUF to %d", DEFAULT_SO_SNDBUF));
-	// Just ignore the error
-    }
-
-    tr = create_transport(mgr, type, sock_hnd, local_addr, addr_name);
-    if (!tr) {
+    const pj_str_t loopback_addr = { "127.0.0.1", 9 };
+    pj_status_t status;
+
+    if (mgr->send_buf_size != 0) {
+        int opt_val = mgr->send_buf_size;
+        status = pj_sock_setsockopt( sock_hnd, PJ_SOL_SOCKET, 
+                                     PJ_SO_SNDBUF, 
+                                     &opt_val, sizeof(opt_val));
+
+        if (status != PJ_SUCCESS) {
+	    return status;
+        }
+    }
+
+    if (mgr->recv_buf_size != 0) {
+        int opt_val = mgr->recv_buf_size;
+        status = pj_sock_setsockopt( sock_hnd, PJ_SOL_SOCKET, 
+                                     PJ_SO_RCVBUF, 
+                                     &opt_val, sizeof(opt_val));
+        if (status != PJ_SUCCESS) {
+	    return status;
+        }
+    }
+
+    status = create_transport(mgr, type, sock_hnd, local_addr, addr_name, &tr);
+    if (status != PJ_SUCCESS) {
 	pj_sock_close(sock_hnd);
-	return -1;
+	return status;
     }
 #if PJ_HAS_TCP
     if (type == PJSIP_TRANSPORT_TCP) {
-	pj_status_t status;
-
-	if (pj_sock_listen(tr->sock, BACKLOG) != 0) {
-	    PJ_PERROR((tr->obj_name, "listen()"));
+
+	status = pj_sock_listen(tr->sock, BACKLOG);
+	if (status != 0) {
 	    destroy_transport(mgr, tr);
-	    return -1;
-	}
-	tr->accept_data.addrlen = sizeof(tr->accept_data.local);
-	status = pj_ioqueue_accept(mgr->ioqueue, tr->key, 
-				   &tr->accept_data.sock, 
-				   &tr->accept_data.local, 
-				   &tr->accept_data.remote,
-				   &tr->accept_data.addrlen);
-	if (status != PJ_IOQUEUE_PENDING) {
-	    PJ_PERROR((tr->obj_name, "pj_ioqueue_accept()"));
-	    destroy_transport(mgr, tr);
-	    return -1;
-	}
+	    return status;
+	}
+	
+	/* Discard immediate connections. */
+	do {
+	    tr->accept_data.addrlen = sizeof(tr->accept_data.local);
+	    status = pj_ioqueue_accept(tr->key, &tr->accept_op,
+				       &tr->accept_data.sock, 
+				       &tr->accept_data.local, 
+				       &tr->accept_data.remote,
+				       &tr->accept_data.addrlen);
+	    if (status==PJ_SUCCESS) {
+		pj_sock_close(tr->accept_data.sock);
+	    } else if (status != PJ_EPENDING) {
+		destroy_transport(mgr, tr);
+		return status;
+	    }
+	} while (status==PJ_SUCCESS);
 
     } else 
 #endif
     if (type == PJSIP_TRANSPORT_UDP) {
-	pj_status_t status;
-
-	tr->rdata->addr_len = sizeof(tr->rdata->addr);
-	status = pj_ioqueue_recvfrom( mgr->ioqueue, tr->key, 
-				      tr->rdata->packet, PJSIP_MAX_PKT_LEN,
-				      &tr->rdata->addr, 
-				      &tr->rdata->addr_len);
-	if (status != PJ_IOQUEUE_PENDING) {
-	    PJ_PERROR((tr->obj_name, "pj_ioqueue_recvfrom()"));
-	    destroy_transport(mgr, tr);
-	    return -1;
-	}
+	pj_ssize_t bytes;
+
+	/* Discard immediate data. */
+	do {
+	    tr->rdata->addr_len = sizeof(tr->rdata->addr);
+	    bytes = PJSIP_MAX_PKT_LEN;
+	    status = pj_ioqueue_recvfrom( tr->key, &tr->rdata->op_key,
+					  tr->rdata->packet, &bytes, 0,
+					  &tr->rdata->addr, 
+					  &tr->rdata->addr_len);
+	    if (status == PJ_SUCCESS) {
+		;
+	    } else if (status != PJ_EPENDING) {
+		destroy_transport(mgr, tr);
+		return status;
+	    }
+	} while (status == PJ_SUCCESS);
     }
 
@@ -902,7 +938,9 @@
      * See further comments on struct pjsip_transport_t definition.
      */
-    if (type == PJSIP_TRANSPORT_UDP && local_addr->sin_addr.s_addr == inet_addr("127.0.0.1")) {
+    if (type == PJSIP_TRANSPORT_UDP && 
+	local_addr->sin_addr.s_addr == pj_inet_addr(&loopback_addr).s_addr)
+    {
 	pj_str_t localaddr = pj_str("127.0.0.1");
-	pj_sockaddr_set_str_addr( &tr->remote_addr, &localaddr);
+	pj_sockaddr_in_set_str_addr( &tr->remote_addr, &localaddr);
     }
     hash_key = pj_pool_alloc(tr->pool, sizeof(transport_key));
@@ -910,15 +948,16 @@
 
     pj_mutex_lock(mgr->mutex);
-    pj_hash_set(tr->pool, mgr->transport_table, hash_key, sizeof(transport_key), tr);
+    pj_hash_set(tr->pool, mgr->transport_table, 
+		hash_key, sizeof(transport_key), tr);
     pj_mutex_unlock(mgr->mutex);
 
     PJ_LOG(4,(tr->obj_name, "Listening at %s %s:%d", 
 			 get_type_name(tr->type), 
-			 pj_sockaddr_get_str_addr(&tr->local_addr),
-			 pj_sockaddr_get_port(&tr->local_addr)));
+			 pj_inet_ntoa(tr->local_addr.sin_addr),
+			 pj_sockaddr_in_get_port(&tr->local_addr)));
     PJ_LOG(4,(tr->obj_name, "Listener public address is at %s %s:%d", 
 			 get_type_name(tr->type), 
-			 pj_sockaddr_get_str_addr(&tr->addr_name),
-			 pj_sockaddr_get_port(&tr->addr_name)));
+			 pj_inet_ntoa(tr->addr_name.sin_addr),
+			 pj_sockaddr_in_get_port(&tr->addr_name)));
     return PJ_SUCCESS;
 }
@@ -933,10 +972,11 @@
 {
     pj_sock_t sock_hnd;
+    pj_status_t status;
 
     PJ_LOG(5, (LOG_TRANSPORT_MGR, "pjsip_create_listener(type=%d)", type));
 
-    sock_hnd = create_socket(type, local_addr);
-    if (sock_hnd == PJ_INVALID_SOCKET) {
-	return -1;
+    status = create_socket(type, local_addr, &sock_hnd);
+    if (status != PJ_SUCCESS) {
+	return status;
     }
 
@@ -952,10 +992,13 @@
 {
     pj_sockaddr_in local_addr;
+    pj_status_t status;
     int addrlen = sizeof(local_addr);
 
-    if (pj_sock_getsockname(sock, (pj_sockaddr_t*)&local_addr, &addrlen) != 0)
-	return -1;
-
-    return create_listener(mgr, PJSIP_TRANSPORT_UDP, sock, &local_addr, addr_name);
+    status = pj_sock_getsockname(sock, (pj_sockaddr_t*)&local_addr, &addrlen);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    return create_listener(mgr, PJSIP_TRANSPORT_UDP, sock, 
+			   &local_addr, addr_name);
 }
 
@@ -974,5 +1017,5 @@
     pjsip_transport_t *tr;
     pj_sockaddr_in local;
-    int sock_hnd;
+    pj_sock_t sock_hnd;
     pj_status_t status;
     struct transport_callback *cb_rec;
@@ -1030,14 +1073,14 @@
     pj_memset(&local, 0, sizeof(local));
     local.sin_family = PJ_AF_INET;
-    sock_hnd = create_socket(type, &local);
-    if (sock_hnd == PJ_INVALID_SOCKET) {
+    status = create_socket(type, &local, &sock_hnd);
+    if (status != PJ_SUCCESS) {
 	pj_mutex_unlock(mgr->mutex);
-	(*cb_rec->cb)(NULL, cb_rec->token, -1);
+	(*cb_rec->cb)(NULL, cb_rec->token, status);
 	return;
     }
-    tr = create_transport(mgr, type, sock_hnd, &local, NULL);
-    if (!tr) {
+    status = create_transport(mgr, type, sock_hnd, &local, NULL, &tr);
+    if (status != PJ_SUCCESS) {
 	pj_mutex_unlock(mgr->mutex);
-	(*cb_rec->cb)(NULL, cb_rec->token, -1);
+	(*cb_rec->cb)(NULL, cb_rec->token, status);
 	return;
     }
@@ -1046,12 +1089,12 @@
     if (type == PJSIP_TRANSPORT_TCP) {
 	pj_memcpy(&tr->remote_addr, remote, sizeof(pj_sockaddr_in));
-	status = pj_ioqueue_connect(mgr->ioqueue, tr->key, 
-				    &tr->remote_addr, sizeof(pj_sockaddr_in));
+	status = pj_ioqueue_connect(tr->key, &tr->remote_addr, 
+				    sizeof(pj_sockaddr_in));
 	pj_assert(status != 0);
-	if (status != PJ_IOQUEUE_PENDING) {
-	    PJ_PERROR((tr->obj_name, "pj_ioqueue_connect()"));
+	if (status != PJ_EPENDING) {
+	    PJ_TODO(HANDLE_IMMEDIATE_CONNECT);
 	    destroy_transport(mgr, tr);
 	    pj_mutex_unlock(mgr->mutex);
-	    (*cb_rec->cb)(NULL, cb_rec->token, -1);
+	    (*cb_rec->cb)(NULL, cb_rec->token, status);
 	    return;
 	}
@@ -1059,18 +1102,19 @@
 #endif
     if (type == PJSIP_TRANSPORT_UDP) {
-	int len;
+	pj_ssize_t size;
 
 	do {
 	    tr->rdata->addr_len = sizeof(tr->rdata->addr);
-	    len = pj_ioqueue_recvfrom( mgr->ioqueue, tr->key, 
-				       tr->rdata->packet, PJSIP_MAX_PKT_LEN,
-				       &tr->rdata->addr, 
-				       &tr->rdata->addr_len);
-	    pj_assert(len < 0);
-	    if (len != PJ_IOQUEUE_PENDING) {
-		PJ_PERROR((tr->obj_name, "pj_ioqueue_recvfrom()"));
+	    size = PJSIP_MAX_PKT_LEN;
+	    status = pj_ioqueue_recvfrom( tr->key, &tr->rdata->op_key,
+					  tr->rdata->packet, &size, 0,
+					  &tr->rdata->addr, 
+					  &tr->rdata->addr_len);
+	    if (status == PJ_SUCCESS)
+		;
+	    else if (status != PJ_EPENDING) {
 		destroy_transport(mgr, tr);
 		pj_mutex_unlock(mgr->mutex);
-		(*cb_rec->cb)(NULL, cb_rec->token, -1);
+		(*cb_rec->cb)(NULL, cb_rec->token, status);
 		return;
 	    }
@@ -1083,5 +1127,5 @@
 	    PJ_TODO(FIXED_BUG_ON_IMMEDIATE_TRANSPORT_DATA);
 
-	} while (len != PJ_IOQUEUE_PENDING);
+	} while (status == PJ_SUCCESS);
 
 	//Bug: cb will never be called!
@@ -1093,13 +1137,14 @@
     } else {
 	pj_mutex_unlock(mgr->mutex);
-	(*cb_rec->cb)(NULL, cb_rec->token, -1);
+	(*cb_rec->cb)(NULL, cb_rec->token, PJSIP_EUNSUPTRANSPORT);
 	return;
     }
 
-    pj_assert(status==PJ_IOQUEUE_PENDING || status==PJ_SUCCESS);
+    pj_assert(status==PJ_EPENDING || status==PJ_SUCCESS);
     pj_mutex_lock(tr->tr_mutex);
     hash_key = pj_pool_alloc(tr->pool, sizeof(transport_key));
     pj_memcpy(hash_key, &search_key, sizeof(transport_key));
-    pj_hash_set(tr->pool, mgr->transport_table, hash_key, sizeof(transport_key), tr);
+    pj_hash_set(tr->pool, mgr->transport_table, 
+		hash_key, sizeof(transport_key), tr);
     if (status == PJ_SUCCESS) {
 	pj_mutex_unlock(tr->tr_mutex);
@@ -1125,21 +1170,25 @@
     pjsip_transport_t *tr;
     transport_key *hash_key;
+    pj_ssize_t size;
 
     pj_assert (listener->type == PJSIP_TRANSPORT_TCP);
 
     if (status != PJ_SUCCESS) {
-	PJ_PERROR((listener->obj_name, "accept() returned error"));
-	return;
+	PJSIP_ENDPT_LOG_ERROR((mgr->endpt, listener->obj_name, status,
+			       "Error in accept() completion"));
+	goto on_return;
     }
 
     PJ_LOG(4,(listener->obj_name, "incoming tcp connection from %s:%d",
-	      pj_sockaddr_get_str_addr(&listener->accept_data.remote),
-	      pj_sockaddr_get_port(&listener->accept_data.remote)));
-
-    tr = create_transport(mgr, listener->type, 
-			  listener->accept_data.sock,
-			  &listener->accept_data.local,
-			  NULL);
-    if (!tr) {
+	      pj_inet_ntoa(listener->accept_data.remote.sin_addr),
+	      pj_sockaddr_in_get_port(&listener->accept_data.remote)));
+
+    status = create_transport(mgr, listener->type, 
+			      listener->accept_data.sock,
+			      &listener->accept_data.local,
+			      NULL, &tr);
+    if (status != PJ_SUCCESS) {
+	PJSIP_ENDPT_LOG_ERROR((mgr->endpt, listener->obj_name, status,
+			       "Error in creating new incoming TCP"));
 	goto on_return;
     }
@@ -1155,17 +1204,23 @@
     tr->rdata->addr_len = listener->accept_data.addrlen;
 
-    status = pj_ioqueue_read (mgr->ioqueue, tr->key, tr->rdata->packet, PJSIP_MAX_PKT_LEN);
-    if (status != PJ_IOQUEUE_PENDING) {
-	PJ_PERROR((tr->obj_name, "pj_ioqueue_read()"));
+    size = PJSIP_MAX_PKT_LEN;
+    status = pj_ioqueue_recv(tr->key, &tr->rdata->op_key, 
+			     tr->rdata->packet, &size, 0);
+    if (status != PJ_EPENDING) {
+	PJSIP_ENDPT_LOG_ERROR((mgr->endpt, listener->obj_name, status,
+			       "Error in receiving data"));
+	PJ_TODO(IMMEDIATE_DATA);
 	destroy_transport(mgr, tr);
 	goto on_return;
     }
 
-    pj_memcpy(&tr->remote_addr, &listener->accept_data.remote, listener->accept_data.addrlen);
+    pj_memcpy(&tr->remote_addr, &listener->accept_data.remote, 
+	      listener->accept_data.addrlen);
     hash_key = pj_pool_alloc(tr->pool, sizeof(transport_key));
     init_key_from_transport(hash_key, tr);
 
     pj_mutex_lock(mgr->mutex);
-    pj_hash_set(tr->pool, mgr->transport_table, hash_key, sizeof(transport_key), tr);
+    pj_hash_set(tr->pool, mgr->transport_table, hash_key, 
+		sizeof(transport_key), tr);
     pj_mutex_unlock(mgr->mutex);
 
@@ -1173,11 +1228,13 @@
     /* Re-initiate asynchronous accept() */
     listener->accept_data.addrlen = sizeof(listener->accept_data.local);
-    status = pj_ioqueue_accept(mgr->ioqueue, listener->key, 
+    status = pj_ioqueue_accept(listener->key, &listener->accept_op,
 			       &listener->accept_data.sock, 
 			       &listener->accept_data.local, 
 			       &listener->accept_data.remote,
 			       &listener->accept_data.addrlen);
-    if (status != PJ_IOQUEUE_PENDING) {
-	PJ_PERROR((listener->obj_name, "pj_ioqueue_accept()"));
+    if (status != PJ_EPENDING) {
+	PJSIP_ENDPT_LOG_ERROR((mgr->endpt, listener->obj_name, status,
+			       "Error in receiving data"));
+	PJ_TODO(IMMEDIATE_ACCEPT);
 	return;
     }
@@ -1194,6 +1251,7 @@
     struct transport_callback new_list;
     struct transport_callback *cb_rec;
-
-    PJ_UNUSED_ARG(mgr)
+    pj_ssize_t recv_size;
+
+    PJ_UNUSED_ARG(mgr);
 
     /* On connect completion, we must call all registered callbacks in
@@ -1222,9 +1280,10 @@
     if (status == PJ_SUCCESS) {
 	int addrlen = sizeof(tr->local_addr);
-	int rc;
-	if ((rc=pj_sock_getsockname(tr->sock, (pj_sockaddr_t*)&tr->local_addr, &addrlen)) == 0) {
+	
+	status = pj_sock_getsockname(tr->sock, 
+				     (pj_sockaddr_t*)&tr->local_addr, 
+				     &addrlen);
+	if (status == PJ_SUCCESS) {
 	    pj_memcpy(&tr->addr_name, &tr->local_addr, sizeof(tr->addr_name));
-	} else {
-	    PJ_LOG(4,(tr->obj_name, "Unable to get local address (getsockname=%d)", rc));
 	}
     }
@@ -1245,12 +1304,15 @@
     if (status != PJ_SUCCESS) {
 	destroy_transport(mgr, tr);
+	PJ_TODO(WTF);
 	return;
     }
 
     /* Initiate read operation to socket. */
-    status = pj_ioqueue_read (mgr->ioqueue, tr->key, tr->rdata->packet, PJSIP_MAX_PKT_LEN);
-    if (status != PJ_IOQUEUE_PENDING) {
-	PJ_PERROR((tr->obj_name, "pj_ioqueue_read()"));
+    recv_size = PJSIP_MAX_PKT_LEN;
+    status = pj_ioqueue_recv( tr->key, &tr->rdata->op_key, tr->rdata->packet, 
+			      &recv_size, 0);
+    if (status != PJ_EPENDING) {
 	destroy_transport(mgr, tr);
+	PJ_TODO(IMMEDIATE_DATA);
 	return;
     }
@@ -1270,5 +1332,4 @@
 {
     pjsip_msg *msg;
-    pjsip_cid_hdr *call_id;
     pjsip_rx_data *rdata = tr->rdata;
     pj_pool_t *rdata_pool;
@@ -1316,6 +1377,6 @@
 
     /* Get source address and port for logging purpose. */
-    src_addr = pj_sockaddr_get_str_addr(&rdata->addr);
-    src_port = pj_sockaddr_get_port(&rdata->addr);
+    src_addr = pj_inet_ntoa(rdata->addr.sin_addr);
+    src_port = pj_sockaddr_in_get_port(&rdata->addr);
 
     /* Print the whole data to the log. */
@@ -1334,13 +1395,13 @@
 	/* For TCP transport, check if the whole message has been received. */
 	if (tr->type != PJSIP_TRANSPORT_UDP) {
-	    pj_bool_t is_complete;
-	    is_complete = pjsip_find_msg(rdata->packet, rdata->len, PJ_FALSE, &msg_fragment_size);
-	    if (!is_complete) {
+	    pj_status_t msg_status;
+	    msg_status = pjsip_find_msg(rdata->packet, rdata->len, PJ_FALSE, 
+                                        &msg_fragment_size);
+	    if (msg_status != PJ_SUCCESS) {
 		if (rdata->len == PJSIP_MAX_PKT_LEN) {
-		    PJ_LOG(1,(tr->obj_name, 
-			      "Transport buffer full (%d bytes) for TCP socket %s:%d "
-			      "(probably too many invalid fragments received). "
-			      "Buffer will be discarded.",
-			      PJSIP_MAX_PKT_LEN, src_addr, src_port));
+                    PJSIP_ENDPT_LOG_ERROR((mgr->endpt, tr->obj_name, 
+                                           PJSIP_EOVERFLOW,
+                                           "Buffer discarded for %s:%d",
+			                   src_addr, src_port));
 		    goto on_return;
 		} else {
@@ -1358,6 +1419,5 @@
 		src_addr, src_port));
 
-	msg = pjsip_parse_msg( rdata->pool, rdata->packet, msg_fragment_size, 
-			       &rdata->parse_err);
+	msg = pjsip_parse_rdata( rdata->packet, msg_fragment_size, rdata);
 	if (msg == NULL) {
 	    PJ_LOG(3,(tr->obj_name, "Bad message (%d bytes from %s:%d)", msg_fragment_size,
@@ -1366,18 +1426,7 @@
 	}
 
-	/* Attach newly created message to rdata. */
-	rdata->msg = msg;
-
-	/* Extract Call-ID, From and To header and tags, topmost Via, and CSeq
-	* header from the message.
-	*/
-	call_id = pjsip_msg_find_hdr( msg, PJSIP_H_CALL_ID, NULL);
-	rdata->from = pjsip_msg_find_hdr( msg, PJSIP_H_FROM, NULL);
-	rdata->to = pjsip_msg_find_hdr( msg, PJSIP_H_TO, NULL);
-	rdata->via = pjsip_msg_find_hdr( msg, PJSIP_H_VIA, NULL);
-	rdata->cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, NULL);
-
-	if (call_id == NULL || rdata->from == NULL || rdata->to == NULL ||
-	    rdata->via == NULL || rdata->cseq == NULL) 
+	/* Perform basic header checking. */
+	if (rdata->call_id.ptr == NULL || rdata->from == NULL || 
+	    rdata->to == NULL || rdata->via == NULL || rdata->cseq == NULL) 
 	{
 	    PJ_LOG(3,(tr->obj_name, "Bad message from %s:%d: missing some header", 
@@ -1385,7 +1434,4 @@
 	    goto finish_process_fragment;
 	}
-	rdata->call_id = call_id->id;
-	rdata->from_tag = rdata->from->tag;
-	rdata->to_tag = rdata->to->tag;
 
 	/* If message is received from address that's different from the sent-by,
@@ -1402,5 +1448,5 @@
 	 */
 	if (rdata->via->rport_param == 0) {
-	    rdata->via->rport_param = pj_sockaddr_get_port(&rdata->addr);
+	    rdata->via->rport_param = pj_sockaddr_in_get_port(&rdata->addr);
 	}
 
@@ -1409,5 +1455,5 @@
 	if (msg->type == PJSIP_RESPONSE_MSG) {
 	    hdr = (pjsip_hdr*)rdata->via->next;
-	    if (hdr) {
+	    if (hdr != &rdata->msg->hdr) {
 		hdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr);
 		if (hdr) {
@@ -1446,7 +1492,9 @@
     rdata->addr_len = sizeof(rdata->addr);
     if (tr->type == PJSIP_TRANSPORT_UDP) {
-	pj_ioqueue_recvfrom( tr->mgr->ioqueue, tr->key,
-			    tr->rdata->packet, PJSIP_MAX_PKT_LEN,
+	pj_ssize_t size = PJSIP_MAX_PKT_LEN;
+	pj_ioqueue_recvfrom(tr->key, &tr->rdata->op_key,
+			    tr->rdata->packet, &size, 0, 
 			    &rdata->addr, &rdata->addr_len);
+	PJ_TODO(HANDLE_IMMEDIATE_DATA);
     }
 
@@ -1457,7 +1505,9 @@
 tcp_read_packet:
     if (tr->type == PJSIP_TRANSPORT_TCP) {
-	pj_ioqueue_read( tr->mgr->ioqueue, tr->key, 
+	pj_ssize_t size = PJSIP_MAX_PKT_LEN - tr->rdata->len;
+	pj_ioqueue_recv( tr->key, &tr->rdata->op_key,
 			 tr->rdata->packet + tr->rdata->len,
-			 PJSIP_MAX_PKT_LEN - tr->rdata->len);
+			 &size, 0);
+	PJ_TODO(HANDLE_IMMEDIATE_DATA_1);
     }
 #endif
@@ -1508,5 +1558,7 @@
 }
 
-static void on_ioqueue_read(pj_ioqueue_key_t *key, pj_ssize_t bytes_read)
+static void on_ioqueue_read(pj_ioqueue_key_t *key, 
+			    pj_ioqueue_op_key_t *op_key, 
+			    pj_ssize_t bytes_read)
 {
     pjsip_transport_t *t;
@@ -1516,8 +1568,10 @@
 }
 
-static void on_ioqueue_write(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent)
-{
-    PJ_UNUSED_ARG(key)
-    PJ_UNUSED_ARG(bytes_sent)
+static void on_ioqueue_write(pj_ioqueue_key_t *key, 
+			     pj_ioqueue_op_key_t *op_key, 
+			     pj_ssize_t bytes_sent)
+{
+    PJ_UNUSED_ARG(key);
+    PJ_UNUSED_ARG(bytes_sent);
 
     /* Completion of write operation. 
@@ -1526,5 +1580,8 @@
 }
 
-static void on_ioqueue_accept(pj_ioqueue_key_t *key, int status)
+static void on_ioqueue_accept(pj_ioqueue_key_t *key, 
+			      pj_ioqueue_op_key_t *op_key, 
+			      pj_sock_t newsock,
+			      int status)
 {
 #if PJ_HAS_TCP
@@ -1534,6 +1591,6 @@
     handle_new_connection( t->mgr, t, status );
 #else
-    PJ_UNUSED_ARG(key)
-    PJ_UNUSED_ARG(status)
+    PJ_UNUSED_ARG(key);
+    PJ_UNUSED_ARG(status);
 #endif
 }
@@ -1547,6 +1604,6 @@
     handle_connect_completion( t->mgr, t, status);
 #else
-    PJ_UNUSED_ARG(key)
-    PJ_UNUSED_ARG(status)
+    PJ_UNUSED_ARG(key);
+    PJ_UNUSED_ARG(status);
 #endif
 }
Index: /pjproject/main/pjsip/src/pjsip/sip_uri.c
===================================================================
--- /pjproject/main/pjsip/src/pjsip/sip_uri.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsip/sip_uri.c	(revision 43)
@@ -1,10 +1,10 @@
 /* $Id$
- *
  */
 #include <pjsip/sip_uri.h>
 #include <pjsip/sip_msg.h>
-#include <pjsip/print.h>
+#include <pjsip/print_util.h>
 #include <pj/string.h>
 #include <pj/pool.h>
+#include <pj/assert.h>
 
 #define IS_SIPS(url)	((url)->vptr==&sips_url_vptr)
@@ -69,5 +69,5 @@
 static const pj_str_t *pjsip_url_get_scheme(const pjsip_url *url)
 {
-    PJ_UNUSED_ARG(url)
+    PJ_UNUSED_ARG(url);
     return &sip_str;
 }
@@ -75,5 +75,5 @@
 static const pj_str_t *pjsips_url_get_scheme(const pjsip_url *url)
 {
-    PJ_UNUSED_ARG(url)
+    PJ_UNUSED_ARG(url);
     return &sips_str;
 }
@@ -254,5 +254,5 @@
     }
 
-    if (strcmp(str_url1, str_url2)) {
+    if (pj_native_strcmp(str_url1, str_url2)) {
 	/* Not equal */
 	return -1;
Index: /pjproject/main/pjsip/src/pjsua/getopt.c
===================================================================
--- /pjproject/main/pjsip/src/pjsua/getopt.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsua/getopt.c	(revision 43)
@@ -279,5 +279,5 @@
    in GCC.  */
 #include <string.h>
-#define	my_index	strchr
+#define	my_index	pj_native_strchr
 #else
 
@@ -645,5 +645,5 @@
 	 then skip everything else like a non-option.  */
 
-      if (optind != argc && !strcmp (argv[optind], "--"))
+      if (optind != argc && !pj_native_strcmp(argv[optind], "--"))
 	{
 	  optind++;
Index: /pjproject/main/pjsip/src/pjsua/main.c
===================================================================
--- /pjproject/main/pjsip/src/pjsua/main.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsua/main.c	(revision 43)
@@ -251,5 +251,5 @@
     urllen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, rdata->from->uri, url, sizeof(url)-1);
     if (urllen < 1) {
-	strcpy(url, "<unknown>");
+	pj_native_strcpy(url, "<unknown>");
     } else {
 	url[urllen] = '\0';
@@ -1104,5 +1104,5 @@
     
     if (global.user_id[0]=='\0') {
-	strcpy(global.user_id, "user");
+	pj_native_strcpy(global.user_id, "user");
     }
 
@@ -1234,10 +1234,10 @@
 			   rdata->from->uri, from, sizeof(from));
     if (len > 0) from[len] = '\0';
-    else strcpy(from, "<URL too long..>");
+    else pj_native_strcpy(from, "<URL too long..>");
 
     len = pjsip_uri_print( PJSIP_URI_IN_CONTACT_HDR, 
 			   rdata->to->uri, to, sizeof(to));
     if (len > 0) to[len] = '\0';
-    else strcpy(to, "<URL too long..>");
+    else pj_native_strcpy(to, "<URL too long..>");
 
     PJ_LOG(3,(THIS_FILE, "Incoming instant message:"));
Index: /pjproject/main/pjsip/src/pjsua/misc.c
===================================================================
--- /pjproject/main/pjsip/src/pjsua/misc.c	(revision 42)
+++ /pjproject/main/pjsip/src/pjsua/misc.c	(revision 43)
@@ -342,5 +342,5 @@
 	    break;
 	case OPT_USE_STUN1:   /* STUN server 1 */
-	    p = strchr(optarg, ':');
+	    p = pj_native_strchr(optarg, ':');
 	    if (p) {
 		*p = '\0';
@@ -357,5 +357,5 @@
 	    break;
 	case OPT_USE_STUN2:   /* STUN server 2 */
-	    p = strchr(optarg, ':');
+	    p = pj_native_strchr(optarg, ':');
 	    if (p) {
 		*p = '\0';
