Index: pjproject/branches/projects/pjsua2/pjsip-apps/build/Makefile
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/build/Makefile	(revision 4596)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/build/Makefile	(revision 4597)
@@ -57,5 +57,6 @@
 #
 #
-TARGETS := pjsua pjsystest samples
+#TARGETS := swig pjsua pjsystest samples
+TARGETS := swig
 
 .PHONY: $(TARGETS)
@@ -63,4 +64,7 @@
 all: $(TARGETS)
 
+swig:
+	$(MAKE) -C ../src/swig
+	
 doc:
 
Index: pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/Makefile
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/Makefile	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/Makefile	(revision 4597)
@@ -0,0 +1,18 @@
+DIRS = python java
+
+export SWIG_FLAGS=-I../../../../pjlib/include \
+		   -I../../../../pjlib-util/include \
+		   -I../../../../pjmedia/include \
+		   -I../../../../pjsip/include \
+		   -I../../../../pjnath/include -c++ 
+export SRC_DIR=../../../../pjsip/include
+export SRCS=$(SRC_DIR)/pjsua2/endpoint.hpp $(SRC_DIR)/pjsua2/types.hpp
+
+all clean dep depend distclean print realclean:
+	for dir in $(DIRS); do \
+		if $(MAKE) $(MAKE_FLAGS) -C $$dir $@; then \
+		    true; \
+		else \
+		    exit 1; \
+		fi; \
+	done
Index: pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/java/Makefile
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/java/Makefile	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/java/Makefile	(revision 4597)
@@ -0,0 +1,21 @@
+include ../../../../build.mak
+
+OUT_DIR=output
+JAVA_SO=$(OUT_DIR)/libpjsua2.so
+
+JDK=/usr/lib/jvm/java-6-sun
+
+all: $(JAVA_SO)
+
+$(JAVA_SO): $(OUT_DIR)/pjsua2_wrap.o
+	gcc -shared -Wl,-soname,libpjsua2.so $(OUT_DIR)/pjsua2_wrap.o -o $(JAVA_SO) -lstdc++ $(APP_LDFLAGS)
+
+$(OUT_DIR)/pjsua2_wrap.o: $(OUT_DIR)/pjsua2_wrap.cpp Makefile
+	gcc -c $(OUT_DIR)/pjsua2_wrap.cpp -fPIC -o $(OUT_DIR)/pjsua2_wrap.o  -I$(JDK)/include -I$(JDK)/include/linux $(APP_CFLAGS)
+
+$(OUT_DIR)/pjsua2_wrap.cpp: ../pjsua2.i $(SRCS)
+	swig $(SWIG_FLAGS) -java  -o $(OUT_DIR)/pjsua2_wrap.cpp ../pjsua2.i
+
+clean distclean realclean:
+	rm -rf $(OUT_DIR)/pjsua2_wrap.cpp $(OUT_DIR)/pjsua2_wrap.o $(JAVA_SO) $(OUT_DIR)/*.java $(OUT_DIR)/*.class
+	ln -s ../test.java output/test.java
Index: pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/java/test.java
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/java/test.java	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/java/test.java	(revision 4597)
@@ -0,0 +1,15 @@
+public class test {
+  static {
+    System.loadLibrary("pjsua2");
+    System.out.println("Library loaded");
+  }
+
+  public static void main(String argv[]) {
+
+	CredInfo cred = new CredInfo();
+
+	cred.setRealm("Hello world");
+    
+	System.out.println(cred.getRealm());
+  }
+}
Index: pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i	(revision 4597)
@@ -0,0 +1,177 @@
+%module(directors="1") pjsua2
+
+//
+// Suppress few warnings
+//
+#pragma SWIG nowarn=312		// 312: nested struct (in types.h, sip_auth.h)
+
+//
+// Header section
+//
+%{
+#include "pjsua2/endpoint.hpp"
+using namespace std;
+%}
+
+//
+// STL stuff.
+//
+%include "std_string.i"
+%include "std_vector.i"
+
+namespace std
+{
+	%template(StringVector) std::vector<std::string>;
+	%template(IntVector) std::vector<int>;
+	%template(AuthCredInfoVector) std::vector<AuthCredInfo>;
+}
+
+//
+// Classes that can be extended in the target language
+//
+%feature("director") LogWriter; 
+%feature("director") EpCallback;
+
+//
+// And include supporting constants etc. Here we don't want to export
+// the whole file, so we start with ignoring everything and then enable
+// selected symbols  
+//
+#define PJ_BEGIN_DECL
+#define PJ_END_DECL
+#define PJ_DECL(type)		type
+#define PJ_INLINE(type)		type
+
+//
+// Start with ignoring everything
+//
+%ignore "";
+
+// Process the files. Keep them sorted.
+
+//
+//
+%rename("%s") pj_file_access;				// Unignore this
+%rename("%s", regexmatch$name="PJ_O_.*") "";		// Unignore this
+%include "pj/file_io.h"
+
+//
+//
+%rename("%s") pj_log_decoration;			// Unignore this
+%rename("%s", regexmatch$name="PJ_LOG_HAS_.*") "";	// Unignore this
+%include "pj/log.h"
+
+//
+//
+%rename("%s") pj_qos_type;				// Unignore this
+%rename("%s", regexmatch$name="PJ_QOS_TYPE_.*") "";	// Unignore this
+%rename("%s") pj_qos_flag;				// Unignore this
+%rename("%s", regexmatch$name="PJ_QOS_PARAM_HAS_.*") "";// Unignore this
+%rename("%s") pj_qos_wmm_prio;				// Unignore this
+%rename("%s", regexmatch$name="PJ_QOS_WMM_PRIO_.*") "";	// Unignore this
+// TODO:
+//  Wish there is a better way to unignore a struct than
+//  listing the fields one by one like below. Using regex
+//  doesn't seem to work?
+%rename("%s") pj_qos_params;				// Unignore this
+%rename("%s") pj_qos_params::flags;			// Unignore this
+%rename("%s") pj_qos_params::dscp_val;			// Unignore this
+%rename("%s") pj_qos_params::so_prio;			// Unignore this
+%rename("%s") pj_qos_params::wmm_prio;			// Unignore this
+%include "pj/sock_qos.h"
+
+//
+//
+%rename("%s") pj_ssl_cipher;				// Unignore this
+%rename("%s", regexmatch$name="PJ_O_.*") "";		// Unignore this
+%include "pj/ssl_sock.h"
+
+//
+//
+%rename("%s") pj_status_t;				// Unignore this
+%rename("%s") PJ_SUCCESS;				// Unignore this
+%include "pj/types.h"
+
+//
+//
+%rename("%s") pj_stun_nat_type;				// Unignore this
+%rename("%s", regexmatch$name="PJ_STUN_NAT_TYPE_.*") "";// Unignore this
+%include "pjnath/nat_detect.h"
+
+//
+//
+%rename("%s") pj_turn_tp_type;				// Unignore this
+%rename("%s", regexmatch$name="PJ_TURN_TP_.*") "";	// Unignore this
+%include "pjnath/turn_session.h"
+
+//
+//
+%rename("%s") pjmedia_vid_stream_rc_method;		// Unignore this
+%rename("%s", regexmatch$name="PJMEDIA_VID_STREAM_RC_.*") "";// Unignore this
+%include "pjmedia/vid_stream.h"
+
+//
+//
+%rename("%s") pjmedia_srtp_use;				// Unignore this
+%rename("%s", regexmatch$name="PJMEDIA_SRTP_.*") "";	// Unignore this
+%include "pjmedia/transport_srtp.h"
+
+//
+//
+%rename("%s") pjmedia_vid_dev_index;			// Unignore this
+%rename("%s") PJMEDIA_VID_DEFAULT_CAPTURE_DEV;		// Unignore this
+%rename("%s") PJMEDIA_VID_DEFAULT_RENDER_DEV;		// Unignore this
+%rename("%s") PJMEDIA_VID_INVALID_DEV;			// Unignore this
+%include "pjmedia-videodev/videodev.h"
+
+//
+//
+%rename("%s") pjsip_cred_data_type;			// Unignore this
+%rename("%s", regexmatch$name="PJSIP_CRED_DATA_.*") "";	// Unignore this
+%include "pjsip/sip_auth.h"
+
+//
+//
+%rename("%s") pjsip_status_code;			// Unignore this
+%rename("%s", regexmatch$name="PJSIP_SC_.*") "";	// Unignore this
+%include "pjsip/sip_msg.h"
+
+//
+//
+%rename("%s") pjsip_transport_type_e;			// Unignore this
+%rename("%s") pjsip_transport_flags_e;			// Unignore this
+%rename("%s") pjsip_transport_state;			// Unignore this
+%rename("%s", regexmatch$name="PJSIP_TRANSPORT_.*") "";	// Unignore this
+%rename("%s", regexmatch$name="PJSIP_TP_STATE_.*") "";	// Unignore this
+%include "pjsip/sip_transport.h"
+
+//
+//
+%rename("%s") pjsip_ssl_method;				// Unignore this
+%rename("%s", regexmatch$name="PJSIP_TLS.*_METHOD") "";	// Unignore this
+%rename("%s", regexmatch$name="PJSIP_SSL.*_METHOD") "";	// Unignore this
+%include "pjsip/sip_transport_tls.h"
+
+//
+//
+%rename("%s") PJSUA_INVALID_ID;				// Unignore this
+%rename("%s") pjsua_state;				// Unignore this
+%rename("%s", regexmatch$name="PJSUA_STATE_.*") "";	// Unignore this
+%rename("%s") pjsua_stun_use;				// Unignore this
+%rename("%s", regexmatch$name="PJSUA_STUN_USE_.*") "";	// Unignore this
+%rename("%s") pjsua_call_hold_type;			// Unignore this
+%rename("%s", regexmatch$name="PJSUA_CALL_HOLD_TYPE_.*") "";// Unignore this
+%rename("%s") pjsua_acc_id;				// Unignore this
+%include "pjsua-lib/pjsua.h"
+
+//
+// Back to unignore everything
+//
+%rename("%s") "";
+
+//
+// Now include the API itself.
+//
+%include "pjsua2/types.hpp"
+%include "pjsua2/endpoint.hpp"
+
Index: pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/Makefile
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/Makefile	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/Makefile	(revision 4597)
@@ -0,0 +1,14 @@
+PYTHON_SO=_pjsua2.so
+
+.PHONY: all
+
+all: $(PYTHON_SO)
+
+$(PYTHON_SO): pjsua2_wrap.cpp setup.py
+	python setup.py build_ext --inplace
+
+pjsua2_wrap.cpp: ../pjsua2.i $(SRCS)
+	swig $(SWIG_FLAGS) -python  -o pjsua2_wrap.cpp ../pjsua2.i
+
+clean distclean realclean:
+	rm -rf $(PYTHON_SO) pjsua2_wrap.cpp pjsua2_wrap.h pjsua2.py build *.pyc
Index: pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/helper.mak
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/helper.mak	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/helper.mak	(revision 4597)
@@ -0,0 +1,17 @@
+include ../../../../build.mak
+
+lib_dir:
+	@for token in `echo $(APP_LDFLAGS)`; do \
+		echo $$token | grep L | sed 's/-L//'; \
+	done
+
+inc_dir:
+	@for token in `echo $(APP_CFLAGS)`; do \
+		echo $$token | grep I | sed 's/-I//'; \
+	done
+
+libs:
+	@for token in `echo $(APP_LDLIBS)`; do \
+		echo $$token | grep \\-l | sed 's/-l//'; \
+	done
+
Index: pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/setup.py
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/setup.py	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/setup.py	(revision 4597)
@@ -0,0 +1,112 @@
+# $Id$
+#
+# pjsua2 Setup script.
+#
+# Copyright (C)2012 Teluu Inc. (http://www.teluu.com)
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+#
+from distutils.core import setup, Extension
+import os
+import sys
+import platform
+
+# find pjsip version
+pj_version=""
+pj_version_major=""
+pj_version_minor=""
+pj_version_rev=""
+pj_version_suffix=""
+f = open('../../../../version.mak', 'r')
+for line in f:
+    if line.find("export PJ_VERSION_MAJOR") != -1:
+    	tokens=line.split("=")
+	if len(tokens)>1:
+		pj_version_major= tokens[1].strip()
+    elif line.find("export PJ_VERSION_MINOR") != -1:
+    	tokens=line.split("=")
+	if len(tokens)>1:
+		pj_version_minor= line.split("=")[1].strip()
+    elif line.find("export PJ_VERSION_REV") != -1:
+    	tokens=line.split("=")
+	if len(tokens)>1:
+		pj_version_rev= line.split("=")[1].strip()
+    elif line.find("export PJ_VERSION_SUFFIX") != -1:
+    	tokens=line.split("=")
+	if len(tokens)>1:
+		pj_version_suffix= line.split("=")[1].strip()
+
+f.close()
+if not pj_version_major:
+    print 'Unable to get PJ_VERSION_MAJOR'
+    sys.exit(1)
+
+pj_version = pj_version_major + "." + pj_version_minor
+if pj_version_rev:
+	pj_version += "." + pj_version_rev
+if pj_version_suffix:
+	pj_version += "-" + pj_version_suffix
+
+#print 'PJ_VERSION = "'+ pj_version + '"'
+
+
+# Fill in pj_inc_dirs
+pj_inc_dirs = []
+f = os.popen("make --no-print-directory -f helper.mak inc_dir")
+for line in f:
+    pj_inc_dirs.append(line.rstrip("\r\n"))
+f.close()
+
+# Fill in pj_lib_dirs
+pj_lib_dirs = []
+f = os.popen("make --no-print-directory -f helper.mak lib_dir")
+for line in f:
+    pj_lib_dirs.append(line.rstrip("\r\n"))
+f.close()
+
+# Fill in pj_libs
+pj_libs = ['pjsua2-x86_64-unknown-linux-gnu']                      ### <--- xxxx HARDCODED xxxx
+f = os.popen("make --no-print-directory -f helper.mak libs")
+for line in f:
+    pj_libs.append(line.rstrip("\r\n"))
+f.close()
+
+# Mac OS X depedencies
+if platform.system() == 'Darwin':
+    extra_link_args = ["-framework", "CoreFoundation", 
+                       "-framework", "AudioToolbox"]
+    # OS X Lion support
+    if platform.mac_ver()[0].startswith("10.7"):
+        extra_link_args += ["-framework", "AudioUnit"]
+else:
+    extra_link_args = []
+
+setup(name="pjsua2", 
+      version=pj_version,
+      description='SIP User Agent Library based on PJSIP',
+      url='http://www.pjsip.org',
+      ext_modules = [Extension("_pjsua2", 
+                               ["pjsua2_wrap.cpp"], 
+                               define_macros=[('PJ_AUTOCONF', '1'),],
+                               include_dirs=pj_inc_dirs, 
+                               library_dirs=pj_lib_dirs, 
+                               libraries=pj_libs,
+                               extra_link_args=extra_link_args
+                              )
+                    ],
+      py_modules=["pjsua2"]
+     )
+
+
Index: pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/test.py
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/test.py	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/python/test.py	(revision 4597)
@@ -0,0 +1,111 @@
+import pjsua2 as pj
+import sys
+
+#
+# Basic data structure test, to make sure basic struct
+# and array operations work
+#
+def ua_data_test():
+	#
+	# CredInfo
+	#
+	print "UA data types test.."
+	the_realm = "pjsip.org"
+	ci = pj.CredInfo()
+	ci.realm = the_realm
+	ci.dataType = 20
+	
+	ci2 = ci
+	assert ci.dataType == 20
+	assert ci2.realm == the_realm
+	
+	#
+	# UaConfig
+	# See here how we manipulate std::vector
+	#
+	uc = pj.UaConfig()
+	uc.maxCalls = 10
+	uc.userAgent = "Python"
+	uc.nameserver = pj.StringVector(["10.0.0.1", "10.0.0.2"])
+	uc.nameserver.append("NS1")
+	
+	uc2 = uc
+	assert uc2.maxCalls == 10
+	assert uc2.userAgent == "Python"
+	assert len(uc2.nameserver) == 3
+	assert uc2.nameserver[0] == "10.0.0.1"
+	assert uc2.nameserver[1] == "10.0.0.2"
+	assert uc2.nameserver[2] == "NS1"
+
+	print "  Dumping nameservers: ",
+	for s in uc2.nameserver:
+		print s,
+	print ""
+
+#
+# Exception test
+#
+def ua_run_test_exception():
+	print "Exception test.."
+	ep = pj.Endpoint.instance()
+	got_exception = False
+	try:
+		ep.testException()
+	except pj.Error, e:
+		got_exception = True
+		print "  Got exception: status=%u, reason=%s,\n  title=%s,\n  srcFile=%s, srcLine=%d" % \
+			(e.status, e.reason, e.title, e.srcFile, e.srcLine)
+		assert e.status == 70013
+		assert e.reason == "Invalid operation (PJ_EINVALIDOP)"
+		assert e.title == "Endpoint::testException()"
+	assert got_exception
+
+#
+# Custom log writer
+#
+class MyLogWriter(pj.LogWriter):
+	def write(self, entry):
+		print "This is Python:", entry.msg
+		
+#
+# Testing log writer callback
+#
+def ua_run_log_test():
+	print "Logging test.."
+	ep_cfg = pj.EpConfig()
+	
+	lw = MyLogWriter()
+	ep_cfg.logConfig.writer = lw
+	ep_cfg.logConfig.decor = ep_cfg.logConfig.decor & ~(pj.PJ_LOG_HAS_CR | pj.PJ_LOG_HAS_NEWLINE) 
+	
+	ep = pj.Endpoint.instance()
+	ep.libCreate()
+	ep.libInit(ep_cfg)
+	ep.libDestroy()
+	
+#
+# Simple create, init, start, and destroy sequence
+#
+def ua_run_ua_test():
+	print "UA test run.."
+	ep_cfg = pj.EpConfig()
+	
+	ep = pj.Endpoint.instance()
+	ep.libCreate()
+	ep.libInit(ep_cfg)
+	ep.libStart()
+	
+	print "************* Endpoint started ok, now shutting down... *************"
+	ep.libDestroy()
+
+#
+# main()
+#
+if __name__ == "__main__":
+	ua_data_test()
+	ua_run_test_exception()
+	ua_run_log_test()
+	ua_run_ua_test()
+	sys.exit(0)
+
+	
Index: pjproject/branches/projects/pjsua2/pjsip/build/Makefile
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/build/Makefile	(revision 4596)
+++ pjproject/branches/projects/pjsua2/pjsip/build/Makefile	(revision 4597)
@@ -19,4 +19,5 @@
 export PJSIP_SIMPLE_LIB:=../lib/libpjsip-simple-$(TARGET_NAME)$(LIBEXT)
 export PJSUA_LIB_LIB=../lib/libpjsua-$(TARGET_NAME)$(LIBEXT)
+export PJSUA2_LIB_LIB=../lib/libpjsua2-$(TARGET_NAME)$(LIBEXT)
 
 
@@ -85,4 +86,28 @@
 
 ###############################################################################
+# Defines for building pjsua2 library
+#
+export PJSUA2_LIB_SRCDIR = ../src/pjsua2
+export PJSUA2_LIB_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
+			   endpoint.o types.o
+export PJSUA2_LIB_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS)
+export PJSUA2_LIB_CXXFLAGS = $(PJSUA2_LIB_CFLAGS) 
+
+
+###############################################################################
+# Defines for building pjsua2-test application
+#
+export PJSUA2_TEST_SRCDIR = ../src/pjsua2-test
+export PJSUA2_TEST_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
+			   main.o
+export PJSUA2_TEST_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS)
+export PJSUA2_TEST_CXXFLAGS = $(PJSUA2_LIB_CFLAGS) 
+export PJSUA2_TEST_LDFLAGS += -lpjsua2-$(TARGET_NAME) $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS)
+export PJSUA2_TEST_EXE := ../bin/pjsua2-test-$(TARGET_NAME)$(HOST_EXE)
+
+export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT 
+
+
+###############################################################################
 # Defines for building test application
 #
@@ -105,5 +130,5 @@
 #
 #
-TARGETS := pjsip pjsip-ua pjsip-simple pjsua-lib pjsip-test
+TARGETS := pjsip pjsip-ua pjsip-simple pjsua-lib pjsua2-lib pjsip-test pjsua2-test
 
 .PHONY: $(TARGETS)
@@ -125,5 +150,5 @@
 distclean: realclean
 
-.PHONY: dep depend pjsip pjsip-ua pjsua-lib clean realclean distclean
+.PHONY: dep depend pjsip pjsip-ua pjsua-lib pjsua2-lib clean realclean distclean
 
 pjsip:
@@ -139,7 +164,13 @@
 	$(MAKE) -f $(RULES_MAK) APP=PJSUA_LIB app=pjsua-lib $(PJSUA_LIB_LIB)
 
+pjsua2-lib: 
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA2_LIB app=pjsua2-lib $(PJSUA2_LIB_LIB)
+
 pjsip-test: pjsip
 	$(MAKE) -f $(RULES_MAK) APP=TEST app=pjsip-test $(TEST_EXE)
 
+pjsua2-test:
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA2_TEST app=pjsua2-test $(PJSUA2_TEST_EXE)
+
 .PHONY: ../lib/pjsip.ko
 ../lib/pjsip.ko:
@@ -167,5 +198,7 @@
 	$(MAKE) -f $(RULES_MAK) APP=PJSIP_SIMPLE app=pjsip-simple $@
 	$(MAKE) -f $(RULES_MAK) APP=PJSUA_LIB app=pjsua-lib $@
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA2_LIB app=pjsua2-lib $@
 	$(MAKE) -f $(RULES_MAK) APP=TEST app=pjsip-test $@
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA2_TEST app=pjsua2-test $@
 
 depend:
@@ -174,6 +207,9 @@
 	$(MAKE) -f $(RULES_MAK) APP=PJSIP_SIMPLE app=pjsip-simple $@
 	$(MAKE) -f $(RULES_MAK) APP=PJSUA_LIB app=pjsua-lib $@
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA2_LIB app=pjsua2-lib $@
 	$(MAKE) -f $(RULES_MAK) APP=TEST app=pjsip-test $@
-	echo '$(TEST_EXE): $(PJMEDIA_LIB) $(PJSUA_LIB_LIB) $(PJSIP_SIMPLE_LIB) $(PJSIP_UA_LIB) $(PJSIP_LIB) $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjsip-test-$(TARGET_NAME).depend
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA2_TEST app=pjsua2-test $@
+	echo '$(TEST_EXE): $(PJMEDIA_LIB)  $(PJSUA2_LIB_LIB) $(PJSUA_LIB_LIB) $(PJSIP_SIMPLE_LIB) $(PJSIP_UA_LIB) $(PJSIP_LIB) $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjsip-test-$(TARGET_NAME).depend
+	echo '$(PJSUA2_TEST_EXE): $(PJSUA2_LIB_LIB)' >> .pjsua2-test-$(TARGET_NAME).depend
 
 realclean:
@@ -182,4 +218,6 @@
 	$(subst @@,$(subst /,$(HOST_PSEP),.pjsip-simple-$(TARGET_NAME).depend),$(HOST_RMR))
 	$(subst @@,$(subst /,$(HOST_PSEP),.pjsua-lib-$(TARGET_NAME).depend),$(HOST_RMR))
+	$(subst @@,$(subst /,$(HOST_PSEP),.pjsua2-lib-$(TARGET_NAME).depend),$(HOST_RMR))
+	$(subst @@,$(subst /,$(HOST_PSEP),.pjsua2-test-$(TARGET_NAME).depend),$(HOST_RMR))
 	$(MAKE) -f $(RULES_MAK) APP=PJSIP app=pjsip $@
 	$(MAKE) -f $(RULES_MAK) APP=PJSIP_UA app=pjsip-ua $@
@@ -187,5 +225,7 @@
 	$(MAKE) -f $(RULES_MAK) APP=TEST app=pjsip-test $@
 	$(MAKE) -f $(RULES_MAK) APP=PJSUA_LIB app=pjsua-lib $@
-
-
-
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA2_LIB app=pjsua2-lib $@
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA2_TEST app=pjsua2-test $@
+
+
+
Index: pjproject/branches/projects/pjsua2/pjsip/docs/doxygen.cfg
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/docs/doxygen.cfg	(revision 4596)
+++ pjproject/branches/projects/pjsua2/pjsip/docs/doxygen.cfg	(revision 4597)
@@ -357,5 +357,5 @@
 # *.h++ *.idl *.odl
 
-FILE_PATTERNS          = *.h
+FILE_PATTERNS          = *.h *.hpp
 
 # The RECURSIVE tag can be used to turn specify whether or not subdirectories 
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/account.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/account.hpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/account.hpp	(revision 4597)
@@ -0,0 +1,975 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __PJSUA2_ACCOUNT_HPP__
+#define __PJSUA2_ACCOUNT_HPP__
+
+/**
+ * @file pjsua2/account.hpp
+ * @brief PJSUA2 Account operations
+ */
+#include <pjsua-lib/pjsua.h>
+
+/**
+ * @defgroup PJSUA2_ACC Account
+ * @ingroup PJSUA2_Ref
+ */
+
+/**
+ * @defgroup PJSUA2_Acc_Data_Structure Data Structure
+ * @ingroup PJSUA2_Ref
+ * @{
+ */
+
+/**
+ * Account registration config. This will be specified in AccountConfig.
+ */
+struct AccountRegConfig
+{
+    /**
+     * This is the URL to be put in the request URI for the registration,
+     * and will look something like "sip:serviceprovider".
+     *
+     * This field should be specified if registration is desired. If the
+     * value is empty, no account registration will be performed.
+     */
+    String		registrarUri;
+
+    /**
+     * Specify whether the account should register as soon as it is
+     * added to the UA. Application can set this to PJ_FALSE and control
+     * the registration manually with pjsua_acc_set_registration().
+     *
+     * Default: True
+     */
+    bool		registerOnAdd;
+
+    /**
+     * The optional custom SIP headers to be put in the registration
+     * request.
+     */
+    StringVector	headers;
+
+    /**
+     * Optional interval for registration, in seconds. If the value is zero,
+     * default interval will be used (PJSUA_REG_INTERVAL, 300 seconds).
+     */
+    unsigned		timeoutSec;
+
+    /**
+     * Specify interval of auto registration retry upon registration failure
+     * (including caused by transport problem), in second. Set to 0 to
+     * disable auto re-registration. Note that if the registration retry
+     * occurs because of transport failure, the first retry will be done
+     * after \a firstRetryIntervalSec seconds instead. Also note that
+     * the interval will be randomized slightly by approximately +/- ten
+     * seconds to avoid all clients re-registering at the same time.
+     *
+     * See also \a firstRetryIntervalSec setting.
+     *
+     * Default: #PJSUA_REG_RETRY_INTERVAL
+     */
+    unsigned		retryIntervalSec;
+
+    /**
+     * This specifies the interval for the first registration retry. The
+     * registration retry is explained in \a retryIntervalSec. Note that
+     * the value here will also be randomized by +/- ten seconds.
+     *
+     * Default: 0
+     */
+    unsigned		firstRetryIntervalSec;
+
+    /**
+     * Specify the number of seconds to refresh the client registration
+     * before the registration expires.
+     *
+     * Default: PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH, 5 seconds
+     */
+    unsigned		delayBeforeRefresh;
+
+    /**
+     * Specify whether calls of the configured account should be dropped
+     * after registration failure and an attempt of re-registration has
+     * also failed.
+     *
+     * Default: FALSE (disabled)
+     */
+    bool		dropCallsOnFail;
+
+    /**
+     * Specify the maximum time to wait for unregistration requests to
+     * complete during library shutdown sequence.
+     *
+     * Default: PJSUA_UNREG_TIMEOUT
+     */
+    unsigned		unregWaitSec;
+
+    /**
+     * Specify whether REGISTER requests will use the proxy settings
+     * of this account. If zero, the REGISTER request will not have any
+     * Route headers.
+     *
+     * Default: 1 (use account proxy)
+     */
+    unsigned		proxyUse;
+};
+
+
+/**
+ * Various SIP settings for the account. This will be specified in
+ * AccountConfig.
+ */
+struct AccountSipConfig
+{
+    /**
+     * Array of credentials. If registration is desired, normally there should
+     * be at least one credential specified, to successfully authenticate
+     * against the service provider. More credentials can be specified, for
+     * example when the requests are expected to be challenged by the
+     * proxies in the route set.
+     */
+    AuthCredInfoVector	authCreds;
+
+    /**
+     * Array of proxy servers to visit for outgoing requests. Each of the
+     * entry is translated into one Route URI.
+     */
+    StringVector	proxies;
+
+    /**
+     * Optional URI to be put as Contact for this account. It is recommended
+     * that this field is left empty, so that the value will be calculated
+     * automatically based on the transport address.
+     */
+    string		contactForced;
+
+    /**
+     * Additional parameters that will be appended in the Contact header
+     * for this account. This will affect the Contact header in all SIP
+     * messages sent on behalf of this account, including but not limited to
+     * REGISTER, INVITE, and SUBCRIBE requests or responses.
+     *
+     * The parameters should be preceeded by semicolon, and all strings must
+     * be properly escaped. Example:
+     *	 ";my-param=X;another-param=Hi%20there"
+     */
+    string		contactParams;
+
+    /**
+     * Additional URI parameters that will be appended in the Contact URI
+     * for this account. This will affect the Contact URI in all SIP
+     * messages sent on behalf of this account, including but not limited to
+     * REGISTER, INVITE, and SUBCRIBE requests or responses.
+     *
+     * The parameters should be preceeded by semicolon, and all strings must
+     * be properly escaped. Example:
+     *	 ";my-param=X;another-param=Hi%20there"
+     */
+    string		contactUriParams;
+
+
+    /**
+     * If this flag is set, the authentication client framework will
+     * send an empty Authorization header in each initial request.
+     * Default is no.
+     */
+    bool		authInitialEmpty;
+
+    /**
+     * Specify the algorithm to use when empty Authorization header
+     * is to be sent for each initial request (see above)
+     */
+    string		authInitialAlgorithm;
+
+    /**
+     * Optionally bind this account to specific transport. This normally is
+     * not a good idea, as account should be able to send requests using
+     * any available transports according to the destination. But some
+     * application may want to have explicit control over the transport to
+     * use, so in that case it can set this field.
+     *
+     * Default: -1 (PJSUA_INVALID_ID)
+     *
+     * @see Account::setTransport()
+     */
+    TransportId		transportId;
+};
+
+/**
+ * Account's call settings. This will be specified in AccountConfig.
+ */
+struct AccountCallConfig
+{
+    /**
+     * Specify how to offer call hold to remote peer. Please see the
+     * documentation on #pjsua_call_hold_type for more info.
+     *
+     * Default: PJSUA_CALL_HOLD_TYPE_DEFAULT
+     */
+    pjsua_call_hold_type holdType;
+
+    /**
+     * Specify how support for reliable provisional response (100rel/
+     * PRACK) should be used for all sessions in this account. See the
+     * documentation of pjsua_100rel_use enumeration for more info.
+     *
+     * Default: PJSUA_100REL_NOT_USED
+     */
+    pjsua_100rel_use	prackUse;
+
+    /**
+     * Specify the usage of Session Timers for all sessions. See the
+     * #pjsua_sip_timer_use for possible values.
+     *
+     * Default: PJSUA_SIP_TIMER_OPTIONAL
+     */
+    pjsua_sip_timer_use	timerUse;
+};
+
+/**
+ * Account presence config. This will be specified in AccountConfig.
+ */
+struct AccountPresConfig
+{
+    /**
+     * The optional custom SIP headers to be put in the presence
+     * subscription request.
+     */
+    StringVector	subHeaders;
+
+    /**
+     * If this flag is set, the presence information of this account will
+     * be PUBLISH-ed to the server where the account belongs.
+     *
+     * Default: PJ_FALSE
+     */
+    bool		publishEnabled;
+
+    /**
+     * Specify whether the client publication session should queue the
+     * PUBLISH request should there be another PUBLISH transaction still
+     * pending. If this is set to false, the client will return error
+     * on the PUBLISH request if there is another PUBLISH transaction still
+     * in progress.
+     *
+     * Default: PJSIP_PUBLISHC_QUEUE_REQUEST (TRUE)
+     */
+    bool		publishQueue;
+
+    /**
+     * Maximum time to wait for unpublication transaction(s) to complete
+     * during shutdown process, before sending unregistration. The library
+     * tries to wait for the unpublication (un-PUBLISH) to complete before
+     * sending REGISTER request to unregister the account, during library
+     * shutdown process. If the value is set too short, it is possible that
+     * the unregistration is sent before unpublication completes, causing
+     * unpublication request to fail.
+     *
+     * Value is in milliseconds.
+     *
+     * Default: PJSUA_UNPUBLISH_MAX_WAIT_TIME_MSEC (2000)
+     */
+    unsigned		publishShutdownWaitMsec;
+
+    /**
+     * Optional PIDF tuple ID for outgoing PUBLISH and NOTIFY. If this value
+     * is not specified, a random string will be used.
+     */
+    string		pidfTupleId;
+};
+
+/**
+ * Account MWI (Message Waiting Indication) settings. This will be specified
+ * in AccountConfig.
+ */
+struct AccountMwiConfig
+{
+    /**
+     * Subscribe to message waiting indication events (RFC 3842).
+     *
+     * See also UaConfig.mwiUnsolicitedEnabled setting.
+     *
+     * Default: FALSE
+     */
+    bool		enabled;
+
+    /**
+     * Specify the default expiration time (in seconds) for Message
+     * Waiting Indication (RFC 3842) event subscription. This must not
+     * be zero.
+     *
+     * Default: PJSIP_MWI_DEFAULT_EXPIRES (3600)
+     */
+    unsigned		expirationSec;
+};
+
+/**
+ * Account's NAT (Network Address Translation) settings. This will be
+ * specified in AccountConfig.
+ */
+struct AccountNatConfig
+{
+    /**
+     * Control the use of STUN for the SIP signaling.
+     *
+     * Default: PJSUA_STUN_USE_DEFAULT
+     */
+    pjsua_stun_use 	sipStunUse;
+
+    /**
+     * Control the use of STUN for the media transports.
+     *
+     * Default: PJSUA_STUN_USE_DEFAULT
+     */
+    pjsua_stun_use 	mediaStunUse;
+
+    /**
+     * Enable ICE for the media transport.
+     *
+     * Default: False
+     */
+    bool		iceEnabled;
+
+    /**
+     * Set the maximum number of ICE host candidates.
+     *
+     * Default: -1 (maximum not set)
+     */
+    int			iceMaxHostCands;
+
+    /**
+     * Specify whether to use aggressive nomination.
+     *
+     * Default: True
+     */
+    bool		iceAggressiveNomination;
+
+    /**
+     * For controlling agent if it uses regular nomination, specify the delay
+     * to perform nominated check (connectivity check with USE-CANDIDATE
+     * attribute) after all components have a valid pair.
+     *
+     * Default value is PJ_ICE_NOMINATED_CHECK_DELAY.
+     */
+    unsigned		iceNominatedCheckDelayMsec;
+
+    /**
+     * For a controlled agent, specify how long it wants to wait (in
+     * milliseconds) for the controlling agent to complete sending
+     * connectivity check with nominated flag set to true for all components
+     * after the controlled agent has found that all connectivity checks in
+     * its checklist have been completed and there is at least one successful
+     * (but not nominated) check for every component.
+     *
+     * Default value for this option is
+     * ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT. Specify -1 to disable
+     * this timer.
+     */
+    int			iceWaitNominationTimeoutMsec;
+
+    /**
+     * Disable RTCP component.
+     *
+     * Default: False
+     */
+    bool		iceNoRtcp;
+
+    /**
+     * Enable TURN candidate in ICE.
+     */
+    bool		turnEnabled;
+
+    /**
+     * Specify TURN domain name or host name, in in "DOMAIN:PORT" or
+     * "HOST:PORT" format.
+     */
+    string		turnServer;
+
+    /**
+     * Specify the connection type to be used to the TURN server. Valid
+     * values are PJ_TURN_TP_UDP or PJ_TURN_TP_TCP.
+     *
+     * Default: PJ_TURN_TP_UDP
+     */
+    pj_turn_tp_type	turnConnType;
+
+    /**
+     * Specify the username to authenticate with the TURN server.
+     */
+    string		turnUserName;
+
+    /**
+     * Specify the type of password. Currently this must be zero to
+     * indicate plain-text password will be used in the password.
+     */
+    int			turnPasswordType;
+
+    /**
+     * Specify the password to authenticate with the TURN server.
+     */
+    string		turnPassword;
+
+    /**
+     * This option is used to update the transport address and the Contact
+     * header of REGISTER request. When this option is  enabled, the library
+     * will keep track of the public IP address from the response of REGISTER
+     * request. Once it detects that the address has changed, it will
+     * unregister current Contact, update the Contact with transport address
+     * learned from Via header, and register a new Contact to the registrar.
+     * This will also update the public name of UDP transport if STUN is
+     * configured.
+     *
+     * See also contactRewriteMethod field.
+     *
+     * Default: TRUE
+     */
+    bool		contactRewriteEnabled;
+
+    /**
+     * Specify how Contact update will be done with the registration, if
+     * contactRewriteEnabled is enabled.
+     *
+     * If set to 1, the Contact update will be done by sending unregistration
+     * to the currently registered Contact, while simultaneously sending new
+     * registration (with different Call-ID) for the updated Contact.
+     *
+     * If set to 2, the Contact update will be done in a single, current
+     * registration session, by removing the current binding (by setting its
+     * Contact's expires parameter to zero) and adding a new Contact binding,
+     * all done in a single request.
+     *
+     * Value 1 is the legacy behavior.
+     *
+     * Default value: PJSUA_CONTACT_REWRITE_METHOD (2)
+     */
+    int			contactRewriteMethod;
+
+    /**
+     * This option is used to overwrite the "sent-by" field of the Via header
+     * for outgoing messages with the same interface address as the one in
+     * the REGISTER request, as long as the request uses the same transport
+     * instance as the previous REGISTER request.
+     *
+     * Default: TRUE
+     */
+    bool		viaRewriteEnabled;
+
+    /**
+     * Control the use of SIP outbound feature. SIP outbound is described in
+     * RFC 5626 to enable proxies or registrar to send inbound requests back
+     * to UA using the same connection initiated by the UA for its
+     * registration. This feature is highly useful in NAT-ed deployemtns,
+     * hence it is enabled by default.
+     *
+     * Note: currently SIP outbound can only be used with TCP and TLS
+     * transports. If UDP is used for the registration, the SIP outbound
+     * feature will be silently ignored for the account.
+     *
+     * Default: TRUE
+     */
+    bool		sipOutboundEnabled;
+
+    /**
+     * Specify SIP outbound (RFC 5626) instance ID to be used by this
+     * account. If empty, an instance ID will be generated based on
+     * the hostname of this agent. If application specifies this parameter, the
+     * value will look like "<urn:uuid:00000000-0000-1000-8000-AABBCCDDEEFF>"
+     * without the double-quotes.
+     *
+     * Default: empty
+     */
+    string		sipOutboundInstanceId;
+
+    /**
+     * Specify SIP outbound (RFC 5626) registration ID. The default value
+     * is empty, which would cause the library to automatically generate
+     * a suitable value.
+     *
+     * Default: empty
+     */
+    string		sipOutboundRegId;
+
+    /**
+     * Set the interval for periodic keep-alive transmission for this account.
+     * If this value is zero, keep-alive will be disabled for this account.
+     * The keep-alive transmission will be sent to the registrar's address,
+     * after successful registration.
+     *
+     * Default: 15 (seconds)
+     */
+    unsigned		udpKaIntervalSec;
+
+    /**
+     * Specify the data to be transmitted as keep-alive packets.
+     *
+     * Default: CR-LF
+     */
+    string		udpKaData;
+};
+
+/**
+ * Account media config (applicable for both audio and video). This will be
+ * specified in AccountConfig.
+ */
+struct AccountMediaConfig
+{
+    /**
+     * Media transport configuration.
+     */
+    TransportConfig	transportConfig;
+
+    /**
+     * If remote sends SDP answer containing more than one format or codec in
+     * the media line, send re-INVITE or UPDATE with just one codec to lock
+     * which codec to use.
+     *
+     * Default: True (Yes).
+     */
+    bool		lockCodecEnabled;
+
+    /**
+     * Specify whether stream keep-alive and NAT hole punching with
+     * non-codec-VAD mechanism (see @ref PJMEDIA_STREAM_ENABLE_KA) is enabled
+     * for this account.
+     *
+     * Default: False
+     */
+    bool		streamKaEnabled;
+
+    /**
+     * Specify whether secure media transport should be used for this account.
+     * Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and
+     * PJMEDIA_SRTP_MANDATORY.
+     *
+     * Default: #PJSUA_DEFAULT_USE_SRTP
+     */
+    pjmedia_srtp_use	srtpUse;
+
+    /**
+     * Specify whether SRTP requires secure signaling to be used. This option
+     * is only used when \a use_srtp option above is non-zero.
+     *
+     * Valid values are:
+     *	0: SRTP does not require secure signaling
+     *	1: SRTP requires secure transport such as TLS
+     *	2: SRTP requires secure end-to-end transport (SIPS)
+     *
+     * Default: #PJSUA_DEFAULT_SRTP_SECURE_SIGNALING
+     */
+    int			srtpSecureSignaling;
+};
+
+/**
+ * Video stream rate control config. This will be specified in
+ * AccountVideoConfig.
+ */
+struct VidRateControlConfig
+{
+    /**
+     * Rate control method.
+     *
+     * Default: PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING.
+     */
+    pjmedia_vid_stream_rc_method    method;
+
+    /**
+     * Upstream/outgoing bandwidth. If this is set to zero, the video stream
+     * will use codec maximum bitrate setting.
+     *
+     * Default: 0 (follow codec maximum bitrate).
+     */
+    unsigned			    bandwidth;
+
+    /** Default constructor */
+    VidRateControlConfig();
+
+    /** Convert to pj */
+    pjmedia_vid_stream_rc_config toPj() const;
+
+    /** Convert from pj */
+    void fromPj(const pjmedia_vid_stream_rc_config &prm);
+};
+
+/**
+ * Account video config. This will be specified in AccountConfig.
+ */
+struct AccountVideoConfig
+{
+    /**
+     * Specify whether incoming video should be shown to screen by default.
+     * This applies to incoming call (INVITE), incoming re-INVITE, and
+     * incoming UPDATE requests.
+     *
+     * Regardless of this setting, application can detect incoming video
+     * by implementing \a on_call_media_state() callback and enumerating
+     * the media stream(s) with #pjsua_call_get_info(). Once incoming
+     * video is recognised, application may retrieve the window associated
+     * with the incoming video and show or hide it with
+     * #pjsua_vid_win_set_show().
+     *
+     * Default: False
+     */
+    bool		autoShowIncoming;
+
+    /**
+     * Specify whether outgoing video should be activated by default when
+     * making outgoing calls and/or when incoming video is detected. This
+     * applies to incoming and outgoing calls, incoming re-INVITE, and
+     * incoming UPDATE. If the setting is non-zero, outgoing video
+     * transmission will be started as soon as response to these requests
+     * is sent (or received).
+     *
+     * Regardless of the value of this setting, application can start and
+     * stop outgoing video transmission with #pjsua_call_set_vid_strm().
+     *
+     * Default: False
+     */
+    bool		autoTransmitOutgoing;
+
+    /**
+     * Specify video window's flags. The value is a bitmask combination of
+     * #pjmedia_vid_dev_wnd_flag.
+     *
+     * Default: 0
+     */
+    unsigned		windowFlags;
+
+    /**
+     * Specify the default capture device to be used by this account. If
+     * vidOutAutoTransmit is enabled, this device will be used for
+     * capturing video.
+     *
+     * Default: PJMEDIA_VID_DEFAULT_CAPTURE_DEV
+     */
+    pjmedia_vid_dev_index defaultCaptureDevice;
+
+    /**
+     * Specify the default rendering device to be used by this account.
+     *
+     * Default: PJMEDIA_VID_DEFAULT_RENDER_DEV
+     */
+    pjmedia_vid_dev_index defaultRenderDevice;
+
+    /**
+     * Specify the send rate control for video stream.
+     */
+    VidRateControlConfig  rateControlConfig;
+};
+
+/**
+ * Account configuration.
+ */
+struct AccountConfig
+{
+    /**
+     * Account priority, which is used to control the order of matching
+     * incoming/outgoing requests. The higher the number means the higher
+     * the priority is, and the account will be matched first.
+     */
+    int			priority;
+
+    /**
+     * The Address of Record or AOR, that is full SIP URL that identifies the
+     * account. The value can take name address or URL format, and will look
+     * something like "sip:account@serviceprovider".
+     *
+     * This field is mandatory.
+     */
+    String		uri;
+
+    /**
+     * Registration settings.
+     */
+    AccountRegConfig	regConfig;
+
+    /**
+     * SIP settings.
+     */
+    AccountSipConfig	sipConfig;
+
+    /**
+     * Call settings.
+     */
+    AccountCallConfig	callConfig;
+
+    /**
+     * Presence settings.
+     */
+    AccountPresConfig	presConfig;
+
+    /**
+     * MWI (Message Waiting Indication) settings.
+     */
+    AccountMwiConfig	mwiConfig;
+
+    /**
+     * NAT settings.
+     */
+    AccountNatConfig	natConfig;
+
+    /**
+     * Media settings (applicable for both audio and video).
+     */
+    AccountMediaConfig	mediaConfig;
+
+    /**
+     * Video settings.
+     */
+    AccountVideoConfig	videoConfig;
+
+    /**
+     * Default constructor will initialize with default values.
+     */
+    AccountConfig();
+
+    /**
+     * Convert to pjsip.
+     */
+    pjsua_acc_config toPj() const;
+
+    /**
+     * Initialize from pjsip.
+     */
+    void fromPj(const pjsua_acc_config &prm);
+};
+
+/**
+ * Account information. Application can query the account information
+ * by calling Account::getInfo().
+ */
+struct AccountInfo
+{
+    /**
+     * The account ID.
+     */
+    pjsua_acc_id	id;
+
+    /**
+     * Flag to indicate whether this is the default account.
+     */
+    bool		isDefault;
+
+    /**
+     * Account URI
+     */
+    string		uri;
+
+    /**
+     * Flag to tell whether this account has registration setting
+     * (reg_uri is not empty).
+     */
+    bool		hasRegistration;
+
+    /**
+     * Flag to tell whether this account is currently registered
+     * (has active registration session).
+     */
+    bool		isRegistered;
+
+    /**
+     * An up to date expiration interval for account registration session.
+     */
+    int			expiresSec;
+
+    /**
+     * Last registration status code. If status code is zero, the account
+     * is currently not registered. Any other value indicates the SIP
+     * status code of the registration.
+     */
+    pjsip_status_code	status;
+
+    /**
+     * String describing the registration status.
+     */
+    string		statusText;
+
+    /**
+     * Last registration error code. When the status field contains a SIP
+     * status code that indicates a registration failure, last registration
+     * error code contains the error code that causes the failure. In any
+     * other case, its value is zero.
+     */
+    pj_status_t		regLastErr;
+
+    /**
+     * Presence online status for this account.
+     */
+    bool		onlineStatus;
+
+    /**
+     * Presence online status text.
+     */
+    string		onlineStatusText;
+
+};
+
+/**
+ * This structure contains parameters for onIncomingCall() callback.
+ */
+struct IncomingCallParam
+{
+    // rdata
+};
+
+/**
+ * This structure contains parameters for onRegState() callback.
+ */
+struct RegStateParam
+{
+    // reginfo
+};
+
+/**
+ * This structure contains parameters for onIncomingSubscribe() callback.
+ */
+struct IncomingSubscribeParam
+{
+    /*
+    * @param srv_pres	    Server presence subscription instance. If
+    *			    application delays the acceptance of the request,
+    *			    it will need to specify this object when calling
+    *			    #pjsua_pres_notify().
+    * @param acc_id	    Account ID most appropriate for this request.
+    * @param buddy_id	    ID of the buddy matching the sender of the
+    *			    request, if any, or PJSUA_INVALID_ID if no
+    *			    matching buddy is found.
+    * @param from	    The From URI of the request.
+    * @param rdata	    The incoming request.
+    * @param code	    The status code to respond to the request. The
+    *			    default value is 200. Application may set this
+    *			    to other final status code to accept or reject
+    *			    the request.
+    * @param reason	    The reason phrase to respond to the request.
+    * @param msg_data	    If the application wants to send additional
+    *			    headers in the response, it can put it in this
+    *			    parameter.
+    */
+
+    //pjsua_srv_pres *srv_pres,
+    // pjsua_buddy_id buddy_id,
+    // const pj_str_t *from,
+    // pjsip_rx_data *rdata,
+    // pjsua_msg_data *msg_data
+
+    /**
+     * The status code to respond to the request. The default value is 200.
+     * Application may set this to other final status code to accept or
+     * reject the request.
+     */
+    pjsip_status_code code;
+
+    /**
+     * The reason phrase to respond to the request.
+     */
+    string reason;
+};
+
+/**
+ * Account callback
+ */
+class AccountCallback
+{
+public:
+    /** Virtual destructor */
+    virtual ~AccountCallback() {}
+
+    /**
+     * Notify application on incoming call.
+     *
+     * @param prm	Callback parameter.
+     */
+    virtual void onIncomingCall(IncomingCallParam &prm)
+    {}
+
+    /**
+     * Notify application when registration status has changed.
+     * Application may then query the account info to get the
+     * registration details.
+     *
+     * @param acc_id	    The account ID.
+     */
+    virtual void onRegState(RegStateParam &prm)
+    {}
+
+    /**
+     * Notification when incoming SUBSCRIBE request is received. Application
+     * may use this callback to authorize the incoming subscribe request
+     * (e.g. ask user permission if the request should be granted).
+     *
+     * If this callback is not implemented, all incoming presence subscription
+     * requests will be accepted.
+     *
+     * If this callback is implemented, application has several choices on
+     * what to do with the incoming request:
+     *	- it may reject the request immediately by specifying non-200 class
+     *    final response in the IncomingSubscribeParam.code parameter.
+     *	- it may immediately accept the request by specifying 200 as the
+     *	  IncomingSubscribeParam.code parameter. This is the default value if
+     *	  application doesn't set any value to the IncomingSubscribeParam.code
+     *	  parameter. In this case, the library will automatically send NOTIFY
+     *	  request upon returning from this callback.
+     *  - it may delay the processing of the request, for example to request
+     *    user permission whether to accept or reject the request. In this
+     *	  case, the application MUST set the IncomingSubscribeParam.code
+     *	  argument to 202, then IMMEDIATELY calls #pjsua_pres_notify() with
+     *	  state PJSIP_EVSUB_STATE_PENDING and later calls #pjsua_pres_notify()
+     *    again to accept or reject the subscription request.
+     *
+     * Any IncomingSubscribeParam.code other than 200 and 202 will be treated
+     * as 200.
+     *
+     * Application MUST return from this callback immediately (e.g. it must
+     * not block in this callback while waiting for user confirmation).
+     */
+    virtual void onIncomingSubscribe(IncomingSubscribeParam &prm)
+    {}
+
+};
+
+
+/**
+ * @}  // PJSUA2_Acc_Data_Structure
+ */
+
+/**
+ * @addtogroup PJSUA2_ACC
+ * @{
+ */
+
+
+/**
+ * Account.
+ */
+class Account
+{
+public:
+    void setTransport();
+
+protected:
+    friend class Endpoint;
+
+    Account();
+};
+
+/**
+ * @}  // PJSUA2_ACC
+ */
+
+#endif	/* __PJSUA2_ACCOUNT_HPP__ */
+
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/approach1.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/approach1.hpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/approach1.hpp	(revision 4597)
@@ -0,0 +1,64 @@
+//////////////////////////////// API ////////////////////////////////
+
+class Account
+{
+public: /* Operations */
+    virtual ~Account();
+
+    void create();
+    void setRegistration(bool renew=true);
+
+public: /* Callbacks */
+    virtual void onRegState(RegStateParam &prm)
+    {}
+
+protected:
+    /* App should always subclass this. */
+    Account(Endpoint &ep, const AccountConfig &cfg);
+};
+
+
+class Endpoint
+{
+public: /* Operations */
+    Endpoint(EndpointCallback *cb);
+
+public:	/* Callbacks */
+    virtual void onTransportStateChanged(
+			const TransportStateChangedParam &prm)
+    {}
+};
+
+///////////////////////////// Sample Application /////////////////////////////
+class MyAccount: public Account
+{
+public:
+    MyAccount(Endpoint &ep, const AccountConfig &cfg);
+
+    void doNewThing() {}
+
+    virtual void onRegState(RegStateParam &prm)
+    { /* do stuff */  }
+
+};
+
+class MyEndpoint : public Endpoint
+{
+public:
+    virtual void onTransportStateChanged(
+			const TransportStateChangedParam &prm)
+    {}
+};
+
+
+int main()
+{
+    MyEndpoint ep;
+
+    // Two steps creation: instantiate, and actually create the acc in pjsua
+    // (why??)
+    MyAccount acc(accCfg);
+    acc.create(ep);
+
+    acc.setRegistration(true);
+};
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/approach2.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/approach2.hpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/approach2.hpp	(revision 4597)
@@ -0,0 +1,105 @@
+//////////////////////////////// API ////////////////////////////////
+
+class AccountCallback
+{
+public:
+    Account *getAccount();
+
+    virtual ~AccountCallback() {}
+
+    virtual void onRegState(RegStateParam &prm);
+
+protected:
+    void setAccount(Account *acc);
+
+private:
+    Account *acc;
+
+};
+
+
+class Account
+{
+public:
+    virtual ~Account();
+
+    void setRegistration(bool renew=true);
+
+protected:
+    friend class EndpointCallback;
+
+    /* Users are not supposed to instantiate this directly. They either need
+     * to subclasss this, or create from endpoint.
+     */
+    Account(const AccountConfig &cfg, AccountCallback &cb);
+};
+
+
+class EndpointCallback
+{
+public:
+    /* By default this creates Account instance, but if the app subclasses
+     * Account, it can implement this callback.
+     */
+    virtual Account *onCreateAccount(const AccountConfig &cfg,
+                                     AccountCallback &cb)
+    {
+	return new Account(cfg, cb);
+    }
+
+    /* Other callbacks: ... */
+    virtual void onTransportStateChanged(
+			const TransportStateChangedParam &prm)
+    {}
+
+};
+
+class Endpoint
+{
+public:
+    Endpoint(EndpointCallback *cb);
+
+    /* This is the only way to create account */
+    Account* createAccount(const AccountConfig &cfg, AccountCallback &cb)
+    {
+	Account *acc = this->endpointCallback->onCreateAccount(cfg, cb);
+	acc->setRegistration();
+	return acc;
+    }
+};
+
+///////////////////////////// Sample Application /////////////////////////////
+class MyAccountCallback : public AccountCallback
+{
+public:
+    virtual void onRegState(RegStateParam &prm)
+    { /* do stuff */  }
+};
+
+class MyAccount: public Account
+{
+public:
+    MyAccount(const AccountConfig &cfg, AccountCallback &cb);
+
+    void doNewThing();
+};
+
+class MyEndpointCallback : public EndpointCallback
+{
+public:
+    virtual Account *onCreateAccount(const AccountConfig &cfg, AccountCallback &cb)
+    {
+	return new MyAccount(cfg, cb);
+    };
+};
+
+
+int main()
+{
+    Endpoint ep(new MyEndpointCallback);
+
+    Account *acc = ep.createAccount(accCfg, new MyAccountCallback);
+    acc->setRegistration(true);
+};
+
+
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/approach3.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/approach3.hpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/approach3.hpp	(revision 4597)
@@ -0,0 +1,82 @@
+//////////////////////////////// API ////////////////////////////////
+
+class AccountCallback
+{
+public:
+    Account *getAccount();
+
+    virtual ~AccountCallback() {}
+
+    virtual void onRegState(RegStateParam &prm);
+
+protected:
+    void setAccount(Account *acc);
+
+private:
+    Account *acc;
+};
+
+class Account
+{
+public: /* Operations */
+    virtual ~Account();
+
+    void create();
+    void setRegistration(bool renew=true);
+
+protected:
+    /* App should always subclass this. */
+    Account(Endpoint &ep, const AccountConfig &cfg);
+};
+
+
+class EndpointCallback
+{
+public:
+
+    /* Other callbacks: ... */
+    virtual void onTransportStateChanged(
+			const TransportStateChangedParam &prm)
+    {}
+
+};
+
+class Endpoint
+{
+public: /* Operations */
+    Endpoint(EndpointCallback *cb);
+
+public:	/* Callbacks */
+    virtual void onTransportStateChanged(
+			const TransportStateChangedParam &prm)
+    {}
+};
+
+///////////////////////////// Sample Application /////////////////////////////
+class MyAccount: public Account
+{
+public:
+    MyAccount(Endpoint &ep, const AccountConfig &cfg);
+
+    void doNewThing() {}
+
+    virtual void onRegState(RegStateParam &prm)
+    { /* do stuff */  }
+
+};
+
+class MyEndpoint : public Endpoint
+{
+public:
+    virtual void onTransportStateChanged(
+			const TransportStateChangedParam &prm)
+    {}
+};
+
+
+int main()
+{
+    MyEndpoint ep;
+    MyAccount acc(ep, accCfg);
+    acc.setRegistration(true);
+};
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/config.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/config.hpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/config.hpp	(revision 4597)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __PJSUA2_CONFIG_HPP__
+#define __PJSUA2_CONFIG_HPP__
+
+/**
+ * @file pjsua2/ua.hpp
+ * @brief PJSUA2 Base Agent Operation
+ */
+#include <pjsua-lib/pjsua.h>
+
+/**
+ * @defgroup PJSUA2_CFG_Compile Compile time settings
+ * @ingroup PJSUA2_Ref
+ * @{
+ */
+
+/**
+ * Specify if the Error exception info should contain operation and source
+ * file information.
+ */
+#ifndef PJSUA2_ERROR_HAS_EXTRA_INFO
+#   define PJSUA2_ERROR_HAS_EXTRA_INFO		1
+#endif
+
+
+/**
+ * @}  PJSUA2_CFG
+ */
+
+#endif	/* __PJSUA2_CONFIG_HPP__ */
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/doxygen.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/doxygen.hpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/doxygen.hpp	(revision 4597)
@@ -0,0 +1,54 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __PJSUA2_DOXYGEN_HPP__
+#define __PJSUA2_DOXYGEN_HPP__
+
+/**
+ * @file pjsua2/doxygen.hpp
+ * @brief PJSUA2 Doxygen documentation
+ */
+
+/**
+ * @defgroup PJSUA2 PJSUA2: High Level Object Oriented PJSUA API
+ * @{
+ * The PJSUA2 API is a new, high-level, object-oriented API that is built
+ * on top of PJSUA-LIB API. The PJSUA2 API is implemented with C++ and
+ * can be used from other high level languages such as Java and Python.
+ * Thanks to <A HREF="http://www.swig.org">SWIG</A>, the API can potentially
+ * be used in other high level or scripting languages where SWIG binding is
+ * available, such as C#, Perl, PHP, Ruby, and Tcl.
+ *
+ * This page mostly contains the reference documentation of the API. For
+ * more guide on the API, please see the PJSUA2 wiki page:
+ * http://trac.pjsip.org/repos/wiki/pjsua2_API
+ * @}
+ */
+
+/**
+ * @defgroup PJSUA2_Ref API Reference
+ * @ingroup PJSUA2
+ */
+
+
+
+/**
+ * @}  PJSUA2_CFG
+ */
+
+#endif	/* __PJSUA2_DOXYGEN_HPP__ */
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp	(revision 4597)
@@ -0,0 +1,406 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJSUA2_UA_HPP__
+#define __PJSUA2_UA_HPP__
+
+/**
+ * @file pjsua2/ua.hpp
+ * @brief PJSUA2 Base Agent Operation
+ */
+#include <pjsua2/types.hpp>
+
+/** PJSUA2 API is inside pj namespace */
+namespace pj
+{
+
+/**
+ * @defgroup PJSUA2_UA Base Endpoint Operations
+ * @ingroup PJSUA2_Ref
+ * @{
+ */
+
+using std::string;
+using std::vector;
+
+
+/**
+ * Interface for receiving callbacks from the library. Application inherits
+ * this class and specify the instance when calling Endpoint::libInit().
+ */
+class EpCallback
+{
+public:
+    /** Virtual destructor */
+    virtual ~EpCallback() {}
+
+    /**
+     * Callback when the Endpoint has finished performing NAT type
+     * detection that is initiated with Endpoint::natDetectType().
+     *
+     * @param prm	Callback parameters containing the detection
+     * 			result.
+     */
+    virtual void onNatDetectionComplete(
+			const NatDetectionCompleteParam &prm)
+    {}
+
+    /**
+     * Callback when the Endpoint has finished performing STUN server
+     * checking that is initiated with Endpoint::natCheckStunServers().
+     *
+     * @param prm	Callback parameters.
+     */
+    virtual void onNatCheckStunServersComplete(
+			const NatCheckStunServersCompleteParam &prm)
+    {}
+
+    /**
+     * This callback is called when transport state has changed.
+     *
+     * @param prm	Callback parameters.
+     */
+    virtual void onTransportStateChanged(
+			const TransportStateChangedParam &prm)
+    {}
+
+    /**
+     * Callback when a timer has fired. The timer was scheduled by
+     * Endpoint::utilTimerSchedule().
+     *
+     * @param prm	Callback parameters.
+     */
+    virtual void OnTimerComplete(const TimerCompleteParam &prm)
+    {}
+};
+
+/**
+ * Endpoint represents an instance of pjsua library. There can only be
+ * one instance of pjsua library in an application, hence this class
+ * is a singleton.
+ */
+class Endpoint
+{
+public:
+    /** Retrieve the singleton instance of the endpoint */
+    static Endpoint &instance();
+
+    /* For testing */
+    void testException() throw(Error);
+
+
+    /*************************************************************************
+     * Base library operations
+     */
+
+    /**
+     * Instantiate pjsua application. Application must call this function before
+     * calling any other functions, to make sure that the underlying libraries
+     * are properly initialized. Once this function has returned success,
+     * application must call destroy() before quitting.
+     */
+    void libCreate() throw(Error);
+
+    /**
+     * Get library state.
+     *
+     * @return			library state.
+     */
+    pjsua_state libGetState() const;
+
+    /**
+     * Initialize pjsua with the specified settings. All the settings are
+     * optional, and the default values will be used when the config is not
+     * specified.
+     *
+     * Note that create() MUST be called before calling this function.
+     *
+     * @param prmEpConfig	Endpoint configurations
+     * @param prmCb		Optional callback to receive events from the
+     * 				library. If specified, this instance must be
+     * 				kept alive throughout the lifetime of the
+     * 				library.
+     */
+    void libInit( const EpConfig &prmEpConfig,
+                  EpCallback *prmCb = NULL) throw(Error);
+
+    /**
+     * Call this function after all initialization is done, so that the
+     * library can do additional checking set up. Application may call this
+     * function any time after init().
+     */
+    void libStart() throw(Error);
+
+    /**
+     * Destroy pjsua. Application is recommended to perform graceful shutdown
+     * before calling this function (such as unregister the account from the
+     * SIP server, terminate presense subscription, and hangup active calls),
+     * however, this function will do all of these if it finds there are
+     * active sessions that need to be terminated. This function will
+     * block for few seconds to wait for replies from remote.
+     *
+     * Application.may safely call this function more than once if it doesn't
+     * keep track of it's state.
+     *
+     * @param prmFlags		Combination of pjsua_destroy_flag enumeration.
+     */
+    void libDestroy(unsigned prmFlags=0) throw(Error);
+
+
+    /*************************************************************************
+     * Utilities
+     */
+
+    /**
+     * Retrieve the error string for the specified status code.
+     *
+     * @param prmErr		The error code.
+     */
+    string utilStrError(pj_status_t prmErr);
+
+    /**
+     * Write a log message.
+     *
+     * @param prmLevel		Log verbosity level (1-5)
+     * @param prmSender		The log sender.
+     * @param prmMsg		The log message.
+     */
+    void utilLogWrite(int prmLevel,
+                      const string &prmSender,
+                      const string &prmMsg);
+
+    /**
+     * This is a utility function to verify that valid SIP url is given. If the
+     * URL is a valid SIP/SIPS scheme, PJ_SUCCESS will be returned.
+     *
+     * @param prmUri		The URL string.
+     *
+     * @return			PJ_SUCCESS on success, or the appropriate error
+     * 				code.
+     *
+     * @see utilVerifyUri()
+     */
+    pj_status_t utilVerifySipUri(const string &prmUri);
+
+    /**
+     * This is a utility function to verify that valid URI is given. Unlike
+     * utilVerifySipUri(), this function will return PJ_SUCCESS if tel: URI
+     * is given.
+     *
+     * @param prmUri		The URL string.
+     *
+     * @return			PJ_SUCCESS on success, or the appropriate error
+     * 				code.
+     *
+     * @see pjsua_verify_sip_url()
+     */
+    pj_status_t utilVerifyUri(const string &prmUri);
+
+    /**
+     * Schedule a timer with the specified interval and user data. When the
+     * interval elapsed, EpCallback::OnTimerComplete() callback will be
+     * called. Note that the callback may be executed by different thread,
+     * depending on whether worker thread is enabled or not.
+     *
+     * @param prmMsecDelay	The time interval in msec.
+     * @param prmUserData	Arbitrary user data, to be given back to
+     * 				application in the callback.
+     *
+     * @return			Token to identify the timer, which could be
+     * 				given to utilTimerCancel().
+     */
+    Token utilTimerSchedule(unsigned prmMsecDelay,
+                            Token prmUserData) throw (Error);
+
+    /**
+     * Cancel previously scheduled timer with the specified timer token.
+     *
+     * @param prmToken		The timer token, which was returned from
+     * 				previous utilTimerSchedule() call.
+     */
+    void utilTimerCancel(Token prmTimerToken);
+
+    /**
+     * Get cipher list supported by SSL/TLS backend.
+     */
+    IntVector utilSslGetAvailableCiphers() throw (Error);
+
+    /*************************************************************************
+     * NAT operations
+     */
+    /**
+     * This is a utility function to detect NAT type in front of this endpoint.
+     * Once invoked successfully, this function will complete asynchronously
+     * and report the result in EpCallback::onNatDetectionComplete().
+     *
+     * After NAT has been detected and the callback is called, application can
+     * get the detected NAT type by calling #natGetType(). Application
+     * can also perform NAT detection by calling #natDetectType()
+     * again at later time.
+     *
+     * Note that STUN must be enabled to run this function successfully.
+     */
+    void natDetectType(void) throw(Error);
+
+    /**
+     * Get the NAT type as detected by #natDetectType() function. This
+     * function will only return useful NAT type after #natDetectType()
+     * has completed successfully and EpCallback::onNatDetectionComplete()
+     * callback has been called.
+     *
+     * Exception: if this function is called while detection is in progress,
+     * PJ_EPENDING exception will be raised.
+     */
+    pj_stun_nat_type natGetType() throw(Error);
+
+    /**
+     * Auxiliary function to resolve and contact each of the STUN server
+     * entries (sequentially) to find which is usable. The #pjsua_init() must
+     * have been called before calling this function.
+     *
+     * @param prmServers	Array of STUN servers to try. The endpoint
+     * 				will try to resolve and contact each of the
+     * 				STUN server entry until it finds one that is
+     * 				usable. Each entry may be a domain name, host
+     * 				name, IP address, and it may contain an
+     * 				optional port number. For example:
+     *				- "pjsip.org" (domain name)
+     *				- "sip.pjsip.org" (host name)
+     *				- "pjsip.org:33478" (domain name and a non-
+     *				   standard port number)
+     *				- "10.0.0.1:3478" (IP address and port number)
+     * @param prmWait		Specify if the function should block until
+     *				it gets the result. In this case, the function
+     *				will block while the resolution is being done,
+     *				and the callback will be called before this
+     *				function returns.
+     * @param prmUserData	Arbitrary user data to be passed back to
+     * 				application in the callback.
+     *
+     * @see natCancelCheckStunServers()
+     */
+    void natCheckStunServers(const StringVector &prmServers,
+                             bool prmWait,
+                             Token prmUserData) throw(Error);
+
+    /**
+     * Cancel pending STUN resolution which match the specified token.
+     *
+     * @param token		The token to match. This token was given to
+     *				natCheckStunServers()
+     * @param notify_cb		Boolean to control whether the callback should
+     *				be called for cancelled resolutions. When the
+     *				callback is called, the status in the result
+     *				will be set as PJ_ECANCELLED.
+     *
+     * Exception: PJ_ENOTFOUND if there is no matching one, or other error.
+     */
+    void natCancelCheckStunServers(Token token,
+                                   bool notify_cb = false) throw(Error);
+
+    /*************************************************************************
+     * Transport operations
+     */
+
+    /**
+     * Create and start a new SIP transport according to the specified
+     * settings.
+     *
+     * @param type		Transport type.
+     * @param cfg		Transport configuration.
+     *
+     * @return			The transport ID.
+     */
+    TransportId transportCreate(pjsip_transport_type_e type,
+                                const TransportConfig &cfg) throw(Error);
+
+    /**
+     * Enumerate all transports currently created in the system. This
+     * function will return all transport IDs, and application may then
+     * call transportGetInfo() function to retrieve detailed information
+     * about the transport.
+     *
+     * @return			Array of transport IDs.
+     */
+    IntVector transportEnum() throw(Error);
+
+    /**
+     * Get information about transport.
+     *
+     * @param id		Transport ID.
+     *
+     * @return			Transport info.
+     */
+    TransportInfo transportGetInfo(TransportId id) throw(Error);
+
+    /**
+     * Disable a transport or re-enable it. By default transport is always
+     * enabled after it is created. Disabling a transport does not necessarily
+     * close the socket, it will only discard incoming messages and prevent
+     * the transport from being used to send outgoing messages.
+     *
+     * @param id		Transport ID.
+     * @param enabled		Enable or disable the transport.
+     *
+     */
+    void transportSetEnable(TransportId id, bool enabled) throw(Error);
+
+    /**
+     * Close the transport. The system will wait until all transactions are
+     * closed while preventing new users from using the transport, and will
+     * close the transport when its usage count reaches zero.
+     *
+     * @param id		Transport ID.
+     */
+    void transportClose(TransportId id) throw(Error);
+
+
+private:
+    /* Anybody else can't instantiate Endpoint */
+    Endpoint();
+
+private:
+    /* Custom writer, if any */
+    LogWriter	*writer;
+    EpCallback	*epCallback;
+
+    /*
+     * Callbacks (static)
+     */
+    static void logFunc(int level, const char *data, int len);
+    static void stun_resolve_cb(const pj_stun_resolve_result *result);
+    static void on_timer(pj_timer_heap_t *timer_heap,
+        		 struct pj_timer_entry *entry);
+    static void on_nat_detect(const pj_stun_nat_detect_result *res);
+    static void on_transport_state(pjsip_transport *tp,
+    				   pjsip_transport_state state,
+    				   const pjsip_transport_state_info *info);
+};
+
+
+
+/**
+ * @}  PJSUA2_UA
+ */
+
+}
+/* End pj namespace */
+
+
+#endif	/* __PJSUA2_UA_HPP__ */
+
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/types.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/types.hpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/types.hpp	(revision 4597)
@@ -0,0 +1,971 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJSUA2_TYPES_HPP__
+#define __PJSUA2_TYPES_HPP__
+
+/**
+ * @file pjsua2/ua.hpp
+ * @brief PJSUA2 Base Agent Operation
+ */
+#include <pjsua2/config.hpp>
+
+#include <string>
+#include <vector>
+
+/**
+ * @defgroup PJSUA2_TYPES Data structure
+ * @ingroup PJSUA2_Ref
+ * @{
+ */
+
+/** PJSUA2 API is inside pj namespace */
+namespace pj
+{
+using std::string;
+using std::vector;
+
+/** Array of strings */
+typedef std::vector<std::string> StringVector;
+
+/** Array of integers */
+typedef std::vector<int> IntVector;
+
+/**
+ * Type of token, i.e. arbitrary application user data
+ */
+typedef void *Token;
+
+/**
+ * Socket address, encoded as string. The socket address contains host
+ * and port number in "host[:port]" format. The host part may contain
+ * hostname, domain name, IPv4 or IPv6 address. For IPv6 address, the
+ * address will be enclosed with square brackets, e.g. "[::1]:5060".
+ */
+typedef string SocketAddress;
+
+/**
+ * Transport ID is an integer.
+ */
+typedef int TransportId;
+
+/**
+ * Transport handle, corresponds to pjsip_transport instance.
+ */
+typedef void *TransportHandle;
+
+
+/**
+ * Constants
+ */
+enum
+{
+    /** Invalid ID, equal to PJSUA_INVALID_ID */
+    INVALID_ID	= -1,
+
+    /** Success, equal to PJ_SUCCESS */
+    SUCCESS = 0
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * This structure contains information about an error that is thrown
+ * as an exception.
+ */
+struct Error
+{
+    /** The error code. */
+    pj_status_t	status;
+
+    /** The error message */
+    string	reason;
+
+    /** The PJSUA API operation that throws the error. */
+    string	title;
+
+    /** The PJSUA source file that throws the error */
+    string	srcFile;
+
+    /** The line number of PJSUA source file that throws the error */
+    int		srcLine;
+
+    /** Default constructor */
+    Error();
+
+    /**
+     * Construct an Error instance from the specified parameters. If
+     * \a prm_reason is empty, it will be filled with the error description
+     *  for the status code.
+     */
+    Error(pj_status_t prm_status,
+          const string &prm_reason,
+          const string &prm_title,
+          const string &prm_src_file,
+          int prm_src_line);
+};
+
+/**
+ * This is a utility macro to check the status code and raise an Error
+ * exception on error.
+ */
+#if PJSUA2_ERROR_HAS_EXTRA_INFO
+#   define PJSUA2_CHECK_RAISE_ERROR(op, status)	\
+	    do { \
+		if (status != PJ_SUCCESS) \
+		    throw Error(status, string(), op, __FILE__, __LINE__); \
+	    } while (0)
+#else
+#   define PJSUA2_CHECK_RAISE_ERROR(op, status)	\
+	    do { \
+		if (status != PJ_SUCCESS) \
+		    throw Error(status, string(), string(), string(), 0); \
+	    } while (0)
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Credential information. Credential contains information to authenticate
+ * against a service.
+ */
+struct AuthCredInfo
+{
+    /**
+     * Realm on which this credential is to be used. Use "*" to make
+     * a credential that can be used to authenticate against any challenges.
+     */
+    string	realm;
+
+    /**
+     * The authentication scheme (e.g. "digest").
+     */
+    string	scheme;
+
+    /**
+     * Authentication user name.
+     */
+    string	username;
+
+    /**
+     * Type of data that is contained in the "data" field. Use 0 if the data
+     * contains plain text password.
+     */
+    int		dataType;
+
+    /**
+     * The data, which can be a plain text password or a hashed digest.
+     */
+    string	data;
+
+    /*
+     * Digest AKA credential information. Note that when AKA credential
+     * is being used, the \a data field of this #pjsip_cred_info is
+     * not used, but it still must be initialized to an empty string.
+     * Please see \ref PJSIP_AUTH_AKA_API for more information.
+     */
+
+    /** Permanent subscriber key. */
+    string	aka_k;
+
+    /** Operator variant key. */
+    string	aka_op;
+
+    /** Authentication Management Field	*/
+    string	aka_amf;
+
+    /**
+     * Default constructor.
+     */
+    AuthCredInfo();
+};
+
+/** Array of SIP credentials */
+typedef std::vector<AuthCredInfo> AuthCredInfoVector;
+
+//////////////////////////////////////////////////////////////////////////////
+
+struct UaConfig
+{
+    /**
+     * Maximum calls to support (default: 4). The value specified here
+     * must be smaller than the compile time maximum settings
+     * PJSUA_MAX_CALLS, which by default is 32. To increase this
+     * limit, the library must be recompiled with new PJSUA_MAX_CALLS
+     * value.
+     */
+    unsigned		maxCalls;
+
+    /**
+     * Number of worker threads. Normally application will want to have at
+     * least one worker thread, unless when it wants to poll the library
+     * periodically, which in this case the worker thread can be set to
+     * zero.
+     */
+    unsigned		threadCnt;
+
+    /**
+     * Array of nameservers to be used by the SIP resolver subsystem.
+     * The order of the name server specifies the priority (first name
+     * server will be used first, unless it is not reachable).
+     */
+    StringVector	nameserver;
+
+    /**
+     * Optional user agent string (default empty). If it's empty, no
+     * User-Agent header will be sent with outgoing requests.
+     */
+    string		userAgent;
+
+    /**
+     * Array of STUN servers to try. The library will try to resolve and
+     * contact each of the STUN server entry until it finds one that is
+     * usable. Each entry may be a domain name, host name, IP address, and
+     * it may contain an optional port number. For example:
+     *	- "pjsip.org" (domain name)
+     *	- "sip.pjsip.org" (host name)
+     *	- "pjsip.org:33478" (domain name and a non-standard port number)
+     *	- "10.0.0.1:3478" (IP address and port number)
+     *
+     * When nameserver is configured in the \a pjsua_config.nameserver field,
+     * if entry is not an IP address, it will be resolved with DNS SRV
+     * resolution first, and it will fallback to use DNS A resolution if this
+     * fails. Port number may be specified even if the entry is a domain name,
+     * in case the DNS SRV resolution should fallback to a non-standard port.
+     *
+     * When nameserver is not configured, entries will be resolved with
+     * #pj_gethostbyname() if it's not an IP address. Port number may be
+     * specified if the server is not listening in standard STUN port.
+     */
+    StringVector	stunServer;
+
+    /**
+     * This specifies if the library startup should ignore failure with the
+     * STUN servers. If this is set to PJ_FALSE, the library will refuse to
+     * start if it fails to resolve or contact any of the STUN servers.
+     *
+     * Default: TRUE
+     */
+    bool		stunIgnoreFailure;
+
+    /**
+     * Support for adding and parsing NAT type in the SDP to assist
+     * troubleshooting. The valid values are:
+     *	- 0: no information will be added in SDP, and parsing is disabled.
+     *	- 1: only the NAT type number is added.
+     *	- 2: add both NAT type number and name.
+     *
+     * Default: 1
+     */
+    int			natTypeInSdp;
+
+    /**
+     * Handle unsolicited NOTIFY requests containing message waiting
+     * indication (MWI) info. Unsolicited MWI is incoming NOTIFY requests
+     * which are not requested by client with SUBSCRIBE request.
+     *
+     * If this is enabled, the library will respond 200/OK to the NOTIFY
+     * request and forward the request to EpCallback.onMwiInfo() callback.
+     *
+     * See also AccountMwiConfig.enabled.
+     *
+     * Default: PJ_TRUE
+     */
+    bool	    	mwiUnsolicitedEnabled;
+
+public:
+    /**
+     * Default constructor to initialize with default values.
+     */
+    UaConfig();
+
+    /**
+     * Construct from pjsua_config.
+     */
+    void fromPj(const pjsua_config &ua_cfg);
+
+    /**
+     * Export to pjsua_config
+     */
+    pjsua_config toPj() const;
+};
+
+
+/**
+ * Data containing log entry to be written by the LogWriter.
+ */
+struct LogEntry
+{
+    /** Log verbosity level of this message */
+    int		level;
+
+    /** The log message */
+    string	msg;
+
+    /** ID of current thread */
+    long	threadId;
+
+    /** The name of the thread that writes this log */
+    string	threadName;
+};
+
+
+/**
+ * Interface for writing log messages. Applications can inherit this class
+ * and supply it in the LogConfig structure to implement custom log
+ * writing facility.
+ */
+class LogWriter
+{
+public:
+    /** Destructor */
+    virtual ~LogWriter() {}
+
+    /** Write a log entry. */
+    virtual void write(const LogEntry &entry) = 0;
+};
+
+
+/**
+ * Logging configuration, which can be (optionally) specified when calling
+ * Lib::init().
+ */
+struct LogConfig
+{
+    /** Log incoming and outgoing SIP message? Yes!  */
+    unsigned		msgLogging;
+
+    /** Input verbosity level. Value 5 is reasonable. */
+    unsigned		level;
+
+    /** Verbosity level for console. Value 4 is reasonable. */
+    unsigned		consoleLevel;
+
+    /** Log decoration. */
+    unsigned		decor;
+
+    /** Optional log filename if app wishes the library to write to log file.
+     */
+    string		filename;
+
+    /**
+     * Additional flags to be given to #pj_file_open() when opening
+     * the log file. By default, the flag is PJ_O_WRONLY. Application
+     * may set PJ_O_APPEND here so that logs are appended to existing
+     * file instead of overwriting it.
+     *
+     * Default is 0.
+     */
+    unsigned		fileFlags;
+
+    /**
+     * Custom log writer, if required. If specified, the instance of LogWriter
+     * must be kept alive througout the duration of the application.
+     */
+    LogWriter		*writer;
+
+public:
+    /** Default constructor initialises with default values */
+    LogConfig();
+
+    /** Construct from pjsua_logging_config */
+    void fromPj(const pjsua_logging_config &lc);
+
+    /** Generate pjsua_logging_config. */
+    pjsua_logging_config toPj() const;
+};
+
+
+/**
+ * This structure describes media configuration, which will be specified
+ * when calling Lib::init().
+ */
+struct MediaConfig
+{
+public:
+    /**
+     * Clock rate to be applied to the conference bridge.
+     * If value is zero, default clock rate will be used
+     * (PJSUA_DEFAULT_CLOCK_RATE, which by default is 16KHz).
+     */
+    unsigned		clockRate;
+
+    /**
+     * Clock rate to be applied when opening the sound device.
+     * If value is zero, conference bridge clock rate will be used.
+     */
+    unsigned		sndClockRate;
+
+    /**
+     * Channel count be applied when opening the sound device and
+     * conference bridge.
+     */
+    unsigned		channelCount;
+
+    /**
+     * Specify audio frame ptime. The value here will affect the
+     * samples per frame of both the sound device and the conference
+     * bridge. Specifying lower ptime will normally reduce the
+     * latency.
+     *
+     * Default value: PJSUA_DEFAULT_AUDIO_FRAME_PTIME
+     */
+    unsigned		audioFramePtime;
+
+    /**
+     * Specify maximum number of media ports to be created in the
+     * conference bridge. Since all media terminate in the bridge
+     * (calls, file player, file recorder, etc), the value must be
+     * large enough to support all of them. However, the larger
+     * the value, the more computations are performed.
+     *
+     * Default value: PJSUA_MAX_CONF_PORTS
+     */
+    unsigned		maxMediaPorts;
+
+    /**
+     * Specify whether the media manager should manage its own
+     * ioqueue for the RTP/RTCP sockets. If yes, ioqueue will be created
+     * and at least one worker thread will be created too. If no,
+     * the RTP/RTCP sockets will share the same ioqueue as SIP sockets,
+     * and no worker thread is needed.
+     *
+     * Normally application would say yes here, unless it wants to
+     * run everything from a single thread.
+     */
+    bool		hasIoqueue;
+
+    /**
+     * Specify the number of worker threads to handle incoming RTP
+     * packets. A value of one is recommended for most applications.
+     */
+    unsigned		threadCnt;
+
+    /**
+     * Media quality, 0-10, according to this table:
+     *   5-10: resampling use large filter,
+     *   3-4:  resampling use small filter,
+     *   1-2:  resampling use linear.
+     * The media quality also sets speex codec quality/complexity to the
+     * number.
+     *
+     * Default: 5 (PJSUA_DEFAULT_CODEC_QUALITY).
+     */
+    unsigned		quality;
+
+    /**
+     * Specify default codec ptime.
+     *
+     * Default: 0 (codec specific)
+     */
+    unsigned		ptime;
+
+    /**
+     * Disable VAD?
+     *
+     * Default: 0 (no (meaning VAD is enabled))
+     */
+    bool		noVad;
+
+    /**
+     * iLBC mode (20 or 30).
+     *
+     * Default: 30 (PJSUA_DEFAULT_ILBC_MODE)
+     */
+    unsigned		ilbcMode;
+
+    /**
+     * Percentage of RTP packet to drop in TX direction
+     * (to simulate packet lost).
+     *
+     * Default: 0
+     */
+    unsigned		txDropPct;
+
+    /**
+     * Percentage of RTP packet to drop in RX direction
+     * (to simulate packet lost).
+     *
+     * Default: 0
+     */
+    unsigned		rxDropPct;
+
+    /**
+     * Echo canceller options (see #pjmedia_echo_create())
+     *
+     * Default: 0.
+     */
+    unsigned		ecOptions;
+
+    /**
+     * Echo canceller tail length, in miliseconds. Setting this to zero
+     * will disable echo cancellation.
+     *
+     * Default: PJSUA_DEFAULT_EC_TAIL_LEN
+     */
+    unsigned		ecTailLen;
+
+    /**
+     * Audio capture buffer length, in milliseconds.
+     *
+     * Default: PJMEDIA_SND_DEFAULT_REC_LATENCY
+     */
+    unsigned		sndRecLatency;
+
+    /**
+     * Audio playback buffer length, in milliseconds.
+     *
+     * Default: PJMEDIA_SND_DEFAULT_PLAY_LATENCY
+     */
+    unsigned		sndPlayLatency;
+
+    /**
+     * Jitter buffer initial prefetch delay in msec. The value must be
+     * between jb_min_pre and jb_max_pre below.
+     *
+     * Default: -1 (to use default stream settings, currently 150 msec)
+     */
+    int			jbInit;
+
+    /**
+     * Jitter buffer minimum prefetch delay in msec.
+     *
+     * Default: -1 (to use default stream settings, currently 60 msec)
+     */
+    int			jbMinPre;
+
+    /**
+     * Jitter buffer maximum prefetch delay in msec.
+     *
+     * Default: -1 (to use default stream settings, currently 240 msec)
+     */
+    int			jbMaxPre;
+
+    /**
+     * Set maximum delay that can be accomodated by the jitter buffer msec.
+     *
+     * Default: -1 (to use default stream settings, currently 360 msec)
+     */
+    int			jbMax;
+
+    /**
+     * Specify idle time of sound device before it is automatically closed,
+     * in seconds. Use value -1 to disable the auto-close feature of sound
+     * device
+     *
+     * Default : 1
+     */
+    int			sndAutoCloseTime;
+
+    /**
+     * Specify whether built-in/native preview should be used if available.
+     * In some systems, video input devices have built-in capability to show
+     * preview window of the device. Using this built-in preview is preferable
+     * as it consumes less CPU power. If built-in preview is not available,
+     * the library will perform software rendering of the input. If this
+     * field is set to PJ_FALSE, software preview will always be used.
+     *
+     * Default: PJ_TRUE
+     */
+    bool		vidPreviewEnableNative;
+
+public:
+    /** Default constructor initialises with default values */
+    MediaConfig();
+
+    /** Construct from pjsua_media_config. */
+    void fromPj(const pjsua_media_config &mc);
+
+    /** Export */
+    pjsua_media_config toPj() const;
+};
+
+
+/**
+ * Endpoint configuration
+ */
+struct EpConfig
+{
+    /** UA config */
+    UaConfig		uaConfig;
+
+    /** Logging config */
+    LogConfig		logConfig;
+
+    /** Media config */
+    MediaConfig		medConfig;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Argument to EpCallback::onNatDetectionComplete() callback.
+ */
+struct NatDetectionCompleteParam
+{
+    /**
+     * Status of the detection process. If this value is not PJ_SUCCESS,
+     * the detection has failed and \a nat_type field will contain
+     * PJ_STUN_NAT_TYPE_UNKNOWN.
+     */
+    pj_status_t		status;
+
+    /**
+     * The text describing the status, if the status is not PJ_SUCCESS.
+     */
+    string		reason;
+
+    /**
+     * This contains the NAT type as detected by the detection procedure.
+     * This value is only valid when the \a status is PJ_SUCCESS.
+     */
+    pj_stun_nat_type	natType;
+
+    /**
+     * Text describing that NAT type.
+     */
+    string		natTypeName;
+
+};
+
+/**
+ * Argument to EpCallback::onNatCheckStunServersComplete() callback.
+ */
+struct NatCheckStunServersCompleteParam
+{
+    /**
+     * Arbitrary user data that was passed to Endpoint::natCheckStunServers()
+     * function.
+     */
+    Token		userData;
+
+    /**
+     * This will contain PJ_SUCCESS if at least one usable STUN server
+     * is found, otherwise it will contain the last error code during
+     * the operation.
+     */
+    pj_status_t		status;
+
+    /**
+     * The server name that yields successful result. This will only
+     * contain value if status is successful.
+     */
+    string		name;
+
+    /**
+     * The server IP address and port in "IP:port" format. This will only
+     * contain value if status is successful.
+     */
+    SocketAddress	addr;
+};
+
+/**
+ * Parameter of EpCallback::OnTimerComplete() callback.
+ */
+struct TimerCompleteParam
+{
+    /**
+     * Arbitrary user data that was passed to Endpoint::utilTimerSchedule()
+     * function.
+     */
+    Token		userData;
+
+    /**
+     * The interval of this timer, in miliseconds.
+     */
+    unsigned		msecDelay;
+};
+
+/**
+ * Parameter of EpCallback::onTransportStateChanged() callback.
+ */
+struct TransportStateChangedParam
+{
+    /**
+     * The transport handle.
+     */
+    TransportHandle	hnd;
+
+    /**
+     * Transport current state.
+     */
+    pjsip_transport_state state;
+
+    /**
+     * The last error code related to the transport state.
+     */
+    pj_status_t		lastError;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * TLS transport settings, to be specified in TransportConfig.
+ */
+struct TlsConfig
+{
+    /**
+     * Certificate of Authority (CA) list file.
+     */
+    string		CaListFile;
+
+    /**
+     * Public endpoint certificate file, which will be used as client-
+     * side  certificate for outgoing TLS connection, and server-side
+     * certificate for incoming TLS connection.
+     */
+    string		certFile;
+
+    /**
+     * Optional private key of the endpoint certificate to be used.
+     */
+    string		privKeyFile;
+
+    /**
+     * Password to open private key.
+     */
+    string		password;
+
+    /**
+     * TLS protocol method from #pjsip_ssl_method.
+     *
+     * Default is PJSIP_SSL_UNSPECIFIED_METHOD (0), which in turn will
+     * use PJSIP_SSL_DEFAULT_METHOD, which default value is
+     * PJSIP_TLSV1_METHOD.
+     */
+    pjsip_ssl_method	method;
+
+    /**
+     * Ciphers and order preference. The Endpoint::utilSslGetAvailableCiphers()
+     * can be used to check the available ciphers supported by backend.
+     * If the array is empty, then default cipher list of the backend
+     * will be used.
+     */
+    IntVector		ciphers;
+
+    /**
+     * Specifies TLS transport behavior on the server TLS certificate
+     * verification result:
+     * - If \a verifyServer is disabled, TLS transport will just notify
+     *   the application via #pjsip_tp_state_callback with state
+     *   PJSIP_TP_STATE_CONNECTED regardless TLS verification result.
+     * - If \a verifyServer is enabled, TLS transport will be shutdown
+     *   and application will be notified with state
+     *   PJSIP_TP_STATE_DISCONNECTED whenever there is any TLS verification
+     *   error, otherwise PJSIP_TP_STATE_CONNECTED will be notified.
+     *
+     * In any cases, application can inspect #pjsip_tls_state_info in the
+     * callback to see the verification detail.
+     *
+     * Default value is false.
+     */
+    bool		verifyServer;
+
+    /**
+     * Specifies TLS transport behavior on the client TLS certificate
+     * verification result:
+     * - If \a verifyClient is disabled, TLS transport will just notify
+     *   the application via #pjsip_tp_state_callback with state
+     *   PJSIP_TP_STATE_CONNECTED regardless TLS verification result.
+     * - If \a verifyClient is enabled, TLS transport will be shutdown
+     *   and application will be notified with state
+     *   PJSIP_TP_STATE_DISCONNECTED whenever there is any TLS verification
+     *   error, otherwise PJSIP_TP_STATE_CONNECTED will be notified.
+     *
+     * In any cases, application can inspect #pjsip_tls_state_info in the
+     * callback to see the verification detail.
+     *
+     * Default value is PJ_FALSE.
+     */
+    bool		verifyClient;
+
+    /**
+     * When acting as server (incoming TLS connections), reject incoming
+     * connection if client doesn't supply a TLS certificate.
+     *
+     * This setting corresponds to SSL_VERIFY_FAIL_IF_NO_PEER_CERT flag.
+     * Default value is PJ_FALSE.
+     */
+    bool		requireClientCert;
+
+    /**
+     * TLS negotiation timeout to be applied for both outgoing and incoming
+     * connection, in milliseconds. If zero, the SSL negotiation doesn't
+     * have a timeout.
+     *
+     * Default: zero
+     */
+    unsigned		msecTimeout;
+
+    /**
+     * QoS traffic type to be set on this transport. When application wants
+     * to apply QoS tagging to the transport, it's preferable to set this
+     * field rather than \a qosParam fields since this is more portable.
+     *
+     * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+     */
+    pj_qos_type 	qosType;
+
+    /**
+     * Set the low level QoS parameters to the transport. This is a lower
+     * level operation than setting the \a qosType field and may not be
+     * supported on all platforms.
+     *
+     * By default all settings in this structure are disabled.
+     */
+    pj_qos_params 	qosParams;
+
+    /**
+     * Specify if the transport should ignore any errors when setting the QoS
+     * traffic type/parameters.
+     *
+     * Default: PJ_TRUE
+     */
+    bool		qosIgnoreError;
+
+public:
+    /** Default constructor initialises with default values */
+    TlsConfig();
+
+    /** Convert to pjsip */
+    pjsip_tls_setting toPj() const;
+
+    /** Convert from pjsip */
+    void fromPj(const pjsip_tls_setting &prm);
+};
+
+
+/**
+ * Parameters to create a transport instance.
+ */
+struct TransportConfig
+{
+    /**
+     * UDP port number to bind locally. This setting MUST be specified
+     * even when default port is desired. If the value is zero, the
+     * transport will be bound to any available port, and application
+     * can query the port by querying the transport info.
+     */
+    unsigned		port;
+
+    /**
+     * Optional address to advertise as the address of this transport.
+     * Application can specify any address or hostname for this field,
+     * for example it can point to one of the interface address in the
+     * system, or it can point to the public address of a NAT router
+     * where port mappings have been configured for the application.
+     *
+     * Note: this option can be used for both UDP and TCP as well!
+     */
+    string		publicAddress;
+
+    /**
+     * Optional address where the socket should be bound to. This option
+     * SHOULD only be used to selectively bind the socket to particular
+     * interface (instead of 0.0.0.0), and SHOULD NOT be used to set the
+     * published address of a transport (the public_addr field should be
+     * used for that purpose).
+     *
+     * Note that unlike public_addr field, the address (or hostname) here
+     * MUST correspond to the actual interface address in the host, since
+     * this address will be specified as bind() argument.
+     */
+    string		boundAddress;
+
+    /**
+     * This specifies TLS settings for TLS transport. It is only be used
+     * when this transport config is being used to create a SIP TLS
+     * transport.
+     */
+    TlsConfig		tlsConfig;
+
+    /**
+     * QoS traffic type to be set on this transport. When application wants
+     * to apply QoS tagging to the transport, it's preferable to set this
+     * field rather than \a qosParam fields since this is more portable.
+     *
+     * Default is QoS not set.
+     */
+    pj_qos_type		qosType;
+
+    /**
+     * Set the low level QoS parameters to the transport. This is a lower
+     * level operation than setting the \a qosType field and may not be
+     * supported on all platforms.
+     *
+     * Default is QoS not set.
+     */
+    pj_qos_params	qosParams;
+
+public:
+    /** Default constructor initialises with default values */
+    TransportConfig();
+
+    /** Convert from pjsip */
+    void fromPj(const pjsua_transport_config &prm);
+
+    /** Convert to pjsip */
+    pjsua_transport_config toPj() const;
+};
+
+/**
+ * This structure describes transport information returned by
+ * Endpoint::transportGetInfo() function.
+ */
+struct TransportInfo
+{
+    /** PJSUA transport identification. */
+    TransportId	    	    id;
+
+    /** Transport type. */
+    pjsip_transport_type_e  type;
+
+    /** Transport type name. */
+    string		    typeName;
+
+    /** Transport string info/description. */
+    string		    info;
+
+    /** Transport flags (see #pjsip_transport_flags_e). */
+    unsigned		    flags;
+
+    /** Local/bound address. */
+    SocketAddress	    localAddress;
+
+    /** Published address (or transport address name). */
+    SocketAddress	    localName;
+
+    /** Current number of objects currently referencing this transport. */
+    unsigned		    usageCount;
+
+    /** Construct from pjsip */
+    TransportInfo(const pjsua_transport_info &info);
+
+};
+
+
+} // namespace pj
+
+/**
+ * @}  PJSUA2
+ */
+
+
+
+#endif	/* __PJSUA2_TYPES_HPP__ */
Index: pjproject/branches/projects/pjsua2/pjsip/src/pjsua2-test/main.cpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/src/pjsua2-test/main.cpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/src/pjsua2-test/main.cpp	(revision 4597)
@@ -0,0 +1,38 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <pjsua2/endpoint.hpp>
+
+using namespace pj;
+
+int main(int argc, char *argv[])
+{
+    Endpoint &ep = Endpoint::instance();
+
+    EpConfig epCfg;
+
+    epCfg.uaConfig.userAgent = "pjsua++-test";
+
+    ep.libCreate();
+    ep.libInit(epCfg);
+    ep.libStart();
+    ep.libDestroy();
+
+    return 0;
+}
+
Index: pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp	(revision 4597)
@@ -0,0 +1,419 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include <pjsua2/endpoint.hpp>
+
+using namespace pj;
+using namespace std;
+
+#define THIS_FILE		"endpoint.cpp"
+#define MAX_STUN_SERVERS	32
+#define TIMER_SIGNATURE		0x600D878A
+
+struct UserTimer
+{
+    pj_uint32_t		signature;
+    TimerCompleteParam	prm;
+    pj_timer_entry	entry;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Endpoint instance
+ */
+Endpoint::Endpoint()
+: writer(NULL), epCallback(NULL)
+{
+}
+
+Endpoint& Endpoint::instance()
+{
+    static Endpoint lib_;
+    return lib_;
+}
+
+void Endpoint::testException() throw(Error)
+{
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::testException()", PJ_EINVALIDOP);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Endpoint static callbacks
+ */
+void Endpoint::logFunc(int level, const char *data, int len)
+{
+    Endpoint &ep = Endpoint::instance();
+
+    if (!ep.writer)
+	return;
+
+    LogEntry entry;
+    entry.level = level;
+    entry.msg = string(data, len);
+    entry.threadId = (long)pj_thread_this();
+    entry.threadName = string(pj_thread_get_name(pj_thread_this()));
+
+    ep.writer->write(entry);
+}
+
+void Endpoint::stun_resolve_cb(const pj_stun_resolve_result *res)
+{
+    Endpoint &ep = Endpoint::instance();
+
+    if (!ep.epCallback || !res)
+	return;
+
+    NatCheckStunServersCompleteParam prm;
+
+    prm.userData = res->token;
+    prm.status = res->status;
+    if (res->status == PJ_SUCCESS) {
+	char straddr[PJ_INET6_ADDRSTRLEN+10];
+
+	prm.name = string(res->name.ptr, res->name.slen);
+	pj_sockaddr_print(&res->addr, straddr, sizeof(straddr), 3);
+	prm.addr = straddr;
+    }
+
+    ep.epCallback->onNatCheckStunServersComplete(prm);
+}
+
+void Endpoint::on_timer(pj_timer_heap_t *timer_heap,
+                        pj_timer_entry *entry)
+{
+    Endpoint &ep = Endpoint::instance();
+    UserTimer *ut = (UserTimer*) entry->user_data;
+
+    if (!ep.epCallback || ut->signature != TIMER_SIGNATURE)
+	return;
+
+    ep.epCallback->OnTimerComplete(ut->prm);
+}
+
+void Endpoint::on_nat_detect(const pj_stun_nat_detect_result *res)
+{
+    Endpoint &ep = Endpoint::instance();
+
+    if (!ep.epCallback || !res)
+	return;
+
+    NatDetectionCompleteParam prm;
+
+    prm.status = res->status;
+    prm.reason = res->status_text;
+    prm.natType = res->nat_type;
+    prm.natTypeName = res->nat_type_name;
+
+    ep.epCallback->onNatDetectionComplete(prm);
+}
+
+void Endpoint::on_transport_state( pjsip_transport *tp,
+				   pjsip_transport_state state,
+				   const pjsip_transport_state_info *info)
+{
+    Endpoint &ep = Endpoint::instance();
+
+    if (!ep.epCallback || !res)
+	return;
+
+    TransportStateChangedParam prm;
+
+    prm.hnd = (TransportHandle)tp;
+    prm.state = state;
+    prm.lastError = info ? info->status : PJ_SUCCESS;
+
+    ep.epCallback->onTransportStateChanged(prm);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Endpoint library operations
+ */
+void Endpoint::libCreate() throw(Error)
+{
+    pj_status_t status;
+
+    status = pjsua_create();
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::libCreate()", status);
+}
+
+pjsua_state Endpoint::libGetState() const
+{
+    return pjsua_get_state();
+}
+
+void Endpoint::libInit( const EpConfig &prmEpConfig,
+                        EpCallback *prmCb) throw(Error)
+{
+    pjsua_config ua_cfg;
+    pjsua_logging_config log_cfg;
+    pjsua_media_config med_cfg;
+    pj_status_t status;
+
+    ua_cfg = prmEpConfig.uaConfig.toPjsip();
+    log_cfg = prmEpConfig.logConfig.toPjsip();
+    med_cfg = prmEpConfig.medConfig.toPjsip();
+
+    /* Setup log callback */
+    if (prmEpConfig.logConfig.writer) {
+	this->writer = prmEpConfig.logConfig.writer;
+	log_cfg.cb = &Endpoint::logFunc;
+    }
+
+    /* Setup UA callbacks */
+    pj_bzero(&ua_cfg.cb, sizeof(ua_cfg.cb));
+    ua_cfg.cb.on_nat_detect = &Endpoint::on_nat_detect;
+    ua_cfg.cb.on_transport_state = &Endpoint::on_transport_state;
+
+    /* Init! */
+    status = pjsua_init(&ua_cfg, &log_cfg, &med_cfg);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::libInit()", status);
+}
+
+void Endpoint::libStart() throw(Error)
+{
+    pj_status_t status;
+
+    status = pjsua_start();
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::libStart()", status);
+}
+
+void Endpoint::libDestroy(unsigned flags) throw(Error)
+{
+    pj_status_t status;
+
+    status = pjsua_destroy2(flags);
+
+    this->writer = NULL;
+    this->epCallback = NULL;
+
+    if (pj_log_get_log_func() == &Endpoint::logFunc) {
+	pj_log_set_log_func(NULL);
+    }
+
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::libDestroy()", status);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Endpoint Utilities
+ */
+string Endpoint::utilStrError(pj_status_t prmErr)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    pj_strerror(prmErr, errmsg, sizeof(errmsg));
+    return errmsg;
+}
+
+static void ept_log_write(int level, const char *sender,
+                          const char *format, ...)
+{
+    va_list arg;
+    va_start(arg, format);
+    pj_log(sender, level, format, arg );
+    va_end(arg);
+}
+
+void Endpoint::utilLogWrite(int prmLevel,
+			    const string &prmSender,
+			    const string &prmMsg)
+{
+    ept_log_write(prmLevel, prmSender.c_str(), "%s", prmMsg.c_str());
+}
+
+pj_status_t Endpoint::utilVerifySipUri(const string &prmUri)
+{
+    return pjsua_verify_sip_url(prmUri.c_str());
+}
+
+pj_status_t Endpoint::utilVerifyUri(const string &prmUri)
+{
+    return pjsua_verify_url(prmUri.c_str());
+}
+
+Token Endpoint::utilTimerSchedule(unsigned prmMsecDelay,
+                                  Token prmUserData) throw (Error)
+{
+    UserTimer *ut;
+    pj_time_val delay;
+    pj_status_t status;
+
+    ut = new UserTimer;
+    ut->signature = TIMER_SIGNATURE;
+    ut->prm.msecDelay = prmMsecDelay;
+    ut->prm.userData = prmUserData;
+    pj_timer_entry_init(&ut->entry, 1, ut, &Endpoint::on_timer);
+
+    delay.sec = 0;
+    delay.msec = prmMsecDelay;
+    pj_time_val_normalize(&delay);
+
+    status = pjsua_schedule_timer(&ut->entry, &delay);
+    if (status != PJ_SUCCESS) {
+	delete ut;
+	PJSUA2_CHECK_RAISE_ERROR("Endpoint::utilTimerSchedule()", status);
+    }
+
+    return (Token)ut;
+}
+
+void Endpoint::utilTimerCancel(Token prmTimerToken)
+{
+    UserTimer *ut = (UserTimer*)(void*)prmTimerToken;
+
+    if (ut->signature != TIMER_SIGNATURE) {
+	PJ_LOG(1,(THIS_FILE,
+		  "Invalid timer token in Endpoint::utilTimerCancel()"));
+	return;
+    }
+
+    ut->entry.id = 0;
+    ut->signature = 0xFFFFFFFE;
+    pjsua_cancel_timer(&ut->entry);
+
+    delete ut;
+}
+
+IntVector Endpoint::utilSslGetAvailableCiphers() throw (Error)
+{
+#if PJ_HAS_SSL_SOCK
+    pj_ssl_cipher ciphers[64];
+    unsigned count = PJ_ARRAY_SIZE(ciphers);
+    pj_status_t status;
+
+    status = pj_ssl_cipher_get_availables(ciphers, &count);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::utilSslGetAvailableCiphers()", status);
+
+    return IntVector(ciphers, ciphers + count);
+#else
+    return IntVector();
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Endpoint NAT operations
+ */
+void Endpoint::natDetectType(void) throw(Error)
+{
+    pj_status_t status;
+
+    status = pjsua_detect_nat_type();
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::natDetectType()", status);
+}
+
+pj_stun_nat_type Endpoint::natGetType() throw(Error)
+{
+    pj_stun_nat_type type;
+    pj_status_t status;
+
+    status = pjsua_get_nat_type(&type);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::natGetType()", status);
+
+    return type;
+}
+
+void Endpoint::natCheckStunServers(const StringVector &servers,
+				   bool wait,
+				   Token token) throw(Error)
+{
+    pj_str_t srv[MAX_STUN_SERVERS];
+    unsigned i, count = 0;
+    pj_status_t status;
+
+    for (i=0; i<servers.size() && i<MAX_STUN_SERVERS; ++i) {
+	srv[count].ptr = (char*)servers[i].c_str();
+	srv[count].slen = servers[i].size();
+	++count;
+    }
+
+    status = pjsua_resolve_stun_servers(count, srv, wait, token,
+    					&Endpoint::stun_resolve_cb);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::natCheckStunServers()", status);
+}
+
+void Endpoint::natCancelCheckStunServers(Token token,
+                                         bool notify_cb) throw(Error)
+{
+    pj_status_t status;
+
+    status = pjsua_cancel_stun_resolution(token, notify_cb);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::natCancelCheckStunServers()", status);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ * Transport API
+ */
+TransportId Endpoint::transportCreate(pjsip_transport_type_e type,
+                                      const TransportConfig &cfg) throw(Error)
+{
+    pjsua_transport_config tcfg;
+    pjsua_transport_id tid;
+    pj_status_t status;
+
+    tcfg = cfg.toPjsip();
+    status = pjsua_transport_create(type, &tcfg, &tid);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportCreate()", status);
+
+    return tid;
+}
+
+IntVector Endpoint::transportEnum() throw(Error)
+{
+    pjsua_transport_id tids[32];
+    unsigned count = PJ_ARRAY_SIZE(tids);
+    pj_status_t status;
+
+    status = pjsua_enum_transports(tids, &count);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportEnum()", status);
+
+    return IntVector(tids, tids+count);
+}
+
+TransportInfo Endpoint::transportGetInfo(TransportId id) throw(Error)
+{
+    pjsua_transport_info tinfo;
+    pj_status_t status;
+
+    status = pjsua_transport_get_info(id, &tinfo);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportGetInfo()", status);
+
+    return TransportInfo(tinfo);
+}
+
+void Endpoint::transportSetEnable(TransportId id, bool enabled) throw(Error)
+{
+    pj_status_t status;
+
+    status = pjsua_transport_set_enable(id, enabled);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportSetEnable()", status);
+}
+
+void Endpoint::transportClose(TransportId id) throw(Error)
+{
+    pj_status_t status;
+
+    status = pjsua_transport_close(id, PJ_FALSE);
+    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportClose()", status);
+}
+
Index: pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/types.cpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/types.cpp	(revision 4597)
+++ pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/types.cpp	(revision 4597)
@@ -0,0 +1,343 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <pjsua2/types.hpp>
+
+using namespace pj;
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////
+inline pj_str_t str2Pj(const string &is)
+{
+    pj_str_t os;
+    os.ptr = (char*)is.c_str();
+    os.slen = is.size();
+    return os;
+}
+
+inline string pj2Str(const pj_str_t &is)
+{
+    return string(is.ptr, is.slen);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+Error::Error()
+: status(PJ_SUCCESS)
+{
+}
+
+Error::Error( pj_status_t prm_status,
+	      const string &prm_reason,
+	      const string &prm_title,
+	      const string &prm_src_file,
+	      int prm_src_line)
+: status(prm_status), reason(prm_reason), title(prm_title),
+  srcFile(prm_src_file), srcLine(prm_src_line)
+{
+    if (this->status != PJ_SUCCESS && prm_reason.empty()) {
+	char errmsg[PJ_ERR_MSG_SIZE];
+	pj_strerror(this->status, errmsg, sizeof(errmsg));
+	this->reason = errmsg;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+AuthCredInfo::AuthCredInfo()
+: dataType(0)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+UaConfig::UaConfig()
+{
+    pjsua_config ua_cfg;
+
+    pjsua_config_default(&ua_cfg);
+    fromPj(ua_cfg);
+}
+
+void UaConfig::fromPj(const pjsua_config &ua_cfg)
+{
+    unsigned i;
+
+    this->maxCalls = ua_cfg.max_calls;
+    this->threadCnt = ua_cfg.thread_cnt;
+    this->userAgent = pj2Str(ua_cfg.user_agent);
+
+    for (i=0; i<ua_cfg.nameserver_count; ++i) {
+	this->nameserver.push_back(pj2Str(ua_cfg.nameserver[i]));
+    }
+
+    for (i=0; i<ua_cfg.stun_srv_cnt; ++i) {
+	this->stunServer.push_back(pj2Str(ua_cfg.stun_srv[i]));
+    }
+
+    this->stunIgnoreFailure = ua_cfg.stun_ignore_failure;
+    this->natTypeInSdp = ua_cfg.nat_type_in_sdp;
+    this->mwiUnsolicitedEnabled = ua_cfg.enable_unsolicited_mwi;
+}
+
+pjsua_config UaConfig::toPj() const
+{
+    unsigned i;
+    pjsua_config pua_cfg;
+
+    pjsua_config_default(&pua_cfg);
+
+    pua_cfg.max_calls = this->maxCalls;
+    pua_cfg.thread_cnt = this->threadCnt;
+    pua_cfg.user_agent = str2Pj(this->userAgent);
+
+    for (i=0; i<this->nameserver.size() && i<PJ_ARRAY_SIZE(pua_cfg.nameserver);
+	 ++i)
+    {
+	pua_cfg.nameserver[i] = str2Pj(this->nameserver[i]);
+    }
+    pua_cfg.nameserver_count = i;
+
+    for (i=0; i<this->stunServer.size() && i<PJ_ARRAY_SIZE(pua_cfg.stun_srv);
+	 ++i)
+    {
+	pua_cfg.stun_srv[i] = str2Pj(this->stunServer[i]);
+    }
+    pua_cfg.stun_srv_count = i;
+
+    pua_cfg.nat_type_in_sdp = this->natTypeInSdp;
+    pua_cfg.enable_unsolicited_mwi = this->mwiUnsolicitedEnabled;
+
+    return pua_cfg;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+LogConfig::LogConfig()
+{
+    pjsua_logging_config lc;
+
+    pjsua_logging_config_default(&lc);
+    fromPj(lc);
+}
+
+void LogConfig::fromPj(const pjsua_logging_config &lc)
+{
+    this->msgLogging = lc.msg_logging;
+    this->level = lc.level;
+    this->consoleLevel = lc.console_level;
+    this->decor = lc.decor;
+    this->filename = pj2Str(lc.log_filename);
+    this->fileFlags = lc.log_file_flags;
+    this->writer = NULL;
+}
+
+pjsua_logging_config LogConfig::toPj() const
+{
+    pjsua_logging_config lc;
+
+    pjsua_logging_config_default(&lc);
+
+    lc.msg_logging = this->msgLogging;
+    lc.level = this->level;
+    lc.console_level = this->consoleLevel;
+    lc.decor = this->decor;
+    lc.log_file_flags = this->fileFlags;
+    lc.log_filename = str2Pj(this->filename);
+
+    return lc;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+MediaConfig::MediaConfig()
+{
+    pjsua_media_config mc;
+
+    pjsua_media_config_default(&mc);
+    fromPj(mc);
+}
+
+void MediaConfig::fromPj(const pjsua_media_config &mc)
+{
+    this->clockRate = mc.clock_rate;
+    this->sndClockRate = mc.snd_clock_rate;
+    this->channelCount = mc.channel_count;
+    this->audioFramePtime = mc.audio_frame_ptime;
+    this->maxMediaPorts = mc.max_media_ports;
+    this->hasIoqueue = mc.has_ioqueue;
+    this->threadCnt = mc.thread_cnt;
+    this->quality = mc.quality;
+    this->ptime = mc.ptime;
+    this->noVad = mc.no_vad;
+    this->ilbcMode = mc.ilbc_mode;
+    this->txDropPct = mc.tx_drop_pct;
+    this->rxDropPct = mc.rx_drop_pct;
+    this->ecOptions = mc.ec_options;
+    this->ecTailLen = mc.ec_tail_len;
+    this->sndRecLatency = mc.snd_rec_latency;
+    this->sndPlayLatency = mc.snd_play_latency;
+    this->jbInit = mc.jb_init;
+    this->jbMinPre = mc.jb_min_pre;
+    this->jbMaxPre = mc.jb_max_pre;
+    this->jbMax = mc.jb_max;
+    this->sndAutoCloseTime = mc.snd_auto_close_time;
+    this->vidPreviewEnableNative = mc.vid_preview_enable_native;
+}
+
+pjsua_media_config MediaConfig::toPj() const
+{
+    pjsua_media_config mcfg;
+
+    pjsua_media_config_default(&mcfg);
+
+    mcfg.clock_rate = this->clockRate;
+    mcfg.snd_clock_rate = this->sndClockRate;
+    mcfg.channel_count = this->channelCount;
+    mcfg.audio_frame_ptime = this->audioFramePtime;
+    mcfg.max_media_ports = this->maxMediaPorts;
+    mcfg.has_ioqueue = this->hasIoqueue;
+    mcfg.thread_cnt = this->threadCnt;
+    mcfg.quality = this->quality;
+    mcfg.ptime = this->ptime;
+    mcfg.no_vad = this->noVad;
+    mcfg.ilbc_mode = this->ilbcMode;
+    mcfg.tx_drop_pct = this->txDropPct;
+    mcfg.rx_drop_pct = this->rxDropPct;
+    mcfg.ec_options = this->ecOptions;
+    mcfg.ec_tail_len = this->ecTailLen;
+    mcfg.snd_rec_latency = this->sndRecLatency;
+    mcfg.snd_play_latency = this->sndPlayLatency;
+    mcfg.jb_init = this->jbInit;
+    mcfg.jb_min_pre = this->jbMinPre;
+    mcfg.jb_max_pre = this->jbMaxPre;
+    mcfg.jb_max = this->jbMax;
+    mcfg.snd_auto_close_time = this->sndAutoCloseTime;
+    mcfg.vid_preview_enable_native = this->vidPreviewEnableNative;
+
+    return mcfg;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+TlsConfig::TlsConfig()
+{
+    pjsip_tls_setting ts;
+    pjsip_tls_setting_default(&ts);
+    this->fromPj(ts);
+}
+
+pjsip_tls_setting TlsConfig::toPj() const
+{
+    pjsip_tls_setting ts;
+
+    ts.ca_list_file	= str2Pj(this->CaListFile);
+    ts.cert_file	= str2Pj(this->certFile);
+    ts.privkey_file	= str2Pj(this->privKeyFile);
+    ts.password		= str2Pj(this->password);
+    ts.method		= this->method;
+    ts.ciphers_num	= this->ciphers.size();
+    // The following will only work if sizeof(enum)==sizeof(int)
+    pj_assert(sizeof(ts.ciphers[0]) == sizeof(int));
+    ts.ciphers		= (pj_ssl_cipher*)&this->ciphers[0];
+    ts.verify_server	= this->verifyServer;
+    ts.verify_client	= this->verifyClient;
+    ts.require_client_cert = this->requireClientCert;
+    ts.timeout.sec 	= this->msecTimeout / 1000;
+    ts.timeout.msec	= this->msecTimeout % 1000;
+    ts.qos_type		= this->qosType;
+    ts.qos_params	= this->qosParams;
+    ts.qos_ignore_error	= this->qosIgnoreError;
+
+    return ts;
+}
+
+void TlsConfig::fromPj(const pjsip_tls_setting &prm)
+{
+    this->CaListFile 	= pj2Str(prm.ca_list_file);
+    this->certFile 	= pj2Str(prm.cert_file);
+    this->privKeyFile 	= pj2Str(prm.privkey_file);
+    this->password 	= pj2Str(prm.password);
+    this->method 	= (pjsip_ssl_method)prm.method;
+    // The following will only work if sizeof(enum)==sizeof(int)
+    pj_assert(sizeof(prm.ciphers[0]) == sizeof(int));
+    this->ciphers 	= IntVector(prm.ciphers, prm.ciphers+prm.ciphers_num);
+    this->verifyServer 	= prm.verify_server;
+    this->verifyClient 	= prm.verify_client;
+    this->requireClientCert = prm.require_client_cert;
+    this->msecTimeout 	= PJ_TIME_VAL_MSEC(prm.timeout);
+    this->qosType 	= prm.qos_type;
+    this->qosParams 	= prm.qos_params;
+    this->qosIgnoreError = prm.qos_ignore_error;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+TransportConfig::TransportConfig()
+{
+    pjsua_transport_config tc;
+    pjsua_transport_config_default(&tc);
+    this->fromPj(tc);
+}
+
+void TransportConfig::fromPj(const pjsua_transport_config &prm)
+{
+    this->port 		= prm.port;
+    this->publicAddress = pj2Str(prm.public_addr);
+    this->boundAddress	= pj2Str(prm.bound_addr);
+    this->tlsConfig.fromPj(prm.tls_setting);
+    this->qosType	= prm.qos_type;
+    this->qosParams	= prm.qos_params;
+}
+
+pjsua_transport_config TransportConfig::toPj() const
+{
+    pjsua_transport_config tc;
+
+    tc.port		= this->port;
+    tc.public_addr	= str2Pj(this->publicAddress);
+    tc.bound_addr	= str2Pj(this->boundAddress);
+    tc.tls_setting	= this->tlsConfig.toPj();
+    tc.qos_type		= this->qosType;
+    tc.qos_params	= this->qosParams;
+
+    return tc;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+TransportInfo::TransportInfo(const pjsua_transport_info &info)
+{
+    this->id = info.id;
+    this->type = info.type;
+    this->typeName = pj2Str(info.type_name);
+    this->info = pj2Str(info.info);
+    this->flags = info.flag;
+
+    char straddr[PJ_INET6_ADDRSTRLEN+10];
+    pj_sockaddr_print(&info.local_addr, straddr, sizeof(straddr), 3);
+    this->localAddress = straddr;
+
+    pj_ansi_snprintf(straddr, sizeof(straddr), "%.*s:%d",
+                     (int)info.local_name.host.slen,
+                     info.local_name.host.ptr,
+                     info.local_name.port);
+    this->localName = straddr;
+    this->usageCount = info.usage_count;
+}
+
