* #40033: Add android makefiles
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/aectest b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/aectest
new file mode 100755
index 0000000..9a8894e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/aectest
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/auddemo b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/auddemo
new file mode 100755
index 0000000..4c0f606
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/auddemo
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/aviplay b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/aviplay
new file mode 100755
index 0000000..29e3592
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/aviplay
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/clidemo b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/clidemo
new file mode 100755
index 0000000..570d46d
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/clidemo
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/confsample b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/confsample
new file mode 100755
index 0000000..1de8ec7
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/confsample
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/encdec b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/encdec
new file mode 100755
index 0000000..825c600
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/encdec
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/httpdemo b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/httpdemo
new file mode 100755
index 0000000..13421d0
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/httpdemo
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/icedemo b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/icedemo
new file mode 100755
index 0000000..7b4e175
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/icedemo
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/jbsim b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/jbsim
new file mode 100755
index 0000000..41ed959
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/jbsim
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/latency b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/latency
new file mode 100755
index 0000000..6366143
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/latency
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/level b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/level
new file mode 100755
index 0000000..a9e4dc9
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/level
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/mix b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/mix
new file mode 100755
index 0000000..50acef9
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/mix
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/pcaputil b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/pcaputil
new file mode 100755
index 0000000..7747e81
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/pcaputil
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/pjsip-perf b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/pjsip-perf
new file mode 100755
index 0000000..cba19cf
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/pjsip-perf
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/pjsua2_demo b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/pjsua2_demo
new file mode 100755
index 0000000..d348fc0
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/pjsua2_demo
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/playfile b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/playfile
new file mode 100755
index 0000000..e982903
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/playfile
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/playsine b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/playsine
new file mode 100755
index 0000000..9fddc52
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/playsine
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/recfile b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/recfile
new file mode 100755
index 0000000..e13a66f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/recfile
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/resampleplay b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/resampleplay
new file mode 100755
index 0000000..82c4d20
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/resampleplay
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/simple_pjsua b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/simple_pjsua
new file mode 100755
index 0000000..56b3314
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/simple_pjsua
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/simpleua b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/simpleua
new file mode 100755
index 0000000..2afc1ca
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/simpleua
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/sipecho b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/sipecho
new file mode 100755
index 0000000..aa4a04b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/sipecho
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/siprtp b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/siprtp
new file mode 100755
index 0000000..384726f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/siprtp
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/sipstateless b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/sipstateless
new file mode 100755
index 0000000..bec8d7a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/sipstateless
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/stateful_proxy b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/stateful_proxy
new file mode 100755
index 0000000..d968fd0
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/stateful_proxy
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/stateless_proxy b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/stateless_proxy
new file mode 100755
index 0000000..6ecc046
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/stateless_proxy
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/stereotest b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/stereotest
new file mode 100755
index 0000000..426e80e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/stereotest
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/streamutil b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/streamutil
new file mode 100755
index 0000000..409c8ca
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/streamutil
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/strerror b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/strerror
new file mode 100755
index 0000000..3201c6d
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/strerror
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/tonegen b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/tonegen
new file mode 100755
index 0000000..3e9fd58
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/tonegen
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/vid_streamutil b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/vid_streamutil
new file mode 100755
index 0000000..d96ed94
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/bin/samples/arm-unknown-linux-androideabi/vid_streamutil
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/build/.pjsua-arm-unknown-linux-androideabi.depend b/jni/libpjsip/sources/pjsip-apps/build/.pjsua-arm-unknown-linux-androideabi.depend
new file mode 100644
index 0000000..f901936
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/.pjsua-arm-unknown-linux-androideabi.depend
@@ -0,0 +1,1531 @@
+output/pjsua-arm-unknown-linux-androideabi/main.o: ../src/pjsua/main.c ../src/pjsua/pjsua_app.h \
+ ../src/pjsua/pjsua_app_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsua-lib/pjsua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/cc_gcc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/os_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/m_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/size_t.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stddef.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config_site.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_autoconf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/errno.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdarg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/list.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_tel_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_multipart.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_parser.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/lock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_module.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_resolve.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ioqueue.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_qos.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tls.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ssl_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs_elf.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/android/api-level.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/malloc.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/stdio.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/types.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_wchar_limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/stddef.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/compiler.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/kernel.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/sysmacros.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdlib.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/alloca.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/strings.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/memory.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_aka.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_ua_layer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_dialog.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/alaw_ulaw.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/avi_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/clock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/format.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/signatures.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/frame.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/os.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/bidirectional.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/circbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/conference.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/converter.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/delaybuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/g711.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/jbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/master_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/mem_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/null_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/plc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/resample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp_xr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/math.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/high_precision.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/math.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/limits.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/internal_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/page.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp_neg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/silencedet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/audiodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/splitcomb.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stereo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/tonegen.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_adapter_sample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_ice.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_strans.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_srtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_tee.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_playlist.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wave.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wsola.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/audio_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/passthrough.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/l16.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/gsm.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/speex.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ilbc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g722.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g7221.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ipp_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/opencore_amr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/silk.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia_videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/avi_dev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_ua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_inv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_regc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_replaces.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_xfer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_100rel.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/iscomposing.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/xml.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/mwi.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/presence.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/pidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/xpidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/rpid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/publish.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/nat_detect.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/getopt.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/base64.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/crc32.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/srv_resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns_server.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/json.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/stun_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/pcap.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/http_client.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/activesock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_console.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_telnet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pjlib.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/addr_resolv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/array.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/ctype.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/except.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/setjmp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/log.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/fifobuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_access.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_io.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/guid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/hash.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ip_helper.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool_buf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rand.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rbtree.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_select.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/unicode.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/signal.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/signal.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm-generic/signal.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/sigcontext.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/siginfo.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm-generic/siginfo.h
+output/pjsua-arm-unknown-linux-androideabi/pjsua_app.o: ../src/pjsua/pjsua_app.c ../src/pjsua/pjsua_app.h \
+ ../src/pjsua/pjsua_app_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsua-lib/pjsua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/cc_gcc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/os_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/m_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/size_t.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stddef.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config_site.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_autoconf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/errno.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdarg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/list.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_tel_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_multipart.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_parser.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/lock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_module.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_resolve.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ioqueue.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_qos.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tls.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ssl_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs_elf.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/android/api-level.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/malloc.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/stdio.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/types.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_wchar_limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/stddef.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/compiler.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/kernel.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/sysmacros.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdlib.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/alloca.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/strings.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/memory.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_aka.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_ua_layer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_dialog.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/alaw_ulaw.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/avi_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/clock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/format.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/signatures.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/frame.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/os.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/bidirectional.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/circbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/conference.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/converter.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/delaybuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/g711.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/jbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/master_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/mem_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/null_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/plc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/resample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp_xr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/math.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/high_precision.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/math.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/limits.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/internal_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/page.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp_neg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/silencedet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/audiodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/splitcomb.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stereo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/tonegen.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_adapter_sample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_ice.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_strans.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_srtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_tee.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_playlist.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wave.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wsola.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/audio_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/passthrough.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/l16.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/gsm.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/speex.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ilbc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g722.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g7221.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ipp_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/opencore_amr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/silk.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia_videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/avi_dev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_ua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_inv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_regc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_replaces.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_xfer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_100rel.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/iscomposing.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/xml.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/mwi.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/presence.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/pidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/xpidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/rpid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/publish.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/nat_detect.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/getopt.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/base64.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/crc32.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/srv_resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns_server.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/json.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/stun_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/pcap.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/http_client.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/activesock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_console.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_telnet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pjlib.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/addr_resolv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/array.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/ctype.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/except.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/setjmp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/log.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/fifobuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_access.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_io.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/guid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/hash.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ip_helper.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool_buf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rand.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rbtree.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_select.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/unicode.h
+output/pjsua-arm-unknown-linux-androideabi/pjsua_app_cli.o: ../src/pjsua/pjsua_app_cli.c \
+ ../src/pjsua/pjsua_app_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsua-lib/pjsua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/cc_gcc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/os_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/m_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/size_t.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stddef.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config_site.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_autoconf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/errno.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdarg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/list.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_tel_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_multipart.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_parser.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/lock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_module.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_resolve.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ioqueue.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_qos.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tls.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ssl_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs_elf.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/android/api-level.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/malloc.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/stdio.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/types.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_wchar_limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/stddef.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/compiler.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/kernel.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/sysmacros.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdlib.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/alloca.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/strings.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/memory.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_aka.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_ua_layer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_dialog.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/alaw_ulaw.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/avi_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/clock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/format.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/signatures.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/frame.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/os.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/bidirectional.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/circbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/conference.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/converter.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/delaybuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/g711.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/jbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/master_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/mem_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/null_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/plc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/resample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp_xr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/math.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/high_precision.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/math.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/limits.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/internal_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/page.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp_neg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/silencedet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/audiodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/splitcomb.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stereo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/tonegen.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_adapter_sample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_ice.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_strans.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_srtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_tee.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_playlist.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wave.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wsola.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/audio_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/passthrough.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/l16.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/gsm.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/speex.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ilbc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g722.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g7221.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ipp_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/opencore_amr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/silk.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia_videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/avi_dev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_ua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_inv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_regc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_replaces.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_xfer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_100rel.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/iscomposing.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/xml.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/mwi.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/presence.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/pidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/xpidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/rpid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/publish.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/nat_detect.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/getopt.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/base64.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/crc32.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/srv_resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns_server.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/json.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/stun_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/pcap.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/http_client.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/activesock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_console.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_telnet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pjlib.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/addr_resolv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/array.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/ctype.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/except.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/setjmp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/log.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/fifobuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_access.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_io.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/guid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/hash.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ip_helper.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool_buf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rand.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rbtree.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_select.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/unicode.h
+output/pjsua-arm-unknown-linux-androideabi/pjsua_app_common.o: ../src/pjsua/pjsua_app_common.c \
+ ../src/pjsua/pjsua_app_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsua-lib/pjsua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/cc_gcc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/os_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/m_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/size_t.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stddef.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config_site.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_autoconf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/errno.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdarg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/list.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_tel_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_multipart.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_parser.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/lock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_module.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_resolve.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ioqueue.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_qos.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tls.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ssl_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs_elf.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/android/api-level.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/malloc.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/stdio.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/types.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_wchar_limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/stddef.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/compiler.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/kernel.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/sysmacros.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdlib.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/alloca.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/strings.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/memory.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_aka.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_ua_layer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_dialog.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/alaw_ulaw.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/avi_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/clock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/format.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/signatures.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/frame.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/os.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/bidirectional.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/circbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/conference.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/converter.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/delaybuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/g711.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/jbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/master_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/mem_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/null_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/plc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/resample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp_xr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/math.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/high_precision.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/math.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/limits.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/internal_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/page.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp_neg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/silencedet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/audiodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/splitcomb.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stereo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/tonegen.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_adapter_sample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_ice.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_strans.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_srtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_tee.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_playlist.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wave.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wsola.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/audio_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/passthrough.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/l16.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/gsm.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/speex.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ilbc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g722.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g7221.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ipp_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/opencore_amr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/silk.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia_videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/avi_dev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_ua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_inv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_regc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_replaces.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_xfer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_100rel.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/iscomposing.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/xml.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/mwi.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/presence.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/pidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/xpidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/rpid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/publish.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/nat_detect.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/getopt.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/base64.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/crc32.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/srv_resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns_server.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/json.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/stun_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/pcap.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/http_client.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/activesock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_console.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_telnet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pjlib.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/addr_resolv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/array.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/ctype.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/except.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/setjmp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/log.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/fifobuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_access.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_io.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/guid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/hash.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ip_helper.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool_buf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rand.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rbtree.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_select.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/unicode.h
+output/pjsua-arm-unknown-linux-androideabi/pjsua_app_config.o: ../src/pjsua/pjsua_app_config.c \
+ ../src/pjsua/pjsua_app_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsua-lib/pjsua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/cc_gcc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/os_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/m_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/size_t.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stddef.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config_site.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_autoconf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/errno.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdarg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/list.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_tel_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_multipart.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_parser.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/lock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_module.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_resolve.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ioqueue.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_qos.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tls.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ssl_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs_elf.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/android/api-level.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/malloc.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/stdio.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/types.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_wchar_limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/stddef.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/compiler.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/kernel.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/sysmacros.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdlib.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/alloca.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/strings.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/memory.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_aka.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_ua_layer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_dialog.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/alaw_ulaw.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/avi_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/clock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/format.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/signatures.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/frame.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/os.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/bidirectional.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/circbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/conference.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/converter.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/delaybuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/g711.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/jbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/master_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/mem_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/null_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/plc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/resample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp_xr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/math.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/high_precision.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/math.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/limits.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/internal_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/page.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp_neg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/silencedet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/audiodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/splitcomb.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stereo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/tonegen.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_adapter_sample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_ice.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_strans.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_srtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_tee.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_playlist.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wave.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wsola.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/audio_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/passthrough.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/l16.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/gsm.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/speex.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ilbc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g722.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g7221.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ipp_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/opencore_amr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/silk.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia_videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/avi_dev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_ua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_inv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_regc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_replaces.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_xfer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_100rel.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/iscomposing.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/xml.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/mwi.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/presence.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/pidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/xpidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/rpid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/publish.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/nat_detect.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/getopt.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/base64.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/crc32.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/srv_resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns_server.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/json.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/stun_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/pcap.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/http_client.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/activesock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_console.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_telnet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pjlib.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/addr_resolv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/array.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/ctype.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/except.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/setjmp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/log.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/fifobuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_access.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_io.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/guid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/hash.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ip_helper.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool_buf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rand.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rbtree.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_select.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/unicode.h
+output/pjsua-arm-unknown-linux-androideabi/pjsua_app_legacy.o: ../src/pjsua/pjsua_app_legacy.c \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsua-lib/pjsua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/cc_gcc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/os_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/m_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/size_t.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stddef.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config_site.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_autoconf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/errno.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdarg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/list.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_tel_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_multipart.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_parser.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/lock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_module.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_resolve.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ioqueue.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_qos.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tls.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ssl_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs_elf.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/android/api-level.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/malloc.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/stdio.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/types.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_wchar_limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/stddef.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/compiler.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/kernel.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/sysmacros.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdlib.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/alloca.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/strings.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/memory.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_aka.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_ua_layer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_dialog.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/alaw_ulaw.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/avi_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/clock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/format.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/signatures.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/frame.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/os.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/bidirectional.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/circbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/conference.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/converter.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/delaybuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/g711.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/jbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/master_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/mem_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/null_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/plc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/resample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp_xr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/math.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/high_precision.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/math.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/limits.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/internal_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/page.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp_neg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/silencedet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/audiodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/splitcomb.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stereo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/tonegen.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_adapter_sample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_ice.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_strans.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_srtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_tee.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_playlist.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wave.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wsola.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/audio_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/passthrough.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/l16.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/gsm.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/speex.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ilbc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g722.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g7221.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ipp_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/opencore_amr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/silk.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia_videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/avi_dev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_ua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_inv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_regc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_replaces.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_xfer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_100rel.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/iscomposing.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/xml.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/mwi.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/presence.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/pidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/xpidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/rpid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/publish.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/nat_detect.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/getopt.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/base64.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/crc32.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/srv_resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns_server.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/json.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/stun_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/pcap.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/http_client.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/activesock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_console.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_telnet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pjlib.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/addr_resolv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/array.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/ctype.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/except.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/setjmp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/log.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/fifobuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_access.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_io.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/guid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/hash.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ip_helper.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool_buf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rand.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rbtree.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_select.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/unicode.h \
+ ../src/pjsua/pjsua_app_common.h
+../bin/pjsua-arm-unknown-linux-androideabi: /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsua2-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsua-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsip-ua-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsip-simple-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsip-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/lib/libpjmedia-codec-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/lib/libpjmedia-videodev-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/lib/libpjmedia-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/lib/libpjmedia-audiodev-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/lib/libpjnath-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/lib/libpjlib-util-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/third_party/lib/libmilenage-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/third_party/lib/libsrtp-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/third_party/lib/libresample-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/lib/libpj-arm-unknown-linux-androideabi.a
diff --git a/jni/libpjsip/sources/pjsip-apps/build/.pjsystest-arm-unknown-linux-androideabi.depend b/jni/libpjsip/sources/pjsip-apps/build/.pjsystest-arm-unknown-linux-androideabi.depend
new file mode 100644
index 0000000..e57e4d5
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/.pjsystest-arm-unknown-linux-androideabi.depend
@@ -0,0 +1,345 @@
+output/pjsystest-arm-unknown-linux-androideabi/systest.o: ../src/pjsystest/systest.c ../src/pjsystest/systest.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pjlib.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/activesock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ioqueue.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/cc_gcc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/os_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/m_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/size_t.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stddef.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config_site.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/addr_resolv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/array.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs_elf.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/android/api-level.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/ctype.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/errno.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdarg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/except.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/setjmp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/log.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/fifobuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_access.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_io.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/guid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/hash.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ip_helper.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/list.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/lock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/math.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/malloc.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/stdio.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/types.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_wchar_limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/stddef.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/compiler.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/kernel.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/sysmacros.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdlib.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/alloca.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/strings.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/memory.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/high_precision.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/math.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/limits.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/internal_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/page.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/os.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool_buf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rand.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rbtree.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_qos.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_select.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ssl_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/unicode.h \
+ ../src/pjsystest/gui.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsua-lib/pjsua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_autoconf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/scanner_cis_bitwise.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_tel_uri.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_multipart.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_parser.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_module.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_resolve.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transport_tls.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_auth_aka.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_ua_layer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip/sip_dialog.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/alaw_ulaw.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/avi_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/clock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/event.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/format.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/signatures.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/frame.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/bidirectional.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/circbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/conference.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/converter.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/delaybuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/echo_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/endpoint.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/g711.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/config_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/jbuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/master_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/mem_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/null_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/plc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/resample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtcp_xr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/rtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sdp_neg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/silencedet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/audiodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/sound_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/splitcomb.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stereo.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/stream_common.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/tonegen.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_adapter_sample.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_ice.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_strans.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/ice_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_auth.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_transaction.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/stun_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/turn_session.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_loop.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_srtp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/transport_udp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_stream.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/vid_tee.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_playlist.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wav_port.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wave.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia/wsola.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/audio_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/passthrough.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/l16.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/gsm.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/speex.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ilbc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g722.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/g7221.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/ipp_codecs.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/opencore_amr.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-codec/silk.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia_videodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/videodev_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-videodev/avi_dev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_ua.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_inv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_regc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_replaces.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_xfer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_100rel.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-ua/sip_timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/evsub_msg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/iscomposing.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/xml.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/mwi.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/presence.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/pidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/xpidf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/rpid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/include/pjsip-simple/publish.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/include/pjnath/nat_detect.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/getopt.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/base64.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/crc32.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/md5.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/hmac_sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/sha1.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/srv_resolver.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/dns_server.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/json.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/stun_simple.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/pcap.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/http_client.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_console.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/include/pjlib-util/cli_telnet.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia_audiodev.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/audiodev_imp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/include/pjmedia-audiodev/audiotest.h
+output/pjsystest-arm-unknown-linux-androideabi/main_console.o: ../src/pjsystest/main_console.c \
+ ../src/pjsystest/systest.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pjlib.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/activesock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ioqueue.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/types.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/cc_gcc.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/os_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/m_auto.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/size_t.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stddef.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/config_site.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/addr_resolv.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/array.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/assert.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/assert.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/cdefs_elf.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/android/api-level.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/ctype.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/ctype.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/errno.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/errno.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdarg.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/except.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/setjmp.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/setjmp.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/log.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/fifobuf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_access.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/file_io.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/guid.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/hash.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ip_helper.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/list.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/lock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/math.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/string.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/string.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/malloc.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/stdio.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/types.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdint.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/_wchar_limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/stddef.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/compiler.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/posix_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/kernel.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/sysmacros.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/stdlib.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/alloca.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/strings.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/memory.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/compat/high_precision.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/math.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/limits.h \
+ /home/lisional/Dev/ADT/ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/include-fixed/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/linux/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/internal_types.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/machine/limits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/sys/syslimits.h \
+ /home/lisional/Dev/ADT/ndk/platforms/android-19/arch-arm/usr/include/asm/page.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/os.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/pool_buf.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rand.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/rbtree.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_qos.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/sock_select.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/ssl_sock.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/timer.h \
+ /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/include/pj/unicode.h \
+ ../src/pjsystest/gui.h
+../bin/pjsystest-arm-unknown-linux-androideabi: /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsua2-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsua-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsip-ua-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsip-simple-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjsip/lib/libpjsip-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/lib/libpjmedia-codec-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/lib/libpjmedia-videodev-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/lib/libpjmedia-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjmedia/lib/libpjmedia-audiodev-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjnath/lib/libpjnath-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib-util/lib/libpjlib-util-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/third_party/lib/libmilenage-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/third_party/lib/libsrtp-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/third_party/lib/libresample-arm-unknown-linux-androideabi.a /home/lisional/git/sflphone-android/jni/pjproject-android/pjlib/lib/libpj-arm-unknown-linux-androideabi.a
diff --git a/jni/libpjsip/sources/pjsip-apps/build/Footprint.mak b/jni/libpjsip/sources/pjsip-apps/build/Footprint.mak
new file mode 100644
index 0000000..cc63179
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/Footprint.mak
@@ -0,0 +1,28 @@
+#
+# This file is used by get-footprint.py script to build samples/footprint.c
+# to get the footprint report for PJSIP/PJMEDIA.
+#
+include ../../build.mak
+include ../../build/common.mak
+
+
+###############################################################################
+# Gather all flags.
+#
+export _CFLAGS 	:= $(APP_CFLAGS) $(CFLAGS)
+export _CXXFLAGS:= $(_CFLAGS)
+
+export _LDFLAGS := $(APP_LDFLAGS) $(APP_LDLIBS) $(LDFLAGS)
+
+EXE := footprint.exe
+
+all: 
+	$(APP_CC) -o $(EXE) ../src/samples/footprint.c $(FCFLAGS) $(_CFLAGS) $(_LDFLAGS)
+	$(CROSS_COMPILE)strip --strip-all $(EXE)
+
+clean:
+	rm -f $(EXE)
+
+print_name:
+	@echo $(MACHINE_NAME) $(OS_NAME) $(CROSS_COMPILE)$(CC_NAME) `$(CROSS_COMPILE)$(CC_NAME) -dumpversion`
+
diff --git a/jni/libpjsip/sources/pjsip-apps/build/Makefile b/jni/libpjsip/sources/pjsip-apps/build/Makefile
new file mode 100644
index 0000000..c776de1
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/Makefile
@@ -0,0 +1,111 @@
+include ../../build.mak
+include $(PJDIR)/build/common.mak
+
+export LIBDIR := ../lib
+export BINDIR := ../bin
+
+RULES_MAK := $(PJDIR)/build/rules.mak
+
+PJLIB_LIB:=../../pjlib/lib/libpj-$(TARGET_NAME)$(LIBEXT)
+PJLIB_UTIL_LIB:=../../pjlib-util/lib/libpjlib-util-$(TARGET_NAME)$(LIBEXT)
+PJNATH_LIB:=../../pjnath/lib/libpjnath-$(TARGET_NAME)$(LIBEXT)
+PJMEDIA_LIB:=../../pjmedia/lib/libpjmedia-$(TARGET_NAME)$(LIBEXT)
+PJMEDIA_AUDIODEV_LIB:=../../pjmedia/lib/libpjmedia-audiodev-$(TARGET_NAME)$(LIBEXT)
+PJMEDIA_CODEC_LIB:=../../pjmedia/lib/libpjmedia-codec-$(TARGET_NAME)$(LIBEXT)
+PJSIP_LIB:=../../pjsip/lib/libpjsip-$(TARGET_NAME)$(LIBEXT)
+PJSIP_UA_LIB:=../../pjsip/lib/libpjsip-ua-$(TARGET_NAME)$(LIBEXT)
+PJSIP_SIMPLE_LIB:=../../pjsip/lib/libpjsip-simple-$(TARGET_NAME)$(LIBEXT)
+PJSUA_LIB_LIB=../../pjsip/lib/libpjsua-$(TARGET_NAME)$(LIBEXT)
+
+
+###############################################################################
+# Gather all flags.
+#
+export _CFLAGS 	:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \
+		   $(PJ_CFLAGS) $(CFLAGS) $(CC_INC)../../pjsip/include \
+		   $(CC_INC)../../pjlib/include \
+		   $(CC_INC)../../pjlib-util/include \
+		   $(CC_INC)../../pjnath/include \
+		   $(CC_INC)../../pjmedia/include
+export _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \
+		   $(HOST_CXXFLAGS) $(CXXFLAGS)
+export _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \
+		   $(APP_LDFLAGS) $(APP_LDLIBS) $(LDFLAGS) 
+
+###############################################################################
+# Defines for building PJSUA
+#
+export PJSUA_SRCDIR = ../src/pjsua
+export PJSUA_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
+            main.o pjsua_app.o pjsua_app_cli.o pjsua_app_common.o \
+            pjsua_app_config.o pjsua_app_legacy.o
+export PJSUA_CFLAGS += $(_CFLAGS)
+export PJSUA_CXXFLAGS += $(_CXXFLAGS)
+export PJSUA_LDFLAGS += $(_LDFLAGS)
+export PJSUA_EXE:=pjsua-$(TARGET_NAME)$(HOST_EXE)
+
+
+###############################################################################
+# Defines for building pjsystest
+#
+export PJSYSTEST_SRCDIR = ../src/pjsystest
+export PJSYSTEST_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
+			systest.o main_console.o
+export PJSYSTEST_CFLAGS += $(_CFLAGS)
+export PJSYSTEST_CXXFLAGS += $(_CXXFLAGS)
+export PJSYSTEST_LDFLAGS += $(_LDFLAGS)
+export PJSYSTEST_EXE:=pjsystest-$(TARGET_NAME)$(HOST_EXE)
+
+
+export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT 
+###############################################################################
+# Main entry
+#
+#
+#  x   x  x  x  x  x  x   x  x  x  x  x  x   x  x  x  x  x  x   x  x  x  x  x
+#
+#                FIX THIS
+#
+#  x   x  x  x  x  x  x   x  x  x  x  x  x   x  x  x  x  x  x   x  x  x  x  x
+TARGETS := $(BINDIR)/$(PJSUA_EXE) $(BINDIR)/$(PJSYSTEST_EXE) samples
+
+all: $(TARGETS)
+
+swig:
+	$(MAKE) -C ../src/swig
+	
+doc:
+
+dep: depend
+distclean: realclean
+
+.PHONY: all dep depend clean realclean distclean
+.PHONY: $(TARGETS)
+.PHONY: $(PJSUA_EXE) $(PJSYSTEST_EXE)
+
+pjsua: $(PJSUA_EXE)
+$(PJSUA_EXE):
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA app=pjsua $(subst /,$(HOST_PSEP),$(BINDIR)/$@)
+
+pjsystest: $(PJSYSTEST_EXE)
+$(PJSYSTEST_EXE):
+	$(MAKE) -f $(RULES_MAK) APP=PJSYSTEST app=pjsystest $(subst /,$(HOST_PSEP),$(BINDIR)/$@)
+
+samples:
+	$(MAKE) -f Samples.mak
+
+.PHONY: pjsua.ko
+pjsua.ko:
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA app=pjsua $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)
+
+clean depend realclean:
+	$(MAKE) -f $(RULES_MAK) APP=PJSUA app=pjsua $@
+	$(MAKE) -f $(RULES_MAK) APP=PJSYSTEST app=pjsystest $@
+	$(MAKE) -f Samples.mak $@
+	@if test "$@" = "depend"; then \
+	  echo '$(BINDIR)/$(PJSUA_EXE): $(APP_LIB_FILES)' >> .pjsua-$(TARGET_NAME).depend; \
+	  echo '$(BINDIR)/$(PJSYSTEST_EXE): $(APP_LIB_FILES)' >> .pjsystest-$(TARGET_NAME).depend; \
+	fi
+
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/build/Samples-vc.mak b/jni/libpjsip/sources/pjsip-apps/build/Samples-vc.mak
new file mode 100644
index 0000000..fed970f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/Samples-vc.mak
@@ -0,0 +1,124 @@
+
+LIBEXT = .lib
+
+!if "$(ARCH)" == "win64"
+TARGET = x86_64-x64-vc$(VC_VER)-$(BUILD_MODE)
+TARGET_FLAGS = /DPJ_WIN64=1 /DPJ_M_X86_64=1 
+!else
+
+TARGET = i386-win32-vc$(VC_VER)-$(BUILD_MODE)
+TARGET_FLAGS = /DPJ_WIN32=1 /DPJ_M_I386=1 
+!endif
+
+!if "$(BUILD_MODE)" == "debug"
+BUILD_FLAGS = /MTd /Od /Zi /W4
+!elseif "$(BUILD_MODE)" == "debug-static"
+BUILD_FLAGS = /MTd /Od /Zi /W4
+!elseif "$(BUILD_MODE)" == "debug-dynamic"
+BUILD_FLAGS = /MDd /Od /Zi /W4
+!elseif "$(BUILD_MODE)" == "release-static"
+BUILD_FLAGS = /Ox /MT /DNDEBUG /W4
+!else
+BUILD_FLAGS = /Ox /MD /DNDEBUG /W4
+!endif
+
+PJLIB_LIB = ..\..\pjlib\lib\pjlib-$(TARGET)$(LIBEXT)
+PJLIB_UTIL_LIB = ..\..\pjlib-util\lib\pjlib-util-$(TARGET)$(LIBEXT)
+PJNATH_LIB = ..\..\pjnath\lib\pjnath-$(TARGET)$(LIBEXT)
+PJMEDIA_LIB = ..\..\pjmedia\lib\pjmedia-$(TARGET)$(LIBEXT)
+PJMEDIA_CODEC_LIB = ..\..\pjmedia\lib\pjmedia-codec-$(TARGET)$(LIBEXT)
+PJMEDIA_AUDIODEV_LIB = ..\..\pjmedia\lib\pjmedia-audiodev-$(TARGET)$(LIBEXT)
+PJMEDIA_VIDEODEV_LIB = ..\..\pjmedia\lib\pjmedia-videodev-$(TARGET)$(LIBEXT)
+PJSIP_LIB = ..\..\pjsip\lib\pjsip-core-$(TARGET)$(LIBEXT)
+PJSIP_UA_LIB = ..\..\pjsip\lib\pjsip-ua-$(TARGET)$(LIBEXT)
+PJSIP_SIMPLE_LIB = ..\..\pjsip\lib\pjsip-simple-$(TARGET)$(LIBEXT)
+PJSUA_LIB_LIB = ..\..\pjsip\lib\pjsua-lib-$(TARGET)$(LIBEXT)
+
+GSM_LIB = ..\..\third_party\lib\libgsmcodec-$(TARGET)$(LIBEXT)
+ILBC_LIB = ..\..\third_party\lib\libilbccodec-$(TARGET)$(LIBEXT)
+PORTAUDIO_LIB = ..\..\third_party\lib\libportaudio-$(TARGET)$(LIBEXT)
+RESAMPLE_LIB = ..\..\third_party\lib\libresample-$(TARGET)$(LIBEXT)
+SPEEX_LIB = ..\..\third_party\lib\libspeex-$(TARGET)$(LIBEXT)
+SRTP_LIB = ..\..\third_party\lib\libsrtp-$(TARGET)$(LIBEXT)
+G7221_LIB = ..\..\third_party\lib\libg7221codec-$(TARGET)$(LIBEXT)
+BASECLASSES_LIB = ..\..\third_party\lib\libbaseclasses-$(TARGET)$(LIBEXT)
+
+THIRD_PARTY_LIBS = $(GSM_LIB) $(ILBC_LIB) $(PORTAUDIO_LIB) $(RESAMPLE_LIB) \
+				   $(SPEEX_LIB) $(SRTP_LIB) $(G7221_LIB) $(BASECLASSES_LIB)
+
+LIBS = $(PJSUA_LIB_LIB) $(PJSIP_UA_LIB) $(PJSIP_SIMPLE_LIB) \
+	  $(PJSIP_LIB) $(PJMEDIA_CODEC_LIB) $(PJMEDIA_AUDIODEV_LIB) \
+	  $(PJMEDIA_VIDEODEV_LIB) \
+	  $(PJMEDIA_LIB) $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB) \
+	  $(THIRD_PARTY_LIBS)
+
+CFLAGS 	= $(TARGET_FLAGS) \
+	  $(BUILD_FLAGS) \
+	  -I..\..\pjsip\include \
+	  -I..\..\pjlib\include \
+	  -I..\..\pjlib-util\include \
+	  -I..\..\pjmedia\include \
+	  -I..\..\pjnath/include
+LDFLAGS = $(BUILD_FLAGS) $(LIBS) \
+	  Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib \
+	  mswsock.lib ws2_32.lib gdi32.lib advapi32.lib oleaut32.lib
+
+SRCDIR = ..\src\samples
+OBJDIR = .\output\samples-$(TARGET)
+BINDIR = ..\bin\samples\$(TARGET)
+
+
+SAMPLES = $(BINDIR)\auddemo.exe \
+	  $(BINDIR)\aectest.exe \
+	  $(BINDIR)\aviplay.exe \
+	  $(BINDIR)\clidemo.exe \
+	  $(BINDIR)\confsample.exe \
+	  $(BINDIR)\confbench.exe \
+	  $(BINDIR)\encdec.exe \
+	  $(BINDIR)\httpdemo.exe \
+	  $(BINDIR)\icedemo.exe \
+	  $(BINDIR)\jbsim.exe \
+	  $(BINDIR)\latency.exe \
+	  $(BINDIR)\level.exe \
+	  $(BINDIR)\mix.exe \
+	  $(BINDIR)\pcaputil.exe\
+	  $(BINDIR)\pjsip-perf.exe \
+	  $(BINDIR)\playfile.exe \
+	  $(BINDIR)\playsine.exe\
+	  $(BINDIR)\recfile.exe  \
+	  $(BINDIR)\resampleplay.exe \
+	  $(BINDIR)\simpleua.exe \
+	  $(BINDIR)\simple_pjsua.exe \
+	  $(BINDIR)\sipecho.exe \
+	  $(BINDIR)\siprtp.exe \
+	  $(BINDIR)\sipstateless.exe \
+	  $(BINDIR)\stateful_proxy.exe \
+	  $(BINDIR)\stateless_proxy.exe \
+	  $(BINDIR)\stereotest.exe \
+	  $(BINDIR)\streamutil.exe \
+	  $(BINDIR)\strerror.exe \
+	  $(BINDIR)\tonegen.exe \
+	  $(BINDIR)\vid_streamutil.exe
+
+
+all: $(BINDIR) $(OBJDIR) $(SAMPLES)
+
+$(SAMPLES): $(SRCDIR)\$(@B).c $(LIBS) $(SRCDIR)\util.h Samples-vc.mak
+	cl -nologo -c $(SRCDIR)\$(@B).c /Fo$(OBJDIR)\$(@B).obj $(CFLAGS) 
+	cl /nologo $(OBJDIR)\$(@B).obj /Fe$@ /Fm$(OBJDIR)\$(@B).map $(LDFLAGS)
+	@rem the following two lines is just for cleaning up the 'bin' directory
+	if exist $(BINDIR)\*.ilk del /Q $(BINDIR)\*.ilk
+	if exist $(BINDIR)\*.pdb del /Q $(BINDIR)\*.pdb
+
+$(BINDIR):
+	if not exist $(BINDIR) mkdir $(BINDIR)
+
+$(OBJDIR):
+	if not exist $(OBJDIR) mkdir $(OBJDIR)
+
+clean:
+	echo Cleaning up samples...
+	if exist $(BINDIR) del /Q $(BINDIR)\*
+	if exist $(BINDIR) rmdir $(BINDIR)
+	if exist $(OBJDIR) del /Q $(OBJDIR)\*.*
+
diff --git a/jni/libpjsip/sources/pjsip-apps/build/Samples.mak b/jni/libpjsip/sources/pjsip-apps/build/Samples.mak
new file mode 100644
index 0000000..65d25b9
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/Samples.mak
@@ -0,0 +1,68 @@
+include ../../build.mak
+include ../../version.mak
+include ../../build/common.mak
+
+RULES_MAK := $(PJDIR)/build/rules.mak
+
+###############################################################################
+# Gather all flags.
+#
+export _CFLAGS 	:= $(PJ_CFLAGS) $(CFLAGS)
+export _CXXFLAGS:= $(PJ_CXXFLAGS)
+export _LDFLAGS := $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS)
+
+SRCDIR := ../src/samples
+OBJDIR := ./output/samples-$(TARGET_NAME)
+BINDIR := ../bin/samples/$(TARGET_NAME)
+
+SAMPLES := auddemo \
+	   aviplay \
+	   aectest \
+	   clidemo \
+	   confsample \
+	   encdec \
+	   httpdemo \
+	   icedemo \
+	   jbsim \
+	   latency \
+	   level \
+	   mix \
+	   pjsip-perf \
+	   pcaputil \
+	   pjsua2_demo \
+	   playfile \
+	   playsine \
+	   recfile \
+	   resampleplay \
+	   simpleua \
+	   simple_pjsua \
+	   sipecho \
+	   siprtp \
+	   sipstateless \
+	   stateful_proxy \
+	   stateless_proxy \
+	   stereotest \
+	   streamutil \
+	   strerror \
+	   tonegen \
+	   vid_streamutil
+
+EXES := $(foreach file, $(SAMPLES), $(file)$(HOST_EXE))
+
+.PHONY: $(EXES)
+
+all: $(EXES)
+
+$(EXES):
+	$(MAKE) --no-print-directory -f $(RULES_MAK) SAMPLE_SRCDIR=$(SRCDIR) SAMPLE_OBJS=$@.o SAMPLE_CFLAGS="$(_CFLAGS)" SAMPLE_CXXFLAGS="$(_CXXFLAGS)" SAMPLE_LDFLAGS="$(_LDFLAGS) -lstdc++" SAMPLE_EXE=$@ APP=SAMPLE app=sample $(subst /,$(HOST_PSEP),$(BINDIR)/$@)
+
+depend:
+
+clean:
+	$(MAKE) -f $(RULES_MAK) APP=SAMPLE app=sample $@
+	$(subst @@,$(EXES),$(HOST_RM))
+	$(subst @@,$(BINDIR),$(HOST_RMDIR))
+
+distclean realclean: clean
+	$(MAKE) -f $(RULES_MAK) APP=SAMPLE app=sample $@
+
diff --git a/jni/libpjsip/sources/pjsip-apps/build/dummy.c b/jni/libpjsip/sources/pjsip-apps/build/dummy.c
new file mode 100644
index 0000000..1cb9b48
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/dummy.c
@@ -0,0 +1,9 @@
+/* $Id: dummy.c 2660 2009-04-28 19:38:43Z nanang $ */
+
+/**
+ * This is an empty C file for helping libpjproject so it gets built properly.
+ */
+
+#ifdef _MSC_VER
+#   pragma warning(disable: 4206)    // translation unit is empty
+#endif
diff --git a/jni/libpjsip/sources/pjsip-apps/build/get-footprint.py b/jni/libpjsip/sources/pjsip-apps/build/get-footprint.py
new file mode 100644
index 0000000..f936c0c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/get-footprint.py
@@ -0,0 +1,338 @@
+# $Id: get-footprint.py 1352 2007-06-08 01:41:25Z bennylp $
+# 
+# This file is used to generate PJSIP/PJMEDIA footprint report.
+# To use this file, just run it in pjsip-apps/build directory, to
+# produce footprint.txt and footprint.htm report files.
+#
+import os
+import sys
+import string
+import time
+
+compile_flags1 = [
+    # Base
+    ['BASE',			'Empty application size'],
+    ['',			'Subtotal: Empty application size'],
+
+    ['HAS_PJLIB', 		'Minimum PJLIB only'],
+
+    # Subtotal
+    ['',			'Subtotal'],
+
+    # PJLIB-UTIL
+    ['HAS_PJLIB_STUN',		'STUN client'],
+    ['HAS_PJLIB_GETOPT',	'getopt() functionality'],
+    
+    # Subtotal
+    ['',			'TOTAL']
+]
+
+compile_flags = [
+    # Base
+    ['BASE',			'Empty application size'],
+    ['', 			'Subtotal: empty application size on this platform'],
+
+    ['HAS_PJLIB', 		'PJLIB (pool, data structures, hash tables, ioqueue, socket, timer heap, etc.). ' +
+			        'For targets that statically link application with LIBC, the size includes ' +
+			        'various LIBC functions that are used by PJLIB.'],
+    ['', 			'Subtotal: Application linked with PJLIB'],
+
+    # PJLIB-UTIL
+    ['HAS_PJLIB_STUN',		'PJLIB-UTIL STUN client'],
+    ['HAS_PJLIB_GETOPT',	'PJLIB-UTIL getopt() functionality'],
+    ['HAS_PJLIB_SCANNER',	'PJLIB-UTIL text scanner (needed by SIP parser)'],
+    ['HAS_PJLIB_XML',		'PJLIB-UTIL tiny XML (parsing and API) (needs text scanner)'],
+    ['HAS_PJLIB_DNS',		'PJLIB-UTIL DNS packet and parsing'],
+    ['HAS_PJLIB_RESOLVER',	'PJLIB-UTIL Asynchronous DNS resolver/caching engine'],
+    ['HAS_PJLIB_CRC32',		'PJLIB-UTIL CRC32 algorithm'],
+    ['HAS_PJLIB_HMAC_MD5',	'PJLIB-UTIL HMAC-MD5 algorithm'],
+    ['HAS_PJLIB_HMAC_SHA1',	'PJLIB-UTIL HMAC-SHA1 algorithm'],
+
+    # PJSIP
+    ['HAS_PJSIP_CORE_MSG_ELEM',	'PJSIP Core - Messaging Elements and Parsing (message, headers, SIP URI, TEL URI/RFC 3966, etc.)'],
+    ['HAS_PJSIP_CORE',		'PJSIP Core - Endpoint (transport management, module management, event distribution, etc.)'],
+    ['HAS_PJSIP_CORE_MSG_UTIL',	'PJSIP Core - Stateless operations, SIP SRV, server resolution and fail-over'],
+    ['HAS_PJSIP_UDP_TRANSPORT',	'PJSIP UDP transport'],
+    ['',			'Subtotal: A minimalistic SIP application (parsing, UDP transport+STUN, no transaction)'],
+   
+    ['HAS_PJSIP_TCP_TRANSPORT',	'PJSIP TCP transport'],
+    ['HAS_PJSIP_TLS_TRANSPORT',	'PJSIP TLS transport'],
+    ['HAS_PJSIP_INFO',		'PJSIP INFO support (RFC 2976) (no special treatment, thus the zero size)'],
+    ['HAS_PJSIP_TRANSACTION',	'PJSIP transaction and stateful API'],
+    ['HAS_PJSIP_AUTH_CLIENT',	'PJSIP digest authentication client'],
+    ['HAS_PJSIP_UA_LAYER',	'PJSIP User agent layer and base dialog and usage management (draft-ietf-sipping-dialogusage-01)'],
+    ['HAS_PJMEDIA_SDP',		'PJMEDIA SDP Parsing and API (RFC 2327), needed by SDP negotiator'],
+    ['HAS_PJMEDIA_SDP_NEGOTIATOR','PJMEDIA SDP negotiator (RFC 3264), needed by INVITE session'],
+    ['HAS_PJSIP_INV_SESSION',	'PJSIP INVITE session API'],
+    ['HAS_PJSIP_REGC',		'PJSIP client registration API'],
+    ['',			'Subtotal: Minimal SIP application with registration (including digest authentication)'],
+    
+    ['HAS_PJSIP_EVENT_FRAMEWORK','PJSIP Event/SUBSCRIBE framework, RFC 3265 (needed by call transfer, and presence)'],
+    ['HAS_PJSIP_CALL_TRANSFER',	'PJSIP Call Transfer/REFER support (RFC 3515)'],
+    ['',			'Subtotal: Minimal SIP application with call transfer'],
+
+
+    ['HAS_PJSIP_PRESENCE',	'PJSIP Presence subscription, including PIDF/X-PIDF support (RFC 3856, RFC 3863, etc) (needs XML)'],
+    ['HAS_PJSIP_MESSAGE',	'PJSIP Instant Messaging/MESSAGE support (RFC 3428) (no special treatment, thus the zero size)'],
+    ['HAS_PJSIP_IS_COMPOSING',	'PJSIP Message Composition indication (RFC 3994)'],
+
+    # Subtotal
+    ['',			'Subtotal: Complete PJSIP package (call, registration, presence, IM) +STUN +GETOPT (+PJLIB), no media'],
+    
+    # PJNATH
+    ['HAS_PJNATH_STUN',		'PJNATH STUN'],
+    ['HAS_PJNATH_ICE',		'PJNATH ICE'],
+
+    # PJMEDIA
+    ['HAS_PJMEDIA_EC',		'PJMEDIA accoustic echo cancellation'],
+    ['HAS_PJMEDIA_SND_DEV',	'PJMEDIA sound device backend (platform specific)'],
+    ['HAS_PJMEDIA_SILENCE_DET',	'PJMEDIA Adaptive silence detector'],
+    ['HAS_PJMEDIA',		'PJMEDIA endpoint'],
+    ['HAS_PJMEDIA_PLC',		'PJMEDIA Packet Lost Concealment implementation (needed by G.711, GSM, and sound device port)'],
+    ['HAS_PJMEDIA_SND_PORT',	'PJMEDIA sound device media port'],
+    ['HAS_PJMEDIA_RESAMPLE',	'PJMEDIA resampling algorithm (large filter disabled)'],
+    ['HAS_PJMEDIA_G711_CODEC',	'PJMEDIA G.711 codec (PCMA/PCMU, including PLC) (may have already been linked by other module)'],
+    ['HAS_PJMEDIA_CONFERENCE',	'PJMEDIA conference bridge (needs resampling and silence detector)'],
+    ['HAS_PJMEDIA_MASTER_PORT',	'PJMEDIA master port'],
+    ['HAS_PJMEDIA_RTP',		'PJMEDIA stand-alone RTP'],
+    ['HAS_PJMEDIA_RTCP',	'PJMEDIA stand-alone RTCP and media quality calculation'],
+    ['HAS_PJMEDIA_JBUF',	'PJMEDIA stand-alone adaptive jitter buffer'],
+    ['HAS_PJMEDIA_STREAM',	'PJMEDIA stream for remote media communication (needs RTP, RTCP, and jitter buffer)'],
+    ['HAS_PJMEDIA_TONEGEN',	'PJMEDIA tone generator'],
+    ['HAS_PJMEDIA_UDP_TRANSPORT','PJMEDIA UDP media transport'],
+    ['HAS_PJMEDIA_FILE_PLAYER',	'PJMEDIA WAV file player'],
+    ['HAS_PJMEDIA_FILE_CAPTURE',	'PJMEDIA WAV file writer'],
+    ['HAS_PJMEDIA_MEM_PLAYER',	'PJMEDIA fixed buffer player'],
+    ['HAS_PJMEDIA_MEM_CAPTURE',	'PJMEDIA fixed buffer writer'],
+    ['HAS_PJMEDIA_ICE',		'PJMEDIA ICE transport'],
+
+    # Subtotal
+    ['',			'Subtotal: Complete SIP and all PJMEDIA features (G.711 codec only)'],
+    
+    # Codecs
+    ['HAS_PJMEDIA_GSM_CODEC',	'PJMEDIA GSM codec (including PLC)'],
+    ['HAS_PJMEDIA_SPEEX_CODEC',	'PJMEDIA Speex codec (narrowband, wideband, ultra-wideband)'],
+    ['HAS_PJMEDIA_ILBC_CODEC',	'PJMEDIA iLBC codec'],
+
+    # Total
+    ['',			'TOTAL: complete libraries (+all codecs)'],
+]
+
+# Executable size report, tuple of:
+#   <all flags>, <flags added>, <text size>, <data>, <bss>, <description>
+exe_size = []
+
+#
+# Write the report to text file
+#
+def print_text_report(filename):
+    output = open(filename, 'w')
+
+    output.write('PJSIP and PJMEDIA footprint report\n')
+    output.write('Auto-generated by pjsip-apps/build/get-footprint.py\n')
+    output.write('\n')
+
+    # Write Revision info.
+    f = os.popen('svn info | grep Revision')
+    output.write(f.readline())
+
+    output.write('Date: ')
+    output.write(time.asctime())
+    output.write('\n')
+    output.write('\n')
+
+    # Write individual module size
+    output.write('Footprint (in bytes):\n')
+    output.write('   .text   .data    .bss    Module Description\n')
+    output.write('==========================================================\n')
+	
+    for i in range(1, len(exe_size)):
+	e = exe_size[i]
+	prev = exe_size[i-1]
+	
+	if e[1]<>'':
+	    output.write(' ')
+	    output.write(  string.rjust(`string.atoi(e[2]) - string.atoi(prev[2])`, 8) )
+	    output.write(  string.rjust(`string.atoi(e[3]) - string.atoi(prev[3])`, 8) )
+	    output.write(  string.rjust(`string.atoi(e[4]) - string.atoi(prev[4])`, 8) )
+	    output.write('   ' + e[5] + '\n')
+	else:
+	    output.write(' ------------------------\n')	
+	    output.write(' ')
+	    output.write( string.rjust(e[2], 8) )
+	    output.write( string.rjust(e[3], 8) )
+	    output.write( string.rjust(e[4], 8) )
+	    output.write('   ' + e[5] + '\n')
+	    output.write('\n')	
+
+	
+    # Done    
+    output.close()
+
+
+#
+# Write the report to HTML file
+#
+def print_html_report():
+
+    # Get Revision info.
+    f = os.popen('svn info | grep Revision')
+    revision = f.readline().split()[1]
+
+    # Get Machine, OS, and CC name
+    f = os.popen('make -f Footprint.mak print_name')
+    names = f.readline().split()
+    m = names[0]
+    o = names[1]
+    cc = names[2]
+    cc_ver = names[3]
+
+    # Open HTML file
+    filename = 'footprint-' + m + '-' + o + '.htm'
+    output = open(filename, 'w')
+
+    title = 'PJSIP and PJMEDIA footprint report for ' + m + '-' + o + ' target'
+    output.write('<HTML><HEAD>\n');
+    output.write(' <TITLE>' + title + '</TITLE>\n')
+    output.write(' <LINK href="/style/style.css" type="text/css" rel="stylesheet">\n')
+    output.write('</HEAD>\n');
+    output.write('<BODY bgcolor="white">\n');
+    output.write('<!--#include virtual="/header.html" -->')
+
+    output.write(' <H1>' + title + '</H1>\n')
+    output.write('Auto-generated by pjsip-apps/build/get-footprint.py script\n')
+    output.write('<p>Date: ' + time.asctime() + '<BR>\n')
+    output.write('Revision: r' + revision + '</p>\n\n')
+    output.write('<HR>\n')
+    output.write('\n')
+
+    # Info
+    output.write('<H2>Build Configuration</H2>\n')
+
+    # build.mak
+    output.write('\n<H3>build.mak</H3>\n')
+    output.write('<tt>\n')
+    f = open('../../build.mak', 'r')
+    s = f.readlines()
+    for l in s:
+	output.write(l + '<BR>\n')
+    output.write('</tt>\n')
+    output.write('<p>Using ' + cc + ' version ' + cc_ver +'</p>\n')
+
+    # user.mak
+    output.write('\n<H3>user.mak</H3>\n')
+    output.write('<tt>\n')
+    f = open('../../user.mak', 'r')
+    s = f.readlines()
+    for l in s:
+	output.write(l + '<BR>\n')
+    output.write('</tt>\n')
+
+    # config_site.h
+    output.write('\n<H3>&lt;pj/config.site.h&gt;</H3>\n')
+    output.write('<tt>\n')
+    f = os.popen('cpp -dM -I../../pjlib/include ../../pjlib/include/pj/config_site.h | grep PJ')
+    s = f.readlines()
+    for l in s:
+	output.write(l + '<BR>\n')
+    output.write('</tt>\n')
+
+
+
+    # Write individual module size
+    output.write('<H2>Footprint Report</H2>\n')
+    output.write('<p>The table below shows the footprint of individual feature, in bytes.</p>')
+    output.write('<TABLE border="1" cellpadding="2" cellspacing="0">\n' + 
+		  '<TR bgcolor="#e8e8ff">\n' + 
+		  '  <TD align="center"><strong>.text</strong></TD>\n' +
+		  '  <TD align="center"><strong>.data</strong></TD>\n' +
+		  '  <TD align="center"><strong>.bss</strong></TD>\n' +
+		  '  <TD align="center"><strong>Features/Module Description</strong></TD>\n' +
+		  '</TR>\n')
+	
+	
+    for i in range(1, len(exe_size)):
+	e = exe_size[i]
+	prev = exe_size[i-1]
+	
+	output.write('<TR>\n')
+	if e[1]<>'':
+	    output.write( '  <TD align="right">' + `string.atoi(e[2]) - string.atoi(prev[2])` + '</TD>\n')
+	    output.write( '  <TD align="right">' + `string.atoi(e[3]) - string.atoi(prev[3])` + '</TD>\n')
+	    output.write( '  <TD align="right">' + `string.atoi(e[4]) - string.atoi(prev[4])` + '</TD>\n' )
+	    output.write( '  <TD>' + e[5] + '</TD>\n')
+	else:
+	    empty_size = exe_size[1]
+	    output.write('<TR bgcolor="#e8e8ff">\n')
+	    output.write( '  <TD align="right">&nbsp;</TD>\n')
+	    output.write( '  <TD align="right">&nbsp;</TD>\n')
+	    output.write( '  <TD align="right">&nbsp;</TD>\n')
+	    output.write( '  <TD><strong>' + e[5] + ': .text=' + e[2]+ ', .data=' + e[3] + ', .bss=' + e[4] )
+	    output.write( '\n </strong> <BR>(Size minus empty application size: ' + \
+			    '.text=' + `string.atoi(e[2]) - string.atoi(empty_size[2])` + \
+			    ', .data=' + `string.atoi(e[3]) - string.atoi(empty_size[3])` + \
+			    ', .data=' + `string.atoi(e[4]) - string.atoi(empty_size[4])` + \
+			    ')\n' )
+	    output.write( ' </TD>\n')
+
+	output.write('</TR>\n')
+
+    output.write('</TABLE>\n')
+    output.write('<!--#include virtual="/footer.html" -->')
+    output.write('</BODY>\n')
+    output.write('</HTML>\n')
+	
+    # Done    
+    output.close()
+
+
+
+
+#
+# Get the size of individual feature
+#
+def get_size(all_flags, flags, desc):
+	file = 'footprint.exe'
+	# Remove file
+	rc = os.system("make -f Footprint.mak FCFLAGS='" + all_flags + "' clean")
+	# Make the executable
+	cmd = "make -f Footprint.mak FCFLAGS='" + all_flags + "' all"
+	#print cmd
+	rc = os.system(cmd)
+	if rc <> 0:
+		sys.exit(1)
+
+	# Run 'size' against the executable
+	f = os.popen('size ' + file)
+	# Skip header of the 'size' output
+	f.readline()
+	# Get the sizes
+	size = f.readline()
+	f.close()
+	# Split into tokens
+	tokens = size.split()
+	# Build the size tuple and add to exe_size
+	elem = all_flags, flags, tokens[0], tokens[1], tokens[2], desc
+	exe_size.append(elem)
+	# Remove file
+	rc = os.system("make -f Footprint.mak FCFLAGS='" + all_flags + "' clean")
+	
+# Main
+elem = '', '',  '0', '0', '0', ''
+exe_size.append(elem)
+
+all_flags = ''
+for elem in compile_flags:
+    if elem[0] <> '':
+	flags = '-D' + elem[0]
+	all_flags += flags + ' '
+	get_size(all_flags, elem[0], elem[1])
+    else:
+	e = exe_size[len(exe_size)-1]
+	n = all_flags, '', e[2], e[3], e[4], elem[1]
+	exe_size.append(n)
+	
+
+#print_text_report('footprint.txt')	
+print_html_report()
+
diff --git a/jni/libpjsip/sources/pjsip-apps/build/libpjproject.vcproj b/jni/libpjsip/sources/pjsip-apps/build/libpjproject.vcproj
new file mode 100644
index 0000000..66eb6b6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/libpjproject.vcproj
@@ -0,0 +1,3132 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="libpjproject"

+	ProjectGUID="{23D7679C-764C-4E02-8B29-BB882CEEEFE2}"

+	RootNamespace="libpjproject"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="Pocket PC 2003 (ARMV4)"

+		/>

+		<Platform

+			Name="Smartphone 2003 (ARMV4)"

+		/>

+		<Platform

+			Name="x64"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Standard SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Professional SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Smartphone 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Smartphone 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Win32"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Smartphone 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|x64"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Win32"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Smartphone 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|x64"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Win32"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|x64"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Win32"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Smartphone 2003 (ARMV4)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|x64"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+				EnableFloatingPointEmulation="false"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				AdditionalOptions=""

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="4"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				PreprocessorDefinitions="_LIB;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				LinkLibraryDependencies="true"

+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\dummy.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/jni/libpjsip/sources/pjsip-apps/build/os-win32.mak b/jni/libpjsip/sources/pjsip-apps/build/os-win32.mak
new file mode 100644
index 0000000..30f422e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/os-win32.mak
@@ -0,0 +1,2 @@
+
+export LDFLAGS += -lwinmm
diff --git a/jni/libpjsip/sources/pjsip-apps/build/pjsua.vcproj b/jni/libpjsip/sources/pjsip-apps/build/pjsua.vcproj
new file mode 100644
index 0000000..fcde749
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/pjsua.vcproj
@@ -0,0 +1,4325 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="pjsua"

+	ProjectGUID="{8310649E-A25E-4AF0-91E8-9E3CC659BB89}"

+	RootNamespace="pjsua"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="Pocket PC 2003 (ARMV4)"

+		/>

+		<Platform

+			Name="Smartphone 2003 (ARMV4)"

+		/>

+		<Platform

+			Name="x64"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Standard SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Professional SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Release|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				IgnoreDefaultLibraryNames="msvcrt.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				IgnoreDefaultLibraryNames="msvcrt.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="pjsua.bmp|$(ProjectDir)\..\src\pjsua\wm\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			ConfigurationType="1"

+			UseOfMFC="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

+			>

+			<File

+				RelativePath="..\src\pjsua\main.c"

+				>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Pocket PC 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Smartphone 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Pocket PC 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Smartphone 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Pocket PC 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Smartphone 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Smartphone 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Pocket PC 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Smartphone 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\pjsua\wm\main_wm.c"

+				>

+				<FileConfiguration

+					Name="Release|Win32"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Win32"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Win32"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|x64"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Win32"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|x64"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Win32"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|x64"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Win32"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|x64"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\pjsua\pjsua_app.c"

+				>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\pjsua\pjsua_app_cli.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\pjsua\pjsua_app_common.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\pjsua\pjsua_app_config.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\pjsua\pjsua_app_legacy.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl"

+			>

+			<File

+				RelativePath="..\src\pjsua\pjsua_app.h"

+				>

+			</File>

+			<File

+				RelativePath="..\src\pjsua\pjsua_app_common.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/jni/libpjsip/sources/pjsip-apps/build/pjsystest.vcproj b/jni/libpjsip/sources/pjsip-apps/build/pjsystest.vcproj
new file mode 100644
index 0000000..48727ef
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/pjsystest.vcproj
@@ -0,0 +1,836 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="pjsystest"

+	ProjectGUID="{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}"

+	RootNamespace="pjsystest"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="Pocket PC 2003 (ARMV4)"

+		/>

+		<Platform

+			Name="x64"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Standard SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Professional SDK (ARMV4I)"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Pocket PC 2003 (ARMV4)"

+			OutputDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"

+			IntermediateDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="1"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				TargetMachine="0"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Pocket PC 2003 (ARMV4)"

+			OutputDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"

+			IntermediateDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="1"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				TargetMachine="0"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../pjmedia/include,../../pjsip/include"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				AdditionalIncludeDirectories=""

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions=" /subsystem:windowsce,5.02"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+				DelayLoadDLLs=""

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="input.8.wav|$(ProjectDir)\..\..\tests\pjsua\wavs\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;tock8.wav|$(ProjectDir)\..\..\tests\pjsua\wavs\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="1"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../pjmedia/include,../../pjsip/include"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES)"

+				Culture="1033"

+				AdditionalIncludeDirectories="$(IntDir)"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions=" /subsystem:windowsce,5.02"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+				DelayLoadDLLs="$(NOINHERIT)"

+				TargetMachine="0"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="input.8.wav|$(ProjectDir)\..\..\tests\pjsua\wavs\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;tock8.wav|$(ProjectDir)\..\..\tests\pjsua\wavs\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops;..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../pjmedia/include,../../pjsip/include"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				AdditionalIncludeDirectories=""

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions=" /subsystem:windowsce,5.02"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+				DelayLoadDLLs=""

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="msvcr80.dll|$(BINDIR)\$(INSTRUCTIONSET)\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;input.8.wav|$(ProjectDir)\..\..\tests\pjsua\wavs\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;tock8.wav|$(ProjectDir)\..\..\tests\pjsua\wavs\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="1"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../pjmedia/include,../../pjsip/include"

+				BufferSecurityCheck="false"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES)"

+				Culture="1033"

+				AdditionalIncludeDirectories="&quot;$(IntDir)&quot;"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions=" /subsystem:windowsce,5.02"

+				AdditionalDependencies="aygshell.lib coredll.lib winsock.lib ws2.lib"

+				IgnoreDefaultLibraryNames="oldnames.lib"

+				DelayLoadDLLs=""

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles="msvcr80.dll|$(BINDIR)\$(INSTRUCTIONSET)\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;input.8.wav|$(ProjectDir)\..\..\tests\pjsua\wavs\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;tock8.wav|$(ProjectDir)\..\..\tests\pjsua\wavs\|%CSIDL_PROGRAM_FILES%\$(ProjectName)|0;"

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath="..\src\pjsystest\main_console.c"

+				>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\pjsystest\main_wm.c"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Pocket PC 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Pocket PC 2003 (ARMV4)"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					ExcludedFromBuild="true"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\pjsystest\systest.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\src\pjsystest\gui.h"

+				>

+			</File>

+			<File

+				RelativePath="..\src\pjsystest\systest.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+			<File

+				RelativePath="..\src\pjsystest\pjsystest_wince.rc"

+				>

+				<FileConfiguration

+					Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCResourceCompilerTool"

+						PreprocessorDefinitions="NDEBUG"

+					/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/jni/libpjsip/sources/pjsip-apps/build/py_pjsua.vcproj b/jni/libpjsip/sources/pjsip-apps/build/py_pjsua.vcproj
new file mode 100644
index 0000000..e03a20c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/py_pjsua.vcproj
@@ -0,0 +1,438 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="py_pjsua"
+	ProjectGUID="{C44FC030-D46A-47FF-B731-B47ECA5B2B10}"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\pjlib\include,..\..\pjlib-util\include,..\..\pjmedia\include,..\..\pjsip\include,../../pjnath/include"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="python24.lib ole32.lib shell32.lib user32.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib"
+				OutputFile="..\bin\py-pjsua-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\pjlib\include,..\..\pjlib-util\include,..\..\pjmedia\include,..\..\pjsip\include,../../pjnath/include"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="python24_d.lib ole32.lib shell32.lib user32.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib"
+				OutputFile="..\bin\py-pjsua-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\pjlib\include,..\..\pjlib-util\include,..\..\pjmedia\include,..\..\pjsip\include,../../pjnath/include"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="python24.lib ole32.lib shell32.lib user32.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib"
+				OutputFile="..\bin\py-pjsua-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\pjlib\include,..\..\pjlib-util\include,..\..\pjmedia\include,..\..\pjsip\include,../../pjnath/include"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="python24_d.lib ole32.lib shell32.lib user32.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib"
+				OutputFile="..\bin\py-pjsua-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+			>
+			<File
+				RelativePath="..\src\py_pjsua\pjsua.py"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\py_pjsua\pjsua_app.py"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\py_pjsua\py_pjsua.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\py_pjsua\py_pjsua.def"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl"
+			>
+			<File
+				RelativePath="..\src\py_pjsua\py_pjsua.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/jni/libpjsip/sources/pjsip-apps/build/python_pjsua.vcproj b/jni/libpjsip/sources/pjsip-apps/build/python_pjsua.vcproj
new file mode 100644
index 0000000..66e322a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/python_pjsua.vcproj
@@ -0,0 +1,268 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="python_pjsua"

+	ProjectGUID="{0C91838B-3372-40B4-A764-DE075A4BC94B}"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory=".\output\python_pjsua-i386-win32-vc8-debug"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="1"

+				TypeLibraryName=".\output\python_pjsua-i386-win32-vc6-debug/python_pjsua.tlb"

+				HeaderFileName=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="..\..\pjlib\include,..\..\pjlib-util\include,..\..\pjmedia\include,..\..\pjsip\include,../../pjnath/include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PY_PJSUA_EXPORTS"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				PrecompiledHeaderFile="$(OutDir)/python_pjsua.pch"

+				AssemblerListingLocation="$(OutDir)/"

+				ObjectFile="$(OutDir)/"

+				ProgramDataBaseFileName="$(OutDir)/"

+				BrowseInformation="1"

+				WarningLevel="4"

+				SuppressStartupBanner="true"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1057"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="python24_d.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib"

+				OutputFile="..\lib\_pjsua_d.pyd"

+				LinkIncremental="2"

+				SuppressStartupBanner="true"

+				AdditionalLibraryDirectories="../../pjlib/lib,../../pjlib-util/lib,../../pjmedia/lib,../../pjsip/lib,F:\incoming\projects\divusi\Python-2.4\Python-2.4\PCbuild,F:\incoming\projects\divusi\Python-2.4\Python-2.4\PC\VC6"

+				ModuleDefinitionFile="..\src\python\_pjsua.def"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/_pjsua_d.pdb"

+				ImportLibrary="$(OutDir)/_pjsua_d.lib"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+				SuppressStartupBanner="true"

+				OutputFile=".\output\python_pjsua-i386-win32-vc6-debug/python_pjsua.bsc"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory=".\output\python_pjsua-i386-win32-vc8-release"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="1"

+				TypeLibraryName=".\output\python_pjsua-i386-win32-vc6-release/python_pjsua.tlb"

+				HeaderFileName=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="1"

+				AdditionalIncludeDirectories="..\..\pjlib\include,..\..\pjlib-util\include,..\..\pjmedia\include,..\..\pjsip\include,../../pjnath/include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PY_PJSUA_EXPORTS"

+				StringPooling="true"

+				RuntimeLibrary="0"

+				EnableFunctionLevelLinking="true"

+				PrecompiledHeaderFile="$(OutDir)/python_pjsua.pch"

+				AssemblerListingLocation="$(OutDir)/"

+				ObjectFile="$(OutDir)/"

+				ProgramDataBaseFileName="$(OutDir)/"

+				BrowseInformation="1"

+				WarningLevel="3"

+				SuppressStartupBanner="true"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1057"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="python24.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib"

+				OutputFile="..\lib\_pjsua.pyd"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				AdditionalLibraryDirectories="../../pjlib/lib,../../pjlib-util/lib,../../pjmedia/lib,../../pjsip/lib"

+				IgnoreDefaultLibraryNames="libcmt.lib"

+				ModuleDefinitionFile="..\src\python\_pjsua.def"

+				ProgramDatabaseFile="$(OutDir)/_pjsua.pdb"

+				GenerateMapFile="true"

+				MapFileName="$(OutDir)/_pjsua.map"

+				ImportLibrary="$(OutDir)/_pjsua.lib"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+				SuppressStartupBanner="true"

+				OutputFile=".\output\python_pjsua-i386-win32-vc6-release/python_pjsua.bsc"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

+			>

+			<File

+				RelativePath="..\src\python\_pjsua.c"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\python\_pjsua.def"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl"

+			>

+			<File

+				RelativePath="..\src\python\_pjsua.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/jni/libpjsip/sources/pjsip-apps/build/sample_debug.vcproj b/jni/libpjsip/sources/pjsip-apps/build/sample_debug.vcproj
new file mode 100644
index 0000000..1f821e4
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/sample_debug.vcproj
@@ -0,0 +1,3751 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="sample_debug"

+	ProjectGUID="{A0F1AA62-0F6F-420D-B09A-AC04B6862821}"

+	RootNamespace="sample_debug"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="Pocket PC 2003 (ARMV4)"

+		/>

+		<Platform

+			Name="Smartphone 2003 (ARMV4)"

+		/>

+		<Platform

+			Name="x64"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Standard SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Professional SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="MSVCRT.LIB"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="MSVCRT.LIB"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames=""

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames=""

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="MSVCRT.LIB"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="MSVCRT.LIB"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames=""

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames=""

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="MSVCRT.LIB"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="MSVCRT.LIB"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="MSVCRT.LIB"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Pocket PC 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Smartphone 2003 (ARMV4)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"

+				IgnoreDefaultLibraryNames="MSVCRT.LIB"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PrecompiledHeaderFile=""

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"

+				OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

+			>

+			<File

+				RelativePath="..\src\samples\debug.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Pocket PC 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Smartphone 2003 (ARMV4)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories=""

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl"

+			>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/jni/libpjsip/sources/pjsip-apps/build/samples.vcproj b/jni/libpjsip/sources/pjsip-apps/build/samples.vcproj
new file mode 100644
index 0000000..5a9294c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/samples.vcproj
@@ -0,0 +1,1905 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="samples"

+	ProjectGUID="{E378A1FC-0C9C-4462-860F-7E60BC1BF84E}"

+	RootNamespace="samples"

+	Keyword="MakeFileProj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="Pocket PC 2003 (ARMV4)"

+		/>

+		<Platform

+			Name="Smartphone 2003 (ARMV4)"

+		/>

+		<Platform

+			Name="x64"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Standard SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 6 Professional SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+		/>

+		<Platform

+			Name="Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Pocket PC 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Smartphone 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory=".\output\$(ProjectName)-x86_64-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 ARCH=win64"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 ARCH=win64 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 ARCH=win64 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 ARCH=win32"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 ARCH=win32 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 ARCH=win32 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Pocket PC 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Smartphone 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory=".\output\$(ProjectName)-x86_64-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 ARCH=win64"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 ARCH=win64 /a "

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 ARCH=win64 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Win32"

+			OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 ARCH=win32s"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 ARCH=win32 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 ARCH=win32 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Pocket PC 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Smartphone 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|x64"

+			OutputDirectory=".\output\$(ProjectName)-x86_64-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 ARCH=win64"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 ARCH=win64 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 ARCH=win64 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Win32"

+			OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 ARCH=win32"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 ARCH=win32 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 ARCH=win32 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Smartphone 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|x64"

+			OutputDirectory=".\output\$(ProjectName)-x86_64-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 ARCH=win64"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 ARCH=win64 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 ARCH=win64 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Win32"

+			OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 ARCH=win32"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 ARCH=win32 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 ARCH=win32 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|x64"

+			OutputDirectory=".\output\$(ProjectName)-x86_64-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 ARCH=win64"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 ARCH=win64 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 ARCH=win64 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Win32"

+			OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 ARCH=win32"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 ARCH=win32 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 ARCH=win32 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Pocket PC 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Smartphone 2003 (ARMV4)"

+			OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|x64"

+			OutputDirectory=".\output\$(ProjectName)-x86_64-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 ARCH=win64"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 ARCH=win64 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 ARCH=win64 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"

+			OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"

+			UseOfMFC="0"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			BuildLogFile=""

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"

+				ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"

+				CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"

+				Output="All samples"

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				ExecutionBucket="7"

+			/>

+			<Tool

+				Name="VCCodeSignTool"

+			/>

+			<DeploymentTool

+				ForceDirty="-1"

+				RemoteDirectory=""

+				RegisterOutput="0"

+				AdditionalFiles=""

+			/>

+			<DebuggerTool

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

+			>

+			<File

+				RelativePath="..\src\samples\aectest.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\auddemo.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\aviplay.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\clidemo.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\confbench.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\confsample.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\encdec.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\footprint.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\httpdemo.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\icedemo.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\jbsim.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\latency.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\level.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\mix.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\pcaputil.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\pjsip-perf.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\playfile.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\playsine.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\recfile.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\resampleplay.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\simple_pjsua.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\simpleua.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\sipecho.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\siprtp.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\siprtp_report.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\sipstateless.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\sndinfo.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\sndtest.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\stateful_proxy.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\stateless_proxy.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\streamutil.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\strerror.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\tonegen.c"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\vid_streamutil.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl"

+			>

+			<File

+				RelativePath="..\src\samples\proxy.h"

+				>

+			</File>

+			<File

+				RelativePath="..\src\samples\util.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"

+			>

+		</Filter>

+		<File

+			RelativePath="Samples-vc.mak"

+			>

+		</File>

+		<File

+			RelativePath="Samples.mak"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/jni/libpjsip/sources/pjsip-apps/build/vidgui.vcproj b/jni/libpjsip/sources/pjsip-apps/build/vidgui.vcproj
new file mode 100644
index 0000000..922595a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/vidgui.vcproj
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="vidgui"

+	ProjectGUID="{A8EFA6F7-5443-46FA-9D35-2AF2668232EA}"

+	RootNamespace="vidgui"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="QtGui4.lib QtCore4.lib Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				GenerateDebugInformation="true"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			ConfigurationType="1"

+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"

+				PreprocessorDefinitions="_CONSOLE;"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="QtGui4.lib QtCore4.lib Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"

+				GenerateDebugInformation="true"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath="..\src\vidgui\moc_vidgui.cpp"

+				>

+			</File>

+			<File

+				RelativePath="..\src\vidgui\moc_vidwin.cpp"

+				>

+			</File>

+			<File

+				RelativePath="..\src\vidgui\vidgui.cpp"

+				>

+			</File>

+			<File

+				RelativePath="..\src\vidgui\vidwin.cpp"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\src\vidgui\vidgui.h"

+				>

+			</File>

+			<File

+				RelativePath="..\src\vidgui\vidwin.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/jni/libpjsip/sources/pjsip-apps/build/wince-evc4/wince_demos.vcw b/jni/libpjsip/sources/pjsip-apps/build/wince-evc4/wince_demos.vcw
new file mode 100644
index 0000000..cb1f4a5
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/build/wince-evc4/wince_demos.vcw
@@ -0,0 +1,305 @@
+Microsoft eMbedded Visual Tools Workspace File, Format Version 4.00

+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!

+

+###############################################################################

+

+Project: "libgsmcodec"="..\..\..\THIRD_PARTY\BUILD\GSM\libgsmcodec.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "libilbccodec"="..\..\..\THIRD_PARTY\BUILD\ILBC\libilbccodec.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "libmilenage"="..\..\..\third_party\build\milenage\libmilenage.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "libportaudio"="..\..\..\THIRD_PARTY\BUILD\PORTAUDIO\libportaudio.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "libresample"="..\..\..\THIRD_PARTY\BUILD\RESAMPLE\libresample.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "libspeex"="..\..\..\THIRD_PARTY\BUILD\SPEEX\libspeex.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "libsrtp"="..\..\..\third_party\build\srtp\libsrtp.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjlib_util_wince"="..\..\..\pjlib-util\build\wince-evc4\pjlib_util_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjlib_wince"="..\..\..\pjlib\build\wince-evc4\pjlib_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjmedia_auddev_wince"="..\..\..\pjmedia\build\wince-evc4\pjmedia_auddev_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjmedia_codec_wince"="..\..\..\pjmedia\build\wince-evc4\pjmedia_codec_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjmedia_wince"="..\..\..\pjmedia\build\wince-evc4\pjmedia_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjnath_wince"="..\..\..\pjnath\build\wince-evc4\pjnath_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjsip_core_wince"="..\..\..\pjsip\build\wince-evc4\pjsip_core_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjsip_simple_wince"="..\..\..\pjsip\build\wince-evc4\pjsip_simple_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjsip_ua_wince"="..\..\..\pjsip\build\wince-evc4\pjsip_ua_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+}}}

+

+###############################################################################

+

+Project: "pjsua_lib_wince"="..\..\..\pjsip\build\wince-evc4\pjsua_lib_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+    Begin Project Dependency

+    Project_Dep_Name pjlib_util_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjlib_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjmedia_codec_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjmedia_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjsip_core_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjsip_simple_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjsip_ua_wince

+    End Project Dependency

+}}}

+

+###############################################################################

+

+Project: "pjsua_wince"="..\..\src\pjsua_wince\pjsua_wince.vcp" - Package Owner=<4>

+

+Package=<5>

+{{{

+}}}

+

+Package=<4>

+{{{

+    Begin Project Dependency

+    Project_Dep_Name pjlib_util_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjlib_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjmedia_codec_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjmedia_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjsip_core_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjsip_simple_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjsip_ua_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjsua_lib_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjnath_wince

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name libgsmcodec

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name libilbccodec

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name libportaudio

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name libresample

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name libspeex

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name libmilenage

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name libsrtp

+    End Project Dependency

+    Begin Project Dependency

+    Project_Dep_Name pjmedia_auddev_wince

+    End Project Dependency

+}}}

+

+###############################################################################

+

+Global:

+

+Package=<5>

+{{{

+}}}

+

+Package=<3>

+{{{

+}}}

+

+###############################################################################

+

diff --git a/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/Makefile b/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/Makefile
new file mode 100644
index 0000000..78e56fd
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/Makefile
@@ -0,0 +1,34 @@
+
+include ../../../build.mak
+
+
+###############################################################################
+# Gather all flags.
+#
+export _CFLAGS 	:= $(PJ_CFLAGS) $(CFLAGS)
+export _CXXFLAGS:= $(PJ_CXXFLAGS)
+export _LDFLAGS := $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS)
+
+OBJS = alt_pjsua_aud.o alt_pjsua_vid.o pjsua_app.o main.o
+
+all: alt_pjsua
+
+alt_pjsua: $(OBJS)
+	$(PJ_CC) -o $@ $(OBJS) $(_CFLAGS) $(_LDFLAGS)
+
+pjsua_app.o: ../pjsua/pjsua_app.c
+	$(PJ_CC) $(_CFLAGS) -c -o $@ $<
+
+main.o: ../pjsua/main.c
+	$(PJ_CC) $(_CFLAGS) -c -o $@ $<
+
+%.o: %.c
+	$(PJ_CC) $(_CFLAGS) -c -o $@ $<
+
+depend:
+
+clean:
+	rm -f *.o alt_pjsua 
+
+distclean realclean: clean
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/alt_pjsua_aud.c b/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/alt_pjsua_aud.c
new file mode 100644
index 0000000..fd2bf71
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/alt_pjsua_aud.c
@@ -0,0 +1,631 @@
+/* $Id: alt_pjsua_aud.c 4174 2012-06-21 08:09:53Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 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 <pjsua-lib/pjsua.h>
+#include <pjsua-lib/pjsua_internal.h>
+
+#if defined(PJSUA_MEDIA_HAS_PJMEDIA) && PJSUA_MEDIA_HAS_PJMEDIA != 0
+#  error The PJSUA_MEDIA_HAS_PJMEDIA should be declared as zero
+#endif
+
+
+#define THIS_FILE		"alt_pjsua_aud.c"
+#define UNIMPLEMENTED(func)	PJ_LOG(2,(THIS_FILE, "*** Call to unimplemented function %s ***", #func));
+
+
+/*****************************************************************************
+ * Our dummy codecs. Since we won't use any PJMEDIA codecs, we need to declare
+ * our own codecs and register them to PJMEDIA's codec manager. We just need
+ * the info so that they can be listed in SDP. The encoding and decoding will
+ * happen in your third party media stream and will not use these codecs,
+ * hence the "dummy" name.
+ */
+static struct alt_codec
+{
+    pj_str_t	encoding_name;
+    pj_uint8_t	payload_type;
+    unsigned	clock_rate;
+    unsigned	channel_cnt;
+    unsigned	frm_ptime;
+    unsigned	avg_bps;
+    unsigned	max_bps;
+} codec_list[] =
+{
+    /* G.729 */
+    { { "G729", 4 }, 18, 8000, 1, 10, 8000, 8000 },
+    /* PCMU */
+    { { "PCMU", 4 }, 0, 8000, 1, 10, 64000, 64000 },
+    /* Our proprietary high end low bit rate (5kbps) codec, if you wish */
+    { { "FOO", 3 }, PJMEDIA_RTP_PT_START+0, 16000, 1, 20, 5000, 5000 },
+};
+
+static struct alt_codec_factory
+{
+    pjmedia_codec_factory	base;
+} alt_codec_factory;
+
+static pj_status_t alt_codec_test_alloc( pjmedia_codec_factory *factory,
+                                         const pjmedia_codec_info *id )
+{
+    unsigned i;
+    for (i=0; i<PJ_ARRAY_SIZE(codec_list); ++i) {
+	if (pj_stricmp(&id->encoding_name, &codec_list[i].encoding_name)==0)
+	    return PJ_SUCCESS;
+    }
+    return PJ_ENOTSUP;
+}
+
+static pj_status_t alt_codec_default_attr( pjmedia_codec_factory *factory,
+                                           const pjmedia_codec_info *id,
+                                           pjmedia_codec_param *attr )
+{
+    struct alt_codec *ac;
+    unsigned i;
+
+    PJ_UNUSED_ARG(factory);
+
+    for (i=0; i<PJ_ARRAY_SIZE(codec_list); ++i) {
+	if (pj_stricmp(&id->encoding_name, &codec_list[i].encoding_name)==0)
+	    break;
+    }
+    if (i == PJ_ARRAY_SIZE(codec_list))
+	return PJ_ENOTFOUND;
+
+    ac = &codec_list[i];
+
+    pj_bzero(attr, sizeof(pjmedia_codec_param));
+    attr->info.clock_rate = ac->clock_rate;
+    attr->info.channel_cnt = ac->channel_cnt;
+    attr->info.avg_bps = ac->avg_bps;
+    attr->info.max_bps = ac->max_bps;
+    attr->info.pcm_bits_per_sample = 16;
+    attr->info.frm_ptime = ac->frm_ptime;
+    attr->info.pt = ac->payload_type;
+
+    attr->setting.frm_per_pkt = 1;
+    attr->setting.vad = 1;
+    attr->setting.plc = 1;
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t alt_codec_enum_codecs(pjmedia_codec_factory *factory,
+					 unsigned *count,
+					 pjmedia_codec_info codecs[])
+{
+    unsigned i;
+
+    for (i=0; i<*count && i<PJ_ARRAY_SIZE(codec_list); ++i) {
+	struct alt_codec *ac = &codec_list[i];
+	pj_bzero(&codecs[i], sizeof(pjmedia_codec_info));
+	codecs[i].encoding_name = ac->encoding_name;
+	codecs[i].pt = ac->payload_type;
+	codecs[i].type = PJMEDIA_TYPE_AUDIO;
+	codecs[i].clock_rate = ac->clock_rate;
+	codecs[i].channel_cnt = ac->channel_cnt;
+    }
+
+    *count = i;
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t alt_codec_alloc_codec(pjmedia_codec_factory *factory,
+					 const pjmedia_codec_info *id,
+					 pjmedia_codec **p_codec)
+{
+    /* This will never get called since we won't be using this codec */
+    UNIMPLEMENTED(alt_codec_alloc_codec)
+    return PJ_ENOTSUP;
+}
+
+static pj_status_t alt_codec_dealloc_codec( pjmedia_codec_factory *factory,
+                                            pjmedia_codec *codec )
+{
+    /* This will never get called */
+    UNIMPLEMENTED(alt_codec_dealloc_codec)
+    return PJ_ENOTSUP;
+}
+
+static pj_status_t alt_codec_deinit(void)
+{
+    pjmedia_codec_mgr *codec_mgr;
+    codec_mgr = pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt);
+    return pjmedia_codec_mgr_unregister_factory(codec_mgr,
+                                                &alt_codec_factory.base);
+
+}
+
+static pjmedia_codec_factory_op alt_codec_factory_op =
+{
+    &alt_codec_test_alloc,
+    &alt_codec_default_attr,
+    &alt_codec_enum_codecs,
+    &alt_codec_alloc_codec,
+    &alt_codec_dealloc_codec,
+    &alt_codec_deinit
+};
+
+
+/*****************************************************************************
+ * API
+ */
+
+/* Initialize third party media library. */
+pj_status_t pjsua_aud_subsys_init()
+{
+    pjmedia_codec_mgr *codec_mgr;
+    pj_status_t status;
+
+    /* Register our "dummy" codecs */
+    alt_codec_factory.base.op = &alt_codec_factory_op;
+    codec_mgr = pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt);
+    status = pjmedia_codec_mgr_register_factory(codec_mgr,
+						&alt_codec_factory.base);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* TODO: initialize your evil library here */
+    return PJ_SUCCESS;
+}
+
+/* Start (audio) media library. */
+pj_status_t pjsua_aud_subsys_start(void)
+{
+    /* TODO: */
+    return PJ_SUCCESS;
+}
+
+/* Cleanup and deinitialize third party media library. */
+pj_status_t pjsua_aud_subsys_destroy()
+{
+    /* TODO: */
+    return PJ_SUCCESS;
+}
+
+/* Our callback to receive incoming RTP packets */
+static void aud_rtp_cb(void *user_data, void *pkt, pj_ssize_t size)
+{
+    pjsua_call_media *call_med = (pjsua_call_media*) user_data;
+
+    /* TODO: Do something with the packet */
+    PJ_LOG(4,(THIS_FILE, "RX %d bytes audio RTP packet", (int)size));
+}
+
+/* Our callback to receive RTCP packets */
+static void aud_rtcp_cb(void *user_data, void *pkt, pj_ssize_t size)
+{
+    pjsua_call_media *call_med = (pjsua_call_media*) user_data;
+
+    /* TODO: Do something with the packet here */
+    PJ_LOG(4,(THIS_FILE, "RX %d bytes audio RTCP packet", (int)size));
+}
+
+/* A demo function to send dummy "RTP" packets periodically. You would not
+ * need to have this function in the real app!
+ */
+static void timer_to_send_aud_rtp(void *user_data)
+{
+    pjsua_call_media *call_med = (pjsua_call_media*) user_data;
+    const char *pkt = "Not RTP packet";
+
+    if (!call_med->call || !call_med->call->inv || !call_med->tp) {
+	/* Call has been disconnected. There is race condition here as
+	 * this cb may be called sometime after call has been disconnected */
+	return;
+    }
+
+    pjmedia_transport_send_rtp(call_med->tp, pkt, strlen(pkt));
+
+    pjsua_schedule_timer2(&timer_to_send_aud_rtp, call_med, 2000);
+}
+
+static void timer_to_send_aud_rtcp(void *user_data)
+{
+    pjsua_call_media *call_med = (pjsua_call_media*) user_data;
+    const char *pkt = "Not RTCP packet";
+
+    if (!call_med->call || !call_med->call->inv || !call_med->tp) {
+	/* Call has been disconnected. There is race condition here as
+	 * this cb may be called sometime after call has been disconnected */
+	return;
+    }
+
+    pjmedia_transport_send_rtcp(call_med->tp, pkt, strlen(pkt));
+
+    pjsua_schedule_timer2(&timer_to_send_aud_rtcp, call_med, 5000);
+}
+
+/* Stop the audio stream of a call. */
+void pjsua_aud_stop_stream(pjsua_call_media *call_med)
+{
+    /* Detach our RTP/RTCP callbacks from transport */
+    pjmedia_transport_detach(call_med->tp, call_med);
+
+    /* TODO: destroy your audio stream here */
+}
+
+/*
+ * This function is called whenever SDP negotiation has completed
+ * successfully. Here you'd want to start your audio stream
+ * based on the info in the SDPs.
+ */
+pj_status_t pjsua_aud_channel_update(pjsua_call_media *call_med,
+                                     pj_pool_t *tmp_pool,
+                                     pjmedia_stream_info *si,
+				     const pjmedia_sdp_session *local_sdp,
+				     const pjmedia_sdp_session *remote_sdp)
+{
+    pj_status_t status = PJ_SUCCESS;
+
+    PJ_LOG(4,(THIS_FILE,"Alt audio channel update.."));
+    pj_log_push_indent();
+
+    /* Check if no media is active */
+    if (si->dir != PJMEDIA_DIR_NONE) {
+	/* Attach our RTP and RTCP callbacks to the media transport */
+	status = pjmedia_transport_attach(call_med->tp, call_med,
+	                                  &si->rem_addr, &si->rem_rtcp,
+	                                  pj_sockaddr_get_len(&si->rem_addr),
+	                                  &aud_rtp_cb, &aud_rtcp_cb);
+
+	/* For a demonstration, let's use a timer to send "RTP" packet
+	 * periodically.
+	 */
+	pjsua_schedule_timer2(&timer_to_send_aud_rtp, call_med, 0);
+	pjsua_schedule_timer2(&timer_to_send_aud_rtcp, call_med, 2500);
+
+	/* TODO:
+	 *   - Create and start your media stream based on the parameters
+	 *     in si
+	 */
+    }
+
+on_return:
+    pj_log_pop_indent();
+    return status;
+}
+
+void pjsua_check_snd_dev_idle()
+{
+}
+
+/*****************************************************************************
+ *
+ * Call API which MAY need to be re-implemented if different backend is used.
+ */
+
+/* Check if call has an active media session. */
+PJ_DEF(pj_bool_t) pjsua_call_has_media(pjsua_call_id call_id)
+{
+    UNIMPLEMENTED(pjsua_call_has_media)
+    return PJ_TRUE;
+}
+
+
+/* Get the conference port identification associated with the call. */
+PJ_DEF(pjsua_conf_port_id) pjsua_call_get_conf_port(pjsua_call_id call_id)
+{
+    UNIMPLEMENTED(pjsua_call_get_conf_port)
+    return PJSUA_INVALID_ID;
+}
+
+/* Get media stream info for the specified media index. */
+PJ_DEF(pj_status_t) pjsua_call_get_stream_info( pjsua_call_id call_id,
+                                                unsigned med_idx,
+                                                pjsua_stream_info *psi)
+{
+    pj_bzero(psi, sizeof(*psi));
+    UNIMPLEMENTED(pjsua_call_get_stream_info)
+    return PJ_ENOTSUP;
+}
+
+/* Get media stream statistic for the specified media index.  */
+PJ_DEF(pj_status_t) pjsua_call_get_stream_stat( pjsua_call_id call_id,
+                                                unsigned med_idx,
+                                                pjsua_stream_stat *stat)
+{
+    pj_bzero(stat, sizeof(*stat));
+    UNIMPLEMENTED(pjsua_call_get_stream_stat)
+    return PJ_ENOTSUP;
+}
+
+/*
+ * Send DTMF digits to remote using RFC 2833 payload formats.
+ */
+PJ_DEF(pj_status_t) pjsua_call_dial_dtmf( pjsua_call_id call_id,
+					  const pj_str_t *digits)
+{
+    UNIMPLEMENTED(pjsua_call_dial_dtmf)
+    return PJ_ENOTSUP;
+}
+
+/*****************************************************************************
+ * Below are auxiliary API that we don't support (feel free to implement them
+ * with the other media stack)
+ */
+
+/* Get maximum number of conference ports. */
+PJ_DEF(unsigned) pjsua_conf_get_max_ports(void)
+{
+    UNIMPLEMENTED(pjsua_conf_get_max_ports)
+    return 0xFF;
+}
+
+/* Get current number of active ports in the bridge. */
+PJ_DEF(unsigned) pjsua_conf_get_active_ports(void)
+{
+    UNIMPLEMENTED(pjsua_conf_get_active_ports)
+    return 0;
+}
+
+/* Enumerate all conference ports. */
+PJ_DEF(pj_status_t) pjsua_enum_conf_ports(pjsua_conf_port_id id[],
+					  unsigned *count)
+{
+    *count = 0;
+    UNIMPLEMENTED(pjsua_enum_conf_ports)
+    return PJ_ENOTSUP;
+}
+
+/* Get information about the specified conference port */
+PJ_DEF(pj_status_t) pjsua_conf_get_port_info( pjsua_conf_port_id id,
+					      pjsua_conf_port_info *info)
+{
+    UNIMPLEMENTED(pjsua_conf_get_port_info)
+    return PJ_ENOTSUP;
+}
+
+/* Add arbitrary media port to PJSUA's conference bridge. */
+PJ_DEF(pj_status_t) pjsua_conf_add_port( pj_pool_t *pool,
+					 pjmedia_port *port,
+					 pjsua_conf_port_id *p_id)
+{
+    *p_id = PJSUA_INVALID_ID;
+    UNIMPLEMENTED(pjsua_conf_add_port)
+    /* We should return PJ_ENOTSUP here, but this API is needed by pjsua
+     * application or otherwise it will refuse to start.
+     */
+    return PJ_SUCCESS;
+}
+
+/* Remove arbitrary slot from the conference bridge. */
+PJ_DEF(pj_status_t) pjsua_conf_remove_port(pjsua_conf_port_id id)
+{
+    UNIMPLEMENTED(pjsua_conf_remove_port)
+    return PJ_ENOTSUP;
+}
+
+/* Establish unidirectional media flow from souce to sink. */
+PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
+					pjsua_conf_port_id sink)
+{
+    UNIMPLEMENTED(pjsua_conf_connect)
+    return PJ_ENOTSUP;
+}
+
+/* Disconnect media flow from the source to destination port. */
+PJ_DEF(pj_status_t) pjsua_conf_disconnect( pjsua_conf_port_id source,
+					   pjsua_conf_port_id sink)
+{
+    UNIMPLEMENTED(pjsua_conf_disconnect)
+    return PJ_ENOTSUP;
+}
+
+/* Adjust the signal level to be transmitted from the bridge to the
+ * specified port by making it louder or quieter.
+ */
+PJ_DEF(pj_status_t) pjsua_conf_adjust_tx_level(pjsua_conf_port_id slot,
+					       float level)
+{
+    UNIMPLEMENTED(pjsua_conf_adjust_tx_level)
+    return PJ_ENOTSUP;
+}
+
+/* Adjust the signal level to be received from the specified port (to
+ * the bridge) by making it louder or quieter.
+ */
+PJ_DEF(pj_status_t) pjsua_conf_adjust_rx_level(pjsua_conf_port_id slot,
+					       float level)
+{
+    UNIMPLEMENTED(pjsua_conf_adjust_rx_level)
+    return PJ_ENOTSUP;
+}
+
+
+/* Get last signal level transmitted to or received from the specified port. */
+PJ_DEF(pj_status_t) pjsua_conf_get_signal_level(pjsua_conf_port_id slot,
+						unsigned *tx_level,
+						unsigned *rx_level)
+{
+    UNIMPLEMENTED(pjsua_conf_get_signal_level)
+    return PJ_ENOTSUP;
+}
+
+/* Create a file player, and automatically connect this player to
+ * the conference bridge.
+ */
+PJ_DEF(pj_status_t) pjsua_player_create( const pj_str_t *filename,
+					 unsigned options,
+					 pjsua_player_id *p_id)
+{
+    UNIMPLEMENTED(pjsua_player_create)
+    return PJ_ENOTSUP;
+}
+
+/* Create a file playlist media port, and automatically add the port
+ * to the conference bridge.
+ */
+PJ_DEF(pj_status_t) pjsua_playlist_create( const pj_str_t file_names[],
+					   unsigned file_count,
+					   const pj_str_t *label,
+					   unsigned options,
+					   pjsua_player_id *p_id)
+{
+    UNIMPLEMENTED(pjsua_playlist_create)
+    return PJ_ENOTSUP;
+}
+
+/* Get conference port ID associated with player. */
+PJ_DEF(pjsua_conf_port_id) pjsua_player_get_conf_port(pjsua_player_id id)
+{
+    UNIMPLEMENTED(pjsua_player_get_conf_port)
+    return -1;
+}
+
+/* Get the media port for the player. */
+PJ_DEF(pj_status_t) pjsua_player_get_port( pjsua_player_id id,
+					   pjmedia_port **p_port)
+{
+    UNIMPLEMENTED(pjsua_player_get_port)
+    return PJ_ENOTSUP;
+}
+
+/* Set playback position. */
+PJ_DEF(pj_status_t) pjsua_player_set_pos( pjsua_player_id id,
+					  pj_uint32_t samples)
+{
+    UNIMPLEMENTED(pjsua_player_set_pos)
+    return PJ_ENOTSUP;
+}
+
+/* Close the file, remove the player from the bridge, and free
+ * resources associated with the file player.
+ */
+PJ_DEF(pj_status_t) pjsua_player_destroy(pjsua_player_id id)
+{
+    UNIMPLEMENTED(pjsua_player_destroy)
+    return PJ_ENOTSUP;
+}
+
+/* Create a file recorder, and automatically connect this recorder to
+ * the conference bridge.
+ */
+PJ_DEF(pj_status_t) pjsua_recorder_create( const pj_str_t *filename,
+					   unsigned enc_type,
+					   void *enc_param,
+					   pj_ssize_t max_size,
+					   unsigned options,
+					   pjsua_recorder_id *p_id)
+{
+    UNIMPLEMENTED(pjsua_recorder_create)
+    return PJ_ENOTSUP;
+}
+
+
+/* Get conference port associated with recorder. */
+PJ_DEF(pjsua_conf_port_id) pjsua_recorder_get_conf_port(pjsua_recorder_id id)
+{
+    UNIMPLEMENTED(pjsua_recorder_get_conf_port)
+    return -1;
+}
+
+/* Get the media port for the recorder. */
+PJ_DEF(pj_status_t) pjsua_recorder_get_port( pjsua_recorder_id id,
+					     pjmedia_port **p_port)
+{
+    UNIMPLEMENTED(pjsua_recorder_get_port)
+    return PJ_ENOTSUP;
+}
+
+/* Destroy recorder (this will complete recording). */
+PJ_DEF(pj_status_t) pjsua_recorder_destroy(pjsua_recorder_id id)
+{
+    UNIMPLEMENTED(pjsua_recorder_destroy)
+    return PJ_ENOTSUP;
+}
+
+/* Enum sound devices. */
+PJ_DEF(pj_status_t) pjsua_enum_aud_devs( pjmedia_aud_dev_info info[],
+					 unsigned *count)
+{
+    UNIMPLEMENTED(pjsua_enum_aud_devs)
+    return PJ_ENOTSUP;
+}
+
+PJ_DEF(pj_status_t) pjsua_enum_snd_devs( pjmedia_snd_dev_info info[],
+					 unsigned *count)
+{
+    UNIMPLEMENTED(pjsua_enum_snd_devs)
+    return PJ_ENOTSUP;
+}
+
+/* Select or change sound device. */
+PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev, int playback_dev)
+{
+    UNIMPLEMENTED(pjsua_set_snd_dev)
+    return PJ_SUCCESS;
+}
+
+/* Get currently active sound devices. */
+PJ_DEF(pj_status_t) pjsua_get_snd_dev(int *capture_dev, int *playback_dev)
+{
+    *capture_dev = *playback_dev = PJSUA_INVALID_ID;
+    UNIMPLEMENTED(pjsua_get_snd_dev)
+    return PJ_ENOTSUP;
+}
+
+/* Use null sound device. */
+PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
+{
+    UNIMPLEMENTED(pjsua_set_null_snd_dev)
+    return PJ_ENOTSUP;
+}
+
+/* Use no device! */
+PJ_DEF(pjmedia_port*) pjsua_set_no_snd_dev(void)
+{
+    UNIMPLEMENTED(pjsua_set_no_snd_dev)
+    return NULL;
+}
+
+/* Configure the AEC settings of the sound port. */
+PJ_DEF(pj_status_t) pjsua_set_ec(unsigned tail_ms, unsigned options)
+{
+    UNIMPLEMENTED(pjsua_set_ec)
+    return PJ_ENOTSUP;
+}
+
+/* Get current AEC tail length. */
+PJ_DEF(pj_status_t) pjsua_get_ec_tail(unsigned *p_tail_ms)
+{
+    UNIMPLEMENTED(pjsua_get_ec_tail)
+    return PJ_ENOTSUP;
+}
+
+/* Check whether the sound device is currently active. */
+PJ_DEF(pj_bool_t) pjsua_snd_is_active(void)
+{
+    UNIMPLEMENTED(pjsua_snd_is_active)
+    return PJ_FALSE;
+}
+
+/* Configure sound device setting to the sound device being used. */
+PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap,
+					   const void *pval, pj_bool_t keep)
+{
+    UNIMPLEMENTED(pjsua_snd_set_setting)
+    return PJ_ENOTSUP;
+}
+
+/* Retrieve a sound device setting. */
+PJ_DEF(pj_status_t) pjsua_snd_get_setting(pjmedia_aud_dev_cap cap, void *pval)
+{
+    UNIMPLEMENTED(pjsua_snd_get_setting)
+    return PJ_ENOTSUP;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/alt_pjsua_vid.c b/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/alt_pjsua_vid.c
new file mode 100644
index 0000000..08f7aff
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/alt_pjsua_vid.c
@@ -0,0 +1,602 @@
+/* $Id: alt_pjsua_vid.c 4174 2012-06-21 08:09:53Z bennylp $ */
+/* 
+ * Copyright (C) 2011-2011 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 <pjsua-lib/pjsua.h>
+#include <pjsua-lib/pjsua_internal.h>
+
+#if defined(PJSUA_MEDIA_HAS_PJMEDIA) && PJSUA_MEDIA_HAS_PJMEDIA != 0
+#  error The PJSUA_MEDIA_HAS_PJMEDIA should be declared as zero
+#endif
+
+#if PJSUA_HAS_VIDEO
+
+#define THIS_FILE		"alt_pjsua_vid.c"
+#define UNIMPLEMENTED(func)	PJ_LOG(2,(THIS_FILE, "*** Call to unimplemented function %s ***", #func));
+
+/*****************************************************************************
+ * Our video codec descriptors
+ */
+struct alt_codec_desc
+{
+    /* Predefined info */
+    pjmedia_vid_codec_info       info;
+    pjmedia_format_id		 base_fmt_id;
+    pj_uint32_t			 avg_bps;
+    pj_uint32_t			 max_bps;
+    pjmedia_codec_fmtp		 dec_fmtp;
+} alt_vid_codecs[] =
+{
+    /* H.263+ */
+    {
+	{PJMEDIA_FORMAT_H263P, PJMEDIA_RTP_PT_H263P, {"H263-1998",9},
+	 {"H.263 codec", 11}, 90000, PJMEDIA_DIR_ENCODING_DECODING,
+	 0, {PJMEDIA_FORMAT_RGB24}, PJMEDIA_VID_PACKING_PACKETS
+	},
+	PJMEDIA_FORMAT_H263,	256000,    512000,
+	{2, { {{"CIF",3},   {"1",1}},
+	      {{"QCIF",4},  {"1",1}}, } },
+    }
+};
+
+static const struct alt_codec_desc* find_codec_desc_by_info(const pjmedia_vid_codec_info *info)
+{
+    unsigned i;
+    for (i=0; i<PJ_ARRAY_SIZE(alt_vid_codecs); ++i) {
+	struct alt_codec_desc *desc = &alt_vid_codecs[i];
+	if ((desc->info.fmt_id == info->fmt_id) &&
+            ((desc->info.dir & info->dir) == info->dir) &&
+	    (desc->info.pt == info->pt) &&
+	    (desc->info.packings & info->packings))
+        {
+            return desc;
+        }
+    }
+
+    return NULL;
+}
+
+static pj_status_t alt_vid_codec_test_alloc( pjmedia_vid_codec_factory *factory,
+                                             const pjmedia_vid_codec_info *id )
+{
+    const struct alt_codec_desc *desc = find_codec_desc_by_info(id);
+    return desc? PJ_SUCCESS : PJMEDIA_CODEC_EUNSUP;
+}
+
+static pj_status_t alt_vid_codec_default_attr( pjmedia_vid_codec_factory *factory,
+                                               const pjmedia_vid_codec_info *info,
+                                               pjmedia_vid_codec_param *attr )
+{
+    const struct alt_codec_desc *desc = find_codec_desc_by_info(info);
+    unsigned i;
+
+    if (!desc)
+        return PJMEDIA_CODEC_EUNSUP;
+
+    pj_bzero(attr, sizeof(pjmedia_vid_codec_param));
+
+    /* Scan the requested packings and use the lowest number */
+    attr->packing = 0;
+    for (i=0; i<15; ++i) {
+	unsigned packing = (1 << i);
+	if ((desc->info.packings & info->packings) & packing) {
+	    attr->packing = (pjmedia_vid_packing)packing;
+	    break;
+	}
+    }
+    if (attr->packing == 0) {
+	/* No supported packing in info */
+	return PJMEDIA_CODEC_EUNSUP;
+    }
+
+    /* Direction */
+    attr->dir = desc->info.dir;
+
+    /* Encoded format */
+    pjmedia_format_init_video(&attr->enc_fmt, desc->info.fmt_id,
+                              720, 480, 30000, 1001);
+
+    /* Decoded format */
+    pjmedia_format_init_video(&attr->dec_fmt, desc->info.dec_fmt_id[0],
+                              //352, 288, 30000, 1001);
+                              720, 576, 30000, 1001);
+
+    /* Decoding fmtp */
+    attr->dec_fmtp = desc->dec_fmtp;
+
+    /* Bitrate */
+    attr->enc_fmt.det.vid.avg_bps = desc->avg_bps;
+    attr->enc_fmt.det.vid.max_bps = desc->max_bps;
+
+    /* MTU */
+    attr->enc_mtu = PJMEDIA_MAX_MTU;
+
+    return PJ_SUCCESS;
+}
+
+
+static pj_status_t alt_vid_codec_enum_codecs( pjmedia_vid_codec_factory *factory,
+					      unsigned *count,
+					      pjmedia_vid_codec_info codecs[])
+{
+    unsigned i, max_cnt;
+
+    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
+
+    max_cnt = PJ_MIN(*count, PJ_ARRAY_SIZE(alt_vid_codecs));
+    *count = 0;
+
+    for (i=0; i<max_cnt; ++i) {
+	pj_memcpy(&codecs[*count], &alt_vid_codecs[i].info,
+		  sizeof(pjmedia_vid_codec_info));
+	(*count)++;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+static pj_status_t alt_vid_codec_alloc_codec( pjmedia_vid_codec_factory *factory,
+					      const pjmedia_vid_codec_info *info,
+					      pjmedia_vid_codec **p_codec)
+{
+    /* This will never get called since we won't be using this codec */
+    UNIMPLEMENTED(alt_vid_codec_alloc_codec)
+    return PJ_ENOTSUP;
+}
+
+
+static pj_status_t alt_vid_codec_dealloc_codec( pjmedia_vid_codec_factory *factory,
+                                                pjmedia_vid_codec *codec )
+{
+    /* This will never get called since we won't be using this codec */
+    UNIMPLEMENTED(alt_vid_codec_dealloc_codec)
+    return PJ_ENOTSUP;
+}
+
+static pjmedia_vid_codec_factory_op alt_vid_codec_factory_op =
+{
+    &alt_vid_codec_test_alloc,
+    &alt_vid_codec_default_attr,
+    &alt_vid_codec_enum_codecs,
+    &alt_vid_codec_alloc_codec,
+    &alt_vid_codec_dealloc_codec
+};
+
+static struct alt_vid_codec_factory {
+    pjmedia_vid_codec_factory    base;
+} alt_vid_codec_factory;
+
+/*****************************************************************************
+ * Video API implementation
+ */
+
+/* Initialize the video library */
+pj_status_t pjsua_vid_subsys_init(void)
+{
+    pjmedia_vid_codec_mgr *mgr;
+    pj_status_t status;
+
+    /* Format manager singleton is needed */
+    status = pjmedia_video_format_mgr_create(pjsua_var.pool, 64, 0, NULL);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(1,(THIS_FILE, status,
+		     "Error creating PJMEDIA video format manager"));
+	return status;
+    }
+
+    /* Create video codec manager singleton */
+    status = pjmedia_vid_codec_mgr_create(pjsua_var.pool, &mgr);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(1,(THIS_FILE, status,
+		     "Error creating PJMEDIA video codec manager"));
+	return status;
+    }
+
+    /* Register our codecs */
+    alt_vid_codec_factory.base.op = &alt_vid_codec_factory_op;
+    alt_vid_codec_factory.base.factory_data = NULL;
+
+    status = pjmedia_vid_codec_mgr_register_factory(mgr, &alt_vid_codec_factory.base);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /*
+     * TODO: put your 3rd party library initialization routine here
+     */
+
+    return PJ_SUCCESS;
+}
+
+/* Start the video library */
+pj_status_t pjsua_vid_subsys_start(void)
+{
+    /*
+     * TODO: put your 3rd party library startup routine here
+     */
+    return PJ_SUCCESS;
+}
+
+/* Cleanup and deinitialize the video library */
+pj_status_t pjsua_vid_subsys_destroy(void)
+{
+    if (pjmedia_vid_codec_mgr_instance())
+	pjmedia_vid_codec_mgr_destroy(NULL);
+
+    if (pjmedia_video_format_mgr_instance())
+	pjmedia_video_format_mgr_destroy(NULL);
+
+    /*
+     * TODO: put your 3rd party library cleanup routine here
+     */
+    return PJ_SUCCESS;
+}
+
+/* Initialize video call media */
+pj_status_t pjsua_vid_channel_init(pjsua_call_media *call_med)
+{
+    /*
+     * TODO: put call media initialization
+     */
+    return PJ_SUCCESS;
+}
+
+/* Internal function to stop video stream */
+void pjsua_vid_stop_stream(pjsua_call_media *call_med)
+{
+    PJ_LOG(4,(THIS_FILE, "Stopping video stream.."));
+
+    if (call_med->tp) {
+	pjmedia_transport_detach(call_med->tp, call_med);
+    }
+
+    /*
+     * TODO:
+     *   - stop your video stream here
+     */
+
+}
+
+/* Our callback to receive incoming RTP packets */
+static void vid_rtp_cb(void *user_data, void *pkt, pj_ssize_t size)
+{
+    pjsua_call_media *call_med = (pjsua_call_media*) user_data;
+
+    /* TODO: Do something with the packet */
+    PJ_LOG(4,(THIS_FILE, "RX %d bytes video RTP packet", (int)size));
+}
+
+/* Our callback to receive RTCP packets */
+static void vid_rtcp_cb(void *user_data, void *pkt, pj_ssize_t size)
+{
+    pjsua_call_media *call_med = (pjsua_call_media*) user_data;
+
+    /* TODO: Do something with the packet here */
+    PJ_LOG(4,(THIS_FILE, "RX %d bytes video RTCP packet", (int)size));
+}
+
+/* A demo function to send dummy "RTP" packets periodically. You would not
+ * need to have this function in the real app!
+ */
+static void timer_to_send_vid_rtp(void *user_data)
+{
+    pjsua_call_media *call_med = (pjsua_call_media*) user_data;
+    const char *pkt = "Not RTP packet";
+
+    if (!call_med->call || !call_med->call->inv || !call_med->tp) {
+	/* Call has been disconnected. There is race condition here as
+	 * this cb may be called sometime after call has been disconnected */
+	return;
+    }
+
+    pjmedia_transport_send_rtp(call_med->tp, pkt, strlen(pkt));
+
+    pjsua_schedule_timer2(&timer_to_send_vid_rtp, call_med, 2000);
+}
+
+static void timer_to_send_vid_rtcp(void *user_data)
+{
+    pjsua_call_media *call_med = (pjsua_call_media*) user_data;
+    const char *pkt = "Not RTCP packet";
+
+    if (!call_med->call || !call_med->call->inv || !call_med->tp) {
+	/* Call has been disconnected. There is race condition here as
+	 * this cb may be called sometime after call has been disconnected */
+	return;
+    }
+
+    pjmedia_transport_send_rtcp(call_med->tp, pkt, strlen(pkt));
+
+    pjsua_schedule_timer2(&timer_to_send_vid_rtcp, call_med, 5000);
+}
+
+/* update video channel after SDP negotiation */
+pj_status_t pjsua_vid_channel_update(pjsua_call_media *call_med,
+				     pj_pool_t *tmp_pool,
+				     pjmedia_vid_stream_info *si,
+				     const pjmedia_sdp_session *local_sdp,
+				     const pjmedia_sdp_session *remote_sdp)
+{
+    pj_status_t status;
+    
+    PJ_LOG(4,(THIS_FILE, "Video channel update.."));
+    pj_log_push_indent();
+
+    /* Check if no media is active */
+    if (si->dir != PJMEDIA_DIR_NONE) {
+	/* Attach our RTP and RTCP callbacks to the media transport */
+	status = pjmedia_transport_attach(call_med->tp, call_med,
+	                                  &si->rem_addr, &si->rem_rtcp,
+	                                  pj_sockaddr_get_len(&si->rem_addr),
+	                                  &vid_rtp_cb, &vid_rtcp_cb);
+	/*
+	 * TODO:
+	 *   - Create and start your video stream based on the parameters
+	 *     in si
+	 */
+
+	/* For a demonstration, let's use a timer to send "RTP" packet
+	 * periodically.
+	 */
+	pjsua_schedule_timer2(&timer_to_send_vid_rtp, call_med, 1000);
+	pjsua_schedule_timer2(&timer_to_send_vid_rtcp, call_med, 3500);
+    }
+
+    pj_log_pop_indent();
+    return PJ_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * Preview
+ */
+
+PJ_DEF(void)
+pjsua_call_vid_strm_op_param_default(pjsua_call_vid_strm_op_param *param)
+{
+    pj_bzero(param, sizeof(*param));
+    param->med_idx = -1;
+    param->dir = PJMEDIA_DIR_ENCODING_DECODING;
+    param->cap_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+}
+
+PJ_DEF(void) pjsua_vid_preview_param_default(pjsua_vid_preview_param *p)
+{
+    p->rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV;
+    p->show = PJ_TRUE;
+}
+
+PJ_DEF(pjsua_vid_win_id) pjsua_vid_preview_get_win(pjmedia_vid_dev_index id)
+{
+    UNIMPLEMENTED(pjsua_vid_preview_get_win)
+    return PJSUA_INVALID_ID;
+}
+
+/* Reset internal window structure. Not sure if this is needed?. */
+PJ_DEF(void) pjsua_vid_win_reset(pjsua_vid_win_id wid)
+{
+    pjsua_vid_win *w = &pjsua_var.win[wid];
+    pj_pool_t *pool = w->pool;
+
+    pj_bzero(w, sizeof(*w));
+    if (pool) pj_pool_reset(pool);
+    w->ref_cnt = 0;
+    w->pool = pool;
+    w->preview_cap_id = PJMEDIA_VID_INVALID_DEV;
+}
+
+/* Does it have built-in preview support. */
+PJ_DEF(pj_bool_t) pjsua_vid_preview_has_native(pjmedia_vid_dev_index id)
+{
+    UNIMPLEMENTED(pjsua_vid_preview_has_native)
+    return PJ_FALSE;
+}
+
+/* Start video preview window for the specified capture device. */
+PJ_DEF(pj_status_t) pjsua_vid_preview_start(pjmedia_vid_dev_index id,
+                                            const pjsua_vid_preview_param *prm)
+{
+    UNIMPLEMENTED(pjsua_vid_preview_start)
+    return PJ_ENOTSUP;
+}
+
+/* Stop video preview. */
+PJ_DEF(pj_status_t) pjsua_vid_preview_stop(pjmedia_vid_dev_index id)
+{
+    UNIMPLEMENTED(pjsua_vid_preview_stop)
+    return PJ_ENOTSUP;
+}
+
+
+/*****************************************************************************
+ * Devices.
+ */
+
+/* Get the number of video devices installed in the system. */
+PJ_DEF(unsigned) pjsua_vid_dev_count(void)
+{
+    UNIMPLEMENTED(pjsua_vid_dev_count)
+    return 0;
+}
+
+/* Retrieve the video device info for the specified device index. */
+PJ_DEF(pj_status_t) pjsua_vid_dev_get_info(pjmedia_vid_dev_index id,
+                                           pjmedia_vid_dev_info *vdi)
+{
+    UNIMPLEMENTED(pjsua_vid_dev_get_info)
+    return PJ_ENOTSUP;
+}
+
+/* Enum all video devices installed in the system. */
+PJ_DEF(pj_status_t) pjsua_vid_enum_devs(pjmedia_vid_dev_info info[],
+					unsigned *count)
+{
+    UNIMPLEMENTED(pjsua_vid_enum_devs)
+    return PJ_ENOTSUP;
+}
+
+
+/*****************************************************************************
+ * Codecs.
+ */
+
+/* Enum all supported video codecs in the system. */
+PJ_DEF(pj_status_t) pjsua_vid_enum_codecs( pjsua_codec_info id[],
+					   unsigned *p_count )
+{
+    pjmedia_vid_codec_info info[32];
+    unsigned i, j, count, prio[32];
+    pj_status_t status;
+
+    count = PJ_ARRAY_SIZE(info);
+    status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, prio);
+    if (status != PJ_SUCCESS) {
+	*p_count = 0;
+	return status;
+    }
+    for (i=0, j=0; i<count && j<*p_count; ++i) {
+	if (info[i].packings & PJMEDIA_VID_PACKING_PACKETS) {
+	    pj_bzero(&id[j], sizeof(pjsua_codec_info));
+
+	    pjmedia_vid_codec_info_to_id(&info[i], id[j].buf_, sizeof(id[j].buf_));
+	    id[j].codec_id = pj_str(id[j].buf_);
+	    id[j].priority = (pj_uint8_t) prio[i];
+
+	    if (id[j].codec_id.slen < sizeof(id[j].buf_)) {
+		id[j].desc.ptr = id[j].codec_id.ptr + id[j].codec_id.slen + 1;
+		pj_strncpy(&id[j].desc, &info[i].encoding_desc,
+			   sizeof(id[j].buf_) - id[j].codec_id.slen - 1);
+	    }
+
+	    ++j;
+	}
+    }
+
+    *p_count = j;
+    return PJ_SUCCESS;
+}
+
+/* Change video codec priority. */
+PJ_DEF(pj_status_t) pjsua_vid_codec_set_priority( const pj_str_t *codec_id,
+						  pj_uint8_t priority )
+{
+    UNIMPLEMENTED(pjsua_vid_codec_set_priority)
+    return PJ_ENOTSUP;
+}
+
+/* Get video codec parameters. */
+PJ_DEF(pj_status_t) pjsua_vid_codec_get_param(
+					const pj_str_t *codec_id,
+					pjmedia_vid_codec_param *param)
+{
+    UNIMPLEMENTED(pjsua_vid_codec_get_param)
+    return PJ_ENOTSUP;
+}
+
+/* Set video codec parameters. */
+PJ_DEF(pj_status_t) pjsua_vid_codec_set_param(
+					const pj_str_t *codec_id,
+					const pjmedia_vid_codec_param *param)
+{
+    UNIMPLEMENTED(pjsua_vid_codec_set_param)
+    return PJ_ENOTSUP;
+}
+
+
+/*****************************************************************************
+ * Window
+ */
+
+/* Enumerates all video windows. */
+PJ_DEF(pj_status_t) pjsua_vid_enum_wins( pjsua_vid_win_id wids[],
+					 unsigned *count)
+{
+    UNIMPLEMENTED(pjsua_vid_enum_wins)
+    return PJ_ENOTSUP;
+}
+
+/* Get window info. */
+PJ_DEF(pj_status_t) pjsua_vid_win_get_info( pjsua_vid_win_id wid,
+                                            pjsua_vid_win_info *wi)
+{
+    UNIMPLEMENTED(pjsua_vid_win_get_info)
+    return PJ_ENOTSUP;
+}
+
+/* Show or hide window. */
+PJ_DEF(pj_status_t) pjsua_vid_win_set_show( pjsua_vid_win_id wid,
+                                            pj_bool_t show)
+{
+    UNIMPLEMENTED(pjsua_vid_win_set_show)
+    return PJ_ENOTSUP;
+}
+
+/* Set video window position. */
+PJ_DEF(pj_status_t) pjsua_vid_win_set_pos( pjsua_vid_win_id wid,
+                                           const pjmedia_coord *pos)
+{
+    UNIMPLEMENTED(pjsua_vid_win_set_pos)
+    return PJ_ENOTSUP;
+}
+
+/* Resize window. */
+PJ_DEF(pj_status_t) pjsua_vid_win_set_size( pjsua_vid_win_id wid,
+                                            const pjmedia_rect_size *size)
+{
+    UNIMPLEMENTED(pjsua_vid_win_set_size)
+    return PJ_ENOTSUP;
+}
+
+/* Set video orientation. */
+PJ_DEF(pj_status_t) pjsua_vid_win_rotate( pjsua_vid_win_id wid,
+                                          int angle)
+{
+    UNIMPLEMENTED(pjsua_vid_win_rotate)
+    return PJ_ENOTSUP;
+}
+
+/* Start, stop, and/or manipulate video transmission for the specified call. */
+PJ_DEF(pj_status_t) pjsua_call_set_vid_strm (
+				pjsua_call_id call_id,
+				pjsua_call_vid_strm_op op,
+				const pjsua_call_vid_strm_op_param *param)
+{
+    UNIMPLEMENTED(pjsua_call_set_vid_strm)
+    return PJ_ENOTSUP;
+}
+
+
+/* Get the media stream index of the default video stream in the call. */
+PJ_DEF(int) pjsua_call_get_vid_stream_idx(pjsua_call_id call_id)
+{
+    UNIMPLEMENTED(pjsua_call_get_vid_stream_idx)
+    return -1;
+}
+
+/* Determine if video stream for the specified call is currently running
+ * for the specified direction.
+ */
+PJ_DEF(pj_bool_t) pjsua_call_vid_stream_is_running( pjsua_call_id call_id,
+                                                    int med_idx,
+                                                    pjmedia_dir dir)
+{
+    UNIMPLEMENTED(pjsua_call_vid_stream_is_running)
+    return PJ_FALSE;
+}
+
+#endif	/* PJSUA_HAS_VIDEO */
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/config_site.h b/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/config_site.h
new file mode 100644
index 0000000..e883cec
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/3rdparty_media_sample/config_site.h
@@ -0,0 +1,42 @@
+/*
+ * Put this file in pjlib/include/pj
+ */
+
+/* sample configure command:
+   CFLAGS="-g -Wno-unused-label" ./aconfigure --enable-ext-sound --disable-speex-aec --disable-g711-codec --disable-l16-codec --disable-gsm-codec --disable-g722-codec --disable-g7221-codec --disable-speex-codec --disable-ilbc-codec --disable-opencore-amrnb --disable-sdl --disable-ffmpeg --disable-v4l2
+ */
+
+#define THIRD_PARTY_MEDIA			1
+
+#if THIRD_PARTY_MEDIA
+/*
+ * Sample settings for using third party media with pjsua-lib
+ */
+#	define PJSUA_MEDIA_HAS_PJMEDIA		0
+#	define PJMEDIA_HAS_G711_CODEC		0
+#	define PJMEDIA_HAS_ALAW_ULAW_TABLE	0
+#	define PJMEDIA_RESAMPLE_IMP		PJMEDIA_RESAMPLE_NONE
+#	define PJMEDIA_HAS_SPEEX_AEC		0
+
+#	define PJMEDIA_HAS_L16_CODEC		0
+#	define PJMEDIA_HAS_GSM_CODEC		0
+#	define PJMEDIA_HAS_SPEEX_CODEC		0
+#	define PJMEDIA_HAS_ILBC_CODEC		0
+#	define PJMEDIA_HAS_G722_CODEC		0
+#	define PJMEDIA_HAS_G7221_CODEC		0
+#	define PJMEDIA_HAS_OPENCORE_AMRNB_CODEC	0
+
+#	define PJMEDIA_HAS_VIDEO		1
+#	define PJMEDIA_HAS_FFMPEG		0
+
+#	undef PJMEDIA_VIDEO_DEV_HAS_SDL
+#	define PJMEDIA_VIDEO_DEV_HAS_SDL	0
+#	define PJMEDIA_VIDEO_DEV_HAS_QT		0
+#	define PJMEDIA_VIDEO_DEV_HAS_IOS	0
+#	define PJMEDIA_VIDEO_DEV_HAS_DSHOW	0
+#	define PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC	0
+#	define PJMEDIA_VIDEO_DEV_HAS_FFMPEG	0
+#	undef PJMEDIA_VIDEO_DEV_HAS_V4L2
+#	define PJMEDIA_VIDEO_DEV_HAS_V4L2	0
+#endif	/* THIRD_PARTY_MEDIA */
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/confbot/confbot.py b/jni/libpjsip/sources/pjsip-apps/src/confbot/confbot.py
new file mode 100644
index 0000000..572c50c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/confbot/confbot.py
@@ -0,0 +1,575 @@
+# $Id: confbot.py 2912 2009-08-24 11:56:13Z bennylp $
+#
+# SIP Conference Bot
+#
+# Copyright (C) 2008-2009 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 
+#
+import pjsua as pj
+import string
+import sys
+
+CFG_FILE = "config"
+
+INFO = 1
+TRACE = 2
+	
+# Call callback. This would just forward the event to the Member class
+class CallCb(pj.CallCallback):
+	def __init__(self, member, call=None):
+		pj.CallCallback.__init__(self, call)
+		self.member = member
+	
+	def on_state(self):
+		self.member.on_call_state(self.call)
+	
+	def on_media_state(self):
+		self.member.on_call_media_state(self.call)
+
+	def on_dtmf_digit(self, digits):
+		self.member.on_call_dtmf_digit(self.call, digits)
+
+	def on_transfer_request(self, dst, code):
+		return self.member.on_call_transfer_request(self.call, dst, code)
+	
+	def on_transfer_status(self, code, reason, final, cont):
+		return self.member.on_call_transfer_status(self.call, code, reason, final, cont)
+
+	def on_replace_request(self, code, reason):
+		return self.member.on_call_replace_request(self.call, code, reason)
+		
+	def on_replaced(self, new_call):
+		self.member.on_call_replaced(self.call, new_call)
+
+	def on_typing(self, is_typing):
+		self.member.on_typing(is_typing, call=self.call)
+
+	def on_pager(self, mime_type, body):
+		self.member.on_pager(mime_type, body, call=self.call)
+	
+	def on_pager_status(self, body, im_id, code, reason):
+		self.member.on_pager_status(body, im_id, code, reason, call=self.call)
+
+# Buddy callback. This would just forward the event to Member class
+class BuddyCb(pj.BuddyCallback):
+	def __init__(self, member, buddy=None):
+		pj.BuddyCallback.__init__(self, buddy)
+		self.member = member
+	
+	def on_pager(self, mime_type, body):
+		self.member.on_pager(mime_type, body, buddy=self.buddy)
+
+	def on_pager_status(self, body, im_id, code, reason):
+		self.member.on_pager_status(body, im_id, code, reason, buddy=self.buddy)
+
+	def on_state(self):
+		self.member.on_pres_state(self.buddy)
+
+	def on_typing(self, is_typing):
+		self.member.on_typing(is_typing, buddy=self.buddy)
+
+
+
+
+##############################################################################
+#
+#
+# This class represents individual room member (either/both chat and voice conf)
+#
+#
+class Member:
+	def __init__(self, bot, uri):
+		self.uri = uri
+		self.bot = bot
+		self.call = None
+		self.buddy = None
+		self.bi = pj.BuddyInfo()
+		self.in_chat = False
+		self.in_voice = False
+		self.im_error = False
+		self.html = False
+	
+	def __str__(self):
+		str = string.ljust(self.uri, 30) + " -- " 
+		if self.buddy:
+			bi = self.buddy.info()
+			str = str + bi.online_text
+		else:
+			str = str + "Offline"
+		str = str + " ["
+		if (self.in_voice):
+			str = str + " voice"
+		if (self.in_chat):
+			str = str + " chat"
+			if (self.html):
+				str = str + " html"
+			else:
+				str = str + " plain"
+
+		if (self.im_error):
+			str = str + " im_error"
+		str = str + "]"
+		return str
+		
+	def join_call(self, call):
+		if self.call:
+			self.call.hangup(603, "You have been disconnected for making another call")
+		self.call = call
+		call.set_callback(CallCb(self, call))
+		msg = "%(uri)s is attempting to join the voice conference" % \
+			  {'uri': self.uri}
+		self.bot.DEBUG(msg + "\n", INFO)
+		self.bot.broadcast_pager(None, msg)
+	
+	def join_chat(self):
+		if not self.buddy:
+			self.bot.DEBUG(self.uri + " joining chatroom...\n", INFO)
+			self.buddy = self.bot.acc.add_buddy(self.uri)
+			self.buddy.set_callback(BuddyCb(self, self.buddy))
+			self.buddy.subscribe()
+		else:
+			self.bot.DEBUG(self.uri + " already in chatroom, resubscribing..\n", INFO)
+			self.buddy.subscribe()
+
+	def send_pager(self, body, mime="text/plain"):
+		self.bot.DEBUG("send_pager() to " + self.uri)
+		if self.in_chat and not self.im_error and self.buddy:
+			if self.html:
+				#This will make us receive html!
+				#mime = "text/html"
+				body = body.replace("<", "&lt;")
+				body = body.replace(">", "&gt;")
+				body = body.replace('"', "&quot;")
+				body = body.replace("\n", "<BR>\n")
+			self.buddy.send_pager(body, content_type=mime)
+			self.bot.DEBUG("..sent\n")
+		else:
+			self.bot.DEBUG("..not sent!\n")
+		
+	def on_call_state(self, call):
+		ci = call.info()
+		if ci.state==pj.CallState.DISCONNECTED:
+			if self.in_voice:
+				msg = "%(uri)s has left the voice conference (%(1)d/%(2)s)" % \
+					  {'uri': self.uri, '1': ci.last_code, '2': ci.last_reason}
+				self.bot.DEBUG(msg + "\n", INFO)
+				self.bot.broadcast_pager(None, msg)
+			self.in_voice = False
+			self.call = None
+			self.bot.on_member_left(self)
+		elif ci.state==pj.CallState.CONFIRMED:
+			msg = "%(uri)s has joined the voice conference" % \
+				  {'uri': self.uri}
+			self.bot.DEBUG(msg + "\n", INFO)
+			self.bot.broadcast_pager(None, msg)
+	
+	def on_call_media_state(self, call):
+		self.bot.DEBUG("Member.on_call_media_state\n")
+		ci = call.info()
+		if ci.conf_slot!=-1:
+			if not self.in_voice:
+				msg = self.uri + " call media is active"
+				self.bot.broadcast_pager(None, msg)
+			self.in_voice = True
+			self.bot.add_to_voice_conf(self)
+		else:
+			if self.in_voice:
+				msg = self.uri + " call media is inactive"
+				self.bot.broadcast_pager(None, msg)
+			self.in_voice = False
+
+	def on_call_dtmf_digit(self, call, digits):
+		msg = "%(uri)s sent DTMF digits %(dig)s" % \
+			  {'uri': self.uri, 'dig': digits}
+		self.bot.broadcast_pager(None, msg)
+
+	def on_call_transfer_request(self, call, dst, code):
+		msg = "%(uri)s is transfering the call to %(dst)s" % \
+			  {'uri': self.uri, 'dst': dst}
+		self.bot.broadcast_pager(None, msg)
+		return 202
+	
+	def on_call_transfer_status(self, call, code, reason, final, cont):
+		msg = "%(uri)s call transfer status is %(code)d/%(res)s" % \
+			  {'uri': self.uri, 'code': code, 'res': reason}
+		self.bot.broadcast_pager(None, msg)
+		return True
+
+	def on_call_replace_request(self, call, code, reason):
+		msg = "%(uri)s is requesting call replace" % \
+			  {'uri': self.uri}
+		self.bot.broadcast_pager(None, msg)
+		return (code, reason)
+		
+	def on_call_replaced(self, call, new_call):
+		msg = "%(uri)s call is replaced" % \
+			  {'uri': self.uri}
+		self.bot.broadcast_pager(None, msg)
+
+	def on_pres_state(self, buddy):
+		old_bi = self.bi
+		self.bi = buddy.info()
+		msg = "%(uri)s status is %(st)s" % \
+		  {'uri': self.uri, 'st': self.bi.online_text}
+		self.bot.DEBUG(msg + "\n", INFO)
+		self.bot.broadcast_pager(self, msg)
+
+		if self.bi.sub_state==pj.SubscriptionState.ACTIVE:
+			if not self.in_chat:
+				self.in_chat = True
+				buddy.send_pager("Welcome to chatroom")
+				self.bot.broadcast_pager(self, self.uri + " has joined the chat room")
+			else:
+				self.in_chat = True
+		elif self.bi.sub_state==pj.SubscriptionState.NULL or \
+			 self.bi.sub_state==pj.SubscriptionState.TERMINATED or \
+			 self.bi.sub_state==pj.SubscriptionState.UNKNOWN:
+			self.buddy.delete()
+			self.buddy = None
+			if self.in_chat:
+				self.in_chat = False
+				self.bot.broadcast_pager(self, self.uri + " has left the chat room")
+			else:
+				self.in_chat = False
+			self.bot.on_member_left(self)
+		
+	def on_typing(self, is_typing, call=None, buddy=None):
+		if is_typing:
+			msg = self.uri + " is typing..."
+		else:
+			msg = self.uri + " has stopped typing"
+		self.bot.broadcast_pager(self, msg)
+
+	def on_pager(self, mime_type, body, call=None, buddy=None):
+		if not self.bot.handle_cmd(self, None, body):
+			msg = self.uri + ": " + body
+			self.bot.broadcast_pager(self, msg, mime_type)
+	
+	def on_pager_status(self, body, im_id, code, reason, call=None, buddy=None):
+		self.im_error = (code/100 != 2)
+
+
+
+##############################################################################
+#
+#
+# The Bot instance (singleton)
+#
+#
+class Bot(pj.AccountCallback):
+	def __init__(self):
+		pj.AccountCallback.__init__(self, None)
+		self.lib = pj.Lib()
+		self.acc = None
+		self.calls = []
+		self.members = {}
+		self.cfg = None
+
+	def DEBUG(self, msg, level=TRACE):
+		print msg,
+		
+	def helpstring(self):
+		return """
+--h[elp]            Display this help screen
+--j[oin]            Join the chat room
+--html on|off       Set to receive HTML or plain text
+
+Participant commands:
+--s[how]            Show confbot settings
+--leave             Leave the chatroom
+--l[ist]            List all members
+
+Admin commands:
+--a[dmin] <CMD> Where <CMD> are:
+    list            List the admins
+    add <URI>       Add URI as admin
+    del <URI>       Remove URI as admin
+    rr              Reregister account to server
+    call <URI>      Make call to the URI and add to voice conf
+    dc <URI>        Disconnect call to URI
+    hold <URI>      Hold call with that URI
+    update <URI>    Send UPDATE to call with that URI
+    reinvite <URI>  Send re-INVITE to call with that URI
+"""
+
+	def listmembers(self):
+		msg = ""
+		for uri, m in self.members.iteritems():
+			msg = msg + str(m) + "\n"
+		return msg
+	
+	def showsettings(self):
+		ai = self.acc.info()
+		msg = """
+ConfBot status and settings:
+  URI:        %(uri)s
+  Status:     %(pres)s
+  Reg Status: %(reg_st)d
+  Reg Reason: %(reg_res)s
+""" % {'uri': ai.uri, 'pres': ai.online_text, \
+	   'reg_st': ai.reg_status, 'reg_res': ai.reg_reason}
+		return msg
+  
+	def main(self, cfg_file):
+		try:
+			cfg = self.cfg = __import__(cfg_file)
+			
+			self.lib.init(ua_cfg=cfg.ua_cfg, log_cfg=cfg.log_cfg, media_cfg=cfg.media_cfg)
+			self.lib.set_null_snd_dev()
+			
+			transport = None
+			if cfg.udp_cfg:
+				transport = self.lib.create_transport(pj.TransportType.UDP, cfg.udp_cfg)
+			if cfg.tcp_cfg:
+				t = self.lib.create_transport(pj.TransportType.TCP, cfg.tcp_cfg)
+				if not transport:
+					transport = t
+				
+			self.lib.start()
+			
+			if cfg.acc_cfg:
+				self.DEBUG("Creating account %(uri)s..\n" % {'uri': cfg.acc_cfg.id}, INFO)
+				self.acc = self.lib.create_account(cfg.acc_cfg, cb=self)
+			else:
+				self.DEBUG("Creating account for %(t)s..\n" % \
+							{'t': transport.info().description}, INFO)
+				self.acc = self.lib.create_account_for_transport(transport, cb=self)
+			
+			self.acc.set_basic_status(True)
+			
+			# Wait for ENTER before quitting
+			print "Press q to quit or --help/--h for help"
+			while True:
+				input = sys.stdin.readline().strip(" \t\r\n")
+				if not self.handle_cmd(None, None, input):
+					if input=="q":
+						break
+			
+			self.lib.destroy()
+			self.lib = None
+
+		except pj.Error, e:
+			print "Exception: " + str(e)
+			if self.lib:
+				self.lib.destroy()
+				self.lib = None
+	
+	def broadcast_pager(self, exclude_member, body, mime_type="text/plain"):
+		self.DEBUG("Broadcast: " + body + "\n")
+		for uri, m in self.members.iteritems():
+			if m != exclude_member:
+				m.send_pager(body, mime_type)
+
+	def add_to_voice_conf(self, member):
+		if not member.call:
+			return
+		src_ci = member.call.info()
+		self.DEBUG("bot.add_to_voice_conf\n")
+		for uri, m in self.members.iteritems():
+			if m==member:
+				continue
+			if not m.call:
+				continue
+			dst_ci = m.call.info()
+			if dst_ci.media_state==pj.MediaState.ACTIVE and dst_ci.conf_slot!=-1:
+				self.lib.conf_connect(src_ci.conf_slot, dst_ci.conf_slot)
+				self.lib.conf_connect(dst_ci.conf_slot, src_ci.conf_slot)
+	
+	def on_member_left(self, member):
+		if not member.call and not member.buddy:
+			del self.members[member.uri]
+			del member
+			
+	def handle_admin_cmd(self, member, body):
+		if member and self.cfg.admins and not member.uri in self.cfg.admins:
+			member.send_pager("You are not admin")
+			return
+		args = body.split()
+		msg = ""
+
+		if len(args)==1:
+			args.append(" ")
+
+		if args[1]=="list":
+			if not self.cfg.admins:
+				msg = "Everyone is admin!"
+			else:
+				msg = str(self.cfg.admins)
+		elif args[1]=="add":
+			if len(args)!=3:
+				msg = "Usage: add <URI>"
+			else:
+				self.cfg.admins.append(args[2])
+				msg = args[2] + " added as admin"
+		elif args[1]=="del":
+			if len(args)!=3:
+				msg = "Usage: del <URI>"
+			elif args[2] not in self.cfg.admins:
+				msg = args[2] + " is not admin"
+			else:
+				self.cfg.admins.remove(args[2])
+				msg = args[2] + " has been removed from admins"
+		elif args[1]=="rr":
+			msg = "Reregistering.."
+			self.acc.set_registration(True)
+		elif args[1]=="call":
+			if len(args)!=3:
+				msg = "Usage: call <URI>"
+			else:
+				uri = args[2]
+				try:
+					call = self.acc.make_call(uri)
+				except pj.Error, e:
+					msg = "Error: " + str(e)
+					call = None
+
+				if call:
+					if not uri in self.members:
+						m = Member(self, uri)
+						self.members[m.uri] = m
+					else:
+						m = self.members[uri]
+					msg = "Adding " + m.uri + " to voice conference.."
+					m.join_call(call)
+		elif args[1]=="dc" or args[1]=="hold" or args[1]=="update" or args[1]=="reinvite":
+			if len(args)!=3:
+				msg = "Usage: " + args[1] + " <URI>"
+			else:
+				uri = args[2]
+				if not uri in self.members:
+					msg = "Member not found/URI doesn't match (note: case matters!)"
+				else:
+					m = self.members[uri]
+					if m.call:
+						if args[1]=="dc":
+							msg = "Disconnecting.."
+							m.call.hangup(603, "You're disconnected by admin")
+						elif args[1]=="hold":
+							msg = "Holding the call"
+							m.call.hold()
+						elif args[1]=="update":
+							msg = "Sending UPDATE"
+							m.call.update()
+						elif args[1]=="reinvite":
+							msg = "Sending re-INVITE"
+							m.call.reinvite()
+					else:
+						msg = "He is not in call"
+		else:
+			msg = "Unknown admin command " + body
+
+		#print "msg is '%(msg)s'" % {'msg': msg}
+
+		if True:
+			if member:
+				member.send_pager(msg)
+			else:
+				print msg
+
+	def handle_cmd(self, member, from_uri, body):
+		body = body.strip(" \t\r\n")
+		msg = ""
+		handled = True
+		if body=="--l" or body=="--list":
+			msg = self.listmembers()
+			if msg=="":
+				msg = "Nobody is here"
+		elif body[0:3]=="--s":
+			msg = self.showsettings()
+		elif body[0:6]=="--html" and member:
+			if body[8:11]=="off":
+				member.html = False
+			else:
+				member.html = True
+		elif body=="--h" or body=="--help":
+			msg = self.helpstring()
+		elif body=="--leave":
+			if not member or not member.buddy:
+				msg = "You are not in chatroom"
+			else:
+				member.buddy.unsubscribe()
+		elif body[0:3]=="--j":
+			if not from_uri in self.members:
+				m = Member(self, from_uri)
+				self.members[m.uri] = m
+				self.DEBUG("Adding " + m.uri + " to chatroom\n")
+				m.join_chat()
+			else:
+				m = self.members[from_uri]
+				self.DEBUG("Adding " + m.uri + " to chatroom\n")
+				m.join_chat()
+		elif body[0:3]=="--a":
+			self.handle_admin_cmd(member, body)
+			handled = True
+		else:
+			handled = False
+
+		if msg:
+			if member:
+				member.send_pager(msg)
+			elif from_uri:
+				self.acc.send_pager(from_uri, msg);
+			else:
+				print msg
+		return handled
+	
+	def on_incoming_call(self, call):
+		self.DEBUG("on_incoming_call from %(uri)s\n" % {'uri': call.info().remote_uri}, INFO)
+		ci = call.info()
+		if not ci.remote_uri in self.members:
+			m = Member(self, ci.remote_uri)
+			self.members[m.uri] = m
+			m.join_call(call)
+		else:
+			m = self.members[ci.remote_uri]
+			m.join_call(call)
+		call.answer(200)
+	
+	def on_incoming_subscribe(self, buddy, from_uri, contact_uri, pres_obj):
+		self.DEBUG("on_incoming_subscribe from %(uri)s\n" % from_uri, INFO)
+		return (200, 'OK')
+
+	def on_reg_state(self):
+		ai = self.acc.info()
+		self.DEBUG("Registration state: %(code)d/%(reason)s\n" % \
+					{'code': ai.reg_status, 'reason': ai.reg_reason}, INFO)
+		if ai.reg_status/100==2 and ai.reg_expires > 0:
+			self.acc.set_basic_status(True)
+
+	def on_pager(self, from_uri, contact, mime_type, body):
+		body = body.strip(" \t\r\n")
+		if not self.handle_cmd(None, from_uri, body):
+			self.acc.send_pager(from_uri, "You have not joined the chat room. Type '--join' to join or '--help' for the help")
+
+	def on_pager_status(self, to_uri, body, im_id, code, reason):
+		pass
+
+	def on_typing(self, from_uri, contact, is_typing):
+		pass
+
+
+
+
+##############################################################################
+#
+#
+# main()
+#
+#
+if __name__ == "__main__":
+	bot = Bot()
+	bot.main(CFG_FILE)
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/confbot/config.py b/jni/libpjsip/sources/pjsip-apps/src/confbot/config.py
new file mode 100644
index 0000000..9dd31b4
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/confbot/config.py
@@ -0,0 +1,41 @@
+# $Id: config.py 2912 2009-08-24 11:56:13Z bennylp $
+#
+# Confbot settings
+#
+import pjsua as pj
+
+# Set of admins. If empty then everyone is admin!
+admins = set([])
+
+# acc_cfg holds the account config (set it to None to disable account)
+acc_cfg = None
+acc_cfg = pj.AccountConfig()
+if acc_cfg:
+	acc_cfg.id = "sip:bot@pjsip.org"
+	acc_cfg.reg_uri = "sip:pjsip.org"
+	acc_cfg.proxy = [ "sip:pjsip.org;lr;transport=tcp" ]
+	acc_cfg.auth_cred = [ pj.AuthCred("*", "bot", "secretpass") ]
+	acc_cfg.publish_enabled = True
+	#acc_cfg.require_timer = True
+
+# Transport configs (set them to None to disable the transport)
+udp_cfg = pj.TransportConfig(5080)
+tcp_cfg = pj.TransportConfig(0)
+#tcp_cfg = None
+
+# Logging Config (you can also set it to None to use default values)
+def log_cb(level, str, len):
+	print str,
+	
+log_cfg = pj.LogConfig()
+#log_cfg.callback = log_cb
+
+# UA Config (you can also set it to None to use default values)
+ua_cfg = pj.UAConfig()
+ua_cfg.user_agent = "PJSIP ConfBot"
+ua_cfg.stun_host = "stun.pjsip.org"
+
+# Media config (you can also set it to None to use default values)
+media_cfg = pj.MediaConfig()
+media_cfg.enable_ice = True
+media_cfg.max_calls = 20
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/RootViewController.h b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/RootViewController.h
new file mode 100644
index 0000000..72627d2
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/RootViewController.h
@@ -0,0 +1,32 @@
+/* $Id: RootViewController.h 3552 2011-05-05 05:50:48Z nanang $ */
+/* 
+ * Copyright (C) 2010-2011 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 
+ */
+#import "TestViewController.h"
+
+@interface RootViewController : UITableViewController {
+    NSMutableArray *titles;
+    NSMutableArray *menus;
+    
+    TestViewController *testView;
+}
+
+@property (nonatomic, retain) NSMutableArray *titles;
+@property (nonatomic, retain) NSMutableArray *menus;
+@property (nonatomic, retain) TestViewController *testView;
+
+@end
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/RootViewController.m b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/RootViewController.m
new file mode 100644
index 0000000..e4cfab0
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/RootViewController.m
@@ -0,0 +1,335 @@
+/* $Id: RootViewController.m 3552 2011-05-05 05:50:48Z nanang $ */
+/* 
+ * Copyright (C) 2010-2011 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 
+ */
+#import "RootViewController.h"
+#import "gui.h"
+#import "systest.h"
+
+/* Sleep interval duration, change to shorter duration for better
+ * interaction but make sure there is enough time for the other
+ * thread to do what it's supposed to do
+ */
+#define SLEEP_INTERVAL 0.5
+
+@implementation RootViewController
+@synthesize titles;
+@synthesize menus;
+@synthesize testView;
+
+RootViewController	*view;
+
+bool			systest_initialized;
+bool			thread_quit;
+gui_menu		*gmenu;
+int			section;
+int			row;
+const char		*ctitle;
+const char		*cmsg; 
+enum gui_flag		cflag;
+
+pj_status_t gui_init(gui_menu *menu)
+{
+    PJ_UNUSED_ARG(menu);
+    return PJ_SUCCESS;
+}
+
+/* Run GUI main loop */
+pj_status_t gui_start(gui_menu *menu)
+{
+    view.titles = [NSMutableArray arrayWithCapacity:menu->submenu_cnt];
+    view.menus = [NSMutableArray arrayWithCapacity:menu->submenu_cnt];
+    NSMutableArray *smenu;
+    for (int i = 0; i < menu->submenu_cnt; i++) {
+	NSString *str = [NSString stringWithFormat:@"%s" , menu->submenus[i]->title];
+	[view.titles addObject: str];
+	smenu = [NSMutableArray arrayWithCapacity:menu->submenus[i]->submenu_cnt];
+	/* We do not need the last two menus of the "Tests" menu (NULL and "Exit"),
+	 * so subtract by 2
+	 */
+	for (int j = 0; j < menu->submenus[i]->submenu_cnt - (i==0? 2: 0); j++) {
+	    str = [NSString stringWithFormat:@"%s" , menu->submenus[i]->submenus[j]->title];
+	    [smenu addObject:str];
+	}
+	[view.menus addObject:smenu];
+    }
+    gmenu = menu;
+    
+    return PJ_SUCCESS;
+}
+
+/* Signal GUI mainloop to stop */
+void gui_destroy(void)
+{
+}
+
+/* AUX: display messagebox */
+enum gui_key gui_msgbox(const char *title, const char *message, enum gui_flag flag)
+{
+    ctitle = title;
+    cmsg = message;
+    cflag = flag;
+    [view performSelectorOnMainThread:@selector(showMsg) withObject:nil waitUntilDone:YES];
+    
+    view.testView.key = 0;
+    while(view.testView.key == 0) {
+	/* Let the main thread do its job (refresh the view) while we wait for 
+	 * user interaction (button click)
+	 */
+	[NSThread sleepForTimeInterval:SLEEP_INTERVAL];
+    }
+    
+    if (view.testView.key == 1)
+	return KEY_OK;
+    else
+	return (flag == WITH_YESNO? KEY_NO: KEY_CANCEL);
+}
+
+/* AUX: sleep */
+void gui_sleep(unsigned sec)
+{
+    [NSThread sleepForTimeInterval:sec];
+}
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    view = self;
+    
+    /* Get a writable path for output files */
+    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+    NSString *documentsDirectory = [paths objectAtIndex:0];
+    [documentsDirectory getCString:doc_path maxLength:PATH_LENGTH encoding:NSASCIIStringEncoding];
+    strncat(doc_path, "/", PATH_LENGTH);
+
+    /* Get path for our test resources (the wav files) */
+    NSString *resPath = [[NSBundle mainBundle] resourcePath];
+    [resPath getCString:res_path maxLength:PATH_LENGTH encoding:NSASCIIStringEncoding];
+    strncat(res_path, "/", PATH_LENGTH);
+    
+    systest_initialized = false;
+    thread_quit = false;
+    [NSThread detachNewThreadSelector:@selector(startTest) toTarget:self withObject:nil];
+    /* Let our new thread initialize */
+    while (!systest_initialized) {
+	[NSThread sleepForTimeInterval:SLEEP_INTERVAL];
+    }
+
+    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
+    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
+}
+
+/*
+ - (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+ }
+ */
+/*
+ - (void)viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+ }
+ */
+/*
+ - (void)viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+ }
+ */
+/*
+ - (void)viewDidDisappear:(BOOL)animated {
+    [super viewDidDisappear:animated];
+ }
+ */
+
+/*
+ // Override to allow orientations other than the default portrait orientation.
+ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    // Return YES for supported orientations.
+    return (interfaceOrientation == UIInterfaceOrientationPortrait);
+ }
+ */
+
+- (void)didReceiveMemoryWarning {
+    // Releases the view if it doesn't have a superview.
+    [super didReceiveMemoryWarning];
+    
+    // Release any cached data, images, etc that aren't in use.
+}
+
+- (void)viewDidUnload {
+    // Release anything that can be recreated in viewDidLoad or on demand.
+    // e.g. self.myOutlet = nil;
+    self.titles = nil;
+    self.menus = nil;
+    
+    thread_quit = true;
+    [NSThread sleepForTimeInterval:SLEEP_INTERVAL];
+}
+
+
+#pragma mark Table view methods
+
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    return [titles count];
+}
+
+
+// Customize the number of rows in the table view.
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return [[menus objectAtIndex:section] count];
+}
+
+
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
+    // The header for the section is the region name -- get this from the region at the section index.
+    return [titles objectAtIndex:section];
+}
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+    static NSString *CellIdentifier = @"Cell";
+    
+    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+    if (cell == nil) {
+        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+    }
+    
+    // Configure the cell.
+    cell.textLabel.text = [[menus objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
+    
+    return cell;
+}
+
+- (void)startTest {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    if (systest_init() != PJ_SUCCESS) {
+	[pool release];
+	return;
+    }
+    
+    systest_run();
+    
+    systest_initialized = 1;
+    while(!thread_quit) {
+	section = -1;
+	while (section == -1) {
+	    [NSThread sleepForTimeInterval:SLEEP_INTERVAL];
+	}
+	(*gmenu->submenus[section]->submenus[row]->handler)();
+	cmsg = NULL;
+	[view performSelectorOnMainThread:@selector(showMsg) withObject:nil waitUntilDone:YES];
+    }
+    
+    systest_deinit();
+    [pool release];
+}
+
+- (void)showMsg {
+    if (cmsg == NULL) {
+	self.testView.testDesc.text = [self.testView.testDesc.text stringByAppendingString: @"Finished"];
+	[self.testView.testDesc scrollRangeToVisible:NSMakeRange([self.testView.testDesc.text length] - 1, 1)];
+	[self.testView.button1 setHidden:true];
+	[self.testView.button2 setHidden:true];
+	return;
+    }
+    self.testView.title = [NSString stringWithFormat:@"%s", ctitle];
+    self.testView.testDesc.text = [self.testView.testDesc.text stringByAppendingString: [NSString stringWithFormat:@"%s\n\n", cmsg]];
+    [self.testView.testDesc scrollRangeToVisible:NSMakeRange([self.testView.testDesc.text length] - 1, 1)];
+    
+    [self.testView.button1 setHidden:false];
+    [self.testView.button2 setHidden:false];
+    if (cflag == WITH_YESNO) {
+	[self.testView.button1 setTitle:@"Yes" forState:UIControlStateNormal];
+	[self.testView.button2 setTitle:@"No" forState:UIControlStateNormal];
+    } else if (cflag == WITH_OK) {
+	[self.testView.button1 setTitle:@"OK" forState:UIControlStateNormal];
+	[self.testView.button2 setHidden:true];
+    } else if (cflag == WITH_OKCANCEL) {
+	[self.testView.button1 setTitle:@"OK" forState:UIControlStateNormal];
+	[self.testView.button2 setTitle:@"Cancel" forState:UIControlStateNormal];
+    }
+}
+
+
+// Override to support row selection in the table view.
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+    // Navigation logic may go here -- for example, create and push another view controller.
+    // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
+    // [self.navigationController pushViewController:anotherViewController animated:YES];
+    // [anotherViewController release];
+    
+    if (self.testView == nil) {
+	self.testView = [[TestViewController alloc] initWithNibName:@"TestViewController" bundle:[NSBundle mainBundle]];
+    }
+    
+    [self.navigationController pushViewController:self.testView animated:YES];
+    self.testView.title = [[menus objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
+    self.testView.testDesc.text = @"";
+    section = indexPath.section;
+    row = indexPath.row;
+}
+
+
+/*
+ // Override to support conditional editing of the table view.
+ - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
+    // Return NO if you do not want the specified item to be editable.
+    return YES;
+ }
+ */
+
+
+/*
+ // Override to support editing the table view.
+ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+ 
+    if (editingStyle == UITableViewCellEditingStyleDelete) {
+	// Delete the row from the data source.
+	[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
+    }   
+    else if (editingStyle == UITableViewCellEditingStyleInsert) {
+	// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
+    }   
+ }
+ */
+
+
+/*
+ // Override to support rearranging the table view.
+ - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
+ }
+ */
+
+
+/*
+ // Override to support conditional rearranging of the table view.
+ - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
+    // Return NO if you do not want the item to be re-orderable.
+    return YES;
+ }
+ */
+
+
+- (void)dealloc {
+    [super dealloc];
+}
+
+
+@end
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/TestViewController.h b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/TestViewController.h
new file mode 100644
index 0000000..9cbc057
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/TestViewController.h
@@ -0,0 +1,35 @@
+/* $Id: TestViewController.h 3552 2011-05-05 05:50:48Z nanang $ */
+/* 
+ * Copyright (C) 2010-2011 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 
+ */
+#import <UIKit/UIKit.h>
+
+
+@interface TestViewController : UIViewController {
+    IBOutlet UITextView *testDesc;
+    IBOutlet UIButton	*button1;
+    IBOutlet UIButton	*button2;
+    
+    NSInteger key;
+}
+
+@property (nonatomic, retain) IBOutlet UITextView *testDesc;
+@property (nonatomic, retain) IBOutlet UIButton *button1;
+@property (nonatomic, retain) IBOutlet UIButton *button2;
+@property (nonatomic) NSInteger key;
+
+@end
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/TestViewController.m b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/TestViewController.m
new file mode 100644
index 0000000..404a0e8
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/TestViewController.m
@@ -0,0 +1,91 @@
+/* $Id: TestViewController.m 3552 2011-05-05 05:50:48Z nanang $ */
+/* 
+ * Copyright (C) 2010-2011 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 
+ */
+#import "TestViewController.h"
+
+@implementation TestViewController
+@synthesize testDesc;
+@synthesize button1;
+@synthesize button2;
+@synthesize key;
+
+- (void)button1Pressed:(id)sender {
+    self.key = 1;
+    [self.button1 setHidden:true];
+    [self.button2 setHidden:true];
+}
+
+- (void)button2Pressed:(id)sender {
+    self.key = 2;
+    [self.button1 setHidden:true];
+    [self.button2 setHidden:true];
+}
+
+/*
+ // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
+ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
+    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
+    // Custom initialization
+ }
+ return self;
+ }
+ */
+
+/*
+ // Implement loadView to create a view hierarchy programmatically, without using a nib.
+ - (void)loadView {
+ }
+ */
+
+
+// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    [button1 addTarget:self action:@selector(button1Pressed:) forControlEvents:(UIControlEvents)UIControlEventTouchDown];
+    [button2 addTarget:self action:@selector(button2Pressed:) forControlEvents:(UIControlEvents)UIControlEventTouchDown];
+    [testDesc setEditable:false];
+}
+
+/*
+ // Override to allow orientations other than the default portrait orientation.
+ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    // Return YES for supported orientations
+    return (interfaceOrientation == UIInterfaceOrientationPortrait);
+ }
+ */
+
+- (void)didReceiveMemoryWarning {
+    // Releases the view if it doesn't have a superview.
+    [super didReceiveMemoryWarning];
+    
+    // Release any cached data, images, etc that aren't in use.
+}
+
+- (void)viewDidUnload {
+    // Release any retained subviews of the main view.
+    // e.g. self.myOutlet = nil;
+}
+
+
+- (void)dealloc {
+    [super dealloc];
+}
+
+
+@end
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/ipjsystestAppDelegate.h b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/ipjsystestAppDelegate.h
new file mode 100644
index 0000000..ddce05c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/ipjsystestAppDelegate.h
@@ -0,0 +1,29 @@
+/* $Id: ipjsystestAppDelegate.h 3552 2011-05-05 05:50:48Z nanang $ */
+/* 
+ * Copyright (C) 2010-2011 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 
+ */
+@interface ipjsystestAppDelegate : NSObject <UIApplicationDelegate> {
+    
+    UIWindow		    *window;
+    UINavigationController  *navigationController;
+}
+
+@property (nonatomic, retain) IBOutlet UIWindow *window;
+@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
+
+@end
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/ipjsystestAppDelegate.m b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/ipjsystestAppDelegate.m
new file mode 100644
index 0000000..f206348
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/Classes/ipjsystestAppDelegate.m
@@ -0,0 +1,55 @@
+/* $Id: ipjsystestAppDelegate.m 3552 2011-05-05 05:50:48Z nanang $ */
+/* 
+ * Copyright (C) 2010-2011 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 
+ */
+#import "ipjsystestAppDelegate.h"
+#import "RootViewController.h"
+
+
+@implementation ipjsystestAppDelegate
+
+@synthesize window;
+@synthesize navigationController;
+
+#pragma mark -
+#pragma mark Application lifecycle
+
+- (void)applicationDidFinishLaunching:(UIApplication *)application {    
+    
+    // Override point for customization after app launch
+    [window addSubview:[navigationController view]];
+    [window makeKeyAndVisible];
+}
+
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+    // Save data if appropriate
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+
+- (void)dealloc {
+    [navigationController release];
+    [window release];
+    [super dealloc];
+}
+
+
+@end
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/MainWindow.xib b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/MainWindow.xib
new file mode 100644
index 0000000..8b08922
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/MainWindow.xib
@@ -0,0 +1,507 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+	<data>
+		<int key="IBDocument.SystemTarget">784</int>
+		<string key="IBDocument.SystemVersion">10C540</string>
+		<string key="IBDocument.InterfaceBuilderVersion">740</string>
+		<string key="IBDocument.AppKitVersion">1038.25</string>
+		<string key="IBDocument.HIToolboxVersion">458.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">62</string>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<integer value="13"/>
+		</object>
+		<object class="NSArray" key="IBDocument.PluginDependencies">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSArray" key="dict.sortedKeys" id="0">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+			<object class="NSMutableArray" key="dict.values">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="IBProxyObject" id="841351856">
+				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+			</object>
+			<object class="IBProxyObject" id="302016328">
+				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+			</object>
+			<object class="IBUICustomObject" id="664661524"/>
+			<object class="IBUIWindow" id="380026005">
+				<nil key="NSNextResponder"/>
+				<int key="NSvFlags">1316</int>
+				<object class="NSPSMatrix" key="NSFrameMatrix"/>
+				<string key="NSFrameSize">{320, 480}</string>
+				<object class="NSColor" key="IBUIBackgroundColor">
+					<int key="NSColorSpace">1</int>
+					<bytes key="NSRGB">MSAxIDEAA</bytes>
+				</object>
+				<bool key="IBUIOpaque">NO</bool>
+				<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+			</object>
+			<object class="IBUINavigationController" id="701001926">
+				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+				<object class="IBUINavigationBar" key="IBUINavigationBar" id="207850653">
+					<nil key="NSNextResponder"/>
+					<int key="NSvFlags">256</int>
+					<string key="NSFrameSize">{0, 0}</string>
+					<bool key="IBUIOpaque">NO</bool>
+					<bool key="IBUIClipsSubviews">YES</bool>
+					<bool key="IBUIMultipleTouchEnabled">YES</bool>
+				</object>
+				<object class="NSArray" key="IBUIViewControllers">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBUIViewController" id="619226028">
+						<object class="IBUINavigationItem" key="IBUINavigationItem" id="394667715">
+							<reference key="IBUINavigationBar"/>
+							<string key="IBUITitle">ipjsystest</string>
+						</object>
+						<reference key="IBUIParentViewController" ref="701001926"/>
+						<string key="IBUINibName">RootViewController</string>
+						<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+					</object>
+				</object>
+			</object>
+		</object>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<object class="NSMutableArray" key="connectionRecords">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">delegate</string>
+						<reference key="source" ref="841351856"/>
+						<reference key="destination" ref="664661524"/>
+					</object>
+					<int key="connectionID">4</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">window</string>
+						<reference key="source" ref="664661524"/>
+						<reference key="destination" ref="380026005"/>
+					</object>
+					<int key="connectionID">5</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">navigationController</string>
+						<reference key="source" ref="664661524"/>
+						<reference key="destination" ref="701001926"/>
+					</object>
+					<int key="connectionID">15</int>
+				</object>
+			</object>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<object class="NSArray" key="orderedObjects">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<reference key="object" ref="0"/>
+						<reference key="children" ref="1000"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">2</int>
+						<reference key="object" ref="380026005"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+						</object>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="841351856"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">3</int>
+						<reference key="object" ref="664661524"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="302016328"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">9</int>
+						<reference key="object" ref="701001926"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="207850653"/>
+							<reference ref="619226028"/>
+						</object>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">11</int>
+						<reference key="object" ref="207850653"/>
+						<reference key="parent" ref="701001926"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">13</int>
+						<reference key="object" ref="619226028"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="394667715"/>
+						</object>
+						<reference key="parent" ref="701001926"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">14</int>
+						<reference key="object" ref="394667715"/>
+						<reference key="parent" ref="619226028"/>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="flattenedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="NSArray" key="dict.sortedKeys">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>-1.CustomClassName</string>
+					<string>-2.CustomClassName</string>
+					<string>11.IBPluginDependency</string>
+					<string>13.CustomClassName</string>
+					<string>13.IBPluginDependency</string>
+					<string>2.IBAttributePlaceholdersKey</string>
+					<string>2.IBEditorWindowLastContentRect</string>
+					<string>2.IBPluginDependency</string>
+					<string>3.CustomClassName</string>
+					<string>3.IBPluginDependency</string>
+					<string>9.IBEditorWindowLastContentRect</string>
+					<string>9.IBPluginDependency</string>
+				</object>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>UIApplication</string>
+					<string>UIResponder</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>RootViewController</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<object class="NSMutableDictionary">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<reference key="dict.sortedKeys" ref="0"/>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+						</object>
+					</object>
+					<string>{{673, 376}, {320, 480}}</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>ipjsystestAppDelegate</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>{{500, 343}, {320, 480}}</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="unlocalizedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="activeLocalization"/>
+			<object class="NSMutableDictionary" key="localizations">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="sourceID"/>
+			<int key="maxID">20</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">RootViewController</string>
+					<string key="superclassName">UITableViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">Classes/RootViewController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">ipjsystestAppDelegate</string>
+					<string key="superclassName">NSObject</string>
+					<object class="NSMutableDictionary" key="outlets">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>navigationController</string>
+							<string>window</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>UINavigationController</string>
+							<string>UIWindow</string>
+						</object>
+					</object>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">Classes/ipjsystestAppDelegate.h</string>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSNetServices.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSPort.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSStream.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSXMLParser.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="457547627">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIApplication</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIApplication.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIBarButtonItem</string>
+					<string key="superclassName">UIBarItem</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIBarButtonItem.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIBarItem</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIBarItem.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UINavigationBar</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="719966566">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINavigationBar.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UINavigationController</string>
+					<string key="superclassName">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="737619010">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UINavigationItem</string>
+					<string key="superclassName">NSObject</string>
+					<reference key="sourceIdentifier" ref="719966566"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIResponder</string>
+					<string key="superclassName">NSObject</string>
+					<reference key="sourceIdentifier" ref="457547627"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchBar</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchDisplayController</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UITableViewController</string>
+					<string key="superclassName">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITableViewController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<reference key="sourceIdentifier" ref="737619010"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIWindow</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIWindow.h</string>
+					</object>
+				</object>
+			</object>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+			<integer value="3100" key="NS.object.0"/>
+		</object>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<string key="IBDocument.LastKnownRelativeProjectPath">ipjsystest.xcodeproj</string>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<string key="IBCocoaTouchPluginVersion">3.1</string>
+	</data>
+</archive>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/RootViewController.xib b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/RootViewController.xib
new file mode 100644
index 0000000..5c44ed2
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/RootViewController.xib
@@ -0,0 +1,380 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+	<data>
+		<int key="IBDocument.SystemTarget">784</int>
+		<string key="IBDocument.SystemVersion">10A405</string>
+		<string key="IBDocument.InterfaceBuilderVersion">732</string>
+		<string key="IBDocument.AppKitVersion">1031</string>
+		<string key="IBDocument.HIToolboxVersion">432.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">62</string>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<integer value="2"/>
+		</object>
+		<object class="NSArray" key="IBDocument.PluginDependencies">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSArray" key="dict.sortedKeys" id="0">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+			<object class="NSMutableArray" key="dict.values">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="IBProxyObject" id="841351856">
+				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+			</object>
+			<object class="IBProxyObject" id="371349661">
+				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+			</object>
+			<object class="IBUITableView" id="709618507">
+				<reference key="NSNextResponder"/>
+				<int key="NSvFlags">274</int>
+				<string key="NSFrameSize">{320, 247}</string>
+				<reference key="NSSuperview"/>
+				<object class="NSColor" key="IBUIBackgroundColor">
+					<int key="NSColorSpace">3</int>
+					<bytes key="NSWhite">MQA</bytes>
+				</object>
+				<bool key="IBUIOpaque">NO</bool>
+				<bool key="IBUIClipsSubviews">YES</bool>
+				<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+				<bool key="IBUIBouncesZoom">NO</bool>
+				<int key="IBUISeparatorStyle">1</int>
+				<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+				<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+				<float key="IBUIRowHeight">44</float>
+				<float key="IBUISectionHeaderHeight">22</float>
+				<float key="IBUISectionFooterHeight">22</float>
+			</object>
+		</object>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<object class="NSMutableArray" key="connectionRecords">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">view</string>
+						<reference key="source" ref="841351856"/>
+						<reference key="destination" ref="709618507"/>
+					</object>
+					<int key="connectionID">3</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">dataSource</string>
+						<reference key="source" ref="709618507"/>
+						<reference key="destination" ref="841351856"/>
+					</object>
+					<int key="connectionID">4</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">delegate</string>
+						<reference key="source" ref="709618507"/>
+						<reference key="destination" ref="841351856"/>
+					</object>
+					<int key="connectionID">5</int>
+				</object>
+			</object>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<object class="NSArray" key="orderedObjects">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<reference key="object" ref="0"/>
+						<reference key="children" ref="1000"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="841351856"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="371349661"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">2</int>
+						<reference key="object" ref="709618507"/>
+						<reference key="parent" ref="0"/>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="flattenedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="NSArray" key="dict.sortedKeys">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>-1.CustomClassName</string>
+					<string>-2.CustomClassName</string>
+					<string>2.IBEditorWindowLastContentRect</string>
+					<string>2.IBPluginDependency</string>
+				</object>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>RootViewController</string>
+					<string>UIResponder</string>
+					<string>{{0, 598}, {320, 247}}</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="unlocalizedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="activeLocalization"/>
+			<object class="NSMutableDictionary" key="localizations">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="sourceID"/>
+			<int key="maxID">5</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">RootViewController</string>
+					<string key="superclassName">UITableViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">Classes/RootViewController.h</string>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSNetServices.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSPort.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSStream.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSXMLParser.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="654420027">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIResponder</string>
+					<string key="superclassName">NSObject</string>
+					<reference key="sourceIdentifier" ref="654420027"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIScrollView</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchBar</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchDisplayController</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UITableView</string>
+					<string key="superclassName">UIScrollView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UITableViewController</string>
+					<string key="superclassName">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITableViewController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+					</object>
+				</object>
+			</object>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+			<integer value="784" key="NS.object.0"/>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+			<integer value="3100" key="NS.object.0"/>
+		</object>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<string key="IBDocument.LastKnownRelativeProjectPath">ipjsystest.xcodeproj</string>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<string key="IBCocoaTouchPluginVersion">3.1</string>
+	</data>
+</archive>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/TestViewController.xib b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/TestViewController.xib
new file mode 100644
index 0000000..3a66c09
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/TestViewController.xib
@@ -0,0 +1,496 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+	<data>
+		<int key="IBDocument.SystemTarget">784</int>
+		<string key="IBDocument.SystemVersion">10C540</string>
+		<string key="IBDocument.InterfaceBuilderVersion">740</string>
+		<string key="IBDocument.AppKitVersion">1038.25</string>
+		<string key="IBDocument.HIToolboxVersion">458.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">62</string>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<integer value="1"/>
+		</object>
+		<object class="NSArray" key="IBDocument.PluginDependencies">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSArray" key="dict.sortedKeys" id="0">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+			<object class="NSMutableArray" key="dict.values">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="IBProxyObject" id="372490531">
+				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+			</object>
+			<object class="IBProxyObject" id="711762367">
+				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+			</object>
+			<object class="IBUIView" id="191373211">
+				<reference key="NSNextResponder"/>
+				<int key="NSvFlags">292</int>
+				<object class="NSMutableArray" key="NSSubviews">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBUITextView" id="613869543">
+						<reference key="NSNextResponder" ref="191373211"/>
+						<int key="NSvFlags">274</int>
+						<string key="NSFrameSize">{320, 358}</string>
+						<reference key="NSSuperview" ref="191373211"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClipsSubviews">YES</bool>
+						<bool key="IBUIMultipleTouchEnabled">YES</bool>
+						<bool key="IBUIShowsHorizontalScrollIndicator">NO</bool>
+						<bool key="IBUIDelaysContentTouches">NO</bool>
+						<bool key="IBUICanCancelContentTouches">NO</bool>
+						<bool key="IBUIBouncesZoom">NO</bool>
+						<string key="IBUIText">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.</string>
+						<object class="IBUITextInputTraits" key="IBUITextInputTraits">
+							<int key="IBUIAutocapitalizationType">2</int>
+						</object>
+					</object>
+					<object class="IBUIButton" id="669764012">
+						<reference key="NSNextResponder" ref="191373211"/>
+						<int key="NSvFlags">292</int>
+						<string key="NSFrame">{{228, 366}, {72, 37}}</string>
+						<reference key="NSSuperview" ref="191373211"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+						<int key="IBUIContentHorizontalAlignment">0</int>
+						<int key="IBUIContentVerticalAlignment">0</int>
+						<object class="NSFont" key="IBUIFont" id="892040736">
+							<string key="NSName">Helvetica-Bold</string>
+							<double key="NSSize">15</double>
+							<int key="NSfFlags">16</int>
+						</object>
+						<int key="IBUIButtonType">1</int>
+						<string key="IBUINormalTitle">OK</string>
+						<object class="NSColor" key="IBUIHighlightedTitleColor" id="501426315">
+							<int key="NSColorSpace">3</int>
+							<bytes key="NSWhite">MQA</bytes>
+						</object>
+						<object class="NSColor" key="IBUINormalTitleColor">
+							<int key="NSColorSpace">1</int>
+							<bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
+						</object>
+						<object class="NSColor" key="IBUINormalTitleShadowColor" id="88580318">
+							<int key="NSColorSpace">3</int>
+							<bytes key="NSWhite">MC41AA</bytes>
+						</object>
+					</object>
+					<object class="IBUIButton" id="970816430">
+						<reference key="NSNextResponder" ref="191373211"/>
+						<int key="NSvFlags">292</int>
+						<string key="NSFrame">{{141, 366}, {72, 37}}</string>
+						<reference key="NSSuperview" ref="191373211"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+						<int key="IBUIContentHorizontalAlignment">0</int>
+						<int key="IBUIContentVerticalAlignment">0</int>
+						<reference key="IBUIFont" ref="892040736"/>
+						<int key="IBUIButtonType">1</int>
+						<string key="IBUINormalTitle">Cancel</string>
+						<reference key="IBUIHighlightedTitleColor" ref="501426315"/>
+						<object class="NSColor" key="IBUINormalTitleColor">
+							<int key="NSColorSpace">1</int>
+							<bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
+						</object>
+						<reference key="IBUINormalTitleShadowColor" ref="88580318"/>
+					</object>
+				</object>
+				<string key="NSFrameSize">{320, 460}</string>
+				<reference key="NSSuperview"/>
+				<object class="NSColor" key="IBUIBackgroundColor">
+					<int key="NSColorSpace">3</int>
+					<bytes key="NSWhite">MQA</bytes>
+					<object class="NSColorSpace" key="NSCustomColorSpace">
+						<int key="NSID">2</int>
+					</object>
+				</object>
+				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+			</object>
+		</object>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<object class="NSMutableArray" key="connectionRecords">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">testDesc</string>
+						<reference key="source" ref="372490531"/>
+						<reference key="destination" ref="613869543"/>
+					</object>
+					<int key="connectionID">4</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">view</string>
+						<reference key="source" ref="372490531"/>
+						<reference key="destination" ref="191373211"/>
+					</object>
+					<int key="connectionID">5</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">button1</string>
+						<reference key="source" ref="372490531"/>
+						<reference key="destination" ref="669764012"/>
+					</object>
+					<int key="connectionID">8</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">button2</string>
+						<reference key="source" ref="372490531"/>
+						<reference key="destination" ref="970816430"/>
+					</object>
+					<int key="connectionID">9</int>
+				</object>
+			</object>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<object class="NSArray" key="orderedObjects">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<reference key="object" ref="0"/>
+						<reference key="children" ref="1000"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">1</int>
+						<reference key="object" ref="191373211"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="613869543"/>
+							<reference ref="669764012"/>
+							<reference ref="970816430"/>
+						</object>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="372490531"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="711762367"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">3</int>
+						<reference key="object" ref="613869543"/>
+						<reference key="parent" ref="191373211"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">6</int>
+						<reference key="object" ref="669764012"/>
+						<reference key="parent" ref="191373211"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">7</int>
+						<reference key="object" ref="970816430"/>
+						<reference key="parent" ref="191373211"/>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="flattenedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="NSArray" key="dict.sortedKeys">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>-1.CustomClassName</string>
+					<string>-2.CustomClassName</string>
+					<string>1.IBEditorWindowLastContentRect</string>
+					<string>1.IBPluginDependency</string>
+					<string>3.IBPluginDependency</string>
+					<string>6.IBPluginDependency</string>
+					<string>7.IBPluginDependency</string>
+				</object>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>TestViewController</string>
+					<string>UIResponder</string>
+					<string>{{461, 327}, {320, 480}}</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="unlocalizedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="activeLocalization"/>
+			<object class="NSMutableDictionary" key="localizations">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="sourceID"/>
+			<int key="maxID">9</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">TestViewController</string>
+					<string key="superclassName">UIViewController</string>
+					<object class="NSMutableDictionary" key="outlets">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>button1</string>
+							<string>button2</string>
+							<string>testDesc</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>UIButton</string>
+							<string>UIButton</string>
+							<string>UITextView</string>
+						</object>
+					</object>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">Classes/TestViewController.h</string>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSNetServices.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSPort.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSStream.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSXMLParser.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="27432675">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIButton</string>
+					<string key="superclassName">UIControl</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIControl</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIResponder</string>
+					<string key="superclassName">NSObject</string>
+					<reference key="sourceIdentifier" ref="27432675"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIScrollView</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchBar</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchDisplayController</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UITextView</string>
+					<string key="superclassName">UIScrollView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITextView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+					</object>
+				</object>
+			</object>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+			<integer value="3100" key="NS.object.0"/>
+		</object>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<string key="IBDocument.LastKnownRelativeProjectPath">ipjsystest.xcodeproj</string>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<string key="IBCocoaTouchPluginVersion">3.1</string>
+	</data>
+</archive>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/ipjsystest-Info.plist b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/ipjsystest-Info.plist
new file mode 100644
index 0000000..e15a90b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/ipjsystest-Info.plist
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.teluu.${PRODUCT_NAME:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSMainNibFile</key>
+	<string>MainWindow</string>
+	<key>UIBackgroundModes</key>
+	<array>
+		<string>audio</string>
+	</array>
+</dict>
+</plist>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/ipjsystest.xcodeproj/project.pbxproj b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/ipjsystest.xcodeproj/project.pbxproj
new file mode 100755
index 0000000..2709d61
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/ipjsystest.xcodeproj/project.pbxproj
@@ -0,0 +1,434 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 45;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		1D3623260D0F684500981E51 /* ipjsystestAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* ipjsystestAppDelegate.m */; };
+		1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
+		1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
+		1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+		2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; };
+		28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD735F0D9D9599002E5188 /* MainWindow.xib */; };
+		28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; };
+		28F335F11007B36200424DE2 /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28F335F01007B36200424DE2 /* RootViewController.xib */; };
+		3A3478AA1154BF8E00D51880 /* TestViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3A3478A91154BF8E00D51880 /* TestViewController.xib */; };
+		3A3478AF1154BFD700D51880 /* TestViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3478AE1154BFD700D51880 /* TestViewController.m */; };
+		3A3479221154DB0800D51880 /* systest.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A3479211154DB0800D51880 /* systest.c */; };
+		3A34794B1154E39900D51880 /* libpjmedia-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A34794A1154E39900D51880 /* libpjmedia-arm-apple-darwin9.a */; };
+		3A34794D1154E39900D51880 /* libpjmedia-audiodev-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A34794C1154E39900D51880 /* libpjmedia-audiodev-arm-apple-darwin9.a */; };
+		3A34794F1154E3F000D51880 /* libpjsip-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A34794E1154E3F000D51880 /* libpjsip-arm-apple-darwin9.a */; };
+		3A3479511154E42400D51880 /* libpjsip-simple-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A3479501154E42400D51880 /* libpjsip-simple-arm-apple-darwin9.a */; };
+		3A3479531154E42400D51880 /* libpjsip-ua-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A3479521154E42400D51880 /* libpjsip-ua-arm-apple-darwin9.a */; };
+		3A3479551154E42400D51880 /* libpjsua-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A3479541154E42400D51880 /* libpjsua-arm-apple-darwin9.a */; };
+		3A34795B1154E45A00D51880 /* libpj-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A34795A1154E45A00D51880 /* libpj-arm-apple-darwin9.a */; };
+		3A34795D1154E48700D51880 /* libpjlib-util-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A34795C1154E48700D51880 /* libpjlib-util-arm-apple-darwin9.a */; };
+		3A3479791154EBDE00D51880 /* libpjmedia-codec-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A3479781154EBDE00D51880 /* libpjmedia-codec-arm-apple-darwin9.a */; };
+		3A34797B1154EBDE00D51880 /* libpjnath-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A34797A1154EBDE00D51880 /* libpjnath-arm-apple-darwin9.a */; };
+		3A3479871154EC4E00D51880 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A3479861154EC4E00D51880 /* AudioToolbox.framework */; };
+		3A34799A1154ECA300D51880 /* libgsmcodec-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A3479991154ECA300D51880 /* libgsmcodec-arm-apple-darwin9.a */; };
+		3A34799C1154ECB100D51880 /* libresample-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A34799B1154ECB100D51880 /* libresample-arm-apple-darwin9.a */; };
+		3ABE0507147CA00B00A57A62 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3ABE0506147CA00B00A57A62 /* CFNetwork.framework */; };
+		3AC6435E1162192900B7A751 /* tock8.wav in Resources */ = {isa = PBXBuildFile; fileRef = 3AC6435D1162192900B7A751 /* tock8.wav */; };
+		3ADA4AB911572300008D95FE /* input.8.wav in Resources */ = {isa = PBXBuildFile; fileRef = 3ADA4AB811572300008D95FE /* input.8.wav */; };
+		3AE90E9B115F7A4F00FAEAA5 /* libg7221codec-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE90E95115F7A4E00FAEAA5 /* libg7221codec-arm-apple-darwin9.a */; };
+		3AE90E9C115F7A4F00FAEAA5 /* libilbccodec-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE90E96115F7A4F00FAEAA5 /* libilbccodec-arm-apple-darwin9.a */; };
+		3AE90E9D115F7A4F00FAEAA5 /* libmilenage-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE90E97115F7A4F00FAEAA5 /* libmilenage-arm-apple-darwin9.a */; };
+		3AE90E9E115F7A4F00FAEAA5 /* libpjsdp-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE90E98115F7A4F00FAEAA5 /* libpjsdp-arm-apple-darwin9.a */; };
+		3AE90E9F115F7A4F00FAEAA5 /* libspeex-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE90E99115F7A4F00FAEAA5 /* libspeex-arm-apple-darwin9.a */; };
+		3AE90EA0115F7A4F00FAEAA5 /* libsrtp-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE90E9A115F7A4F00FAEAA5 /* libsrtp-arm-apple-darwin9.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+		1D3623240D0F684500981E51 /* ipjsystestAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipjsystestAppDelegate.h; sourceTree = "<group>"; };
+		1D3623250D0F684500981E51 /* ipjsystestAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ipjsystestAppDelegate.m; sourceTree = "<group>"; };
+		1D6058910D05DD3D006BFB54 /* ipjsystest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ipjsystest.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+		2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+		28A0AAE50D9B0CCF005BE974 /* ipjsystest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipjsystest_Prefix.pch; sourceTree = "<group>"; };
+		28AD735F0D9D9599002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = "<group>"; };
+		28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = "<group>"; };
+		28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = "<group>"; };
+		28F335F01007B36200424DE2 /* RootViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RootViewController.xib; sourceTree = "<group>"; };
+		29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		3A3478A91154BF8E00D51880 /* TestViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TestViewController.xib; sourceTree = "<group>"; };
+		3A3478AD1154BFD700D51880 /* TestViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestViewController.h; sourceTree = "<group>"; };
+		3A3478AE1154BFD700D51880 /* TestViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestViewController.m; sourceTree = "<group>"; };
+		3A3479211154DB0800D51880 /* systest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = systest.c; path = ../pjsystest/systest.c; sourceTree = SOURCE_ROOT; };
+		3A34794A1154E39900D51880 /* libpjmedia-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjmedia-arm-apple-darwin9.a"; path = "../../../pjmedia/lib/libpjmedia-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A34794C1154E39900D51880 /* libpjmedia-audiodev-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjmedia-audiodev-arm-apple-darwin9.a"; path = "../../../pjmedia/lib/libpjmedia-audiodev-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A34794E1154E3F000D51880 /* libpjsip-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsip-arm-apple-darwin9.a"; path = "../../../pjsip/lib/libpjsip-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A3479501154E42400D51880 /* libpjsip-simple-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsip-simple-arm-apple-darwin9.a"; path = "../../../pjsip/lib/libpjsip-simple-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A3479521154E42400D51880 /* libpjsip-ua-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsip-ua-arm-apple-darwin9.a"; path = "../../../pjsip/lib/libpjsip-ua-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A3479541154E42400D51880 /* libpjsua-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsua-arm-apple-darwin9.a"; path = "../../../pjsip/lib/libpjsua-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A34795A1154E45A00D51880 /* libpj-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpj-arm-apple-darwin9.a"; path = "../../../pjlib/lib/libpj-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A34795C1154E48700D51880 /* libpjlib-util-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjlib-util-arm-apple-darwin9.a"; path = "../../../pjlib-util/lib/libpjlib-util-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A3479721154EB5B00D51880 /* gui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gui.h; path = ../pjsystest/gui.h; sourceTree = SOURCE_ROOT; };
+		3A3479731154EB6B00D51880 /* systest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = systest.h; path = ../pjsystest/systest.h; sourceTree = SOURCE_ROOT; };
+		3A3479781154EBDE00D51880 /* libpjmedia-codec-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjmedia-codec-arm-apple-darwin9.a"; path = "../../../pjmedia/lib/libpjmedia-codec-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A34797A1154EBDE00D51880 /* libpjnath-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjnath-arm-apple-darwin9.a"; path = "../../../pjnath/lib/libpjnath-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A3479861154EC4E00D51880 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+		3A3479991154ECA300D51880 /* libgsmcodec-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libgsmcodec-arm-apple-darwin9.a"; path = "../../../third_party/lib/libgsmcodec-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3A34799B1154ECB100D51880 /* libresample-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libresample-arm-apple-darwin9.a"; path = "../../../third_party/lib/libresample-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3ABE0506147CA00B00A57A62 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
+		3AC6435D1162192900B7A751 /* tock8.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = tock8.wav; path = ../../../tests/pjsua/wavs/tock8.wav; sourceTree = SOURCE_ROOT; };
+		3ADA4AB811572300008D95FE /* input.8.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = input.8.wav; path = "../../../../../../../../teluu/pjproject-new-iphone/tests/pjsua/wavs/input.8.wav"; sourceTree = BUILT_PRODUCTS_DIR; };
+		3AE90E95115F7A4E00FAEAA5 /* libg7221codec-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libg7221codec-arm-apple-darwin9.a"; path = "../../../third_party/lib/libg7221codec-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3AE90E96115F7A4F00FAEAA5 /* libilbccodec-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libilbccodec-arm-apple-darwin9.a"; path = "../../../third_party/lib/libilbccodec-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3AE90E97115F7A4F00FAEAA5 /* libmilenage-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmilenage-arm-apple-darwin9.a"; path = "../../../third_party/lib/libmilenage-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3AE90E98115F7A4F00FAEAA5 /* libpjsdp-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsdp-arm-apple-darwin9.a"; path = "../../../pjmedia/lib/libpjsdp-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3AE90E99115F7A4F00FAEAA5 /* libspeex-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libspeex-arm-apple-darwin9.a"; path = "../../../third_party/lib/libspeex-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		3AE90E9A115F7A4F00FAEAA5 /* libsrtp-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libsrtp-arm-apple-darwin9.a"; path = "../../../third_party/lib/libsrtp-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
+		8D1107310486CEB800E47090 /* ipjsystest-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ipjsystest-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
+				1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
+				2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */,
+				3A34794B1154E39900D51880 /* libpjmedia-arm-apple-darwin9.a in Frameworks */,
+				3A34794D1154E39900D51880 /* libpjmedia-audiodev-arm-apple-darwin9.a in Frameworks */,
+				3A34794F1154E3F000D51880 /* libpjsip-arm-apple-darwin9.a in Frameworks */,
+				3A3479511154E42400D51880 /* libpjsip-simple-arm-apple-darwin9.a in Frameworks */,
+				3A3479531154E42400D51880 /* libpjsip-ua-arm-apple-darwin9.a in Frameworks */,
+				3A3479551154E42400D51880 /* libpjsua-arm-apple-darwin9.a in Frameworks */,
+				3A34795B1154E45A00D51880 /* libpj-arm-apple-darwin9.a in Frameworks */,
+				3A34795D1154E48700D51880 /* libpjlib-util-arm-apple-darwin9.a in Frameworks */,
+				3A3479791154EBDE00D51880 /* libpjmedia-codec-arm-apple-darwin9.a in Frameworks */,
+				3A34797B1154EBDE00D51880 /* libpjnath-arm-apple-darwin9.a in Frameworks */,
+				3A3479871154EC4E00D51880 /* AudioToolbox.framework in Frameworks */,
+				3A34799A1154ECA300D51880 /* libgsmcodec-arm-apple-darwin9.a in Frameworks */,
+				3A34799C1154ECB100D51880 /* libresample-arm-apple-darwin9.a in Frameworks */,
+				3AE90E9B115F7A4F00FAEAA5 /* libg7221codec-arm-apple-darwin9.a in Frameworks */,
+				3AE90E9C115F7A4F00FAEAA5 /* libilbccodec-arm-apple-darwin9.a in Frameworks */,
+				3AE90E9D115F7A4F00FAEAA5 /* libmilenage-arm-apple-darwin9.a in Frameworks */,
+				3AE90E9E115F7A4F00FAEAA5 /* libpjsdp-arm-apple-darwin9.a in Frameworks */,
+				3AE90E9F115F7A4F00FAEAA5 /* libspeex-arm-apple-darwin9.a in Frameworks */,
+				3AE90EA0115F7A4F00FAEAA5 /* libsrtp-arm-apple-darwin9.a in Frameworks */,
+				3ABE0507147CA00B00A57A62 /* CFNetwork.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		080E96DDFE201D6D7F000001 /* Classes */ = {
+			isa = PBXGroup;
+			children = (
+				3A3478AD1154BFD700D51880 /* TestViewController.h */,
+				3A3478AE1154BFD700D51880 /* TestViewController.m */,
+				28C286DF0D94DF7D0034E888 /* RootViewController.h */,
+				28C286E00D94DF7D0034E888 /* RootViewController.m */,
+				1D3623240D0F684500981E51 /* ipjsystestAppDelegate.h */,
+				1D3623250D0F684500981E51 /* ipjsystestAppDelegate.m */,
+			);
+			path = Classes;
+			sourceTree = "<group>";
+		};
+		19C28FACFE9D520D11CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				1D6058910D05DD3D006BFB54 /* ipjsystest.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
+			isa = PBXGroup;
+			children = (
+				080E96DDFE201D6D7F000001 /* Classes */,
+				29B97315FDCFA39411CA2CEA /* Other Sources */,
+				29B97317FDCFA39411CA2CEA /* Resources */,
+				29B97323FDCFA39411CA2CEA /* Frameworks */,
+				3A3479941154EC6B00D51880 /* Libraries */,
+				19C28FACFE9D520D11CA2CBB /* Products */,
+			);
+			name = CustomTemplate;
+			sourceTree = "<group>";
+		};
+		29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+			isa = PBXGroup;
+			children = (
+				3A3479201154DAE600D51880 /* pjsystest */,
+				28A0AAE50D9B0CCF005BE974 /* ipjsystest_Prefix.pch */,
+				29B97316FDCFA39411CA2CEA /* main.m */,
+			);
+			name = "Other Sources";
+			sourceTree = "<group>";
+		};
+		29B97317FDCFA39411CA2CEA /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				3AC6435D1162192900B7A751 /* tock8.wav */,
+				3ADA4AB811572300008D95FE /* input.8.wav */,
+				3A3478A91154BF8E00D51880 /* TestViewController.xib */,
+				28F335F01007B36200424DE2 /* RootViewController.xib */,
+				28AD735F0D9D9599002E5188 /* MainWindow.xib */,
+				8D1107310486CEB800E47090 /* ipjsystest-Info.plist */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				3ABE0506147CA00B00A57A62 /* CFNetwork.framework */,
+				3A3479861154EC4E00D51880 /* AudioToolbox.framework */,
+				1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
+				1D30AB110D05D00D00671497 /* Foundation.framework */,
+				2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		3A3479201154DAE600D51880 /* pjsystest */ = {
+			isa = PBXGroup;
+			children = (
+				3A3479731154EB6B00D51880 /* systest.h */,
+				3A3479721154EB5B00D51880 /* gui.h */,
+				3A3479211154DB0800D51880 /* systest.c */,
+			);
+			name = pjsystest;
+			sourceTree = "<group>";
+		};
+		3A3479941154EC6B00D51880 /* Libraries */ = {
+			isa = PBXGroup;
+			children = (
+				3AE90E95115F7A4E00FAEAA5 /* libg7221codec-arm-apple-darwin9.a */,
+				3AE90E96115F7A4F00FAEAA5 /* libilbccodec-arm-apple-darwin9.a */,
+				3AE90E97115F7A4F00FAEAA5 /* libmilenage-arm-apple-darwin9.a */,
+				3AE90E98115F7A4F00FAEAA5 /* libpjsdp-arm-apple-darwin9.a */,
+				3AE90E99115F7A4F00FAEAA5 /* libspeex-arm-apple-darwin9.a */,
+				3AE90E9A115F7A4F00FAEAA5 /* libsrtp-arm-apple-darwin9.a */,
+				3A3479991154ECA300D51880 /* libgsmcodec-arm-apple-darwin9.a */,
+				3A34799B1154ECB100D51880 /* libresample-arm-apple-darwin9.a */,
+				3A34794A1154E39900D51880 /* libpjmedia-arm-apple-darwin9.a */,
+				3A34794C1154E39900D51880 /* libpjmedia-audiodev-arm-apple-darwin9.a */,
+				3A34794E1154E3F000D51880 /* libpjsip-arm-apple-darwin9.a */,
+				3A3479501154E42400D51880 /* libpjsip-simple-arm-apple-darwin9.a */,
+				3A3479521154E42400D51880 /* libpjsip-ua-arm-apple-darwin9.a */,
+				3A3479541154E42400D51880 /* libpjsua-arm-apple-darwin9.a */,
+				3A34795A1154E45A00D51880 /* libpj-arm-apple-darwin9.a */,
+				3A34795C1154E48700D51880 /* libpjlib-util-arm-apple-darwin9.a */,
+				3A3479781154EBDE00D51880 /* libpjmedia-codec-arm-apple-darwin9.a */,
+				3A34797A1154EBDE00D51880 /* libpjnath-arm-apple-darwin9.a */,
+			);
+			name = Libraries;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		1D6058900D05DD3D006BFB54 /* ipjsystest */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "ipjsystest" */;
+			buildPhases = (
+				1D60588D0D05DD3D006BFB54 /* Resources */,
+				1D60588E0D05DD3D006BFB54 /* Sources */,
+				1D60588F0D05DD3D006BFB54 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = ipjsystest;
+			productName = ipjsystest;
+			productReference = 1D6058910D05DD3D006BFB54 /* ipjsystest.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		29B97313FDCFA39411CA2CEA /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				ORGANIZATIONNAME = Teluu;
+			};
+			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ipjsystest" */;
+			compatibilityVersion = "Xcode 3.1";
+			developmentRegion = English;
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				English,
+				Japanese,
+				French,
+				German,
+				en,
+			);
+			mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				1D6058900D05DD3D006BFB54 /* ipjsystest */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		1D60588D0D05DD3D006BFB54 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */,
+				28F335F11007B36200424DE2 /* RootViewController.xib in Resources */,
+				3A3478AA1154BF8E00D51880 /* TestViewController.xib in Resources */,
+				3ADA4AB911572300008D95FE /* input.8.wav in Resources */,
+				3AC6435E1162192900B7A751 /* tock8.wav in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		1D60588E0D05DD3D006BFB54 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				1D60589B0D05DD56006BFB54 /* main.m in Sources */,
+				1D3623260D0F684500981E51 /* ipjsystestAppDelegate.m in Sources */,
+				28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */,
+				3A3478AF1154BFD700D51880 /* TestViewController.m in Sources */,
+				3A3479221154DB0800D51880 /* systest.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		1D6058940D05DD3E006BFB54 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = ipjsystest_Prefix.pch;
+				GCC_PREPROCESSOR_DEFINITIONS = "PJ_AUTOCONF=1";
+				INFOPLIST_FILE = "ipjsystest-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)/../../../pjmedia/lib\"",
+					"\"$(SRCROOT)/../../../pjsip/lib\"",
+					"\"$(SRCROOT)/../../../pjlib/lib\"",
+					"\"$(SRCROOT)/../../../pjlib-util/lib\"",
+					"\"$(SRCROOT)/../../../pjnath/lib\"",
+					"\"$(SRCROOT)/../../../third_party/lib\"",
+				);
+				PRODUCT_NAME = ipjsystest;
+				SDKROOT = iphoneos;
+			};
+			name = Debug;
+		};
+		1D6058950D05DD3E006BFB54 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = YES;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = ipjsystest_Prefix.pch;
+				GCC_PREPROCESSOR_DEFINITIONS = "PJ_AUTOCONF=1";
+				INFOPLIST_FILE = "ipjsystest-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)/../../../pjmedia/lib\"",
+					"\"$(SRCROOT)/../../../pjsip/lib\"",
+					"\"$(SRCROOT)/../../../pjlib/lib\"",
+					"\"$(SRCROOT)/../../../pjlib-util/lib\"",
+					"\"$(SRCROOT)/../../../pjnath/lib\"",
+					"\"$(SRCROOT)/../../../third_party/lib\"",
+				);
+				PRODUCT_NAME = ipjsystest;
+				SDKROOT = iphoneos;
+			};
+			name = Release;
+		};
+		C01FCF4F08A954540054247B /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					../../../pjsip/include,
+					../../../pjlib/include,
+					"../../../pjlib-util/include",
+					../../../pjnath/include,
+					../../../pjmedia/include,
+				);
+				LIBRARY_SEARCH_PATHS = (
+					../../../pjlib/lib,
+					"../../../pjlib-util/lib",
+					../../../pjnath/lib,
+					../../../pjmedia/lib,
+					../../../pjsip/lib,
+					../../../third_party/lib,
+				);
+				PREBINDING = NO;
+				SDKROOT = iphoneos4.0;
+			};
+			name = Debug;
+		};
+		C01FCF5008A954540054247B /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					../../../pjsip/include,
+					../../../pjlib/include,
+					"../../../pjlib-util/include",
+					../../../pjnath/include,
+					../../../pjmedia/include,
+				);
+				LIBRARY_SEARCH_PATHS = (
+					../../../pjlib/lib,
+					"../../../pjlib-util/lib",
+					../../../pjnath/lib,
+					../../../pjmedia/lib,
+					../../../pjsip/lib,
+					../../../third_party/lib,
+				);
+				PREBINDING = NO;
+				SDKROOT = iphoneos4.0;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "ipjsystest" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1D6058940D05DD3E006BFB54 /* Debug */,
+				1D6058950D05DD3E006BFB54 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ipjsystest" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				C01FCF4F08A954540054247B /* Debug */,
+				C01FCF5008A954540054247B /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/ipjsystest_Prefix.pch b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/ipjsystest_Prefix.pch
new file mode 100644
index 0000000..8f7b754
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/ipjsystest_Prefix.pch
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'ipjsystest' target in the 'ipjsystest' project
+//
+#import <Availability.h>
+
+#ifndef __IPHONE_3_0
+#warning "This project uses features only available in iPhone SDK 3.0 and later."
+#endif
+
+
+#ifdef __OBJC__
+    #import <Foundation/Foundation.h>
+    #import <UIKit/UIKit.h>
+#endif
diff --git a/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/main.m b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/main.m
new file mode 100644
index 0000000..186fe8a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/ipjsystest/main.m
@@ -0,0 +1,27 @@
+/* $Id: main.m 3552 2011-05-05 05:50:48Z nanang $ */
+/* 
+ * Copyright (C) 2010-2011 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 
+ */
+#import <UIKit/UIKit.h>
+
+int main(int argc, char *argv[]) {
+    
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+    int retVal = UIApplicationMain(argc, argv, nil, nil);
+    [pool release];
+    return retVal;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/AndroidManifest.xml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/AndroidManifest.xml
new file mode 100644
index 0000000..e5a0088
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.pjsip.pjsua"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="15"
+        android:targetSdkVersion="15" />
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.USE_SIP" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.CAMERA" />
+
+    <uses-feature
+        android:name="android.hardware.microphone"
+        android:required="true" />
+
+    <application
+        android:icon="@drawable/main_image"
+        android:label="@string/app_name"
+        android:theme="@android:style/Theme.DeviceDefault.NoActionBar" >
+        <activity
+            android:name=".MainActivity"
+            android:windowSoftInputMode="stateHidden"
+            android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/Android.mk b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/Android.mk
new file mode 100644
index 0000000..b1f99af
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/Android.mk
@@ -0,0 +1,38 @@
+# $Id$
+
+LOCAL_PATH	:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# Get PJ build settings
+include ../../../../build.mak
+include $(PJDIR)/build/common.mak
+
+# Path to SWIG
+MY_SWIG		:= swig
+
+MY_MODULE_PATH  := $(PJDIR)/pjsip-apps/build/output/pjsua-$(TARGET_NAME)
+MY_MODULES      := $(MY_MODULE_PATH)/pjsua_app.o \
+		   $(MY_MODULE_PATH)/pjsua_app_cli.o \
+		   $(MY_MODULE_PATH)/pjsua_app_common.o \
+		   $(MY_MODULE_PATH)/pjsua_app_config.o \
+		   $(MY_MODULE_PATH)/pjsua_app_legacy.o
+
+# Constants
+MY_JNI_WRAP	:= pjsua_wrap.cpp
+MY_JNI_DIR	:= jni
+
+# Android build settings
+LOCAL_MODULE    := libpjsua
+LOCAL_CFLAGS    := -Werror $(APP_CFLAGS) -frtti
+LOCAL_LDFLAGS   := $(APP_LDFLAGS)
+LOCAL_LDLIBS    := $(MY_MODULES) $(APP_LDLIBS)
+LOCAL_SRC_FILES := $(MY_JNI_WRAP) pjsua_app_callback.cpp
+
+# Invoke SWIG
+$(MY_JNI_DIR)/$(MY_JNI_WRAP):
+	@echo "Invoking SWIG..."
+	$(MY_SWIG) -c++ -o $(MY_JNI_DIR)/$(MY_JNI_WRAP) -package org.pjsip.pjsua -outdir src/org/pjsip/pjsua -java $(MY_JNI_DIR)/pjsua.i
+
+.PHONY: $(MY_JNI_DIR)/$(MY_JNI_WRAP)
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/pjsua.i b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/pjsua.i
new file mode 100755
index 0000000..9944316
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/pjsua.i
@@ -0,0 +1,29 @@
+%module (directors="1") pjsua
+
+%{
+#include "pjsua_app_callback.h"
+#include "../../pjsua_app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+	int pjsuaStart();
+	void pjsuaDestroy();
+	int pjsuaRestart();
+	void setCallbackObject(PjsuaAppCallback* callback);	
+#ifdef __cplusplus
+}
+#endif
+%}
+
+int pjsuaStart();
+void pjsuaDestroy();
+int pjsuaRestart();
+
+/* turn on director wrapping PjsuaAppCallback */
+%feature("director") PjsuaAppCallback;
+
+%include "pjsua_app_callback.h"
+
+void setCallbackObject(PjsuaAppCallback* callback);
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.cpp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.cpp
new file mode 100644
index 0000000..6268b55
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.cpp
@@ -0,0 +1,113 @@
+/* $Id: pjsua_app_callback.cpp $ */
+/* 
+ * Copyright (C) 2012-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 "pjsua_app_callback.h"
+#include "../../pjsua_app.h"
+#include "../../pjsua_app_config.h"
+
+#if defined(PJ_ANDROID) && PJ_ANDROID != 0
+
+static PjsuaAppCallback* registeredCallbackObject = NULL;
+static pjsua_app_cfg_t android_app_config;
+static int restart_argc;
+static char **restart_argv;
+
+extern const char *pjsua_app_def_argv[];
+
+#define THIS_FILE	"pjsua_app_callback.cpp"
+
+/** Callback wrapper **/
+void on_cli_started(pj_status_t status, const char *msg)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    if (registeredCallbackObject) {
+	if ((status != PJ_SUCCESS) && (!msg || !*msg)) {
+	    pj_strerror(status, errmsg, sizeof(errmsg));
+	    msg = errmsg;
+	}
+	registeredCallbackObject->onStarted(msg);
+    }
+}
+
+void on_cli_stopped(pj_bool_t restart, int argc, char **argv)
+{
+    if (restart) {
+	restart_argc = argc;
+	restart_argv = argv;
+    }
+
+    if (registeredCallbackObject) {
+	registeredCallbackObject->onStopped(restart);
+    }
+}
+
+static int initMain(int argc, char **argv)
+{
+    pj_status_t status;
+    android_app_config.argc = argc;
+    android_app_config.argv = argv;
+
+    status = pjsua_app_init(&android_app_config);
+    if (status == PJ_SUCCESS) {
+	status = pjsua_app_run(PJ_FALSE);
+    } else {
+	pjsua_app_destroy();
+    }
+
+    return status;
+}
+
+int pjsuaStart()
+{
+    pj_status_t status;
+
+    const char **argv = pjsua_app_def_argv;
+    int argc = pjsua_app_def_argc;
+
+    pj_bzero(&android_app_config, sizeof(android_app_config));
+
+    android_app_config.on_started = &on_cli_started;
+    android_app_config.on_stopped = &on_cli_stopped;
+
+    return initMain(argc, (char**)argv);
+}
+
+void pjsuaDestroy()
+{
+    pjsua_app_destroy();
+
+    /** This is on purpose **/
+    pjsua_app_destroy();
+}
+
+int pjsuaRestart()
+{
+    pj_status_t status;
+
+    pjsuaDestroy();
+
+    return initMain(restart_argc, restart_argv);
+}
+
+void setCallbackObject(PjsuaAppCallback* callback)
+{
+    registeredCallbackObject = callback;
+}
+
+#endif
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.h
new file mode 100644
index 0000000..561b5ce
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/jni/pjsua_app_callback.h
@@ -0,0 +1,36 @@
+/* $Id: pjsua_app_callback.h $ */
+/*
+ * Copyright (C) 2008-2011 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 __PJSUA_APP_CALLBACK_H__
+#define __PJSUA_APP_CALLBACK_H__
+
+class PjsuaAppCallback {
+public:
+    virtual ~PjsuaAppCallback() {}
+    virtual void onStarted(const char *msg) {}
+    virtual void onStopped(int restart) {}
+};
+
+extern "C" {
+int pjsuaStart();
+void pjsuaDestroy();
+int pjsuaRestart();
+void setCallbackObject(PjsuaAppCallback* callback);
+}
+
+#endif /* __PJSUA_APP_CALLBACK_H__ */
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/lint.xml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/lint.xml
new file mode 100644
index 0000000..ee0eead
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/lint.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+</lint>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/proguard-project.txt b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/project.properties b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/project.properties
new file mode 100644
index 0000000..9b84a6b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-16
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-hdpi/main_image.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-hdpi/main_image.png
new file mode 100755
index 0000000..a9c5328
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-hdpi/main_image.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-ldpi/main_image.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-ldpi/main_image.png
new file mode 100755
index 0000000..969971f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-ldpi/main_image.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-mdpi/main_image.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-mdpi/main_image.png
new file mode 100755
index 0000000..8312fcf
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-mdpi/main_image.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-xhdpi/main_image.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-xhdpi/main_image.png
new file mode 100755
index 0000000..9978b0a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/drawable-xhdpi/main_image.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/layout/activity_main.xml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/layout/activity_main.xml
new file mode 100644
index 0000000..da258b7
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/layout/activity_main.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+    <ImageView
+        android:id="@+id/imageApp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/textApp"
+        android:layout_centerHorizontal="true"
+        android:contentDescription="@string/app_name"
+        android:src="@drawable/main_image" />
+
+    <TextView
+        android:id="@+id/textApp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:text="@string/app_name"
+        android:textSize="40sp"
+        android:typeface="serif" />
+
+    <TextView
+        android:id="@+id/textStatus"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true" 
+        android:textIsSelectable="false"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values-v11/styles.xml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values-v11/styles.xml
new file mode 100644
index 0000000..d408cbc
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values-v11/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values-v14/styles.xml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values-v14/styles.xml
new file mode 100644
index 0000000..1c089a7
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values-v14/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values/strings.xml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values/strings.xml
new file mode 100644
index 0000000..dd5ee69
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values/strings.xml
@@ -0,0 +1,6 @@
+<resources>
+
+    <string name="app_name">pjsua</string>
+    <string name="title_activity_main">MainActivity</string>
+
+</resources>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values/styles.xml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values/styles.xml
new file mode 100644
index 0000000..4dba0d0
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/res/values/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/src/org/pjsip/pjsua/MainActivity.java b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/src/org/pjsip/pjsua/MainActivity.java
new file mode 100644
index 0000000..aa0f987
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/android/src/org/pjsip/pjsua/MainActivity.java
@@ -0,0 +1,242 @@
+/* $Id: MainActivity.java $ */
+/*
+ * Copyright (C) 2008-2011 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
+ */
+
+package org.pjsip.pjsua;
+
+import java.lang.ref.WeakReference;
+
+import android.app.Activity;
+import android.content.pm.ApplicationInfo;
+import android.os.Bundle;
+import android.util.Log;
+import android.os.Handler;
+import android.os.Message;
+import android.widget.TextView;
+
+class CONST {
+	public static final String LIB_FILENAME = "pjsua";
+	public static final String TAG = "pjsua";
+	public static final Boolean AUTOKILL_ON_FINISH = true;
+	public enum MSG_TYPE {
+		STR_DEBUG,
+		STR_INFO,
+		STR_ERROR,
+		CLI_STOP,
+		CLI_RESTART,
+		QUIT
+	};	
+}
+
+class LOG {
+	public static void DEBUG(Handler h, String str) {
+		Message msg = Message.obtain(h, CONST.MSG_TYPE.STR_DEBUG.ordinal(), 
+									 str);
+		msg.sendToTarget();
+	}	
+	public static void INFO(Handler h, String str) {
+		Message msg = Message.obtain(h, CONST.MSG_TYPE.STR_INFO.ordinal(), 
+									 str);
+		msg.sendToTarget();
+	}
+	public static void ERROR(Handler h, String str) {
+		Message msg = Message.obtain(h, CONST.MSG_TYPE.STR_ERROR.ordinal(), 
+									 str);
+		msg.sendToTarget();
+	}
+}
+
+public class MainActivity extends Activity {
+	private MyHandler ui_handler = new MyHandler(this);
+	private static MyCallback callback;
+	
+	private static class MyHandler extends Handler {
+		private final WeakReference<MainActivity> mTarget;
+		
+		public MyHandler(MainActivity target) {
+			mTarget = new WeakReference<MainActivity>(target); 
+		}
+		
+		@Override
+		public void handleMessage(Message m) {
+			MainActivity target = mTarget.get();
+			if (target == null)
+				return;
+			
+			if (m.what == CONST.MSG_TYPE.STR_DEBUG.ordinal()) {
+				Log.d(CONST.TAG, (String)m.obj);	
+			} else if (m.what == CONST.MSG_TYPE.STR_INFO.ordinal()) {
+				target.updateStatus((String)m.obj);
+				Log.i(CONST.TAG, (String)m.obj);				
+			} else if (m.what == CONST.MSG_TYPE.STR_ERROR.ordinal()) {
+				target.updateStatus((String)m.obj);
+				Log.e(CONST.TAG, (String)m.obj);
+			} else if (m.what == CONST.MSG_TYPE.CLI_STOP.ordinal()) {
+				pjsua.pjsuaDestroy();
+				LOG.INFO(this, "Telnet Unavailable");
+			} else if (m.what == CONST.MSG_TYPE.CLI_RESTART.ordinal()) {
+				int status = pjsua.pjsuaRestart();
+				if (status != 0) {
+					LOG.INFO(this, "Failed restarting telnet");
+				}
+			} else if (m.what == CONST.MSG_TYPE.QUIT.ordinal()) {
+				target.finish();
+				System.gc();
+				android.os.Process.killProcess(android.os.Process.myPid());
+			}
+		}
+    }
+	
+	/** Callback object **/
+	private static class MyCallback extends PjsuaAppCallback {
+		private WeakReference<Handler> ui_handler;
+		
+		public MyCallback(Handler in_ui_handler) {
+			set_ui_handler(in_ui_handler);			
+		}
+		
+		public void set_ui_handler(Handler in_ui_handler) {
+			ui_handler = new WeakReference<Handler>(in_ui_handler);
+		}		
+		
+		@Override
+	    public void onStarted(String msg) {
+			Handler ui = ui_handler.get();
+			LOG.INFO(ui, msg);			
+		}
+		
+		@Override
+	    public void onStopped(int restart) {
+			Handler ui = ui_handler.get();
+			/** Use timer to stopped/restart **/
+			if (restart != 0) {
+				LOG.INFO(ui, "Telnet Restarting");
+				Message msg = Message.obtain(ui, 
+										  CONST.MSG_TYPE.CLI_RESTART.ordinal());
+				ui.sendMessageDelayed(msg, 100);
+			} else {
+				LOG.INFO(ui, "Telnet Stopping");
+				Message msg = Message.obtain(ui, 
+											 CONST.MSG_TYPE.CLI_STOP.ordinal());
+				ui.sendMessageDelayed(msg, 100);
+			}
+		}
+	}
+	
+	private void updateStatus(String output) {
+        TextView tStatus = (TextView) findViewById(R.id.textStatus);
+        tStatus.setText(output);        
+	}
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+    	LOG.DEBUG(ui_handler, "=== Activity::onCreate() ===");
+    	super.onCreate(savedInstanceState);
+    	
+    	init_view();
+
+    	init_lib();
+	}
+
+    @Override
+    protected void onStart() {
+    	LOG.DEBUG(ui_handler, "=== Activity::onStart() ===");
+    	super.onStart();
+    }
+    
+    @Override
+    protected void onRestart() {
+    	LOG.DEBUG(ui_handler, "=== Activity::onRestart() ===");
+    	super.onRestart();
+    }
+
+    @Override
+    protected void onResume() {
+    	LOG.DEBUG(ui_handler, "=== Activity::onResume() ===");
+    	super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+    	LOG.DEBUG(ui_handler, "=== Activity::onPause() ===");
+    	super.onPause();
+    }
+
+    @Override
+    protected void onStop() {
+    	LOG.DEBUG(ui_handler, "=== Activity::onStop() ===");
+    	super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+    	LOG.DEBUG(ui_handler, "=== Activity::onDestroy() ===");
+    	super.onDestroy();
+    }
+    
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+		super.onSaveInstanceState(outState);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+		super.onRestoreInstanceState(savedInstanceState);
+    }
+    
+	private void init_view() {
+    	setContentView(R.layout.activity_main);
+	}
+	
+	private int init_lib() {        
+		LOG.INFO(ui_handler, "Loading module...");
+		try {
+			System.loadLibrary(CONST.LIB_FILENAME);
+		} catch (UnsatisfiedLinkError e) {
+			LOG.ERROR(ui_handler, "UnsatisfiedLinkError: " + e.getMessage());
+			return -1;
+		}
+		
+		// Wait for GDB to init
+		if ((getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) 
+		{
+			try {
+				Thread.sleep(5000);
+	        } catch (InterruptedException e) {
+	        	LOG.ERROR(ui_handler, "InterruptedException: " + 
+	        			  e.getMessage());
+	        }
+		}
+		
+		// Set callback object
+		if (callback == null)
+			callback = new MyCallback(ui_handler);
+		
+		pjsua.setCallbackObject(callback);
+
+		LOG.INFO(ui_handler, "Starting module..");
+
+		int rc = pjsua.pjsuaStart();
+        
+		if (rc != 0) {
+			LOG.INFO(ui_handler, "Failed starting telnet");
+		}
+		
+		return 0;
+	}
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/.cproject b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/.cproject
new file mode 100644
index 0000000..b4161a4
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/.cproject
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.qnx.qcc.toolChain.1397290099">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.toolChain.1397290099" moduleId="org.eclipse.cdt.core.settings" name="Device-Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildProperties="" description="" id="com.qnx.qcc.toolChain.1397290099" name="Device-Debug" parent="org.eclipse.cdt.build.core.emptycfg">
+					<folderInfo id="com.qnx.qcc.toolChain.1397290099.1659648293" name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.790780694" name="com.qnx.qcc.toolChain" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.os.1073596392" name="Target OS:" superClass="com.qnx.qcc.option.os"/>
+							<option id="com.qnx.qcc.option.cpu.445652033" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
+							<option id="com.qnx.qcc.option.compiler.278023129" name="Compiler:" superClass="com.qnx.qcc.option.compiler"/>
+							<option id="com.qnx.qcc.option.runtime.160497848" name="Runtime:" superClass="com.qnx.qcc.option.runtime"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1555299200" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder autoBuildTarget="Device-Debug" enableAutoBuild="false" id="com.qnx.qcc.toolChain.1397290099.290481886" incrementalBuildTarget="Device-Debug" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
+							<tool id="com.qnx.qcc.tool.compiler.2070167245" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.270041523" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<inputType id="com.qnx.qcc.inputType.compiler.2061152979" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.788884401" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<inputType id="com.qnx.qcc.inputType.assembler.361985539" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.367677280" name="QCC Linker" superClass="com.qnx.qcc.tool.linker"/>
+							<tool id="com.qnx.qcc.tool.archiver.44861338" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.toolChain.2079401108">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.toolChain.2079401108" moduleId="org.eclipse.cdt.core.settings" name="Device-Release">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildProperties="" description="" id="com.qnx.qcc.toolChain.2079401108" name="Device-Release" parent="org.eclipse.cdt.build.core.emptycfg">
+					<folderInfo id="com.qnx.qcc.toolChain.2079401108.1026133684" name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.1240537150" name="com.qnx.qcc.toolChain" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.os.1756939211" name="Target OS:" superClass="com.qnx.qcc.option.os"/>
+							<option id="com.qnx.qcc.option.cpu.751904034" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
+							<option id="com.qnx.qcc.option.compiler.1111407921" name="Compiler:" superClass="com.qnx.qcc.option.compiler"/>
+							<option id="com.qnx.qcc.option.runtime.1247073904" name="Runtime:" superClass="com.qnx.qcc.option.runtime"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1300126991" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder autoBuildTarget="Device-Release" enableAutoBuild="true" id="com.qnx.qcc.toolChain.2079401108.467426564" incrementalBuildTarget="Device-Release" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
+							<tool id="com.qnx.qcc.tool.compiler.115320452" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.77840692" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<inputType id="com.qnx.qcc.inputType.compiler.153511514" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.256115398" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<inputType id="com.qnx.qcc.inputType.assembler.162112550" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.1459781959" name="QCC Linker" superClass="com.qnx.qcc.tool.linker"/>
+							<tool id="com.qnx.qcc.tool.archiver.1458121549" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.toolChain.53641783">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.toolChain.53641783" moduleId="org.eclipse.cdt.core.settings" name="Device-Profile">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildProperties="" id="com.qnx.qcc.toolChain.53641783" name="Device-Profile" parent="org.eclipse.cdt.build.core.emptycfg">
+					<folderInfo id="com.qnx.qcc.toolChain.53641783.495169588" name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.1960069138" name="com.qnx.qcc.toolChain" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.os.1576125079" name="Target OS:" superClass="com.qnx.qcc.option.os"/>
+							<option id="com.qnx.qcc.option.cpu.660725627" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
+							<option id="com.qnx.qcc.option.compiler.2088257189" name="Compiler:" superClass="com.qnx.qcc.option.compiler"/>
+							<option id="com.qnx.qcc.option.runtime.313772446" name="Runtime:" superClass="com.qnx.qcc.option.runtime"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1321686798" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder autoBuildTarget="Device-Profile" enableAutoBuild="true" id="com.qnx.qcc.toolChain.53641783.656984560" incrementalBuildTarget="Device-Profile" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
+							<tool id="com.qnx.qcc.tool.compiler.880882739" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.92132752" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<inputType id="com.qnx.qcc.inputType.compiler.556018821" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.517973191" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<inputType id="com.qnx.qcc.inputType.assembler.521596283" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.1497857873" name="QCC Linker" superClass="com.qnx.qcc.tool.linker"/>
+							<tool id="com.qnx.qcc.tool.archiver.877613266" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.toolChain.1381352734">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.toolChain.1381352734" moduleId="org.eclipse.cdt.core.settings" name="Simulator-Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildProperties="" id="com.qnx.qcc.toolChain.1381352734" name="Simulator-Debug" parent="org.eclipse.cdt.build.core.emptycfg">
+					<folderInfo id="com.qnx.qcc.toolChain.1381352734.493421125" name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.1137547274" name="com.qnx.qcc.toolChain" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.os.1965499677" name="Target OS:" superClass="com.qnx.qcc.option.os"/>
+							<option id="com.qnx.qcc.option.cpu.1766020621" name="Target CPU:" superClass="com.qnx.qcc.option.cpu"/>
+							<option id="com.qnx.qcc.option.compiler.1426881303" name="Compiler:" superClass="com.qnx.qcc.option.compiler"/>
+							<option id="com.qnx.qcc.option.runtime.1550481284" name="Runtime:" superClass="com.qnx.qcc.option.runtime"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.574443581" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder autoBuildTarget="Simulator-Debug" enableAutoBuild="true" id="com.qnx.qcc.toolChain.1381352734.544509991" incrementalBuildTarget="Simulator-Debug" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
+							<tool id="com.qnx.qcc.tool.compiler.1948744989" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.1706221075" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/>
+								<inputType id="com.qnx.qcc.inputType.compiler.804607589" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.129468570" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<inputType id="com.qnx.qcc.inputType.assembler.721693989" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.417318241" name="QCC Linker" superClass="com.qnx.qcc.tool.linker"/>
+							<tool id="com.qnx.qcc.tool.archiver.189535208" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="PjsuaBB.null.929882782" name="PjsuaBB"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.toolChain.1381352734">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.toolChain.53641783">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.toolChain.1397290099">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.toolChain.2079401108">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="refreshScope" versionNumber="1">
+		<resource resourceType="PROJECT" workspacePath="/PjsuaBB"/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+</cproject>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/Makefile b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/Makefile
new file mode 100644
index 0000000..9b92238
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/Makefile
@@ -0,0 +1,6 @@
+QMAKE_TARGET  = PjsuaBB
+PROJECT_DIR	  := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
+I18N_DIR	  := $(PROJECT_DIR)/translations
+
+include mk/cs-base.mk
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/PjsuaBB.pro b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/PjsuaBB.pro
new file mode 100644
index 0000000..737698f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/PjsuaBB.pro
@@ -0,0 +1,31 @@
+APP_NAME = PjsuaBB
+
+CONFIG += qt warn_on cascades10
+
+include(config.pri)
+
+SOURCES +=  ../../pjsua_app.c \
+            ../../pjsua_app_cli.c \
+            ../../pjsua_app_common.c \
+            ../../pjsua_app_config.c \
+            ../../pjsua_app_legacy.c
+
+device {
+    CONFIG(debug, debug|release) {
+        # Device-Debug custom configuration
+        include(../../../../pjsip.pri)
+        LIBS += -lbb
+    }
+
+    CONFIG(release, debug|release) {
+        # Device-Release custom configuration
+        include(../../../../pjsip.pri)
+        LIBS += -lbb
+    }
+}
+
+simulator {
+    CONFIG(debug, debug|release) {
+        # Simulator-Debug custom configuration
+    }
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/assets/.assets.index b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/assets/.assets.index
new file mode 100644
index 0000000..d084d03
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/assets/.assets.index
@@ -0,0 +1,4 @@
+1
+2
+main.qml
+images/teluu-logo.png
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/assets/images/teluu-logo.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/assets/images/teluu-logo.png
new file mode 100644
index 0000000..97fadb5
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/assets/images/teluu-logo.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/assets/main.qml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/assets/main.qml
new file mode 100644
index 0000000..dc3f7f3
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/assets/main.qml
@@ -0,0 +1,41 @@
+// Default empty project template
+import bb.cascades 1.0
+
+// creates one page with a label
+Page {
+    Container {
+        layout: StackLayout {
+        }
+        background: Color.Black
+        Label {
+            text: qsTr("")
+            horizontalAlignment: HorizontalAlignment.Center
+        }
+        ImageView {
+            imageSource: "asset:///images/teluu-logo.png"
+            topMargin: 200
+            preferredWidth: 500
+            preferredHeight: 500
+            verticalAlignment: VerticalAlignment.Center
+            horizontalAlignment: HorizontalAlignment.Center
+        }
+        Label {
+            text: qsTr("pjsua BB10")
+            textStyle.base: SystemDefaults.TextStyles.BigText
+            horizontalAlignment: HorizontalAlignment.Center
+            textStyle {
+                color: Color.White
+            }
+        }
+        Label {
+            objectName: "telnetMsg"
+            text: qsTr("Starting..")
+            topMargin: 200
+            horizontalAlignment: HorizontalAlignment.Center
+            textStyle {
+                color: Color.White
+            }
+        }
+    }
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/bar-descriptor.xml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/bar-descriptor.xml
new file mode 100644
index 0000000..c3b1d8f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/bar-descriptor.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--
+  
+   Copyright (c) 2011, 2012, 2013 Research In Motion Limited.
+  
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+  
+   http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+  
+-->
+<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
+
+<!-- BlackBerry Tablet OS application descriptor file.
+
+    Specifies parameters for identifying, installing, and launching native applications on BlackBerry Tablet OS.
+
+-->
+
+    <!-- A universally unique application identifier. Must be unique across all BlackBerry Tablet OS applications.
+         Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
+    <id>com.example.PjsuaBB</id>
+
+    <!-- The name that is displayed in the BlackBerry Tablet OS application installer. 
+         May have multiple values for each language. See samples or xsd schema file. Optional. -->
+    <name>PjsuaBB</name>
+    
+    <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. 
+         Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
+         An updated version of application must have a versionNumber value higher than the previous version. Required. -->
+    <versionNumber>1.0.0</versionNumber>
+
+    <!-- Fourth digit segment of the package version. First three segments are taken from the 
+         <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
+    <buildId>1</buildId>
+                 
+    <!-- A string value (such as "v1", "2.5", or "Alpha 1") that represents the version of the application, as it should be shown to users. Optional. -->
+    <!-- <versionLabel></versionLabel> -->
+
+    <!-- Description, displayed in the BlackBerry Tablet OS application installer.
+         May have multiple values for each language. See samples or xsd schema file. Optional. -->
+    <description>Teluu Ltd. pjsua Demo App</description>
+
+    <!-- Copyright information. Optional. -->
+    <!-- <copyright></copyright> -->
+
+    <!--  Name of author which is used for signing. Must match the developer name of your development certificate. -->
+    <author>Teluu Ltd.</author>
+    
+    <!--  Unique author ID assigned by signing authority. Required if using debug tokens. -->
+    <!-- <authorId>ABC1234YjsnUk235h</authorId> -->
+   
+    <initialWindow>
+        <autoOrients>true</autoOrients>
+        <systemChrome>none</systemChrome>
+        <transparent>false</transparent>
+    </initialWindow>
+    
+    <!--  The category where the application appears. Either core.games or core.media. -->
+    <category>core.media</category>
+    <configuration name="Device-Debug">
+       <platformArchitecture>armle-v7</platformArchitecture>
+       <asset path="arm/o.le-v7-g/PjsuaBB" entry="true" type="Qnx/Elf">PjsuaBB</asset>
+       <asset path="/home/bennylp/Desktop/opt/bb10/lib/libopencore-amrnb.so.0" type="Qnx/Elf">lib/libopencore-amrnb.so.0</asset>
+       <asset path="/home/bennylp/Desktop/opt/bb10/lib/libopencore-amrwb.so.0" type="Qnx/Elf">lib/libopencore-amrwb.so.0</asset>
+    </configuration>
+    <configuration name="Device-Release">
+       <entryPointType>Qnx/Cascades</entryPointType>
+       <platformArchitecture>armle-v7</platformArchitecture>
+       <asset path="arm/o.le-v7/PjsuaBB.so" entry="true" type="Qnx/Elf">PjsuaBB.so</asset>
+    </configuration>
+    <configuration name="Device-Profile">
+       <platformArchitecture>armle-v7</platformArchitecture>
+       <asset path="arm-p/o.le-v7-g/PjsuaBB" entry="true" type="Qnx/Elf">PjsuaBB</asset>
+    </configuration>
+    <configuration name="Simulator-Debug">
+       <platformArchitecture>x86</platformArchitecture>
+       <asset path="x86/o-g/PjsuaBB" entry="true" type="Qnx/Elf">PjsuaBB</asset>
+    </configuration>
+    
+    <!--  The icon for the application -->
+    <icon>
+        <image>icon.png</image>
+    </icon>
+
+    <asset path="icon.png">icon.png</asset>
+    <asset path="assets">assets</asset>
+    
+    <!-- Locale support -->
+    
+    <!-- Request permission to execute native code.  Required for native applications. -->
+    <permission system="true">run_native</permission>
+    <permission>access_internet</permission>
+    <permission>record_audio</permission>
+    <permission>run_when_backgrounded</permission>
+    <env var="LD_LIBRARY_PATH" value="app/native/lib:/usr/lib/qt4/lib"/>
+
+</qnx>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/config.pri b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/config.pri
new file mode 100644
index 0000000..2f80a4f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/config.pri
@@ -0,0 +1,52 @@
+# Auto-generated by IDE. Any changes made by user will be lost!
+BASEDIR =  $$quote($$_PRO_FILE_PWD_)
+
+device {
+    CONFIG(debug, debug|release) {
+        SOURCES +=  $$quote($$BASEDIR/src/applicationui.cpp) \
+                 $$quote($$BASEDIR/src/main.cpp)
+
+        HEADERS +=  $$quote($$BASEDIR/src/applicationui.h)
+    }
+
+    CONFIG(release, debug|release) {
+        SOURCES +=  $$quote($$BASEDIR/src/applicationui.cpp) \
+                 $$quote($$BASEDIR/src/main.cpp)
+
+        HEADERS +=  $$quote($$BASEDIR/src/applicationui.h)
+    }
+}
+
+simulator {
+    CONFIG(debug, debug|release) {
+        SOURCES +=  $$quote($$BASEDIR/src/applicationui.cpp) \
+                 $$quote($$BASEDIR/src/main.cpp)
+
+        HEADERS +=  $$quote($$BASEDIR/src/applicationui.h)
+    }
+}
+
+INCLUDEPATH +=  $$quote($$BASEDIR/src)
+
+CONFIG += precompile_header
+
+PRECOMPILED_HEADER =  $$quote($$BASEDIR/precompiled.h)
+
+lupdate_inclusion {
+    SOURCES +=  $$quote($$BASEDIR/../src/*.c) \
+             $$quote($$BASEDIR/../src/*.c++) \
+             $$quote($$BASEDIR/../src/*.cc) \
+             $$quote($$BASEDIR/../src/*.cpp) \
+             $$quote($$BASEDIR/../src/*.cxx) \
+             $$quote($$BASEDIR/../assets/*.qml) \
+             $$quote($$BASEDIR/../assets/*.js) \
+             $$quote($$BASEDIR/../assets/*.qs)
+
+    HEADERS +=  $$quote($$BASEDIR/../src/*.h) \
+             $$quote($$BASEDIR/../src/*.h++) \
+             $$quote($$BASEDIR/../src/*.hh) \
+             $$quote($$BASEDIR/../src/*.hpp) \
+             $$quote($$BASEDIR/../src/*.hxx)
+}
+
+TRANSLATIONS =  $$quote($${TARGET}.ts)
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/icon.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/icon.png
new file mode 100644
index 0000000..dab6e7a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/icon.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/precompiled.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/precompiled.h
new file mode 100644
index 0000000..6213dc4
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/precompiled.h
@@ -0,0 +1,2 @@
+// This file is used to store precompiled headers.
+// It is intentionally left blank. It is up to you to decide which headers should be included here. 
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/src/applicationui.cpp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/src/applicationui.cpp
new file mode 100644
index 0000000..73c0d3c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/src/applicationui.cpp
@@ -0,0 +1,179 @@
+// Default empty project template
+#include "applicationui.h"
+
+#include <bb/cascades/Application>
+#include <bb/cascades/QmlDocument>
+#include <bb/cascades/AbstractPane>
+#include <bb/cascades/Label>
+
+#define THIS_FILE	"applicationui.cpp"
+
+using namespace bb::cascades;
+
+/* appUI singleton */
+ApplicationUI *ApplicationUI::instance_;
+
+#include "../../pjsua_app_config.h"
+
+void ApplicationUI::extDisplayMsg(const char *msg)
+{
+    /* Qt's way to invoke method from "foreign" thread */
+    QMetaObject::invokeMethod((QObject*)ApplicationUI::instance(),
+			      "displayMsg", Qt::AutoConnection,
+			      Q_ARG(QString,msg));
+}
+
+
+void ApplicationUI::pjsuaOnStartedCb(pj_status_t status, const char* msg)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    if (status != PJ_SUCCESS && (!msg || !*msg)) {
+	pj_strerror(status, errmsg, sizeof(errmsg));
+	PJ_LOG(3,(THIS_FILE, "Error: %s", errmsg));
+	msg = errmsg;
+    } else {
+	PJ_LOG(3,(THIS_FILE, "Started: %s", msg));
+    }
+
+    ApplicationUI::extDisplayMsg(msg);
+}
+
+
+void ApplicationUI::pjsuaOnStoppedCb(pj_bool_t restart,
+				     int argc, char** argv)
+{
+    PJ_LOG(3,("ipjsua", "CLI %s request", (restart? "restart" : "shutdown")));
+    if (restart) {
+	ApplicationUI::extDisplayMsg("Restarting..");
+	pj_thread_sleep(100);
+	ApplicationUI::instance()->extRestartRequest(argc, argv);
+    } else {
+	ApplicationUI::extDisplayMsg("Shutting down..");
+	pj_thread_sleep(100);
+	ApplicationUI::instance()->isShuttingDown = true;
+
+	bb::cascades::Application *app = bb::cascades::Application::instance();
+	app->quit();
+    }
+}
+
+
+void ApplicationUI::pjsuaOnAppConfigCb(pjsua_app_config *cfg)
+{
+    PJ_UNUSED_ARG(cfg);
+}
+
+
+void ApplicationUI::extRestartRequest(int argc, char **argv)
+{
+    restartArgc = argc;
+    restartArgv = argv;
+    QMetaObject::invokeMethod((QObject*)this, "restartPjsua",
+			      Qt::QueuedConnection);
+}
+
+
+void ApplicationUI::pjsuaStart()
+{
+    // TODO: read from config?
+    const char **argv = pjsua_app_def_argv;
+    int argc = PJ_ARRAY_SIZE(pjsua_app_def_argv) -1;
+    pjsua_app_cfg_t app_cfg;
+    pj_status_t status;
+
+    isShuttingDown = false;
+    displayMsg("Starting..");
+
+    pj_bzero(&app_cfg, sizeof(app_cfg));
+    if (restartArgc) {
+	app_cfg.argc = restartArgc;
+	app_cfg.argv = restartArgv;
+    } else {
+	app_cfg.argc = argc;
+	app_cfg.argv = (char**)argv;
+    }
+    app_cfg.on_started = &pjsuaOnStartedCb;
+    app_cfg.on_stopped = &pjsuaOnStoppedCb;
+    app_cfg.on_config_init = &pjsuaOnAppConfigCb;
+
+    status = pjsua_app_init(&app_cfg);
+    if (status != PJ_SUCCESS) {
+	char errmsg[PJ_ERR_MSG_SIZE];
+	pj_strerror(status, errmsg, sizeof(errmsg));
+	displayMsg(QString("Init error:") + errmsg);
+	pjsua_app_destroy();
+	return;
+    }
+
+    status = pjsua_app_run(PJ_FALSE);
+    if (status != PJ_SUCCESS) {
+	char errmsg[PJ_ERR_MSG_SIZE];
+	pj_strerror(status, errmsg, sizeof(errmsg));
+	displayMsg(QString("Error:") + errmsg);
+	pjsua_app_destroy();
+    }
+
+    restartArgv = NULL;
+    restartArgc = 0;
+}
+
+void ApplicationUI::pjsuaDestroy()
+{
+    pjsua_app_destroy();
+}
+
+
+ApplicationUI::ApplicationUI(bb::cascades::Application *app)
+: QObject(app), isShuttingDown(false), restartArgv(NULL), restartArgc(0)
+{
+    instance_ = this;
+
+    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
+    AbstractPane *root = qml->createRootObject<AbstractPane>();
+    app->setScene(root);
+
+    app->setAutoExit(true);
+    connect(app, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));
+
+    pjsuaStart();
+}
+
+
+ApplicationUI::~ApplicationUI()
+{
+    instance_ = NULL;
+}
+
+
+ApplicationUI* ApplicationUI::instance()
+{
+    return instance_;
+}
+
+
+void ApplicationUI::aboutToQuit()
+{
+    if (!isShuttingDown) {
+	isShuttingDown = true;
+	PJ_LOG(3,(THIS_FILE, "Quit signal from GUI, shutting down pjsua.."));
+	pjsuaDestroy();
+    }
+}
+
+
+void ApplicationUI::displayMsg(const QString &msg)
+{
+    bb::cascades::Application *app = bb::cascades::Application::instance();
+    Label *telnetMsg = app->scene()->findChild<Label*>("telnetMsg");
+    if (telnetMsg) {
+	telnetMsg->setText(msg);
+    }
+}
+
+
+void ApplicationUI::restartPjsua()
+{
+    pjsuaDestroy();
+    pjsuaStart();
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/src/applicationui.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/src/applicationui.h
new file mode 100644
index 0000000..790a25e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/src/applicationui.h
@@ -0,0 +1,54 @@
+// Default empty project template
+#ifndef ApplicationUI_HPP_
+#define ApplicationUI_HPP_
+
+#include <QObject>
+
+#include "../../pjsua_app.h"
+
+namespace bb { namespace cascades { class Application; }}
+
+/*!
+ * @brief Application pane object
+ *
+ *Use this object to create and init app UI, to create context objects, to register the new meta types etc.
+ */
+class ApplicationUI : public QObject
+{
+    Q_OBJECT
+public:
+    ApplicationUI(bb::cascades::Application *app);
+    virtual ~ApplicationUI();
+
+    bool isShuttingDown;
+    static ApplicationUI *instance();
+
+    /* Write msg to label (from different thread) */
+    static void extDisplayMsg(const char *msg);
+
+    /* Restart request (from different thread) */
+    void extRestartRequest(int argc, char **argv);
+
+public slots:
+    void aboutToQuit();
+
+    Q_INVOKABLE void restartPjsua();
+    Q_INVOKABLE void displayMsg(const QString &msg);
+
+private:
+    static ApplicationUI *instance_;
+    char **restartArgv;
+    int restartArgc;
+
+    /* pjsua main operations */
+    void pjsuaStart();
+    void pjsuaDestroy();
+
+    /* pjsua app callbacks */
+    static void pjsuaOnStartedCb(pj_status_t status, const char* msg);
+    static void pjsuaOnStoppedCb(pj_bool_t restart, int argc, char** argv);
+    static void pjsuaOnAppConfigCb(pjsua_app_config *cfg);
+};
+
+
+#endif /* ApplicationUI_HPP_ */
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/src/main.cpp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/src/main.cpp
new file mode 100644
index 0000000..cd2a4b6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/src/main.cpp
@@ -0,0 +1,32 @@
+// Default empty project template
+#include <bb/cascades/Application>
+
+#include <QLocale>
+#include <QTranslator>
+#include "applicationui.h"
+
+// include JS Debugger / CS Profiler enabler
+// this feature is enabled by default in the debug build only
+#include <Qt/qdeclarativedebug.h>
+
+using namespace bb::cascades;
+
+Q_DECL_EXPORT int main(int argc, char **argv)
+{
+    // this is where the server is started etc
+    Application app(argc, argv);
+
+    // localization support
+    QTranslator translator;
+    QString locale_string = QLocale().name();
+    QString filename = QString( "PjsuaBB_%1" ).arg( locale_string );
+    if (translator.load(filename, "app/native/qm")) {
+        app.installTranslator( &translator );
+    }
+
+    new ApplicationUI(&app);
+
+    // we complete the transaction started in the app constructor and start the client event loop here
+    return Application::exec();
+    // when loop is exited the Application deletes the scene which deletes all its children (per qt rules for children)
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/translations/Makefile b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/translations/Makefile
new file mode 100644
index 0000000..28fd97c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/translations/Makefile
@@ -0,0 +1,12 @@
+QMAKE_TARGET  = PjsuaBB
+LUPDATE       = $(QNX_HOST)/usr/bin/lupdate
+LRELEASE      = $(QNX_HOST)/usr/bin/lrelease
+
+update: $(QMAKE_TARGET).pro FORCE
+	$(LUPDATE) $(QMAKE_TARGET).pro
+
+release: $(QMAKE_TARGET).pro $(QMAKE_TARGET).ts
+	$(LRELEASE) $(QMAKE_TARGET).pro
+
+FORCE:
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/translations/PjsuaBB.pro b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/translations/PjsuaBB.pro
new file mode 100644
index 0000000..3f7c659
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/translations/PjsuaBB.pro
@@ -0,0 +1 @@
+include (../PjsuaBB.pro)
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/translations/PjsuaBB.ts b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/translations/PjsuaBB.ts
new file mode 100644
index 0000000..cdc53c8
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/bb10/translations/PjsuaBB.ts
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+    <name>main</name>
+    <message>
+        <location filename="../assets/main.qml" line="11"/>
+        <source></source>
+        <translation></translation>
+    </message>
+    <message>
+        <location filename="../assets/main.qml" line="23"/>
+        <source>pjsua BB10</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../assets/main.qml" line="32"/>
+        <source>Starting..</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+</TS>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/gui.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/gui.h
new file mode 100644
index 0000000..f7ad169
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/gui.h
@@ -0,0 +1,39 @@
+/* $Id: gui.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 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 __GUI_H__
+#define __GUI_H__
+
+PJ_BEGIN_DECL
+
+#ifdef USE_GUI
+
+#define printf showMsg
+#define puts(str) showMsg("%s\n", str)
+#define fgets getInput
+
+void showMsg(const char *format, ...);
+char * getInput(char *s, int n, FILE *stream);
+pj_bool_t showNotification(pjsua_call_id call_id);
+
+#endif
+
+PJ_END_DECL
+
+
+#endif	/* __GUI_H__ */
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua.xcodeproj/project.pbxproj b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..1c6b0bd
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua.xcodeproj/project.pbxproj
@@ -0,0 +1,491 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		3A92068F16F1DE7100D49F96 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A92068E16F1DE7100D49F96 /* AudioToolbox.framework */; };
+		3A92069316F1DEA500D49F96 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A92069216F1DEA500D49F96 /* CFNetwork.framework */; };
+		3ADCCD171715338D0007BE8E /* pjsua.png in Resources */ = {isa = PBXBuildFile; fileRef = 3ADCCD161715338D0007BE8E /* pjsua.png */; };
+		3ADCCD2D172E40120007BE8E /* pjsua_app_cli.c in Sources */ = {isa = PBXBuildFile; fileRef = 3ADCCD28172E40120007BE8E /* pjsua_app_cli.c */; };
+		3ADCCD2E172E40120007BE8E /* pjsua_app_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 3ADCCD29172E40120007BE8E /* pjsua_app_common.c */; };
+		3ADCCD2F172E40120007BE8E /* pjsua_app_config.c in Sources */ = {isa = PBXBuildFile; fileRef = 3ADCCD2A172E40120007BE8E /* pjsua_app_config.c */; };
+		3ADCCD30172E40120007BE8E /* pjsua_app_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3ADCCD2B172E40120007BE8E /* pjsua_app_legacy.c */; };
+		3ADCCD31172E40120007BE8E /* pjsua_app.c in Sources */ = {isa = PBXBuildFile; fileRef = 3ADCCD2C172E40120007BE8E /* pjsua_app.c */; };
+		3ADFCCFD1803B00600B0A097 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3ADFCCFC1803B00600B0A097 /* AVFoundation.framework */; };
+		3AF0580916F050770046B835 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0580816F050770046B835 /* UIKit.framework */; };
+		3AF0580B16F050770046B835 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0580A16F050770046B835 /* Foundation.framework */; };
+		3AF0580D16F050770046B835 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0580C16F050770046B835 /* CoreGraphics.framework */; };
+		3AF0581316F050780046B835 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3AF0581116F050780046B835 /* InfoPlist.strings */; };
+		3AF0581516F050780046B835 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF0581416F050780046B835 /* main.m */; };
+		3AF0581916F050780046B835 /* ipjsuaAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF0581816F050780046B835 /* ipjsuaAppDelegate.m */; };
+		3AF0581B16F050780046B835 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 3AF0581A16F050780046B835 /* Default.png */; };
+		3AF0581D16F050780046B835 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3AF0581C16F050780046B835 /* Default@2x.png */; };
+		3AF0581F16F050780046B835 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3AF0581E16F050780046B835 /* Default-568h@2x.png */; };
+		3AF0582216F050780046B835 /* ipjsuaViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF0582116F050780046B835 /* ipjsuaViewController.m */; };
+		3AF0582516F050780046B835 /* ipjsuaViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3AF0582316F050780046B835 /* ipjsuaViewController_iPhone.xib */; };
+		3AF0582816F050780046B835 /* ipjsuaViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3AF0582616F050780046B835 /* ipjsuaViewController_iPad.xib */; };
+		3AF0583716F057740046B835 /* libpj-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0583616F057740046B835 /* libpj-arm-apple-darwin9.a */; };
+		3AF0583916F057890046B835 /* libpjlib-util-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0583816F057890046B835 /* libpjlib-util-arm-apple-darwin9.a */; };
+		3AF0583F16F057B20046B835 /* libpjmedia-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0583A16F057B20046B835 /* libpjmedia-arm-apple-darwin9.a */; };
+		3AF0584016F057B30046B835 /* libpjmedia-audiodev-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0583B16F057B20046B835 /* libpjmedia-audiodev-arm-apple-darwin9.a */; };
+		3AF0584116F057B30046B835 /* libpjmedia-codec-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0583C16F057B20046B835 /* libpjmedia-codec-arm-apple-darwin9.a */; };
+		3AF0584216F057B30046B835 /* libpjmedia-videodev-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0583D16F057B20046B835 /* libpjmedia-videodev-arm-apple-darwin9.a */; };
+		3AF0584316F057B30046B835 /* libpjsdp-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0583E16F057B20046B835 /* libpjsdp-arm-apple-darwin9.a */; };
+		3AF0584516F057D30046B835 /* libpjnath-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0584416F057D30046B835 /* libpjnath-arm-apple-darwin9.a */; };
+		3AF0584A16F057F70046B835 /* libpjsip-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0584616F057F70046B835 /* libpjsip-arm-apple-darwin9.a */; };
+		3AF0584B16F057F70046B835 /* libpjsip-simple-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0584716F057F70046B835 /* libpjsip-simple-arm-apple-darwin9.a */; };
+		3AF0584C16F057F70046B835 /* libpjsip-ua-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0584816F057F70046B835 /* libpjsip-ua-arm-apple-darwin9.a */; };
+		3AF0584D16F057F70046B835 /* libpjsua-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0584916F057F70046B835 /* libpjsua-arm-apple-darwin9.a */; };
+		3AF0585516F058290046B835 /* libg7221codec-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0584E16F058290046B835 /* libg7221codec-arm-apple-darwin9.a */; };
+		3AF0585616F058290046B835 /* libgsmcodec-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0584F16F058290046B835 /* libgsmcodec-arm-apple-darwin9.a */; };
+		3AF0585716F058290046B835 /* libilbccodec-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0585016F058290046B835 /* libilbccodec-arm-apple-darwin9.a */; };
+		3AF0585816F058290046B835 /* libmilenage-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0585116F058290046B835 /* libmilenage-arm-apple-darwin9.a */; };
+		3AF0585916F058290046B835 /* libresample-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0585216F058290046B835 /* libresample-arm-apple-darwin9.a */; };
+		3AF0585A16F058290046B835 /* libspeex-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0585316F058290046B835 /* libspeex-arm-apple-darwin9.a */; };
+		3AF0585B16F058290046B835 /* libsrtp-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF0585416F058290046B835 /* libsrtp-arm-apple-darwin9.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		3A92068E16F1DE7100D49F96 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+		3A92069216F1DEA500D49F96 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
+		3ADCCD161715338D0007BE8E /* pjsua.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pjsua.png; sourceTree = "<group>"; };
+		3ADCCD28172E40120007BE8E /* pjsua_app_cli.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pjsua_app_cli.c; path = ../../pjsua_app_cli.c; sourceTree = "<group>"; };
+		3ADCCD29172E40120007BE8E /* pjsua_app_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pjsua_app_common.c; path = ../../pjsua_app_common.c; sourceTree = "<group>"; };
+		3ADCCD2A172E40120007BE8E /* pjsua_app_config.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pjsua_app_config.c; path = ../../pjsua_app_config.c; sourceTree = "<group>"; };
+		3ADCCD2B172E40120007BE8E /* pjsua_app_legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pjsua_app_legacy.c; path = ../../pjsua_app_legacy.c; sourceTree = "<group>"; };
+		3ADCCD2C172E40120007BE8E /* pjsua_app.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pjsua_app.c; path = ../../pjsua_app.c; sourceTree = "<group>"; };
+		3ADFCCFC1803B00600B0A097 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
+		3AF0580416F050770046B835 /* ipjsua.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ipjsua.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		3AF0580816F050770046B835 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+		3AF0580A16F050770046B835 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+		3AF0580C16F050770046B835 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+		3AF0581016F050780046B835 /* ipjsua-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ipjsua-Info.plist"; sourceTree = "<group>"; };
+		3AF0581216F050780046B835 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		3AF0581416F050780046B835 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		3AF0581616F050780046B835 /* ipjsua-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ipjsua-Prefix.pch"; sourceTree = "<group>"; };
+		3AF0581716F050780046B835 /* ipjsuaAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ipjsuaAppDelegate.h; sourceTree = "<group>"; };
+		3AF0581816F050780046B835 /* ipjsuaAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ipjsuaAppDelegate.m; sourceTree = "<group>"; };
+		3AF0581A16F050780046B835 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };
+		3AF0581C16F050780046B835 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = "<group>"; };
+		3AF0581E16F050780046B835 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
+		3AF0582016F050780046B835 /* ipjsuaViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ipjsuaViewController.h; sourceTree = "<group>"; };
+		3AF0582116F050780046B835 /* ipjsuaViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ipjsuaViewController.m; sourceTree = "<group>"; };
+		3AF0582416F050780046B835 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ipjsuaViewController_iPhone.xib; sourceTree = "<group>"; };
+		3AF0582716F050780046B835 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ipjsuaViewController_iPad.xib; sourceTree = "<group>"; };
+		3AF0583616F057740046B835 /* libpj-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpj-arm-apple-darwin9.a"; path = "../../../../pjlib/lib/libpj-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0583816F057890046B835 /* libpjlib-util-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjlib-util-arm-apple-darwin9.a"; path = "../../../../pjlib-util/lib/libpjlib-util-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0583A16F057B20046B835 /* libpjmedia-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjmedia-arm-apple-darwin9.a"; path = "../../../../pjmedia/lib/libpjmedia-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0583B16F057B20046B835 /* libpjmedia-audiodev-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjmedia-audiodev-arm-apple-darwin9.a"; path = "../../../../pjmedia/lib/libpjmedia-audiodev-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0583C16F057B20046B835 /* libpjmedia-codec-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjmedia-codec-arm-apple-darwin9.a"; path = "../../../../pjmedia/lib/libpjmedia-codec-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0583D16F057B20046B835 /* libpjmedia-videodev-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjmedia-videodev-arm-apple-darwin9.a"; path = "../../../../pjmedia/lib/libpjmedia-videodev-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0583E16F057B20046B835 /* libpjsdp-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsdp-arm-apple-darwin9.a"; path = "../../../../pjmedia/lib/libpjsdp-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0584416F057D30046B835 /* libpjnath-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjnath-arm-apple-darwin9.a"; path = "../../../../pjnath/lib/libpjnath-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0584616F057F70046B835 /* libpjsip-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsip-arm-apple-darwin9.a"; path = "../../../../pjsip/lib/libpjsip-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0584716F057F70046B835 /* libpjsip-simple-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsip-simple-arm-apple-darwin9.a"; path = "../../../../pjsip/lib/libpjsip-simple-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0584816F057F70046B835 /* libpjsip-ua-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsip-ua-arm-apple-darwin9.a"; path = "../../../../pjsip/lib/libpjsip-ua-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0584916F057F70046B835 /* libpjsua-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjsua-arm-apple-darwin9.a"; path = "../../../../pjsip/lib/libpjsua-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0584E16F058290046B835 /* libg7221codec-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libg7221codec-arm-apple-darwin9.a"; path = "../../../../third_party/lib/libg7221codec-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0584F16F058290046B835 /* libgsmcodec-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libgsmcodec-arm-apple-darwin9.a"; path = "../../../../third_party/lib/libgsmcodec-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0585016F058290046B835 /* libilbccodec-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libilbccodec-arm-apple-darwin9.a"; path = "../../../../third_party/lib/libilbccodec-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0585116F058290046B835 /* libmilenage-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmilenage-arm-apple-darwin9.a"; path = "../../../../third_party/lib/libmilenage-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0585216F058290046B835 /* libresample-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libresample-arm-apple-darwin9.a"; path = "../../../../third_party/lib/libresample-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0585316F058290046B835 /* libspeex-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libspeex-arm-apple-darwin9.a"; path = "../../../../third_party/lib/libspeex-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AF0585416F058290046B835 /* libsrtp-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libsrtp-arm-apple-darwin9.a"; path = "../../../../third_party/lib/libsrtp-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		3AF0580116F050770046B835 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3ADFCCFD1803B00600B0A097 /* AVFoundation.framework in Frameworks */,
+				3A92069316F1DEA500D49F96 /* CFNetwork.framework in Frameworks */,
+				3A92068F16F1DE7100D49F96 /* AudioToolbox.framework in Frameworks */,
+				3AF0580916F050770046B835 /* UIKit.framework in Frameworks */,
+				3AF0580B16F050770046B835 /* Foundation.framework in Frameworks */,
+				3AF0580D16F050770046B835 /* CoreGraphics.framework in Frameworks */,
+				3AF0583716F057740046B835 /* libpj-arm-apple-darwin9.a in Frameworks */,
+				3AF0583916F057890046B835 /* libpjlib-util-arm-apple-darwin9.a in Frameworks */,
+				3AF0583F16F057B20046B835 /* libpjmedia-arm-apple-darwin9.a in Frameworks */,
+				3AF0584016F057B30046B835 /* libpjmedia-audiodev-arm-apple-darwin9.a in Frameworks */,
+				3AF0584116F057B30046B835 /* libpjmedia-codec-arm-apple-darwin9.a in Frameworks */,
+				3AF0584216F057B30046B835 /* libpjmedia-videodev-arm-apple-darwin9.a in Frameworks */,
+				3AF0584316F057B30046B835 /* libpjsdp-arm-apple-darwin9.a in Frameworks */,
+				3AF0584516F057D30046B835 /* libpjnath-arm-apple-darwin9.a in Frameworks */,
+				3AF0584A16F057F70046B835 /* libpjsip-arm-apple-darwin9.a in Frameworks */,
+				3AF0584B16F057F70046B835 /* libpjsip-simple-arm-apple-darwin9.a in Frameworks */,
+				3AF0584C16F057F70046B835 /* libpjsip-ua-arm-apple-darwin9.a in Frameworks */,
+				3AF0584D16F057F70046B835 /* libpjsua-arm-apple-darwin9.a in Frameworks */,
+				3AF0585516F058290046B835 /* libg7221codec-arm-apple-darwin9.a in Frameworks */,
+				3AF0585616F058290046B835 /* libgsmcodec-arm-apple-darwin9.a in Frameworks */,
+				3AF0585716F058290046B835 /* libilbccodec-arm-apple-darwin9.a in Frameworks */,
+				3AF0585816F058290046B835 /* libmilenage-arm-apple-darwin9.a in Frameworks */,
+				3AF0585916F058290046B835 /* libresample-arm-apple-darwin9.a in Frameworks */,
+				3AF0585A16F058290046B835 /* libspeex-arm-apple-darwin9.a in Frameworks */,
+				3AF0585B16F058290046B835 /* libsrtp-arm-apple-darwin9.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		3A92068D16F1D1A100D49F96 /* pjsua */ = {
+			isa = PBXGroup;
+			children = (
+				3ADCCD28172E40120007BE8E /* pjsua_app_cli.c */,
+				3ADCCD29172E40120007BE8E /* pjsua_app_common.c */,
+				3ADCCD2A172E40120007BE8E /* pjsua_app_config.c */,
+				3ADCCD2B172E40120007BE8E /* pjsua_app_legacy.c */,
+				3ADCCD2C172E40120007BE8E /* pjsua_app.c */,
+			);
+			name = pjsua;
+			sourceTree = "<group>";
+		};
+		3AF057F916F050770046B835 = {
+			isa = PBXGroup;
+			children = (
+				3AF0580E16F050770046B835 /* ipjsua */,
+				3AF0580716F050770046B835 /* Frameworks */,
+				3AF0580516F050770046B835 /* Products */,
+				3AF0583516F056CC0046B835 /* Libraries */,
+			);
+			sourceTree = "<group>";
+		};
+		3AF0580516F050770046B835 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				3AF0580416F050770046B835 /* ipjsua.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		3AF0580716F050770046B835 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				3ADFCCFC1803B00600B0A097 /* AVFoundation.framework */,
+				3A92069216F1DEA500D49F96 /* CFNetwork.framework */,
+				3A92068E16F1DE7100D49F96 /* AudioToolbox.framework */,
+				3AF0580816F050770046B835 /* UIKit.framework */,
+				3AF0580A16F050770046B835 /* Foundation.framework */,
+				3AF0580C16F050770046B835 /* CoreGraphics.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		3AF0580E16F050770046B835 /* ipjsua */ = {
+			isa = PBXGroup;
+			children = (
+				3A92068D16F1D1A100D49F96 /* pjsua */,
+				3AF0581716F050780046B835 /* ipjsuaAppDelegate.h */,
+				3AF0581816F050780046B835 /* ipjsuaAppDelegate.m */,
+				3AF0582016F050780046B835 /* ipjsuaViewController.h */,
+				3AF0582116F050780046B835 /* ipjsuaViewController.m */,
+				3AF0582316F050780046B835 /* ipjsuaViewController_iPhone.xib */,
+				3AF0582616F050780046B835 /* ipjsuaViewController_iPad.xib */,
+				3AF0580F16F050780046B835 /* Supporting Files */,
+			);
+			path = ipjsua;
+			sourceTree = "<group>";
+		};
+		3AF0580F16F050780046B835 /* Supporting Files */ = {
+			isa = PBXGroup;
+			children = (
+				3AF0581016F050780046B835 /* ipjsua-Info.plist */,
+				3AF0581116F050780046B835 /* InfoPlist.strings */,
+				3AF0581416F050780046B835 /* main.m */,
+				3AF0581616F050780046B835 /* ipjsua-Prefix.pch */,
+				3ADCCD161715338D0007BE8E /* pjsua.png */,
+				3AF0581A16F050780046B835 /* Default.png */,
+				3AF0581C16F050780046B835 /* Default@2x.png */,
+				3AF0581E16F050780046B835 /* Default-568h@2x.png */,
+			);
+			name = "Supporting Files";
+			sourceTree = "<group>";
+		};
+		3AF0583516F056CC0046B835 /* Libraries */ = {
+			isa = PBXGroup;
+			children = (
+				3AF0584E16F058290046B835 /* libg7221codec-arm-apple-darwin9.a */,
+				3AF0584F16F058290046B835 /* libgsmcodec-arm-apple-darwin9.a */,
+				3AF0585016F058290046B835 /* libilbccodec-arm-apple-darwin9.a */,
+				3AF0585116F058290046B835 /* libmilenage-arm-apple-darwin9.a */,
+				3AF0585216F058290046B835 /* libresample-arm-apple-darwin9.a */,
+				3AF0585316F058290046B835 /* libspeex-arm-apple-darwin9.a */,
+				3AF0585416F058290046B835 /* libsrtp-arm-apple-darwin9.a */,
+				3AF0584616F057F70046B835 /* libpjsip-arm-apple-darwin9.a */,
+				3AF0584716F057F70046B835 /* libpjsip-simple-arm-apple-darwin9.a */,
+				3AF0584816F057F70046B835 /* libpjsip-ua-arm-apple-darwin9.a */,
+				3AF0584916F057F70046B835 /* libpjsua-arm-apple-darwin9.a */,
+				3AF0584416F057D30046B835 /* libpjnath-arm-apple-darwin9.a */,
+				3AF0583A16F057B20046B835 /* libpjmedia-arm-apple-darwin9.a */,
+				3AF0583B16F057B20046B835 /* libpjmedia-audiodev-arm-apple-darwin9.a */,
+				3AF0583C16F057B20046B835 /* libpjmedia-codec-arm-apple-darwin9.a */,
+				3AF0583D16F057B20046B835 /* libpjmedia-videodev-arm-apple-darwin9.a */,
+				3AF0583E16F057B20046B835 /* libpjsdp-arm-apple-darwin9.a */,
+				3AF0583816F057890046B835 /* libpjlib-util-arm-apple-darwin9.a */,
+				3AF0583616F057740046B835 /* libpj-arm-apple-darwin9.a */,
+			);
+			name = Libraries;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		3AF0580316F050770046B835 /* ipjsua */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 3AF0582B16F050780046B835 /* Build configuration list for PBXNativeTarget "ipjsua" */;
+			buildPhases = (
+				3AF0580016F050770046B835 /* Sources */,
+				3AF0580116F050770046B835 /* Frameworks */,
+				3AF0580216F050770046B835 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = ipjsua;
+			productName = ipjsua;
+			productReference = 3AF0580416F050770046B835 /* ipjsua.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		3AF057FB16F050770046B835 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				CLASSPREFIX = ipjsua;
+				LastUpgradeCheck = 0450;
+				ORGANIZATIONNAME = Teluu;
+			};
+			buildConfigurationList = 3AF057FE16F050770046B835 /* Build configuration list for PBXProject "ipjsua" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 3AF057F916F050770046B835;
+			productRefGroup = 3AF0580516F050770046B835 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				3AF0580316F050770046B835 /* ipjsua */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		3AF0580216F050770046B835 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3AF0581316F050780046B835 /* InfoPlist.strings in Resources */,
+				3AF0581B16F050780046B835 /* Default.png in Resources */,
+				3AF0581D16F050780046B835 /* Default@2x.png in Resources */,
+				3AF0581F16F050780046B835 /* Default-568h@2x.png in Resources */,
+				3AF0582516F050780046B835 /* ipjsuaViewController_iPhone.xib in Resources */,
+				3AF0582816F050780046B835 /* ipjsuaViewController_iPad.xib in Resources */,
+				3ADCCD171715338D0007BE8E /* pjsua.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		3AF0580016F050770046B835 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3AF0581516F050780046B835 /* main.m in Sources */,
+				3AF0581916F050780046B835 /* ipjsuaAppDelegate.m in Sources */,
+				3AF0582216F050780046B835 /* ipjsuaViewController.m in Sources */,
+				3ADCCD2D172E40120007BE8E /* pjsua_app_cli.c in Sources */,
+				3ADCCD2E172E40120007BE8E /* pjsua_app_common.c in Sources */,
+				3ADCCD2F172E40120007BE8E /* pjsua_app_config.c in Sources */,
+				3ADCCD30172E40120007BE8E /* pjsua_app_legacy.c in Sources */,
+				3ADCCD31172E40120007BE8E /* pjsua_app.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		3AF0581116F050780046B835 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				3AF0581216F050780046B835 /* en */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+		3AF0582316F050780046B835 /* ipjsuaViewController_iPhone.xib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				3AF0582416F050780046B835 /* en */,
+			);
+			name = ipjsuaViewController_iPhone.xib;
+			sourceTree = "<group>";
+		};
+		3AF0582616F050780046B835 /* ipjsuaViewController_iPad.xib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				3AF0582716F050780046B835 /* en */,
+			);
+			name = ipjsuaViewController_iPad.xib;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		3AF0582916F050780046B835 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		3AF0582A16F050780046B835 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+				OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		3AF0582C16F050780046B835 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "ipjsua/ipjsua-Prefix.pch";
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"PJ_AUTOCONF=1",
+					USE_GUI,
+				);
+				HEADER_SEARCH_PATHS = (
+					../../../../pjsip/include,
+					../../../../pjlib/include,
+					"../../../../pjlib-util/include",
+					../../../../pjnath/include,
+					../../../../pjmedia/include,
+					..,
+				);
+				INFOPLIST_FILE = "ipjsua/ipjsua-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)\"",
+					"\"$(SRCROOT)/../../../../pjlib/lib\"",
+					"\"$(SRCROOT)/../../../../pjlib-util/lib\"",
+					"\"$(SRCROOT)/../../../../pjmedia/lib\"",
+					"\"$(SRCROOT)/../../../../pjnath/lib\"",
+					"\"$(SRCROOT)/../../../../pjsip/lib\"",
+					"\"$(SRCROOT)/../../../../third_party/lib\"",
+				);
+				ONLY_ACTIVE_ARCH = YES;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				VALID_ARCHS = armv7;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Debug;
+		};
+		3AF0582D16F050780046B835 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "ipjsua/ipjsua-Prefix.pch";
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"PJ_AUTOCONF=1",
+					USE_GUI,
+				);
+				HEADER_SEARCH_PATHS = (
+					../../../../pjsip/include,
+					../../../../pjlib/include,
+					"../../../../pjlib-util/include",
+					../../../../pjnath/include,
+					../../../../pjmedia/include,
+					..,
+				);
+				INFOPLIST_FILE = "ipjsua/ipjsua-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)\"",
+					"\"$(SRCROOT)/../../../../pjlib/lib\"",
+					"\"$(SRCROOT)/../../../../pjlib-util/lib\"",
+					"\"$(SRCROOT)/../../../../pjmedia/lib\"",
+					"\"$(SRCROOT)/../../../../pjnath/lib\"",
+					"\"$(SRCROOT)/../../../../pjsip/lib\"",
+					"\"$(SRCROOT)/../../../../third_party/lib\"",
+				);
+				ONLY_ACTIVE_ARCH = YES;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				VALID_ARCHS = armv7;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		3AF057FE16F050770046B835 /* Build configuration list for PBXProject "ipjsua" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3AF0582916F050780046B835 /* Debug */,
+				3AF0582A16F050780046B835 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		3AF0582B16F050780046B835 /* Build configuration list for PBXNativeTarget "ipjsua" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3AF0582C16F050780046B835 /* Debug */,
+				3AF0582D16F050780046B835 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 3AF057FB16F050770046B835 /* Project object */;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/Default-568h@2x.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/Default-568h@2x.png
new file mode 100644
index 0000000..0891b7a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/Default-568h@2x.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/Default.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/Default.png
new file mode 100644
index 0000000..4c8ca6f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/Default.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/Default@2x.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/Default@2x.png
new file mode 100644
index 0000000..35b84cf
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/Default@2x.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/en.lproj/InfoPlist.strings b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/en.lproj/InfoPlist.strings
new file mode 100644
index 0000000..477b28f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/en.lproj/ipjsuaViewController_iPad.xib b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/en.lproj/ipjsuaViewController_iPad.xib
new file mode 100644
index 0000000..4f574f6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/en.lproj/ipjsuaViewController_iPad.xib
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
+	<data>
+		<int key="IBDocument.SystemTarget">1536</int>
+		<string key="IBDocument.SystemVersion">12A206j</string>
+		<string key="IBDocument.InterfaceBuilderVersion">2519</string>
+		<string key="IBDocument.AppKitVersion">1172.1</string>
+		<string key="IBDocument.HIToolboxVersion">613.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">1856</string>
+		</object>
+		<array key="IBDocument.IntegratedClassDependencies">
+			<string>IBProxyObject</string>
+			<string>IBUIView</string>
+		</array>
+		<array key="IBDocument.PluginDependencies">
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</array>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+			<integer value="1" key="NS.object.0"/>
+		</object>
+		<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+			<object class="IBProxyObject" id="841351856">
+				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+			</object>
+			<object class="IBProxyObject" id="606714003">
+				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+			</object>
+			<object class="IBUIView" id="766721923">
+				<reference key="NSNextResponder"/>
+				<int key="NSvFlags">274</int>
+				<string key="NSFrame">{{0, 20}, {768, 1004}}</string>
+				<reference key="NSSuperview"/>
+				<reference key="NSWindow"/>
+				<object class="NSColor" key="IBUIBackgroundColor">
+					<int key="NSColorSpace">3</int>
+					<bytes key="NSWhite">MQA</bytes>
+					<object class="NSColorSpace" key="NSCustomColorSpace">
+						<int key="NSID">2</int>
+					</object>
+				</object>
+				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics">
+					<int key="IBUIStatusBarStyle">2</int>
+				</object>
+				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+			</object>
+		</array>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<array class="NSMutableArray" key="connectionRecords">
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">view</string>
+						<reference key="source" ref="841351856"/>
+						<reference key="destination" ref="766721923"/>
+					</object>
+					<int key="connectionID">3</int>
+				</object>
+			</array>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<array key="orderedObjects">
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<array key="object" id="0"/>
+						<reference key="children" ref="1000"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="841351856"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="606714003"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">2</int>
+						<reference key="object" ref="766721923"/>
+						<reference key="parent" ref="0"/>
+					</object>
+				</array>
+			</object>
+			<dictionary class="NSMutableDictionary" key="flattenedProperties">
+				<string key="-1.CustomClassName">ipjsuaViewController</string>
+				<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="-2.CustomClassName">UIResponder</string>
+				<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			</dictionary>
+			<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+			<nil key="activeLocalization"/>
+			<dictionary class="NSMutableDictionary" key="localizations"/>
+			<nil key="sourceID"/>
+			<int key="maxID">3</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<array class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<object class="IBPartialClassDescription">
+					<string key="className">ipjsuaViewController</string>
+					<string key="superclassName">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">./Classes/ipjsuaViewController.h</string>
+					</object>
+				</object>
+			</array>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<bool key="IBDocument.UseAutolayout">YES</bool>
+		<string key="IBCocoaTouchPluginVersion">1856</string>
+	</data>
+</archive>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/en.lproj/ipjsuaViewController_iPhone.xib b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/en.lproj/ipjsuaViewController_iPhone.xib
new file mode 100644
index 0000000..37bf20d
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/en.lproj/ipjsuaViewController_iPhone.xib
@@ -0,0 +1,369 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+	<data>
+		<int key="IBDocument.SystemTarget">1536</int>
+		<string key="IBDocument.SystemVersion">11G63b</string>
+		<string key="IBDocument.InterfaceBuilderVersion">2840</string>
+		<string key="IBDocument.AppKitVersion">1138.51</string>
+		<string key="IBDocument.HIToolboxVersion">569.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">1926</string>
+		</object>
+		<array key="IBDocument.IntegratedClassDependencies">
+			<string>IBNSLayoutConstraint</string>
+			<string>IBProxyObject</string>
+			<string>IBUIImageView</string>
+			<string>IBUILabel</string>
+			<string>IBUIView</string>
+		</array>
+		<array key="IBDocument.PluginDependencies">
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</array>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+			<integer value="1" key="NS.object.0"/>
+		</object>
+		<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+			<object class="IBProxyObject" id="372490531">
+				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+			<object class="IBProxyObject" id="843779117">
+				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+			<object class="IBUIView" id="774585933">
+				<reference key="NSNextResponder"/>
+				<int key="NSvFlags">274</int>
+				<array class="NSMutableArray" key="NSSubviews">
+					<object class="IBUIImageView" id="481975117">
+						<reference key="NSNextResponder" ref="774585933"/>
+						<int key="NSvFlags">292</int>
+						<string key="NSFrameSize">{320, 528}</string>
+						<reference key="NSSuperview" ref="774585933"/>
+						<reference key="NSWindow"/>
+						<reference key="NSNextKeyView" ref="774652835"/>
+						<string key="NSReuseIdentifierKey">_NS:9</string>
+						<object class="NSColor" key="IBUIBackgroundColor" id="548338407">
+							<int key="NSColorSpace">3</int>
+							<bytes key="NSWhite">MAA</bytes>
+						</object>
+						<int key="IBUIContentMode">5</int>
+						<bool key="IBUIUserInteractionEnabled">NO</bool>
+						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+						<object class="NSCustomResource" key="IBUIImage">
+							<string key="NSClassName">NSImage</string>
+							<string key="NSResourceName">pjsua.png</string>
+						</object>
+					</object>
+					<object class="IBUILabel" id="774652835">
+						<reference key="NSNextResponder" ref="774585933"/>
+						<int key="NSvFlags">292</int>
+						<string key="NSFrame">{{0, 527}, {328, 21}}</string>
+						<reference key="NSSuperview" ref="774585933"/>
+						<reference key="NSWindow"/>
+						<reference key="NSNextKeyView"/>
+						<string key="NSReuseIdentifierKey">_NS:9</string>
+						<reference key="IBUIBackgroundColor" ref="548338407"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClipsSubviews">YES</bool>
+						<int key="IBUIContentMode">7</int>
+						<bool key="IBUIUserInteractionEnabled">NO</bool>
+						<string key="IBUIRestorationIdentifier"/>
+						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+						<string key="IBUIText">Telnet to IP:PORT</string>
+						<object class="NSColor" key="IBUITextColor">
+							<int key="NSColorSpace">1</int>
+							<bytes key="NSRGB">MSAxIDEgMC42AA</bytes>
+							<string key="IBUIColorCocoaTouchKeyPath">lightTextColor</string>
+						</object>
+						<nil key="IBUIHighlightedColor"/>
+						<int key="IBUIBaselineAdjustment">0</int>
+						<int key="IBUITextAlignment">1</int>
+						<object class="IBUIFontDescription" key="IBUIFontDescription">
+							<int key="type">1</int>
+							<double key="pointSize">17</double>
+						</object>
+						<object class="NSFont" key="IBUIFont">
+							<string key="NSName">Helvetica</string>
+							<double key="NSSize">17</double>
+							<int key="NSfFlags">16</int>
+						</object>
+						<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+					</object>
+				</array>
+				<string key="NSFrame">{{0, 20}, {320, 548}}</string>
+				<reference key="NSSuperview"/>
+				<reference key="NSWindow"/>
+				<reference key="NSNextKeyView" ref="481975117"/>
+				<object class="NSColor" key="IBUIBackgroundColor">
+					<int key="NSColorSpace">3</int>
+					<bytes key="NSWhite">MC43NQA</bytes>
+					<object class="NSColorSpace" key="NSCustomColorSpace">
+						<int key="NSID">2</int>
+					</object>
+				</object>
+				<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+				<object class="IBUIScreenMetrics" key="IBUISimulatedDestinationMetrics">
+					<string key="IBUISimulatedSizeMetricsClass">IBUIScreenMetrics</string>
+					<object class="NSMutableDictionary" key="IBUINormalizedOrientationToSizeMap">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<array key="dict.sortedKeys">
+							<integer value="1"/>
+							<integer value="3"/>
+						</array>
+						<array key="dict.values">
+							<string>{320, 568}</string>
+							<string>{568, 320}</string>
+						</array>
+					</object>
+					<string key="IBUITargetRuntime">IBCocoaTouchFramework</string>
+					<string key="IBUIDisplayName">Retina 4 Full Screen</string>
+					<int key="IBUIType">2</int>
+				</object>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+		</array>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<array class="NSMutableArray" key="connectionRecords">
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">view</string>
+						<reference key="source" ref="372490531"/>
+						<reference key="destination" ref="774585933"/>
+					</object>
+					<int key="connectionID">37</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">textLabel</string>
+						<reference key="source" ref="372490531"/>
+						<reference key="destination" ref="774652835"/>
+					</object>
+					<int key="connectionID">38</int>
+				</object>
+			</array>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<array key="orderedObjects">
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<array key="object" id="0"/>
+						<reference key="children" ref="1000"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="372490531"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="843779117"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">6</int>
+						<reference key="object" ref="774585933"/>
+						<array class="NSMutableArray" key="children">
+							<object class="IBNSLayoutConstraint" id="475319955">
+								<reference key="firstItem" ref="774652835"/>
+								<int key="firstAttribute">5</int>
+								<int key="relation">0</int>
+								<reference key="secondItem" ref="774585933"/>
+								<int key="secondAttribute">5</int>
+								<float key="multiplier">1</float>
+								<object class="IBLayoutConstant" key="constant">
+									<double key="value">0.0</double>
+								</object>
+								<float key="priority">1000</float>
+								<reference key="containingView" ref="774585933"/>
+								<int key="scoringType">8</int>
+								<float key="scoringTypeFloat">29</float>
+								<int key="contentType">3</int>
+							</object>
+							<object class="IBNSLayoutConstraint" id="853380236">
+								<reference key="firstItem" ref="774652835"/>
+								<int key="firstAttribute">4</int>
+								<int key="relation">0</int>
+								<reference key="secondItem" ref="774585933"/>
+								<int key="secondAttribute">4</int>
+								<float key="multiplier">1</float>
+								<object class="IBLayoutConstant" key="constant">
+									<double key="value">0.0</double>
+								</object>
+								<float key="priority">1000</float>
+								<reference key="containingView" ref="774585933"/>
+								<int key="scoringType">8</int>
+								<float key="scoringTypeFloat">29</float>
+								<int key="contentType">3</int>
+							</object>
+							<object class="IBNSLayoutConstraint" id="540227159">
+								<reference key="firstItem" ref="481975117"/>
+								<int key="firstAttribute">3</int>
+								<int key="relation">0</int>
+								<reference key="secondItem" ref="774585933"/>
+								<int key="secondAttribute">3</int>
+								<float key="multiplier">1</float>
+								<object class="IBLayoutConstant" key="constant">
+									<double key="value">0.0</double>
+								</object>
+								<float key="priority">1000</float>
+								<reference key="containingView" ref="774585933"/>
+								<int key="scoringType">8</int>
+								<float key="scoringTypeFloat">29</float>
+								<int key="contentType">3</int>
+							</object>
+							<object class="IBNSLayoutConstraint" id="591865091">
+								<reference key="firstItem" ref="481975117"/>
+								<int key="firstAttribute">5</int>
+								<int key="relation">0</int>
+								<reference key="secondItem" ref="774585933"/>
+								<int key="secondAttribute">5</int>
+								<float key="multiplier">1</float>
+								<object class="IBLayoutConstant" key="constant">
+									<double key="value">0.0</double>
+								</object>
+								<float key="priority">1000</float>
+								<reference key="containingView" ref="774585933"/>
+								<int key="scoringType">8</int>
+								<float key="scoringTypeFloat">29</float>
+								<int key="contentType">3</int>
+							</object>
+							<reference ref="774652835"/>
+							<reference ref="481975117"/>
+						</array>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">8</int>
+						<reference key="object" ref="774652835"/>
+						<array class="NSMutableArray" key="children">
+							<object class="IBNSLayoutConstraint" id="830204274">
+								<reference key="firstItem" ref="774652835"/>
+								<int key="firstAttribute">7</int>
+								<int key="relation">0</int>
+								<nil key="secondItem"/>
+								<int key="secondAttribute">0</int>
+								<float key="multiplier">1</float>
+								<object class="IBLayoutConstant" key="constant">
+									<double key="value">328</double>
+								</object>
+								<float key="priority">1000</float>
+								<reference key="containingView" ref="774652835"/>
+								<int key="scoringType">3</int>
+								<float key="scoringTypeFloat">9</float>
+								<int key="contentType">1</int>
+							</object>
+						</array>
+						<reference key="parent" ref="774585933"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">15</int>
+						<reference key="object" ref="830204274"/>
+						<reference key="parent" ref="774652835"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">19</int>
+						<reference key="object" ref="853380236"/>
+						<reference key="parent" ref="774585933"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">20</int>
+						<reference key="object" ref="475319955"/>
+						<reference key="parent" ref="774585933"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">21</int>
+						<reference key="object" ref="481975117"/>
+						<array class="NSMutableArray" key="children"/>
+						<reference key="parent" ref="774585933"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">31</int>
+						<reference key="object" ref="540227159"/>
+						<reference key="parent" ref="774585933"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">30</int>
+						<reference key="object" ref="591865091"/>
+						<reference key="parent" ref="774585933"/>
+					</object>
+				</array>
+			</object>
+			<dictionary class="NSMutableDictionary" key="flattenedProperties">
+				<string key="-1.CustomClassName">ipjsuaViewController</string>
+				<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="-2.CustomClassName">UIResponder</string>
+				<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="15.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="19.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="20.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="21.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<boolean value="NO" key="21.IBViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+				<string key="30.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="31.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<array class="NSMutableArray" key="6.IBViewMetadataConstraints">
+					<reference ref="591865091"/>
+					<reference ref="540227159"/>
+					<reference ref="853380236"/>
+					<reference ref="475319955"/>
+				</array>
+				<string key="8.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<array class="NSMutableArray" key="8.IBViewMetadataConstraints">
+					<reference ref="830204274"/>
+				</array>
+				<boolean value="NO" key="8.IBViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+			</dictionary>
+			<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+			<nil key="activeLocalization"/>
+			<dictionary class="NSMutableDictionary" key="localizations"/>
+			<nil key="sourceID"/>
+			<int key="maxID">45</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<array class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<object class="IBPartialClassDescription">
+					<string key="className">NSLayoutConstraint</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">ipjsuaViewController</string>
+					<string key="superclassName">UIViewController</string>
+					<object class="NSMutableDictionary" key="outlets">
+						<string key="NS.key.0">textLabel</string>
+						<string key="NS.object.0">UILabel</string>
+					</object>
+					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
+						<string key="NS.key.0">textLabel</string>
+						<object class="IBToOneOutletInfo" key="NS.object.0">
+							<string key="name">textLabel</string>
+							<string key="candidateClassName">UILabel</string>
+						</object>
+					</object>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">./Classes/ipjsuaViewController.h</string>
+					</object>
+				</object>
+			</array>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+			<string key="NS.key.0">pjsua.png</string>
+			<string key="NS.object.0">{320, 528}</string>
+		</object>
+		<bool key="IBDocument.UseAutolayout">YES</bool>
+		<string key="IBCocoaTouchPluginVersion">1926</string>
+	</data>
+</archive>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsua-Info.plist b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsua-Info.plist
new file mode 100644
index 0000000..3811acf
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsua-Info.plist
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.teluu.${PRODUCT_NAME:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UIBackgroundModes</key>
+	<array>
+		<string>audio</string>
+		<string>voip</string>
+	</array>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+	</array>
+</dict>
+</plist>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsua-Prefix.pch b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsua-Prefix.pch
new file mode 100644
index 0000000..352e658
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsua-Prefix.pch
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'ipjsua' target in the 'ipjsua' project
+//
+
+#import <Availability.h>
+
+#ifndef __IPHONE_4_0
+#warning "This project uses features only available in iOS SDK 4.0 and later."
+#endif
+
+#ifdef __OBJC__
+    #import <UIKit/UIKit.h>
+    #import <Foundation/Foundation.h>
+#endif
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaAppDelegate.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaAppDelegate.h
new file mode 100644
index 0000000..56e6d3e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaAppDelegate.h
@@ -0,0 +1,19 @@
+//
+//  ipjsuaAppDelegate.h
+//  ipjsua
+//
+//  Created by Liong Sauw Ming on 13/3/13.
+//  Copyright (c) 2013 Teluu. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class ipjsuaViewController;
+
+@interface ipjsuaAppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+@property (strong, nonatomic) ipjsuaViewController *viewController;
+
+@end
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaAppDelegate.m b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaAppDelegate.m
new file mode 100644
index 0000000..5bcf240
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaAppDelegate.m
@@ -0,0 +1,218 @@
+//
+//  ipjsuaAppDelegate.m
+//  ipjsua
+//
+//  Created by Liong Sauw Ming on 13/3/13.
+//  Copyright (c) 2013 Teluu. All rights reserved.
+//
+
+#import "ipjsuaAppDelegate.h"
+#import <pjlib.h>
+#import <pjsua.h>
+#import <pj/log.h>
+
+#include "../../pjsua_app.h"
+#include "../../pjsua_app_config.h"
+
+#import "ipjsuaViewController.h"
+
+@implementation ipjsuaAppDelegate
+
+#define THIS_FILE	"ipjsuaAppDelegate.m"
+
+#define KEEP_ALIVE_INTERVAL 600
+
+ipjsuaAppDelegate      *app;
+static pjsua_app_cfg_t  app_cfg;
+static bool             isShuttingDown;
+static char           **restartArgv;
+static int              restartArgc;
+static pj_thread_desc   a_thread_desc;
+static pj_thread_t     *a_thread;
+
+static void displayMsg(const char *msg)
+{
+    NSString *str = [NSString stringWithFormat:@"%s", msg];
+    [app performSelectorOnMainThread:@selector(displayMsg:) withObject:str
+                       waitUntilDone:NO];
+}
+
+static void pjsuaOnStartedCb(pj_status_t status, const char* msg)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    
+    if (status != PJ_SUCCESS && (!msg || !*msg)) {
+	pj_strerror(status, errmsg, sizeof(errmsg));
+	PJ_LOG(3,(THIS_FILE, "Error: %s", errmsg));
+	msg = errmsg;
+    } else {
+	PJ_LOG(3,(THIS_FILE, "Started: %s", msg));
+    }
+
+    displayMsg(msg);
+}
+
+static void pjsuaOnStoppedCb(pj_bool_t restart,
+                             int argc, char** argv)
+{
+    PJ_LOG(3,("ipjsua", "CLI %s request", (restart? "restart" : "shutdown")));
+    if (restart) {
+        displayMsg("Restarting..");
+	pj_thread_sleep(100);
+        app_cfg.argc = argc;
+        app_cfg.argv = argv;
+    } else {
+        displayMsg("Shutting down..");
+	pj_thread_sleep(100);
+        isShuttingDown = true;
+    }
+}
+
+static void pjsuaOnAppConfigCb(pjsua_app_config *cfg)
+{
+    PJ_UNUSED_ARG(cfg);
+}
+
+- (void)displayMsg:(NSString *)str
+{
+    app.viewController.textLabel.text = str;
+}
+
+- (void)pjsuaStart
+{
+    // TODO: read from config?
+    const char **argv = pjsua_app_def_argv;
+    int argc = PJ_ARRAY_SIZE(pjsua_app_def_argv) -1;
+    pj_status_t status;
+    
+    isShuttingDown = false;
+    displayMsg("Starting..");
+    
+    pj_bzero(&app_cfg, sizeof(app_cfg));
+    if (restartArgc) {
+	app_cfg.argc = restartArgc;
+	app_cfg.argv = restartArgv;
+    } else {
+	app_cfg.argc = argc;
+	app_cfg.argv = (char**)argv;
+    }
+    app_cfg.on_started = &pjsuaOnStartedCb;
+    app_cfg.on_stopped = &pjsuaOnStoppedCb;
+    app_cfg.on_config_init = &pjsuaOnAppConfigCb;
+    
+    while (!isShuttingDown) {
+        status = pjsua_app_init(&app_cfg);
+        if (status != PJ_SUCCESS) {
+            char errmsg[PJ_ERR_MSG_SIZE];
+            pj_strerror(status, errmsg, sizeof(errmsg));
+            displayMsg(errmsg);
+            pjsua_app_destroy();
+            return;
+        }
+    
+        status = pjsua_app_run(PJ_TRUE);
+        if (status != PJ_SUCCESS) {
+            char errmsg[PJ_ERR_MSG_SIZE];
+            pj_strerror(status, errmsg, sizeof(errmsg));
+            displayMsg(errmsg);
+        }
+    
+        pjsua_app_destroy();
+    }
+    
+    restartArgv = NULL;
+    restartArgc = 0;
+}
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+    // Override point for customization after application launch.
+    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
+        self.viewController = [[ipjsuaViewController alloc] initWithNibName:@"ipjsuaViewController_iPhone" bundle:nil];
+    } else {
+        self.viewController = [[ipjsuaViewController alloc] initWithNibName:@"ipjsuaViewController_iPad" bundle:nil];
+    }
+    self.window.rootViewController = self.viewController;
+    [self.window makeKeyAndVisible];
+    
+    app = self;
+    
+    /* Start pjsua app thread */
+    [NSThread detachNewThreadSelector:@selector(pjsuaStart) toTarget:self withObject:nil];
+
+    return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)keepAlive {
+    int i;
+    
+    if (!pj_thread_is_registered())
+    {
+	pj_thread_register("ipjsua", a_thread_desc, &a_thread);
+    }
+    
+    /* Since iOS requires that the minimum keep alive interval is 600s,
+     * application needs to make sure that the account's registration
+     * timeout is long enough.
+     */
+    for (i = 0; i < (int)pjsua_acc_get_count(); ++i) {
+        if (pjsua_acc_is_valid(i)) {
+            pjsua_acc_set_registration(i, PJ_TRUE);
+        }
+    }
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
+    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+    [self performSelectorOnMainThread:@selector(keepAlive) withObject:nil waitUntilDone:YES];
+    [application setKeepAliveTimeout:KEEP_ALIVE_INTERVAL handler: ^{
+	[self performSelectorOnMainThread:@selector(keepAlive) withObject:nil waitUntilDone:YES];
+    }];
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+
+pj_bool_t showNotification(pjsua_call_id call_id)
+{
+    // Create a new notification
+    UILocalNotification* alert = [[UILocalNotification alloc] init];
+    if (alert)
+    {
+	alert.repeatInterval = 0;
+	alert.alertBody = @"Incoming call received...";
+        /* This action just brings the app to the FG, it doesn't
+         * automatically answer the call (unless you specify the
+         * --auto-answer option).
+         */
+	alert.alertAction = @"Activate app";
+	
+	[[UIApplication sharedApplication] presentLocalNotificationNow:alert];
+    }
+    
+    return PJ_FALSE;
+}
+
+@end
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaViewController.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaViewController.h
new file mode 100644
index 0000000..1b892756
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaViewController.h
@@ -0,0 +1,15 @@
+//
+//  ipjsuaViewController.h
+//  ipjsua
+//
+//  Created by Liong Sauw Ming on 13/3/13.
+//  Copyright (c) 2013 Teluu. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface ipjsuaViewController : UIViewController
+
+@property (nonatomic, retain) IBOutlet UILabel *textLabel;
+
+@end
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaViewController.m b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaViewController.m
new file mode 100644
index 0000000..44b335e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaViewController.m
@@ -0,0 +1,33 @@
+//
+//  ipjsuaViewController.m
+//  ipjsua
+//
+//  Created by Liong Sauw Ming on 13/3/13.
+//  Copyright (c) 2013 Teluu. All rights reserved.
+//
+
+#import "ipjsuaViewController.h"
+
+@interface ipjsuaViewController ()
+
+@end
+
+@implementation ipjsuaViewController
+
+@synthesize textLabel;
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    // Do any additional setup after loading the view, typically from a nib.
+
+    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
+}
+
+- (void)didReceiveMemoryWarning
+{
+    [super didReceiveMemoryWarning];
+    // Dispose of any resources that can be recreated.
+}
+
+@end
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/main.m b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/main.m
new file mode 100644
index 0000000..dc2242d
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/main.m
@@ -0,0 +1,18 @@
+//
+//  main.m
+//  ipjsua
+//
+//  Created by Liong Sauw Ming on 13/3/13.
+//  Copyright (c) 2013 Teluu. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+#import "ipjsuaAppDelegate.h"
+
+int main(int argc, char *argv[])
+{
+    @autoreleasepool {
+        return UIApplicationMain(argc, argv, nil, NSStringFromClass([ipjsuaAppDelegate class]));
+    }
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/pjsua.png b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/pjsua.png
new file mode 100644
index 0000000..4ce4011
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/ios/ipjsua/pjsua.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/main.c b/jni/libpjsip/sources/pjsip-apps/src/pjsua/main.c
new file mode 100644
index 0000000..5c785f9
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/main.c
@@ -0,0 +1,125 @@
+/* $Id: main.c 4704 2014-01-16 05:30:46Z ming $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 "pjsua_app.h"
+
+#define THIS_FILE	"main.c"
+
+static pj_bool_t	    running = PJ_TRUE;
+static pj_status_t	    receive_end_sig;
+static pj_thread_t	    *sig_thread;
+static pjsua_app_cfg_t	    cfg;
+
+/* Called when CLI (re)started */
+void on_app_started(pj_status_t status, const char *msg)
+{
+    pj_perror(3, THIS_FILE, status, (msg)?msg:"");
+}
+
+void on_app_stopped(pj_bool_t restart, int argc, char** argv)
+{
+    if (argv) {
+	cfg.argc = argc;
+	cfg.argv = argv;
+    }
+
+    running = restart;
+}
+
+#if defined(PJ_WIN32) && PJ_WIN32!=0
+#include <windows.h>
+
+static pj_thread_desc handler_desc;
+
+static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
+{   
+    switch (fdwCtrlType) 
+    { 
+        // Handle the CTRL+C signal. 
+ 
+        case CTRL_C_EVENT: 
+        case CTRL_CLOSE_EVENT: 
+        case CTRL_BREAK_EVENT: 
+        case CTRL_LOGOFF_EVENT: 
+        case CTRL_SHUTDOWN_EVENT: 
+	    pj_thread_register("ctrlhandler", handler_desc, &sig_thread);
+	    PJ_LOG(3,(THIS_FILE, "Ctrl-C detected, quitting.."));
+	    receive_end_sig = PJ_TRUE;
+            pjsua_app_destroy();	    
+	    ExitProcess(1);
+            PJ_UNREACHED(return TRUE;)
+ 
+        default: 
+ 
+            return FALSE; 
+    } 
+}
+
+static void setup_socket_signal()
+{
+}
+
+static void setup_signal_handler(void)
+{
+    SetConsoleCtrlHandler(&CtrlHandler, TRUE);
+}
+
+#else
+#include <signal.h>
+
+static void setup_socket_signal()
+{
+    signal(SIGPIPE, SIG_IGN);
+}
+
+static void setup_signal_handler(void) {}
+#endif
+
+int main(int argc, char *argv[])
+{
+    pj_status_t status = PJ_TRUE;
+
+    pj_bzero(&cfg, sizeof(cfg));
+    cfg.on_started = &on_app_started;
+    cfg.on_stopped = &on_app_stopped;
+    cfg.argc = argc;
+    cfg.argv = argv;
+
+    setup_signal_handler();
+    setup_socket_signal();
+
+    while (running) {        
+	status = pjsua_app_init(&cfg);
+	if (status == PJ_SUCCESS) {
+	    status = pjsua_app_run(PJ_TRUE);
+	} else {
+	    running = PJ_FALSE;
+	}
+
+	if (!receive_end_sig) {
+	    pjsua_app_destroy();
+
+	    /* This is on purpose */
+	    pjsua_app_destroy();
+	} else {
+	    pj_thread_join(sig_thread);
+	}
+    }
+    return 0;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/main_rtems.c b/jni/libpjsip/sources/pjsip-apps/src/pjsua/main_rtems.c
new file mode 100644
index 0000000..d26605a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/main_rtems.c
@@ -0,0 +1,12 @@
+
+/* 
+ *  !! OIY OIY !!
+ *
+ *  The purpose of this file is only to get the executable linked. I haven't
+ *  actually tried to run this on RTEMS!!
+ *
+ */
+
+#include "../../pjlib/src/pjlib-test/main_rtems.c"
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app.c b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app.c
new file mode 100644
index 0000000..e7b66ff
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app.c
@@ -0,0 +1,2116 @@
+/* $Id: pjsua_app.c 4634 2013-10-23 09:29:35Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 "pjsua_app.h"
+
+#define THIS_FILE	"pjsua_app.c"
+
+//#define STEREO_DEMO
+//#define TRANSPORT_ADAPTER_SAMPLE
+//#define HAVE_MULTIPART_TEST
+
+/* Ringtones		    US	       UK  */
+#define RINGBACK_FREQ1	    440	    /* 400 */
+#define RINGBACK_FREQ2	    480	    /* 450 */
+#define RINGBACK_ON	    2000    /* 400 */
+#define RINGBACK_OFF	    4000    /* 200 */
+#define RINGBACK_CNT	    1	    /* 2   */
+#define RINGBACK_INTERVAL   4000    /* 2000 */
+
+#define RING_FREQ1	    800
+#define RING_FREQ2	    640
+#define RING_ON		    200
+#define RING_OFF	    100
+#define RING_CNT	    3
+#define RING_INTERVAL	    3000
+
+#define current_acc	pjsua_acc_get_default()
+
+#ifdef STEREO_DEMO
+static void stereo_demo();
+#endif
+
+static void ringback_start(pjsua_call_id call_id);
+static void ring_start(pjsua_call_id call_id);
+static void ring_stop(pjsua_call_id call_id);
+static pj_status_t app_init();
+static pj_status_t app_destroy();
+
+static pjsua_app_cfg_t app_cfg;
+pj_str_t		    uri_arg;
+pj_bool_t		    app_running	= PJ_FALSE;
+
+/*****************************************************************************
+ * Configuration manipulation
+ */
+
+/*****************************************************************************
+ * Callback 
+ */
+static void ringback_start(pjsua_call_id call_id)
+{
+    if (app_config.no_tones)
+	return;
+
+    if (app_config.call_data[call_id].ringback_on)
+	return;
+
+    app_config.call_data[call_id].ringback_on = PJ_TRUE;
+
+    if (++app_config.ringback_cnt==1 && 
+	app_config.ringback_slot!=PJSUA_INVALID_ID) 
+    {
+	pjsua_conf_connect(app_config.ringback_slot, 0);
+    }
+}
+
+static void ring_stop(pjsua_call_id call_id)
+{
+    if (app_config.no_tones)
+	return;
+
+    if (app_config.call_data[call_id].ringback_on) {
+	app_config.call_data[call_id].ringback_on = PJ_FALSE;
+
+	pj_assert(app_config.ringback_cnt>0);
+	if (--app_config.ringback_cnt == 0 && 
+	    app_config.ringback_slot!=PJSUA_INVALID_ID) 
+	{
+	    pjsua_conf_disconnect(app_config.ringback_slot, 0);
+	    pjmedia_tonegen_rewind(app_config.ringback_port);
+	}
+    }
+
+    if (app_config.call_data[call_id].ring_on) {
+	app_config.call_data[call_id].ring_on = PJ_FALSE;
+
+	pj_assert(app_config.ring_cnt>0);
+	if (--app_config.ring_cnt == 0 && 
+	    app_config.ring_slot!=PJSUA_INVALID_ID) 
+	{
+	    pjsua_conf_disconnect(app_config.ring_slot, 0);
+	    pjmedia_tonegen_rewind(app_config.ring_port);
+	}
+    }
+}
+
+static void ring_start(pjsua_call_id call_id)
+{
+    if (app_config.no_tones)
+	return;
+
+    if (app_config.call_data[call_id].ring_on)
+	return;
+
+    app_config.call_data[call_id].ring_on = PJ_TRUE;
+
+    if (++app_config.ring_cnt==1 && 
+	app_config.ring_slot!=PJSUA_INVALID_ID) 
+    {
+	pjsua_conf_connect(app_config.ring_slot, 0);
+    }
+}
+
+/* Callback from timer when the maximum call duration has been
+ * exceeded.
+ */
+static void call_timeout_callback(pj_timer_heap_t *timer_heap,
+				  struct pj_timer_entry *entry)
+{
+    pjsua_call_id call_id = entry->id;
+    pjsua_msg_data msg_data;
+    pjsip_generic_string_hdr warn;
+    pj_str_t hname = pj_str("Warning");
+    pj_str_t hvalue = pj_str("399 pjsua \"Call duration exceeded\"");
+
+    PJ_UNUSED_ARG(timer_heap);
+
+    if (call_id == PJSUA_INVALID_ID) {
+	PJ_LOG(1,(THIS_FILE, "Invalid call ID in timer callback"));
+	return;
+    }
+    
+    /* Add warning header */
+    pjsua_msg_data_init(&msg_data);
+    pjsip_generic_string_hdr_init2(&warn, &hname, &hvalue);
+    pj_list_push_back(&msg_data.hdr_list, &warn);
+
+    /* Call duration has been exceeded; disconnect the call */
+    PJ_LOG(3,(THIS_FILE, "Duration (%d seconds) has been exceeded "
+			 "for call %d, disconnecting the call",
+			 app_config.duration, call_id));
+    entry->id = PJSUA_INVALID_ID;
+    pjsua_call_hangup(call_id, 200, NULL, &msg_data);
+}
+
+/*
+ * Handler when invite state has changed.
+ */
+static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
+{
+    pjsua_call_info call_info;
+
+    PJ_UNUSED_ARG(e);
+
+    pjsua_call_get_info(call_id, &call_info);
+
+    if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) {
+
+	/* Stop all ringback for this call */
+	ring_stop(call_id);
+
+	/* Cancel duration timer, if any */
+	if (app_config.call_data[call_id].timer.id != PJSUA_INVALID_ID) {
+	    app_call_data *cd = &app_config.call_data[call_id];
+	    pjsip_endpoint *endpt = pjsua_get_pjsip_endpt();
+
+	    cd->timer.id = PJSUA_INVALID_ID;
+	    pjsip_endpt_cancel_timer(endpt, &cd->timer);
+	}
+
+	/* Rewind play file when hangup automatically, 
+	 * since file is not looped
+	 */
+	if (app_config.auto_play_hangup)
+	    pjsua_player_set_pos(app_config.wav_id, 0);
+
+
+	PJ_LOG(3,(THIS_FILE, "Call %d is DISCONNECTED [reason=%d (%s)]", 
+		  call_id,
+		  call_info.last_status,
+		  call_info.last_status_text.ptr));
+
+	if (call_id == current_call) {
+	    find_next_call();
+	}
+
+	/* Dump media state upon disconnected */
+	if (1) {
+	    PJ_LOG(5,(THIS_FILE, 
+		      "Call %d disconnected, dumping media stats..", 
+		      call_id));
+	    log_call_dump(call_id);
+	}
+
+    } else {
+
+	if (app_config.duration != PJSUA_APP_NO_LIMIT_DURATION && 
+	    call_info.state == PJSIP_INV_STATE_CONFIRMED) 
+	{
+	    /* Schedule timer to hangup call after the specified duration */
+	    app_call_data *cd = &app_config.call_data[call_id];
+	    pjsip_endpoint *endpt = pjsua_get_pjsip_endpt();
+	    pj_time_val delay;
+
+	    cd->timer.id = call_id;
+	    delay.sec = app_config.duration;
+	    delay.msec = 0;
+	    pjsip_endpt_schedule_timer(endpt, &cd->timer, &delay);
+	}
+
+	if (call_info.state == PJSIP_INV_STATE_EARLY) {
+	    int code;
+	    pj_str_t reason;
+	    pjsip_msg *msg;
+
+	    /* This can only occur because of TX or RX message */
+	    pj_assert(e->type == PJSIP_EVENT_TSX_STATE);
+
+	    if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
+		msg = e->body.tsx_state.src.rdata->msg_info.msg;
+	    } else {
+		msg = e->body.tsx_state.src.tdata->msg;
+	    }
+
+	    code = msg->line.status.code;
+	    reason = msg->line.status.reason;
+
+	    /* Start ringback for 180 for UAC unless there's SDP in 180 */
+	    if (call_info.role==PJSIP_ROLE_UAC && code==180 && 
+		msg->body == NULL && 
+		call_info.media_status==PJSUA_CALL_MEDIA_NONE) 
+	    {
+		ringback_start(call_id);
+	    }
+
+	    PJ_LOG(3,(THIS_FILE, "Call %d state changed to %s (%d %.*s)", 
+		      call_id, call_info.state_text.ptr,
+		      code, (int)reason.slen, reason.ptr));
+	} else {
+	    PJ_LOG(3,(THIS_FILE, "Call %d state changed to %s", 
+		      call_id,
+		      call_info.state_text.ptr));
+	}
+
+	if (current_call==PJSUA_INVALID_ID)
+	    current_call = call_id;
+
+    }
+}
+
+/**
+ * Handler when there is incoming call.
+ */
+static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
+			     pjsip_rx_data *rdata)
+{
+    pjsua_call_info call_info;
+
+    PJ_UNUSED_ARG(acc_id);
+    PJ_UNUSED_ARG(rdata);
+
+    pjsua_call_get_info(call_id, &call_info);
+
+    if (current_call==PJSUA_INVALID_ID)
+	current_call = call_id;
+
+#ifdef USE_GUI
+    if (!showNotification(call_id))
+	return;
+#endif
+
+    /* Start ringback */
+    ring_start(call_id);
+    
+    if (app_config.auto_answer > 0) {
+	pjsua_call_setting call_opt;
+
+	pjsua_call_setting_default(&call_opt);
+	call_opt.aud_cnt = app_config.aud_cnt;
+	call_opt.vid_cnt = app_config.vid.vid_cnt;
+
+	pjsua_call_answer2(call_id, &call_opt, app_config.auto_answer, NULL,
+			   NULL);
+    }
+    
+    if (app_config.auto_answer < 200) {
+	char notif_st[80] = {0};
+
+#if PJSUA_HAS_VIDEO
+	if (call_info.rem_offerer && call_info.rem_vid_cnt) {
+	    snprintf(notif_st, sizeof(notif_st), 
+		     "To %s the video, type \"vid %s\" first, "
+		     "before answering the call!\n",
+		     (app_config.vid.vid_cnt? "reject":"accept"),
+		     (app_config.vid.vid_cnt? "disable":"enable"));
+	}
+#endif
+
+	PJ_LOG(3,(THIS_FILE,
+		  "Incoming call for account %d!\n"
+		  "Media count: %d audio & %d video\n"
+		  "%s"
+		  "From: %s\n"
+		  "To: %s\n"
+		  "Press %s to answer or %s to reject call",
+		  acc_id,
+		  call_info.rem_aud_cnt,
+		  call_info.rem_vid_cnt,
+		  notif_st,
+		  call_info.remote_info.ptr,
+		  call_info.local_info.ptr,
+		  (app_config.use_cli?"ca a":"a"),
+		  (app_config.use_cli?"g":"h")));
+    }
+}
+
+/*
+ * Handler when a transaction within a call has changed state.
+ */
+static void on_call_tsx_state(pjsua_call_id call_id,
+			      pjsip_transaction *tsx,
+			      pjsip_event *e)
+{
+    const pjsip_method info_method = 
+    {
+	PJSIP_OTHER_METHOD,
+	{ "INFO", 4 }
+    };
+
+    if (pjsip_method_cmp(&tsx->method, &info_method)==0) {
+	/*
+	 * Handle INFO method.
+	 */
+	const pj_str_t STR_APPLICATION = { "application", 11};
+	const pj_str_t STR_DTMF_RELAY  = { "dtmf-relay", 10 };
+	pjsip_msg_body *body = NULL;
+	pj_bool_t dtmf_info = PJ_FALSE;
+	
+	if (tsx->role == PJSIP_ROLE_UAC) {
+	    if (e->body.tsx_state.type == PJSIP_EVENT_TX_MSG)
+		body = e->body.tsx_state.src.tdata->msg->body;
+	    else
+		body = e->body.tsx_state.tsx->last_tx->msg->body;
+	} else {
+	    if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
+		body = e->body.tsx_state.src.rdata->msg_info.msg->body;
+	}
+	
+	/* Check DTMF content in the INFO message */
+	if (body && body->len &&
+	    pj_stricmp(&body->content_type.type, &STR_APPLICATION)==0 &&
+	    pj_stricmp(&body->content_type.subtype, &STR_DTMF_RELAY)==0)
+	{
+	    dtmf_info = PJ_TRUE;
+	}
+
+	if (dtmf_info && tsx->role == PJSIP_ROLE_UAC && 
+	    (tsx->state == PJSIP_TSX_STATE_COMPLETED ||
+	       (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
+	        e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED))) 
+	{
+	    /* Status of outgoing INFO request */
+	    if (tsx->status_code >= 200 && tsx->status_code < 300) {
+		PJ_LOG(4,(THIS_FILE, 
+			  "Call %d: DTMF sent successfully with INFO",
+			  call_id));
+	    } else if (tsx->status_code >= 300) {
+		PJ_LOG(4,(THIS_FILE, 
+			  "Call %d: Failed to send DTMF with INFO: %d/%.*s",
+			  call_id,
+		          tsx->status_code,
+			  (int)tsx->status_text.slen,
+			  tsx->status_text.ptr));
+	    }
+	} else if (dtmf_info && tsx->role == PJSIP_ROLE_UAS &&
+		   tsx->state == PJSIP_TSX_STATE_TRYING)
+	{
+	    /* Answer incoming INFO with 200/OK */
+	    pjsip_rx_data *rdata;
+	    pjsip_tx_data *tdata;
+	    pj_status_t status;
+
+	    rdata = e->body.tsx_state.src.rdata;
+
+	    if (rdata->msg_info.msg->body) {
+		status = pjsip_endpt_create_response(tsx->endpt, rdata,
+						     200, NULL, &tdata);
+		if (status == PJ_SUCCESS)
+		    status = pjsip_tsx_send_msg(tsx, tdata);
+
+		PJ_LOG(3,(THIS_FILE, "Call %d: incoming INFO:\n%.*s", 
+			  call_id,
+			  (int)rdata->msg_info.msg->body->len,
+			  rdata->msg_info.msg->body->data));
+	    } else {
+		status = pjsip_endpt_create_response(tsx->endpt, rdata,
+						     400, NULL, &tdata);
+		if (status == PJ_SUCCESS)
+		    status = pjsip_tsx_send_msg(tsx, tdata);
+	    }
+	}
+    }
+}
+
+/* General processing for media state. "mi" is the media index */
+static void on_call_generic_media_state(pjsua_call_info *ci, unsigned mi,
+                                        pj_bool_t *has_error)
+{
+    const char *status_name[] = {
+        "None",
+        "Active",
+        "Local hold",
+        "Remote hold",
+        "Error"
+    };
+
+    PJ_UNUSED_ARG(has_error);
+
+    pj_assert(ci->media[mi].status <= PJ_ARRAY_SIZE(status_name));
+    pj_assert(PJSUA_CALL_MEDIA_ERROR == 4);
+
+    PJ_LOG(4,(THIS_FILE, "Call %d media %d [type=%s], status is %s",
+	      ci->id, mi, pjmedia_type_name(ci->media[mi].type),
+	      status_name[ci->media[mi].status]));
+}
+
+/* Process audio media state. "mi" is the media index. */
+static void on_call_audio_state(pjsua_call_info *ci, unsigned mi,
+                                pj_bool_t *has_error)
+{
+    PJ_UNUSED_ARG(has_error);
+
+    /* Stop ringback */
+    ring_stop(ci->id);
+
+    /* Connect ports appropriately when media status is ACTIVE or REMOTE HOLD,
+     * otherwise we should NOT connect the ports.
+     */
+    if (ci->media[mi].status == PJSUA_CALL_MEDIA_ACTIVE ||
+	ci->media[mi].status == PJSUA_CALL_MEDIA_REMOTE_HOLD)
+    {
+	pj_bool_t connect_sound = PJ_TRUE;
+	pj_bool_t disconnect_mic = PJ_FALSE;
+	pjsua_conf_port_id call_conf_slot;
+
+	call_conf_slot = ci->media[mi].stream.aud.conf_slot;
+
+	/* Loopback sound, if desired */
+	if (app_config.auto_loop) {
+	    pjsua_conf_connect(call_conf_slot, call_conf_slot);
+	    connect_sound = PJ_FALSE;
+	}
+
+	/* Automatically record conversation, if desired */
+	if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) {
+	    pjsua_conf_connect(call_conf_slot, app_config.rec_port);
+	}
+
+	/* Stream a file, if desired */
+	if ((app_config.auto_play || app_config.auto_play_hangup) && 
+	    app_config.wav_port != PJSUA_INVALID_ID)
+	{
+	    pjsua_conf_connect(app_config.wav_port, call_conf_slot);
+	    connect_sound = PJ_FALSE;
+	}
+
+	/* Stream AVI, if desired */
+	if (app_config.avi_auto_play &&
+	    app_config.avi_def_idx != PJSUA_INVALID_ID &&
+	    app_config.avi[app_config.avi_def_idx].slot != PJSUA_INVALID_ID)
+	{
+	    pjsua_conf_connect(app_config.avi[app_config.avi_def_idx].slot,
+			       call_conf_slot);
+	    disconnect_mic = PJ_TRUE;
+	}
+
+	/* Put call in conference with other calls, if desired */
+	if (app_config.auto_conf) {
+	    pjsua_call_id call_ids[PJSUA_MAX_CALLS];
+	    unsigned call_cnt=PJ_ARRAY_SIZE(call_ids);
+	    unsigned i;
+
+	    /* Get all calls, and establish media connection between
+	     * this call and other calls.
+	     */
+	    pjsua_enum_calls(call_ids, &call_cnt);
+
+	    for (i=0; i<call_cnt; ++i) {
+		if (call_ids[i] == ci->id)
+		    continue;
+		
+		if (!pjsua_call_has_media(call_ids[i]))
+		    continue;
+
+		pjsua_conf_connect(call_conf_slot,
+				   pjsua_call_get_conf_port(call_ids[i]));
+		pjsua_conf_connect(pjsua_call_get_conf_port(call_ids[i]),
+		                   call_conf_slot);
+
+		/* Automatically record conversation, if desired */
+		if (app_config.auto_rec && app_config.rec_port !=
+					   PJSUA_INVALID_ID)
+		{
+		    pjsua_conf_connect(pjsua_call_get_conf_port(call_ids[i]), 
+				       app_config.rec_port);
+		}
+
+	    }
+
+	    /* Also connect call to local sound device */
+	    connect_sound = PJ_TRUE;
+	}
+
+	/* Otherwise connect to sound device */
+	if (connect_sound) {
+	    pjsua_conf_connect(call_conf_slot, 0);
+	    if (!disconnect_mic)
+		pjsua_conf_connect(0, call_conf_slot);
+
+	    /* Automatically record conversation, if desired */
+	    if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID)
+	    {
+		pjsua_conf_connect(call_conf_slot, app_config.rec_port);
+		pjsua_conf_connect(0, app_config.rec_port);
+	    }
+	}
+    }
+}
+
+/* Process video media state. "mi" is the media index. */
+static void on_call_video_state(pjsua_call_info *ci, unsigned mi,
+                                pj_bool_t *has_error)
+{
+    if (ci->media_status != PJSUA_CALL_MEDIA_ACTIVE)
+	return;
+
+    arrange_window(ci->media[mi].stream.vid.win_in);
+
+    PJ_UNUSED_ARG(has_error);
+}
+
+/*
+ * Callback on media state changed event.
+ * The action may connect the call to sound device, to file, or
+ * to loop the call.
+ */
+static void on_call_media_state(pjsua_call_id call_id)
+{
+    pjsua_call_info call_info;
+    unsigned mi;
+    pj_bool_t has_error = PJ_FALSE;
+
+    pjsua_call_get_info(call_id, &call_info);
+
+    for (mi=0; mi<call_info.media_cnt; ++mi) {
+	on_call_generic_media_state(&call_info, mi, &has_error);
+
+	switch (call_info.media[mi].type) {
+	case PJMEDIA_TYPE_AUDIO:
+	    on_call_audio_state(&call_info, mi, &has_error);
+	    break;
+	case PJMEDIA_TYPE_VIDEO:
+	    on_call_video_state(&call_info, mi, &has_error);
+	    break;
+	default:
+	    /* Make gcc happy about enum not handled by switch/case */
+	    break;
+	}
+    }
+
+    if (has_error) {
+	pj_str_t reason = pj_str("Media failed");
+	pjsua_call_hangup(call_id, 500, &reason, NULL);
+    }
+
+#if PJSUA_HAS_VIDEO
+    /* Check if remote has just tried to enable video */
+    if (call_info.rem_offerer && call_info.rem_vid_cnt)
+    {
+	int vid_idx;
+
+	/* Check if there is active video */
+	vid_idx = pjsua_call_get_vid_stream_idx(call_id);
+	if (vid_idx == -1 || call_info.media[vid_idx].dir == PJMEDIA_DIR_NONE) {
+	    PJ_LOG(3,(THIS_FILE,
+		      "Just rejected incoming video offer on call %d, "
+		      "use \"vid call enable %d\" or \"vid call add\" to "
+		      "enable video!", call_id, vid_idx));
+	}
+    }
+#endif
+}
+
+/*
+ * DTMF callback.
+ */
+static void call_on_dtmf_callback(pjsua_call_id call_id, int dtmf)
+{
+    PJ_LOG(3,(THIS_FILE, "Incoming DTMF on call %d: %c", call_id, dtmf));
+}
+
+/*
+ * Redirection handler.
+ */
+static pjsip_redirect_op call_on_redirected(pjsua_call_id call_id, 
+					    const pjsip_uri *target,
+					    const pjsip_event *e)
+{
+    PJ_UNUSED_ARG(e);
+
+    if (app_config.redir_op == PJSIP_REDIRECT_PENDING) {
+	char uristr[PJSIP_MAX_URL_SIZE];
+	int len;
+
+	len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, target, uristr, 
+			      sizeof(uristr));
+	if (len < 1) {
+	    pj_ansi_strcpy(uristr, "--URI too long--");
+	}
+
+	PJ_LOG(3,(THIS_FILE, "Call %d is being redirected to %.*s. "
+		  "Press 'Ra' to accept+replace To header, 'RA' to accept, "
+		  "'Rr' to reject, or 'Rd' to disconnect.",
+		  call_id, len, uristr));
+    }
+
+    return app_config.redir_op;
+}
+
+/*
+ * Handler registration status has changed.
+ */
+static void on_reg_state(pjsua_acc_id acc_id)
+{
+    PJ_UNUSED_ARG(acc_id);
+
+    // Log already written.
+}
+
+/*
+ * Handler for incoming presence subscription request
+ */
+static void on_incoming_subscribe(pjsua_acc_id acc_id,
+				  pjsua_srv_pres *srv_pres,
+				  pjsua_buddy_id buddy_id,
+				  const pj_str_t *from,
+				  pjsip_rx_data *rdata,
+				  pjsip_status_code *code,
+				  pj_str_t *reason,
+				  pjsua_msg_data *msg_data)
+{
+    /* Just accept the request (the default behavior) */
+    PJ_UNUSED_ARG(acc_id);
+    PJ_UNUSED_ARG(srv_pres);
+    PJ_UNUSED_ARG(buddy_id);
+    PJ_UNUSED_ARG(from);
+    PJ_UNUSED_ARG(rdata);
+    PJ_UNUSED_ARG(code);
+    PJ_UNUSED_ARG(reason);
+    PJ_UNUSED_ARG(msg_data);
+}
+
+
+/*
+ * Handler on buddy state changed.
+ */
+static void on_buddy_state(pjsua_buddy_id buddy_id)
+{
+    pjsua_buddy_info info;
+    pjsua_buddy_get_info(buddy_id, &info);
+
+    PJ_LOG(3,(THIS_FILE, "%.*s status is %.*s, subscription state is %s "
+			 "(last termination reason code=%d %.*s)",
+	      (int)info.uri.slen,
+	      info.uri.ptr,
+	      (int)info.status_text.slen,
+	      info.status_text.ptr,
+	      info.sub_state_name,
+	      info.sub_term_code,
+	      (int)info.sub_term_reason.slen,
+	      info.sub_term_reason.ptr));
+}
+
+
+/*
+ * Subscription state has changed.
+ */
+static void on_buddy_evsub_state(pjsua_buddy_id buddy_id,
+				 pjsip_evsub *sub,
+				 pjsip_event *event)
+{
+    char event_info[80];
+
+    PJ_UNUSED_ARG(sub);
+
+    event_info[0] = '\0';
+
+    if (event->type == PJSIP_EVENT_TSX_STATE &&
+	    event->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
+    {
+	pjsip_rx_data *rdata = event->body.tsx_state.src.rdata;
+	snprintf(event_info, sizeof(event_info),
+		 " (RX %s)",
+		 pjsip_rx_data_get_info(rdata));
+    }
+
+    PJ_LOG(4,(THIS_FILE,
+	      "Buddy %d: subscription state: %s (event: %s%s)",
+	      buddy_id, pjsip_evsub_get_state_name(sub),
+	      pjsip_event_str(event->type),
+	      event_info));
+
+}
+
+
+/**
+ * Incoming IM message (i.e. MESSAGE request)!
+ */
+static void on_pager(pjsua_call_id call_id, const pj_str_t *from, 
+		     const pj_str_t *to, const pj_str_t *contact,
+		     const pj_str_t *mime_type, const pj_str_t *text)
+{
+    /* Note: call index may be -1 */
+    PJ_UNUSED_ARG(call_id);
+    PJ_UNUSED_ARG(to);
+    PJ_UNUSED_ARG(contact);
+    PJ_UNUSED_ARG(mime_type);
+
+    PJ_LOG(3,(THIS_FILE,"MESSAGE from %.*s: %.*s (%.*s)",
+	      (int)from->slen, from->ptr,
+	      (int)text->slen, text->ptr,
+	      (int)mime_type->slen, mime_type->ptr));
+}
+
+
+/**
+ * Received typing indication
+ */
+static void on_typing(pjsua_call_id call_id, const pj_str_t *from,
+		      const pj_str_t *to, const pj_str_t *contact,
+		      pj_bool_t is_typing)
+{
+    PJ_UNUSED_ARG(call_id);
+    PJ_UNUSED_ARG(to);
+    PJ_UNUSED_ARG(contact);
+
+    PJ_LOG(3,(THIS_FILE, "IM indication: %.*s %s",
+	      (int)from->slen, from->ptr,
+	      (is_typing?"is typing..":"has stopped typing")));
+}
+
+
+/**
+ * Call transfer request status.
+ */
+static void on_call_transfer_status(pjsua_call_id call_id,
+				    int status_code,
+				    const pj_str_t *status_text,
+				    pj_bool_t final,
+				    pj_bool_t *p_cont)
+{
+    PJ_LOG(3,(THIS_FILE, "Call %d: transfer status=%d (%.*s) %s",
+	      call_id, status_code,
+	      (int)status_text->slen, status_text->ptr,
+	      (final ? "[final]" : "")));
+
+    if (status_code/100 == 2) {
+	PJ_LOG(3,(THIS_FILE, 
+	          "Call %d: call transfered successfully, disconnecting call",
+		  call_id));
+	pjsua_call_hangup(call_id, PJSIP_SC_GONE, NULL, NULL);
+	*p_cont = PJ_FALSE;
+    }
+}
+
+
+/*
+ * Notification that call is being replaced.
+ */
+static void on_call_replaced(pjsua_call_id old_call_id,
+			     pjsua_call_id new_call_id)
+{
+    pjsua_call_info old_ci, new_ci;
+
+    pjsua_call_get_info(old_call_id, &old_ci);
+    pjsua_call_get_info(new_call_id, &new_ci);
+
+    PJ_LOG(3,(THIS_FILE, "Call %d with %.*s is being replaced by "
+			 "call %d with %.*s",
+			 old_call_id, 
+			 (int)old_ci.remote_info.slen, old_ci.remote_info.ptr,
+			 new_call_id,
+			 (int)new_ci.remote_info.slen, new_ci.remote_info.ptr));
+}
+
+
+/*
+ * NAT type detection callback.
+ */
+static void on_nat_detect(const pj_stun_nat_detect_result *res)
+{
+    if (res->status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "NAT detection failed", res->status);
+    } else {
+	PJ_LOG(3, (THIS_FILE, "NAT detected as %s", res->nat_type_name));
+    }
+}
+
+
+/*
+ * MWI indication
+ */
+static void on_mwi_info(pjsua_acc_id acc_id, pjsua_mwi_info *mwi_info)
+{
+    pj_str_t body;
+    
+    PJ_LOG(3,(THIS_FILE, "Received MWI for acc %d:", acc_id));
+
+    if (mwi_info->rdata->msg_info.ctype) {
+	const pjsip_ctype_hdr *ctype = mwi_info->rdata->msg_info.ctype;
+
+	PJ_LOG(3,(THIS_FILE, " Content-Type: %.*s/%.*s",
+	          (int)ctype->media.type.slen,
+		  ctype->media.type.ptr,
+		  (int)ctype->media.subtype.slen,
+		  ctype->media.subtype.ptr));
+    }
+
+    if (!mwi_info->rdata->msg_info.msg->body) {
+	PJ_LOG(3,(THIS_FILE, "  no message body"));
+	return;
+    }
+
+    body.ptr = (char *)mwi_info->rdata->msg_info.msg->body->data;
+    body.slen = mwi_info->rdata->msg_info.msg->body->len;
+
+    PJ_LOG(3,(THIS_FILE, " Body:\n%.*s", (int)body.slen, body.ptr));
+}
+
+
+/*
+ * Transport status notification
+ */
+static void on_transport_state(pjsip_transport *tp, 
+			       pjsip_transport_state state,
+			       const pjsip_transport_state_info *info)
+{
+    char host_port[128];
+
+    pj_ansi_snprintf(host_port, sizeof(host_port), "[%.*s:%d]",
+		     (int)tp->remote_name.host.slen,
+		     tp->remote_name.host.ptr,
+		     tp->remote_name.port);
+
+    switch (state) {
+    case PJSIP_TP_STATE_CONNECTED:
+	{
+	    PJ_LOG(3,(THIS_FILE, "SIP %s transport is connected to %s",
+		     tp->type_name, host_port));
+	}
+	break;
+
+    case PJSIP_TP_STATE_DISCONNECTED:
+	{
+	    char buf[100];
+
+	    snprintf(buf, sizeof(buf), "SIP %s transport is disconnected "
+		    "from %s", tp->type_name, host_port);
+	    pjsua_perror(THIS_FILE, buf, info->status);
+	}
+	break;
+
+    default:
+	break;
+    }
+
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0
+
+    if (!pj_ansi_stricmp(tp->type_name, "tls") && info->ext_info &&
+	(state == PJSIP_TP_STATE_CONNECTED || 
+	 ((pjsip_tls_state_info*)info->ext_info)->
+			         ssl_sock_info->verify_status != PJ_SUCCESS))
+    {
+	pjsip_tls_state_info *tls_info = (pjsip_tls_state_info*)info->ext_info;
+	pj_ssl_sock_info *ssl_sock_info = tls_info->ssl_sock_info;
+	char buf[2048];
+	const char *verif_msgs[32];
+	unsigned verif_msg_cnt;
+
+	/* Dump server TLS cipher */
+	PJ_LOG(4,(THIS_FILE, "TLS cipher used: 0x%06X/%s",
+		  ssl_sock_info->cipher,
+		  pj_ssl_cipher_name(ssl_sock_info->cipher) ));
+
+	/* Dump server TLS certificate */
+	pj_ssl_cert_info_dump(ssl_sock_info->remote_cert_info, "  ",
+			      buf, sizeof(buf));
+	PJ_LOG(4,(THIS_FILE, "TLS cert info of %s:\n%s", host_port, buf));
+
+	/* Dump server TLS certificate verification result */
+	verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs);
+	pj_ssl_cert_get_verify_status_strings(ssl_sock_info->verify_status,
+					      verif_msgs, &verif_msg_cnt);
+	PJ_LOG(3,(THIS_FILE, "TLS cert verification result of %s : %s",
+			     host_port,
+			     (verif_msg_cnt == 1? verif_msgs[0]:"")));
+	if (verif_msg_cnt > 1) {
+	    unsigned i;
+	    for (i = 0; i < verif_msg_cnt; ++i)
+		PJ_LOG(3,(THIS_FILE, "- %s", verif_msgs[i]));
+	}
+
+	if (ssl_sock_info->verify_status &&
+	    !app_config.udp_cfg.tls_setting.verify_server) 
+	{
+	    PJ_LOG(3,(THIS_FILE, "PJSUA is configured to ignore TLS cert "
+				 "verification errors"));
+	}
+    }
+
+#endif
+
+}
+
+/*
+ * Notification on ICE error.
+ */
+static void on_ice_transport_error(int index, pj_ice_strans_op op,
+				   pj_status_t status, void *param)
+{
+    PJ_UNUSED_ARG(op);
+    PJ_UNUSED_ARG(param);
+    PJ_PERROR(1,(THIS_FILE, status,
+	         "ICE keep alive failure for transport %d", index));
+}
+
+/*
+ * Notification on sound device operation.
+ */
+static pj_status_t on_snd_dev_operation(int operation)
+{
+    PJ_LOG(3,(THIS_FILE, "Turning sound device %s", (operation? "ON":"OFF")));
+    return PJ_SUCCESS;
+}
+
+/* Callback on media events */
+static void on_call_media_event(pjsua_call_id call_id,
+                                unsigned med_idx,
+                                pjmedia_event *event)
+{
+    char event_name[5];
+
+    PJ_LOG(5,(THIS_FILE, "Event %s",
+	      pjmedia_fourcc_name(event->type, event_name)));
+
+#if PJSUA_HAS_VIDEO
+    if (event->type == PJMEDIA_EVENT_FMT_CHANGED) {
+	/* Adjust renderer window size to original video size */
+	pjsua_call_info ci;
+	pjsua_vid_win_id wid;
+	pjmedia_rect_size size;
+
+	pjsua_call_get_info(call_id, &ci);
+
+	if ((ci.media[med_idx].type == PJMEDIA_TYPE_VIDEO) &&
+	    (ci.media[med_idx].dir & PJMEDIA_DIR_DECODING))
+	{
+	    wid = ci.media[med_idx].stream.vid.win_in;
+	    size = event->data.fmt_changed.new_fmt.det.vid.size;
+	    pjsua_vid_win_set_size(wid, &size);
+	}
+
+	/* Re-arrange video windows */
+	arrange_window(PJSUA_INVALID_ID);
+    }
+#else
+    PJ_UNUSED_ARG(call_id);
+    PJ_UNUSED_ARG(med_idx);
+    PJ_UNUSED_ARG(event);
+#endif
+}
+
+#ifdef TRANSPORT_ADAPTER_SAMPLE
+/*
+ * This callback is called when media transport needs to be created.
+ */
+static pjmedia_transport* on_create_media_transport(pjsua_call_id call_id,
+						    unsigned media_idx,
+						    pjmedia_transport *base_tp,
+						    unsigned flags)
+{
+    pjmedia_transport *adapter;
+    pj_status_t status;
+
+    /* Create the adapter */
+    status = pjmedia_tp_adapter_create(pjsua_get_pjmedia_endpt(),
+                                       NULL, base_tp,
+                                       (flags & PJSUA_MED_TP_CLOSE_MEMBER),
+                                       &adapter);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(1,(THIS_FILE, status, "Error creating adapter"));
+	return NULL;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Media transport is created for call %d media %d",
+	      call_id, media_idx));
+
+    return adapter;
+}
+#endif
+
+/* Playfile done notification, set timer to hangup calls */
+pj_status_t on_playfile_done(pjmedia_port *port, void *usr_data)
+{
+    pj_time_val delay;
+
+    PJ_UNUSED_ARG(port);
+    PJ_UNUSED_ARG(usr_data);
+
+    /* Just rewind WAV when it is played outside of call */
+    if (pjsua_call_get_count() == 0) {
+	pjsua_player_set_pos(app_config.wav_id, 0);
+	return PJ_SUCCESS;
+    }
+
+    /* Timer is already active */
+    if (app_config.auto_hangup_timer.id == 1)
+	return PJ_SUCCESS;
+
+    app_config.auto_hangup_timer.id = 1;
+    delay.sec = 0;
+    delay.msec = 200; /* Give 200 ms before hangup */
+    pjsip_endpt_schedule_timer(pjsua_get_pjsip_endpt(), 
+			       &app_config.auto_hangup_timer, 
+			       &delay);
+
+    return PJ_SUCCESS;
+}
+
+/* Auto hangup timer callback */
+static void hangup_timeout_callback(pj_timer_heap_t *timer_heap,
+				    struct pj_timer_entry *entry)
+{
+    PJ_UNUSED_ARG(timer_heap);
+    PJ_UNUSED_ARG(entry);
+
+    app_config.auto_hangup_timer.id = 0;
+    pjsua_call_hangup_all();
+}
+
+/*
+ * A simple registrar, invoked by default_mod_on_rx_request()
+ */
+static void simple_registrar(pjsip_rx_data *rdata)
+{
+    pjsip_tx_data *tdata;
+    const pjsip_expires_hdr *exp;
+    const pjsip_hdr *h;
+    unsigned cnt = 0;
+    pjsip_generic_string_hdr *srv;
+    pj_status_t status;
+
+    status = pjsip_endpt_create_response(pjsua_get_pjsip_endpt(),
+					 rdata, 200, NULL, &tdata);
+    if (status != PJ_SUCCESS)
+    return;
+
+    exp = (pjsip_expires_hdr *)pjsip_msg_find_hdr(rdata->msg_info.msg, 
+						  PJSIP_H_EXPIRES, NULL);
+
+    h = rdata->msg_info.msg->hdr.next;
+    while (h != &rdata->msg_info.msg->hdr) {
+	if (h->type == PJSIP_H_CONTACT) {
+	    const pjsip_contact_hdr *c = (const pjsip_contact_hdr*)h;
+	    int e = c->expires;
+
+	    if (e < 0) {
+		if (exp)
+		    e = exp->ivalue;
+		else
+		    e = 3600;
+	    }
+
+	    if (e > 0) {
+		pjsip_contact_hdr *nc = (pjsip_contact_hdr *)pjsip_hdr_clone(
+								tdata->pool, h);
+		nc->expires = e;
+		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)nc);
+		++cnt;
+	    }
+	}
+	h = h->next;
+    }
+
+    srv = pjsip_generic_string_hdr_create(tdata->pool, NULL, NULL);
+    srv->name = pj_str("Server");
+    srv->hvalue = pj_str("pjsua simple registrar");
+    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)srv);
+
+    pjsip_endpt_send_response2(pjsua_get_pjsip_endpt(),
+		       rdata, tdata, NULL, NULL);
+}
+
+/*****************************************************************************
+ * A simple module to handle otherwise unhandled request. We will register
+ * this with the lowest priority.
+ */
+
+/* Notification on incoming request */
+static pj_bool_t default_mod_on_rx_request(pjsip_rx_data *rdata)
+{
+    pjsip_tx_data *tdata;
+    pjsip_status_code status_code;
+    pj_status_t status;
+
+    /* Don't respond to ACK! */
+    if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
+			 &pjsip_ack_method) == 0)
+	return PJ_TRUE;
+
+    /* Simple registrar */
+    if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
+                         &pjsip_register_method) == 0)
+    {
+	simple_registrar(rdata);
+	return PJ_TRUE;
+    }
+
+    /* Create basic response. */
+    if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, 
+			 &pjsip_notify_method) == 0)
+    {
+	/* Unsolicited NOTIFY's, send with Bad Request */
+	status_code = PJSIP_SC_BAD_REQUEST;
+    } else {
+	/* Probably unknown method */
+	status_code = PJSIP_SC_METHOD_NOT_ALLOWED;
+    }
+    status = pjsip_endpt_create_response(pjsua_get_pjsip_endpt(), 
+					 rdata, status_code, 
+					 NULL, &tdata);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Unable to create response", status);
+	return PJ_TRUE;
+    }
+
+    /* Add Allow if we're responding with 405 */
+    if (status_code == PJSIP_SC_METHOD_NOT_ALLOWED) {
+	const pjsip_hdr *cap_hdr;
+	cap_hdr = pjsip_endpt_get_capability(pjsua_get_pjsip_endpt(), 
+					     PJSIP_H_ALLOW, NULL);
+	if (cap_hdr) {
+	    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)pjsip_hdr_clone(
+							 tdata->pool, cap_hdr));
+	}
+    }
+
+    /* Add User-Agent header */
+    {
+	pj_str_t user_agent;
+	char tmp[80];
+	const pj_str_t USER_AGENT = { "User-Agent", 10};
+	pjsip_hdr *h;
+
+	pj_ansi_snprintf(tmp, sizeof(tmp), "PJSUA v%s/%s", 
+			 pj_get_version(), PJ_OS_NAME);
+	pj_strdup2_with_null(tdata->pool, &user_agent, tmp);
+
+	h = (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool,
+							 &USER_AGENT,
+							 &user_agent);
+	pjsip_msg_add_hdr(tdata->msg, h);
+    }
+
+    pjsip_endpt_send_response2(pjsua_get_pjsip_endpt(), rdata, tdata, 
+			       NULL, NULL);
+
+    return PJ_TRUE;
+}
+
+/* The module instance. */
+static pjsip_module mod_default_handler = 
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-default-handler", 19 },	/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION+99,	/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &default_mod_on_rx_request,		/* on_rx_request()	*/
+    NULL,				/* on_rx_response()	*/
+    NULL,				/* on_tx_request.	*/
+    NULL,				/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
+/** CLI callback **/
+
+/* Called on CLI (re)started, e.g: initial start, after iOS bg */
+void cli_on_started(pj_status_t status)
+{
+    /* Notify app */
+    if (app_cfg.on_started) {
+	if (status == PJ_SUCCESS) {
+	    char info[128];
+	    cli_get_info(info, sizeof(info));
+	    if (app_cfg.on_started) {
+		(*app_cfg.on_started)(status, info);		
+	    } 
+	} else {
+	    if (app_cfg.on_started) {
+		(*app_cfg.on_started)(status, NULL);
+	    } 		
+	}
+    }
+}
+
+/* Called on CLI quit */
+void cli_on_stopped(pj_bool_t restart, int argc, char* argv[])
+{
+    /* Notify app */
+    if (app_cfg.on_stopped)
+	(*app_cfg.on_stopped)(restart, argc, argv);
+}
+
+
+/* Called on pjsua legacy quit */
+void legacy_on_stopped(pj_bool_t restart)
+{
+    /* Notify app */
+    if (app_cfg.on_stopped)
+	(*app_cfg.on_stopped)(restart, 1, NULL);
+}
+
+/*****************************************************************************
+ * Public API
+ */
+
+int stdout_refresh_proc(void *arg)
+{
+    extern char *stdout_refresh_text;
+
+    PJ_UNUSED_ARG(arg);
+
+    /* Set thread to lowest priority so that it doesn't clobber
+     * stdout output
+     */
+    pj_thread_set_prio(pj_thread_this(), 
+		       pj_thread_get_prio_min(pj_thread_this()));
+
+    while (!stdout_refresh_quit) {
+	pj_thread_sleep(stdout_refresh * 1000);
+	puts(stdout_refresh_text);
+	fflush(stdout);
+    }
+
+    return 0;
+}
+
+static pj_status_t app_init()
+{
+    pjsua_transport_id transport_id = -1;
+    pjsua_transport_config tcp_cfg;
+    unsigned i;
+    pj_pool_t *tmp_pool;
+    pj_status_t status;
+
+    /** Create pjsua **/
+    status = pjsua_create();
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Create pool for application */
+    app_config.pool = pjsua_pool_create("pjsua-app", 1000, 1000);
+    tmp_pool = pjsua_pool_create("tmp-pjsua", 1000, 1000);;
+
+    /* Init CLI & its FE settings */
+    if (!app_running) {
+	pj_cli_cfg_default(&app_config.cli_cfg.cfg);
+	pj_cli_telnet_cfg_default(&app_config.cli_cfg.telnet_cfg);
+	pj_cli_console_cfg_default(&app_config.cli_cfg.console_cfg);
+	app_config.cli_cfg.telnet_cfg.on_started = cli_on_started;
+    }
+
+    /** Parse args **/
+    status = load_config(app_cfg.argc, app_cfg.argv, &uri_arg);
+    if (status != PJ_SUCCESS) {
+	pj_pool_release(tmp_pool);
+	return status;
+    }
+
+    /* Initialize application callbacks */
+    app_config.cfg.cb.on_call_state = &on_call_state;
+    app_config.cfg.cb.on_call_media_state = &on_call_media_state;
+    app_config.cfg.cb.on_incoming_call = &on_incoming_call;
+    app_config.cfg.cb.on_call_tsx_state = &on_call_tsx_state;
+    app_config.cfg.cb.on_dtmf_digit = &call_on_dtmf_callback;
+    app_config.cfg.cb.on_call_redirected = &call_on_redirected;
+    app_config.cfg.cb.on_reg_state = &on_reg_state;
+    app_config.cfg.cb.on_incoming_subscribe = &on_incoming_subscribe;
+    app_config.cfg.cb.on_buddy_state = &on_buddy_state;
+    app_config.cfg.cb.on_buddy_evsub_state = &on_buddy_evsub_state;
+    app_config.cfg.cb.on_pager = &on_pager;
+    app_config.cfg.cb.on_typing = &on_typing;
+    app_config.cfg.cb.on_call_transfer_status = &on_call_transfer_status;
+    app_config.cfg.cb.on_call_replaced = &on_call_replaced;
+    app_config.cfg.cb.on_nat_detect = &on_nat_detect;
+    app_config.cfg.cb.on_mwi_info = &on_mwi_info;
+    app_config.cfg.cb.on_transport_state = &on_transport_state;
+    app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
+    app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
+    app_config.cfg.cb.on_call_media_event = &on_call_media_event;
+#ifdef TRANSPORT_ADAPTER_SAMPLE
+    app_config.cfg.cb.on_create_media_transport = &on_create_media_transport;
+#endif
+
+    /* Set sound device latency */
+    if (app_config.capture_lat > 0)
+	app_config.media_cfg.snd_rec_latency = app_config.capture_lat;
+    if (app_config.playback_lat)
+	app_config.media_cfg.snd_play_latency = app_config.playback_lat;
+
+    if (app_cfg.on_config_init)
+	(*app_cfg.on_config_init)(&app_config);
+
+    /* Initialize pjsua */
+    status = pjsua_init(&app_config.cfg, &app_config.log_cfg,
+			&app_config.media_cfg);
+    if (status != PJ_SUCCESS) {
+	pj_pool_release(tmp_pool);
+	return status;
+    }
+
+    /* Initialize our module to handle otherwise unhandled request */
+    status = pjsip_endpt_register_module(pjsua_get_pjsip_endpt(),
+					 &mod_default_handler);
+    if (status != PJ_SUCCESS)
+	return status;
+
+#ifdef STEREO_DEMO
+    stereo_demo();
+#endif
+
+    /* Initialize calls data */
+    for (i=0; i<PJ_ARRAY_SIZE(app_config.call_data); ++i) {
+	app_config.call_data[i].timer.id = PJSUA_INVALID_ID;
+	app_config.call_data[i].timer.cb = &call_timeout_callback;
+    }
+
+    /* Optionally registers WAV file */
+    for (i=0; i<app_config.wav_count; ++i) {
+	pjsua_player_id wav_id;
+	unsigned play_options = 0;
+
+	if (app_config.auto_play_hangup)
+	    play_options |= PJMEDIA_FILE_NO_LOOP;
+
+	status = pjsua_player_create(&app_config.wav_files[i], play_options, 
+				     &wav_id);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	if (app_config.wav_id == PJSUA_INVALID_ID) {
+	    app_config.wav_id = wav_id;
+	    app_config.wav_port = pjsua_player_get_conf_port(app_config.wav_id);
+	    if (app_config.auto_play_hangup) {
+		pjmedia_port *port;
+
+		pjsua_player_get_port(app_config.wav_id, &port);
+		status = pjmedia_wav_player_set_eof_cb(port, NULL, 
+						       &on_playfile_done);
+		if (status != PJ_SUCCESS)
+		    goto on_error;
+
+		pj_timer_entry_init(&app_config.auto_hangup_timer, 0, NULL, 
+				    &hangup_timeout_callback);
+	    }
+	}
+    }
+
+    /* Optionally registers tone players */
+    for (i=0; i<app_config.tone_count; ++i) {
+	pjmedia_port *tport;
+	char name[80];
+	pj_str_t label;
+	pj_status_t status;
+
+	pj_ansi_snprintf(name, sizeof(name), "tone-%d,%d",
+			 app_config.tones[i].freq1, 
+			 app_config.tones[i].freq2);
+	label = pj_str(name);
+	status = pjmedia_tonegen_create2(app_config.pool, &label,
+					 8000, 1, 160, 16, 
+					 PJMEDIA_TONEGEN_LOOP,  &tport);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Unable to create tone generator", status);
+	    goto on_error;
+	}
+
+	status = pjsua_conf_add_port(app_config.pool, tport, 
+				     &app_config.tone_slots[i]);
+	pj_assert(status == PJ_SUCCESS);
+
+	status = pjmedia_tonegen_play(tport, 1, &app_config.tones[i], 0);
+	pj_assert(status == PJ_SUCCESS);
+    }
+
+    /* Optionally create recorder file, if any. */
+    if (app_config.rec_file.slen) {
+	status = pjsua_recorder_create(&app_config.rec_file, 0, NULL, 0, 0,
+				       &app_config.rec_id);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	app_config.rec_port = pjsua_recorder_get_conf_port(app_config.rec_id);
+    }
+
+    pj_memcpy(&tcp_cfg, &app_config.udp_cfg, sizeof(tcp_cfg));
+
+    /* Create ringback tones */
+    if (app_config.no_tones == PJ_FALSE) {
+	unsigned i, samples_per_frame;
+	pjmedia_tone_desc tone[RING_CNT+RINGBACK_CNT];
+	pj_str_t name;
+
+	samples_per_frame = app_config.media_cfg.audio_frame_ptime * 
+			    app_config.media_cfg.clock_rate *
+			    app_config.media_cfg.channel_count / 1000;
+
+	/* Ringback tone (call is ringing) */
+	name = pj_str("ringback");
+	status = pjmedia_tonegen_create2(app_config.pool, &name, 
+					 app_config.media_cfg.clock_rate,
+					 app_config.media_cfg.channel_count, 
+					 samples_per_frame,
+					 16, PJMEDIA_TONEGEN_LOOP, 
+					 &app_config.ringback_port);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	pj_bzero(&tone, sizeof(tone));
+	for (i=0; i<RINGBACK_CNT; ++i) {
+	    tone[i].freq1 = RINGBACK_FREQ1;
+	    tone[i].freq2 = RINGBACK_FREQ2;
+	    tone[i].on_msec = RINGBACK_ON;
+	    tone[i].off_msec = RINGBACK_OFF;
+	}
+	tone[RINGBACK_CNT-1].off_msec = RINGBACK_INTERVAL;
+
+	pjmedia_tonegen_play(app_config.ringback_port, RINGBACK_CNT, tone,
+			     PJMEDIA_TONEGEN_LOOP);
+
+
+	status = pjsua_conf_add_port(app_config.pool, app_config.ringback_port,
+				     &app_config.ringback_slot);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	/* Ring (to alert incoming call) */
+	name = pj_str("ring");
+	status = pjmedia_tonegen_create2(app_config.pool, &name, 
+					 app_config.media_cfg.clock_rate,
+					 app_config.media_cfg.channel_count, 
+					 samples_per_frame,
+					 16, PJMEDIA_TONEGEN_LOOP, 
+					 &app_config.ring_port);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	for (i=0; i<RING_CNT; ++i) {
+	    tone[i].freq1 = RING_FREQ1;
+	    tone[i].freq2 = RING_FREQ2;
+	    tone[i].on_msec = RING_ON;
+	    tone[i].off_msec = RING_OFF;
+	}
+	tone[RING_CNT-1].off_msec = RING_INTERVAL;
+
+	pjmedia_tonegen_play(app_config.ring_port, RING_CNT, 
+			     tone, PJMEDIA_TONEGEN_LOOP);
+
+	status = pjsua_conf_add_port(app_config.pool, app_config.ring_port,
+				     &app_config.ring_slot);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+    }
+
+    /* Create AVI player virtual devices */
+    if (app_config.avi_cnt) {
+#if PJMEDIA_HAS_VIDEO && PJMEDIA_VIDEO_DEV_HAS_AVI
+	pjmedia_vid_dev_factory *avi_factory;
+
+	status = pjmedia_avi_dev_create_factory(pjsua_get_pool_factory(),
+	                                        app_config.avi_cnt,
+	                                        &avi_factory);
+	if (status != PJ_SUCCESS) {
+	    PJ_PERROR(1,(THIS_FILE, status, "Error creating AVI factory"));
+	    goto on_error;
+	}
+
+	for (i=0; i<app_config.avi_cnt; ++i) {
+	    pjmedia_avi_dev_param avdp;
+	    pjmedia_vid_dev_index avid;
+	    unsigned strm_idx, strm_cnt;
+
+	    app_config.avi[i].dev_id = PJMEDIA_VID_INVALID_DEV;
+	    app_config.avi[i].slot = PJSUA_INVALID_ID;
+
+	    pjmedia_avi_dev_param_default(&avdp);
+	    avdp.path = app_config.avi[i].path;
+
+	    status =  pjmedia_avi_dev_alloc(avi_factory, &avdp, &avid);
+	    if (status != PJ_SUCCESS) {
+		PJ_PERROR(1,(THIS_FILE, status,
+			     "Error creating AVI player for %.*s",
+			     (int)avdp.path.slen, avdp.path.ptr));
+		goto on_error;
+	    }
+
+	    PJ_LOG(4,(THIS_FILE, "AVI player %.*s created, dev_id=%d",
+		      (int)avdp.title.slen, avdp.title.ptr, avid));
+
+	    app_config.avi[i].dev_id = avid;
+	    if (app_config.avi_def_idx == PJSUA_INVALID_ID)
+		app_config.avi_def_idx = i;
+
+	    strm_cnt = pjmedia_avi_streams_get_num_streams(avdp.avi_streams);
+	    for (strm_idx=0; strm_idx<strm_cnt; ++strm_idx) {
+		pjmedia_port *aud;
+		pjmedia_format *fmt;
+		pjsua_conf_port_id slot;
+		char fmt_name[5];
+
+		aud = pjmedia_avi_streams_get_stream(avdp.avi_streams,
+		                                     strm_idx);
+		fmt = &aud->info.fmt;
+
+		pjmedia_fourcc_name(fmt->id, fmt_name);
+
+		if (fmt->id == PJMEDIA_FORMAT_PCM) {
+		    status = pjsua_conf_add_port(app_config.pool, aud,
+		                                 &slot);
+		    if (status == PJ_SUCCESS) {
+			PJ_LOG(4,(THIS_FILE,
+				  "AVI %.*s: audio added to slot %d",
+				  (int)avdp.title.slen, avdp.title.ptr,
+				  slot));
+			app_config.avi[i].slot = slot;
+		    }
+		} else {
+		    PJ_LOG(4,(THIS_FILE,
+			      "AVI %.*s: audio ignored, format=%s",
+			      (int)avdp.title.slen, avdp.title.ptr,
+			      fmt_name));
+		}
+	    }
+	}
+#else
+	PJ_LOG(2,(THIS_FILE,
+		  "Warning: --play-avi is ignored because AVI is disabled"));
+#endif	/* PJMEDIA_VIDEO_DEV_HAS_AVI */
+    }
+
+    /* Add UDP transport unless it's disabled. */
+    if (!app_config.no_udp) {
+	pjsua_acc_id aid;
+	pjsip_transport_type_e type = PJSIP_TRANSPORT_UDP;
+
+	status = pjsua_transport_create(type,
+					&app_config.udp_cfg,
+					&transport_id);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	/* Add local account */
+	pjsua_acc_add_local(transport_id, PJ_TRUE, &aid);
+
+	/* Adjust local account config based on pjsua app config */
+	{
+	    pjsua_acc_config acc_cfg;
+	    pjsua_acc_get_config(aid, tmp_pool, &acc_cfg);
+
+	    app_config_init_video(&acc_cfg);
+	    acc_cfg.rtp_cfg = app_config.rtp_cfg;
+	    pjsua_acc_modify(aid, &acc_cfg);
+	}
+
+	//pjsua_acc_set_transport(aid, transport_id);
+	pjsua_acc_set_online_status(current_acc, PJ_TRUE);
+
+	if (app_config.udp_cfg.port == 0) {
+	    pjsua_transport_info ti;
+	    pj_sockaddr_in *a;
+
+	    pjsua_transport_get_info(transport_id, &ti);
+	    a = (pj_sockaddr_in*)&ti.local_addr;
+
+	    tcp_cfg.port = pj_ntohs(a->sin_port);
+	}
+    }
+
+    /* Add UDP IPv6 transport unless it's disabled. */
+    if (!app_config.no_udp && app_config.ipv6) {
+	pjsua_acc_id aid;
+	pjsip_transport_type_e type = PJSIP_TRANSPORT_UDP6;
+	pjsua_transport_config udp_cfg;
+
+	udp_cfg = app_config.udp_cfg;
+	if (udp_cfg.port == 0)
+	    udp_cfg.port = 5060;
+	else
+	    udp_cfg.port += 10;
+	status = pjsua_transport_create(type,
+					&udp_cfg,
+					&transport_id);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	/* Add local account */
+	pjsua_acc_add_local(transport_id, PJ_TRUE, &aid);
+
+	/* Adjust local account config based on pjsua app config */
+	{
+	    pjsua_acc_config acc_cfg;
+	    pjsua_acc_get_config(aid, tmp_pool, &acc_cfg);
+
+	    app_config_init_video(&acc_cfg);
+	    acc_cfg.rtp_cfg = app_config.rtp_cfg;
+	    acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
+	    pjsua_acc_modify(aid, &acc_cfg);
+	}
+
+	//pjsua_acc_set_transport(aid, transport_id);
+	pjsua_acc_set_online_status(current_acc, PJ_TRUE);
+
+	if (app_config.udp_cfg.port == 0) {
+	    pjsua_transport_info ti;
+	    pj_sockaddr_in *a;
+
+	    pjsua_transport_get_info(transport_id, &ti);
+	    a = (pj_sockaddr_in*)&ti.local_addr;
+
+	    tcp_cfg.port = pj_ntohs(a->sin_port);
+	}
+    }
+
+    /* Add TCP transport unless it's disabled */
+    if (!app_config.no_tcp) {
+	pjsua_acc_id aid;
+
+	status = pjsua_transport_create(PJSIP_TRANSPORT_TCP,
+					&tcp_cfg, 
+					&transport_id);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	/* Add local account */
+	pjsua_acc_add_local(transport_id, PJ_TRUE, &aid);
+
+	/* Adjust local account config based on pjsua app config */
+	{
+	    pjsua_acc_config acc_cfg;
+	    pjsua_acc_get_config(aid, tmp_pool, &acc_cfg);
+
+	    app_config_init_video(&acc_cfg);
+	    acc_cfg.rtp_cfg = app_config.rtp_cfg;
+	    pjsua_acc_modify(aid, &acc_cfg);
+	}
+
+	pjsua_acc_set_online_status(current_acc, PJ_TRUE);
+
+    }
+
+    /* Add TCP IPv6 transport unless it's disabled. */
+    if (!app_config.no_tcp && app_config.ipv6) {
+	pjsua_acc_id aid;
+	pjsip_transport_type_e type = PJSIP_TRANSPORT_TCP6;
+
+	tcp_cfg.port += 10;
+
+	status = pjsua_transport_create(type,
+					&tcp_cfg,
+					&transport_id);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	/* Add local account */
+	pjsua_acc_add_local(transport_id, PJ_TRUE, &aid);
+
+	/* Adjust local account config based on pjsua app config */
+	{
+	    pjsua_acc_config acc_cfg;
+	    pjsua_acc_get_config(aid, tmp_pool, &acc_cfg);
+
+	    app_config_init_video(&acc_cfg);
+	    acc_cfg.rtp_cfg = app_config.rtp_cfg;
+	    acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
+	    pjsua_acc_modify(aid, &acc_cfg);
+	}
+
+	//pjsua_acc_set_transport(aid, transport_id);
+	pjsua_acc_set_online_status(current_acc, PJ_TRUE);
+    }
+
+
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0
+    /* Add TLS transport when application wants one */
+    if (app_config.use_tls) {
+
+	pjsua_acc_id acc_id;
+
+	/* Copy the QoS settings */
+	tcp_cfg.tls_setting.qos_type = tcp_cfg.qos_type;
+	pj_memcpy(&tcp_cfg.tls_setting.qos_params, &tcp_cfg.qos_params, 
+		  sizeof(tcp_cfg.qos_params));
+
+	/* Set TLS port as TCP port+1 */
+	tcp_cfg.port++;
+	status = pjsua_transport_create(PJSIP_TRANSPORT_TLS,
+					&tcp_cfg, 
+					&transport_id);
+	tcp_cfg.port--;
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+	
+	/* Add local account */
+	pjsua_acc_add_local(transport_id, PJ_FALSE, &acc_id);
+
+	/* Adjust local account config based on pjsua app config */
+	{
+	    pjsua_acc_config acc_cfg;
+	    pjsua_acc_get_config(acc_id, tmp_pool, &acc_cfg);
+
+	    app_config_init_video(&acc_cfg);
+	    acc_cfg.rtp_cfg = app_config.rtp_cfg;
+	    pjsua_acc_modify(acc_id, &acc_cfg);
+	}
+
+	pjsua_acc_set_online_status(acc_id, PJ_TRUE);
+    }
+
+    /* Add TLS IPv6 transport unless it's disabled. */
+    if (app_config.use_tls && app_config.ipv6) {
+	pjsua_acc_id aid;
+	pjsip_transport_type_e type = PJSIP_TRANSPORT_TLS6;
+
+	tcp_cfg.port += 10;
+
+	status = pjsua_transport_create(type,
+					&tcp_cfg,
+					&transport_id);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+
+	/* Add local account */
+	pjsua_acc_add_local(transport_id, PJ_TRUE, &aid);
+
+	/* Adjust local account config based on pjsua app config */
+	{
+	    pjsua_acc_config acc_cfg;
+	    pjsua_acc_get_config(aid, tmp_pool, &acc_cfg);
+
+	    app_config_init_video(&acc_cfg);
+	    acc_cfg.rtp_cfg = app_config.rtp_cfg;
+	    acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
+	    pjsua_acc_modify(aid, &acc_cfg);
+	}
+
+	//pjsua_acc_set_transport(aid, transport_id);
+	pjsua_acc_set_online_status(current_acc, PJ_TRUE);
+    }
+
+#endif
+
+    if (transport_id == -1) {
+	PJ_LOG(1,(THIS_FILE, "Error: no transport is configured"));
+	status = -1;
+	goto on_error;
+    }
+
+
+    /* Add accounts */
+    for (i=0; i<app_config.acc_cnt; ++i) {
+	app_config.acc_cfg[i].rtp_cfg = app_config.rtp_cfg;
+	app_config.acc_cfg[i].reg_retry_interval = 300;
+	app_config.acc_cfg[i].reg_first_retry_interval = 60;
+
+	app_config_init_video(&app_config.acc_cfg[i]);
+
+	status = pjsua_acc_add(&app_config.acc_cfg[i], PJ_TRUE, NULL);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+	pjsua_acc_set_online_status(current_acc, PJ_TRUE);
+    }
+
+    /* Add buddies */
+    for (i=0; i<app_config.buddy_cnt; ++i) {
+	status = pjsua_buddy_add(&app_config.buddy_cfg[i], NULL);
+	if (status != PJ_SUCCESS) {
+	    PJ_PERROR(1,(THIS_FILE, status, "Error adding buddy"));
+	    goto on_error;
+	}
+    }
+
+    /* Optionally disable some codec */
+    for (i=0; i<app_config.codec_dis_cnt; ++i) {
+	pjsua_codec_set_priority(&app_config.codec_dis[i],
+				 PJMEDIA_CODEC_PRIO_DISABLED);
+#if PJSUA_HAS_VIDEO
+	pjsua_vid_codec_set_priority(&app_config.codec_dis[i],
+				     PJMEDIA_CODEC_PRIO_DISABLED);
+#endif
+    }
+
+    /* Optionally set codec orders */
+    for (i=0; i<app_config.codec_cnt; ++i) {
+	pjsua_codec_set_priority(&app_config.codec_arg[i],
+				 (pj_uint8_t)(PJMEDIA_CODEC_PRIO_NORMAL+i+9));
+#if PJSUA_HAS_VIDEO
+	pjsua_vid_codec_set_priority(&app_config.codec_arg[i],
+				   (pj_uint8_t)(PJMEDIA_CODEC_PRIO_NORMAL+i+9));
+#endif
+    }
+
+    /* Use null sound device? */
+#ifndef STEREO_DEMO
+    if (app_config.null_audio) {
+	status = pjsua_set_null_snd_dev();
+	if (status != PJ_SUCCESS)
+	    return status;
+    }
+#endif
+
+    if (app_config.capture_dev  != PJSUA_INVALID_ID ||
+        app_config.playback_dev != PJSUA_INVALID_ID) 
+    {
+	status = pjsua_set_snd_dev(app_config.capture_dev, 
+				   app_config.playback_dev);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+    }
+
+    /* Init call setting */
+    pjsua_call_setting_default(&call_opt);
+    call_opt.aud_cnt = app_config.aud_cnt;
+    call_opt.vid_cnt = app_config.vid.vid_cnt;
+
+    pj_pool_release(tmp_pool);
+    return PJ_SUCCESS;
+
+on_error:
+    pj_pool_release(tmp_pool);
+    app_destroy();
+    return status;
+}
+
+pj_status_t pjsua_app_init(const pjsua_app_cfg_t *cfg)
+{
+    pj_status_t status;
+    pj_memcpy(&app_cfg, cfg, sizeof(app_cfg));
+
+    status = app_init();
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Init CLI if configured */    
+    if (app_config.use_cli) {
+	status = cli_init();
+    } 
+    return status;
+}
+
+pj_status_t pjsua_app_run(pj_bool_t wait_telnet_cli)
+{
+    pj_thread_t *stdout_refresh_thread = NULL;
+    pj_status_t status;
+
+    /* Start console refresh thread */
+    if (stdout_refresh > 0) {
+	pj_thread_create(app_config.pool, "stdout", &stdout_refresh_proc,
+			 NULL, 0, 0, &stdout_refresh_thread);
+    }
+
+    status = pjsua_start();
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    if (app_config.use_cli && (app_config.cli_cfg.cli_fe & CLI_FE_TELNET)) {
+	char info[128];
+	cli_get_info(info, sizeof(info));
+	if (app_cfg.on_started) {
+	    (*app_cfg.on_started)(status, info);
+	}
+    } else {
+	if (app_cfg.on_started) {
+	    (*app_cfg.on_started)(status, "Ready");
+	}    
+    }
+
+    /* If user specifies URI to call, then call the URI */
+    if (uri_arg.slen) {
+	pjsua_call_setting_default(&call_opt);
+	call_opt.aud_cnt = app_config.aud_cnt;
+	call_opt.vid_cnt = app_config.vid.vid_cnt;
+
+	pjsua_call_make_call(current_acc, &uri_arg, &call_opt, NULL, 
+			     NULL, NULL);
+    }   
+
+    app_running = PJ_TRUE;
+
+    if (app_config.use_cli)
+	cli_main(wait_telnet_cli);	
+    else
+	legacy_main();
+
+    status = PJ_SUCCESS;
+
+on_return:
+    if (stdout_refresh_thread) {
+	stdout_refresh_quit = PJ_TRUE;
+	pj_thread_join(stdout_refresh_thread);
+	pj_thread_destroy(stdout_refresh_thread);
+	stdout_refresh_quit = PJ_FALSE;
+    }
+    return status;
+}
+
+static pj_status_t app_destroy()
+{
+    pj_status_t status = PJ_SUCCESS;
+    unsigned i;
+    pj_bool_t use_cli = PJ_FALSE;
+    int cli_fe = 0;
+    pj_uint16_t cli_telnet_port = 0;
+
+#ifdef STEREO_DEMO
+    if (app_config.snd) {
+	pjmedia_snd_port_destroy(app_config.snd);
+	app_config.snd = NULL;
+    }
+    if (app_config.sc_ch1) {
+	pjsua_conf_remove_port(app_config.sc_ch1_slot);
+	app_config.sc_ch1_slot = PJSUA_INVALID_ID;
+	pjmedia_port_destroy(app_config.sc_ch1);
+	app_config.sc_ch1 = NULL;
+    }
+    if (app_config.sc) {
+	pjmedia_port_destroy(app_config.sc);
+	app_config.sc = NULL;
+    }
+#endif
+
+    /* Close avi devs and ports */
+    for (i=0; i<app_config.avi_cnt; ++i) {
+	if (app_config.avi[i].slot != PJSUA_INVALID_ID)
+	    pjsua_conf_remove_port(app_config.avi[i].slot);
+#if PJMEDIA_HAS_VIDEO && PJMEDIA_VIDEO_DEV_HAS_AVI
+	if (app_config.avi[i].dev_id != PJMEDIA_VID_INVALID_DEV)
+	    pjmedia_avi_dev_free(app_config.avi[i].dev_id);
+#endif
+    }
+
+    /* Close ringback port */
+    if (app_config.ringback_port && 
+	app_config.ringback_slot != PJSUA_INVALID_ID) 
+    {
+	pjsua_conf_remove_port(app_config.ringback_slot);
+	app_config.ringback_slot = PJSUA_INVALID_ID;
+	pjmedia_port_destroy(app_config.ringback_port);
+	app_config.ringback_port = NULL;
+    }
+
+    /* Close ring port */
+    if (app_config.ring_port && app_config.ring_slot != PJSUA_INVALID_ID) {
+	pjsua_conf_remove_port(app_config.ring_slot);
+	app_config.ring_slot = PJSUA_INVALID_ID;
+	pjmedia_port_destroy(app_config.ring_port);
+	app_config.ring_port = NULL;
+    }
+
+    /* Close tone generators */
+    for (i=0; i<app_config.tone_count; ++i) {
+	pjsua_conf_remove_port(app_config.tone_slots[i]);
+    }
+
+    if (app_config.pool) {
+	pj_pool_release(app_config.pool);
+	app_config.pool = NULL;
+    }
+
+    status = pjsua_destroy();
+
+    if (app_config.use_cli) {
+	use_cli = app_config.use_cli;
+	cli_fe = app_config.cli_cfg.cli_fe;
+	cli_telnet_port = app_config.cli_cfg.telnet_cfg.port;	
+    }
+
+    /* Reset config */
+    pj_bzero(&app_config, sizeof(app_config));
+
+    if (use_cli) {    
+	app_config.use_cli = use_cli;
+	app_config.cli_cfg.cli_fe = cli_fe;
+	app_config.cli_cfg.telnet_cfg.port = cli_telnet_port;
+    }
+
+    return status;
+}
+
+pj_status_t pjsua_app_destroy()
+{
+    pj_status_t status;
+
+    status = app_destroy();
+
+    if (app_config.use_cli) {	
+	cli_destroy();
+    }
+    
+    return status;
+}
+
+/** ======================= **/
+
+#ifdef STEREO_DEMO
+/*
+ * In this stereo demo, we open the sound device in stereo mode and
+ * arrange the attachment to the PJSUA-LIB conference bridge as such
+ * so that channel0/left channel of the sound device corresponds to
+ * slot 0 in the bridge, and channel1/right channel of the sound
+ * device corresponds to slot 1 in the bridge. Then user can independently
+ * feed different media to/from the speakers/microphones channels, by
+ * connecting them to slot 0 or 1 respectively.
+ *
+ * Here's how the connection looks like:
+ *
+   +-----------+ stereo +-----------------+ 2x mono +-----------+
+   | AUDIO DEV |<------>| SPLITCOMB   left|<------->|#0  BRIDGE |
+   +-----------+        |            right|<------->|#1         |
+                        +-----------------+         +-----------+
+ */
+static void stereo_demo()
+{
+    pjmedia_port *conf;
+    pj_status_t status;
+
+    /* Disable existing sound device */
+    conf = pjsua_set_no_snd_dev();
+
+    /* Create stereo-mono splitter/combiner */
+    status = pjmedia_splitcomb_create(app_config.pool, 
+				      conf->info.clock_rate /* clock rate */,
+				      2	    /* stereo */,
+				      2 * conf->info.samples_per_frame,
+				      conf->info.bits_per_sample,
+				      0	    /* options */,
+				      &app_config.sc);
+    pj_assert(status == PJ_SUCCESS);
+
+    /* Connect channel0 (left channel?) to conference port slot0 */
+    status = pjmedia_splitcomb_set_channel(app_config.sc, 0 /* ch0 */, 
+					   0 /*options*/,
+					   conf);
+    pj_assert(status == PJ_SUCCESS);
+
+    /* Create reverse channel for channel1 (right channel?)... */
+    status = pjmedia_splitcomb_create_rev_channel(app_config.pool,
+						  app_config.sc,
+						  1  /* ch1 */,
+						  0  /* options */,
+						  &app_config.sc_ch1);
+    pj_assert(status == PJ_SUCCESS);
+
+    /* .. and register it to conference bridge (it would be slot1
+     * if there's no other devices connected to the bridge)
+     */
+    status = pjsua_conf_add_port(app_config.pool, app_config.sc_ch1, 
+				 &app_config.sc_ch1_slot);
+    pj_assert(status == PJ_SUCCESS);
+    
+    /* Create sound device */
+    status = pjmedia_snd_port_create(app_config.pool, -1, -1, 
+				     conf->info.clock_rate,
+				     2	    /* stereo */,
+				     2 * conf->info.samples_per_frame,
+				     conf->info.bits_per_sample,
+				     0, &app_config.snd);
+    pj_assert(status == PJ_SUCCESS);
+
+
+    /* Connect the splitter to the sound device */
+    status = pjmedia_snd_port_connect(app_config.snd, app_config.sc);
+    pj_assert(status == PJ_SUCCESS);
+}
+#endif
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app.h
new file mode 100644
index 0000000..568fa76
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app.h
@@ -0,0 +1,88 @@
+/* $Id: pjsua_app.h 4489 2013-04-23 07:53:25Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 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 __PJSUA_APP_H__
+#define __PJSUA_APP_H__
+
+/**
+ * Interface for user application to use pjsua with CLI/menu based UI. 
+ */
+
+#include "pjsua_app_common.h"
+
+PJ_BEGIN_DECL
+
+/**
+ * This structure contains the configuration of application.
+ */
+typedef struct pjsua_app_cfg_t
+{
+    /**
+     * The number of runtime arguments passed to the application.
+     */
+    int       argc;
+
+    /**
+     * The array of arguments string passed to the application. 
+     */
+    char    **argv;
+
+    /** 
+     * Tell app that CLI (and pjsua) is (re)started.
+     * msg will contain start error message such as “Telnet to X:Y”,
+     * “failed to start pjsua lib”, “port busy”..
+     */
+    void (*on_started)(pj_status_t status, const char* title);
+
+    /**
+     * Tell app that library request to stopped/restart.
+     * GUI app needs to use a timer mechanism to wait before invoking the 
+     * cleanup procedure.
+     */
+    void (*on_stopped)(pj_bool_t restart, int argc, char** argv);
+
+    /**
+     * This will enable application to supply customize configuration other than
+     * the basic configuration provided by pjsua. 
+     */
+    void (*on_config_init)(pjsua_app_config *cfg);
+} pjsua_app_cfg_t;
+
+/**
+ * This will initiate the pjsua and the user interface (CLI/menu UI) based on 
+ * the provided configuration.
+ */
+pj_status_t pjsua_app_init(const pjsua_app_cfg_t *app_cfg);
+
+/**
+ * This will run the CLI/menu based UI.
+ * wait_telnet_cli is used for CLI based UI. It will tell the library to block
+ * or wait until user invoke the "shutdown"/"restart" command. GUI based app
+ * should define this param as PJ_FALSE.
+ */
+pj_status_t pjsua_app_run(pj_bool_t wait_telnet_cli);
+
+/**
+ * This will destroy/cleanup the application library.
+ */
+pj_status_t pjsua_app_destroy();
+
+PJ_END_DECL
+    
+#endif	/* __PJSUA_APP_H__ */
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_cli.c b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_cli.c
new file mode 100644
index 0000000..7228ad7
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_cli.c
@@ -0,0 +1,3126 @@
+/* $Id: pjsua_app_cli.c 4709 2014-01-22 08:02:56Z bennylp $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 "pjsua_app_common.h"
+
+#define THIS_FILE	"pjsua_app_cli.c"
+
+#define CHECK_PJSUA_RUNNING() if (pjsua_get_state()!=PJSUA_STATE_RUNNING) \
+				  return PJ_EINVALIDOP
+
+/* CLI command id */
+/* level 1 command */
+#define CMD_CALL		    100
+#define CMD_PRESENCE		    200
+#define CMD_ACCOUNT		    300
+#define CMD_MEDIA		    400
+#define CMD_CONFIG		    500
+#define CMD_VIDEO		    600
+#define CMD_SLEEP		    700
+#define CMD_ECHO		    800
+#define CMD_NETWORK		    900
+#define CMD_QUIT		    110
+#define CMD_RESTART		    120
+
+/* call level 2 command */
+#define CMD_CALL_NEW		    ((CMD_CALL*10)+1)
+#define CMD_CALL_MULTI		    ((CMD_CALL*10)+2)
+#define CMD_CALL_ANSWER		    ((CMD_CALL*10)+3)
+#define CMD_CALL_HANGUP		    ((CMD_CALL*10)+4)
+#define CMD_CALL_HANGUP_ALL	    ((CMD_CALL*10)+5)
+#define CMD_CALL_HOLD		    ((CMD_CALL*10)+6)
+#define CMD_CALL_REINVITE	    ((CMD_CALL*10)+7)
+#define CMD_CALL_UPDATE		    ((CMD_CALL*10)+8)
+#define CMD_CALL_NEXT		    ((CMD_CALL*10)+9)
+#define CMD_CALL_PREVIOUS	    ((CMD_CALL*10)+10)
+#define CMD_CALL_TRANSFER	    ((CMD_CALL*10)+11)
+#define CMD_CALL_TRANSFER_REPLACE   ((CMD_CALL*10)+12)
+#define CMD_CALL_REDIRECT	    ((CMD_CALL*10)+13)
+#define CMD_CALL_D2833		    ((CMD_CALL*10)+14)
+#define CMD_CALL_INFO		    ((CMD_CALL*10)+15)
+#define CMD_CALL_DUMP_Q		    ((CMD_CALL*10)+16)
+#define CMD_CALL_SEND_ARB	    ((CMD_CALL*10)+17)
+#define CMD_CALL_LIST		    ((CMD_CALL*10)+18)
+
+/* im & presence level 2 command */
+#define CMD_PRESENCE_ADD_BUDDY	    ((CMD_PRESENCE*10)+1)
+#define CMD_PRESENCE_DEL_BUDDY	    ((CMD_PRESENCE*10)+2)
+#define CMD_PRESENCE_SEND_IM	    ((CMD_PRESENCE*10)+3)
+#define CMD_PRESENCE_SUB	    ((CMD_PRESENCE*10)+4)
+#define CMD_PRESENCE_UNSUB	    ((CMD_PRESENCE*10)+5)
+#define CMD_PRESENCE_TOG_STATE	    ((CMD_PRESENCE*10)+6)
+#define CMD_PRESENCE_TEXT	    ((CMD_PRESENCE*10)+7)
+#define CMD_PRESENCE_LIST	    ((CMD_PRESENCE*10)+8)
+
+/* account level 2 command */
+#define CMD_ACCOUNT_ADD		    ((CMD_ACCOUNT*10)+1)
+#define CMD_ACCOUNT_DEL		    ((CMD_ACCOUNT*10)+2)
+#define CMD_ACCOUNT_MOD		    ((CMD_ACCOUNT*10)+3)
+#define CMD_ACCOUNT_REG		    ((CMD_ACCOUNT*10)+4)
+#define CMD_ACCOUNT_UNREG	    ((CMD_ACCOUNT*10)+5)
+#define CMD_ACCOUNT_NEXT	    ((CMD_ACCOUNT*10)+6)
+#define CMD_ACCOUNT_PREV	    ((CMD_ACCOUNT*10)+7)
+#define CMD_ACCOUNT_SHOW	    ((CMD_ACCOUNT*10)+8)
+
+/* conference & media level 2 command */
+#define CMD_MEDIA_LIST		    ((CMD_MEDIA*10)+1)
+#define CMD_MEDIA_CONF_CONNECT	    ((CMD_MEDIA*10)+2)
+#define CMD_MEDIA_CONF_DISCONNECT   ((CMD_MEDIA*10)+3)
+#define CMD_MEDIA_ADJUST_VOL	    ((CMD_MEDIA*10)+4)
+#define CMD_MEDIA_CODEC_PRIO	    ((CMD_MEDIA*10)+5)
+#define CMD_MEDIA_SPEAKER_TOGGLE    ((CMD_MEDIA*10)+6)
+
+/* status & config level 2 command */
+#define CMD_CONFIG_DUMP_STAT	    ((CMD_CONFIG*10)+1)
+#define CMD_CONFIG_DUMP_DETAIL	    ((CMD_CONFIG*10)+2)
+#define CMD_CONFIG_DUMP_CONF	    ((CMD_CONFIG*10)+3)
+#define CMD_CONFIG_WRITE_SETTING    ((CMD_CONFIG*10)+4)
+
+/* video level 2 command */
+#define CMD_VIDEO_ENABLE	    ((CMD_VIDEO*10)+1)
+#define CMD_VIDEO_DISABLE	    ((CMD_VIDEO*10)+2)
+#define CMD_VIDEO_ACC		    ((CMD_VIDEO*10)+3)
+#define CMD_VIDEO_CALL		    ((CMD_VIDEO*10)+4)
+#define CMD_VIDEO_DEVICE	    ((CMD_VIDEO*10)+5)
+#define CMD_VIDEO_CODEC		    ((CMD_VIDEO*10)+6)
+#define CMD_VIDEO_WIN		    ((CMD_VIDEO*10)+7)
+
+/* video level 3 command */
+#define CMD_VIDEO_ACC_SHOW	    ((CMD_VIDEO_ACC*10)+1)
+#define CMD_VIDEO_ACC_AUTORX	    ((CMD_VIDEO_ACC*10)+2)
+#define CMD_VIDEO_ACC_AUTOTX	    ((CMD_VIDEO_ACC*10)+3)
+#define CMD_VIDEO_ACC_CAP_ID	    ((CMD_VIDEO_ACC*10)+4)
+#define CMD_VIDEO_ACC_REN_ID	    ((CMD_VIDEO_ACC*10)+5)
+#define CMD_VIDEO_CALL_RX	    ((CMD_VIDEO_CALL*10)+1)
+#define CMD_VIDEO_CALL_TX	    ((CMD_VIDEO_CALL*10)+2)
+#define CMD_VIDEO_CALL_ADD	    ((CMD_VIDEO_CALL*10)+3)
+#define CMD_VIDEO_CALL_ENABLE	    ((CMD_VIDEO_CALL*10)+4)
+#define CMD_VIDEO_CALL_DISABLE	    ((CMD_VIDEO_CALL*10)+5)
+#define CMD_VIDEO_CALL_CAP	    ((CMD_VIDEO_CALL*10)+6)
+#define CMD_VIDEO_DEVICE_LIST	    ((CMD_VIDEO_DEVICE*10)+1)
+#define CMD_VIDEO_DEVICE_REFRESH    ((CMD_VIDEO_DEVICE*10)+2)
+#define CMD_VIDEO_DEVICE_PREVIEW    ((CMD_VIDEO_DEVICE*10)+3)
+#define CMD_VIDEO_CODEC_LIST	    ((CMD_VIDEO_CODEC*10)+1)
+#define CMD_VIDEO_CODEC_PRIO	    ((CMD_VIDEO_CODEC*10)+2)
+#define CMD_VIDEO_CODEC_FPS	    ((CMD_VIDEO_CODEC*10)+3)
+#define CMD_VIDEO_CODEC_BITRATE	    ((CMD_VIDEO_CODEC*10)+4)
+#define CMD_VIDEO_CODEC_SIZE	    ((CMD_VIDEO_CODEC*10)+5)
+#define CMD_VIDEO_WIN_LIST	    ((CMD_VIDEO_WIN*10)+1)
+#define CMD_VIDEO_WIN_ARRANGE	    ((CMD_VIDEO_WIN*10)+2)
+#define CMD_VIDEO_WIN_SHOW	    ((CMD_VIDEO_WIN*10)+3)
+#define CMD_VIDEO_WIN_HIDE	    ((CMD_VIDEO_WIN*10)+4)
+#define CMD_VIDEO_WIN_MOVE	    ((CMD_VIDEO_WIN*10)+5)
+#define CMD_VIDEO_WIN_RESIZE	    ((CMD_VIDEO_WIN*10)+6)
+
+/* dynamic choice argument list */
+#define DYN_CHOICE_START	    9900
+#define DYN_CHOICE_BUDDY_ID	    (DYN_CHOICE_START)+1
+#define DYN_CHOICE_ACCOUNT_ID	    (DYN_CHOICE_START)+2
+#define DYN_CHOICE_MEDIA_PORT	    (DYN_CHOICE_START)+3
+#define DYN_CHOICE_AUDIO_CODEC_ID   (DYN_CHOICE_START)+4
+#define DYN_CHOICE_CAP_DEV_ID	    (DYN_CHOICE_START)+5
+#define DYN_CHOICE_REN_DEV_ID	    (DYN_CHOICE_START)+6
+#define DYN_CHOICE_VID_DEV_ID	    (DYN_CHOICE_START)+7
+#define DYN_CHOICE_STREAM_ID	    (DYN_CHOICE_START)+8
+#define DYN_CHOICE_VIDEO_CODEC_ID   (DYN_CHOICE_START)+9
+#define DYN_CHOICE_WIN_ID	    (DYN_CHOICE_START)+10
+#define DYN_CHOICE_CALL_ID	    (DYN_CHOICE_START)+11
+#define DYN_CHOICE_ADDED_BUDDY_ID   (DYN_CHOICE_START)+12
+
+static pj_bool_t	   pj_inited = PJ_FALSE;
+static pj_caching_pool	   cli_cp;
+static pj_bool_t	   cli_cp_inited = PJ_FALSE;
+static pj_cli_t		   *cli = NULL;
+static pj_cli_sess	   *cli_cons_sess = NULL;
+static pj_cli_front_end	   *telnet_front_end = NULL;
+
+/** Forward declaration **/
+pj_status_t cli_setup_command(pj_cli_t *cli);
+void cli_destroy();
+
+PJ_DEF(void) cli_get_info(char *info, pj_size_t size) 
+{
+    pj_cli_telnet_info telnet_info;
+    pj_cli_telnet_get_info(telnet_front_end, &telnet_info);
+
+    pj_ansi_snprintf(info, size, "Telnet to %.*s:%d",
+		     (int)telnet_info.ip_address.slen, 
+		     telnet_info.ip_address.ptr, 
+		     telnet_info.port);
+}
+
+static void cli_log_writer(int level, const char *buffer, int len)
+{
+    if (cli)
+        pj_cli_write_log(cli, level, buffer, len);
+}
+
+pj_status_t cli_init()
+{
+    pj_status_t status;
+
+    pj_cli_cfg *cfg = &app_config.cli_cfg.cfg;
+
+    /* Init PJLIB */
+    status = pj_init();
+    if (status != PJ_SUCCESS)
+	goto on_error;
+
+    pj_inited = PJ_TRUE;
+
+    /* Init PJLIB-UTIL */
+    status = pjlib_util_init();
+    if (status != PJ_SUCCESS)
+	goto on_error;
+
+    /* Init CLI */
+    pj_caching_pool_init(&cli_cp, NULL, 0);
+    cli_cp_inited = PJ_TRUE;
+    cfg->pf = &cli_cp.factory;
+    cfg->name = pj_str("pjsua_cli");
+    cfg->title = pj_str("Pjsua CLI Application");
+    status = pj_cli_create(cfg, &cli);
+    if (status != PJ_SUCCESS)
+	goto on_error;
+
+    status = cli_setup_command(cli);
+    if (status != PJ_SUCCESS)
+	goto on_error;
+
+    /* Init telnet frontend */
+    if (app_config.cli_cfg.cli_fe & CLI_FE_TELNET) {
+	pj_cli_telnet_cfg *fe_cfg = &app_config.cli_cfg.telnet_cfg;
+	pj_pool_t *pool;
+
+	pool = pj_pool_create(cfg->pf, "cli_cp", 128, 128, NULL);
+	pj_assert(pool);
+
+	status = pj_cli_telnet_create(cli, fe_cfg, &telnet_front_end);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+    }
+
+    /* Init console frontend */
+    if (app_config.cli_cfg.cli_fe & CLI_FE_CONSOLE) {
+	pj_cli_console_cfg *fe_cfg = &app_config.cli_cfg.console_cfg;
+	
+	fe_cfg->quit_command = pj_str("shutdown");
+	status = pj_cli_console_create(cli, fe_cfg,
+				       &cli_cons_sess, NULL);
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+    }
+
+    return PJ_SUCCESS;
+
+on_error:
+    cli_destroy();
+    return status;
+}
+
+pj_status_t cli_main(pj_bool_t wait_telnet_cli)
+{
+    char cmdline[PJ_CLI_MAX_CMDBUF];
+
+    /* ReInit logging */
+    app_config.log_cfg.cb = &cli_log_writer;
+    pjsua_reconfigure_logging(&app_config.log_cfg);
+
+    if (app_config.cli_cfg.cli_fe & CLI_FE_CONSOLE) {
+	/* Main loop for CLI FE console */
+	while (!pj_cli_is_quitting(cli)) {
+	    pj_cli_console_process(cli_cons_sess, cmdline, sizeof(cmdline));
+	}
+    } else if (wait_telnet_cli) {
+	/* Just wait for CLI quit */
+	while (!pj_cli_is_quitting(cli)) {
+	    pj_thread_sleep(200);
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
+void cli_destroy()
+{
+    /* Destroy CLI, it will automatically destroy any FEs */
+    if (cli) {		
+	pj_cli_destroy(cli);
+	cli = NULL;
+    }
+
+    /* Destroy CLI caching pool factory */
+    if (cli_cp_inited) {
+	pj_caching_pool_destroy(&cli_cp);
+	cli_cp_inited = PJ_FALSE;
+    }
+
+    /* Shutdown PJLIB */
+    if (pj_inited) {
+	pj_shutdown();
+	pj_inited = PJ_FALSE;
+    }
+}
+
+/* Get input URL */
+static void get_input_url(char *buf, 
+			  pj_size_t len,
+			  pj_cli_cmd_val *cval,
+			  struct input_result *result)
+{
+    static const pj_str_t err_invalid_input = {"Invalid input\n", 15};
+    result->nb_result = PJSUA_APP_NO_NB;
+    result->uri_result = NULL;
+
+    len = strlen(buf);
+
+    /* Left trim */
+    while (pj_isspace(*buf)) {
+	++buf;
+	--len;
+    }
+
+    /* Remove trailing newlines */
+    while (len && (buf[len-1] == '\r' || buf[len-1] == '\n'))
+	buf[--len] = '\0';
+
+    if (len == 0 || buf[0]=='q')
+	return;
+
+    if (pj_isdigit(*buf) || *buf=='-') {
+
+	unsigned i;
+
+	if (*buf=='-')
+	    i = 1;
+	else
+	    i = 0;
+
+	for (; i<len; ++i) {
+	    if (!pj_isdigit(buf[i])) {
+		pj_cli_sess_write_msg(cval->sess, err_invalid_input.ptr, 
+				      (int)err_invalid_input.slen);
+		return;
+	    }
+	}
+
+	result->nb_result = my_atoi(buf);
+
+	if (result->nb_result >= 0 && 
+	    result->nb_result <= (int)pjsua_get_buddy_count()) 
+	{
+	    return;
+	}
+	if (result->nb_result == -1)
+	    return;
+
+	pj_cli_sess_write_msg(cval->sess, err_invalid_input.ptr, 
+			      (int)err_invalid_input.slen);
+	result->nb_result = PJSUA_APP_NO_NB;
+	return;
+
+    } else {
+	pj_status_t status;
+
+	if ((status=pjsua_verify_url(buf)) != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Invalid URL", status);
+	    return;
+	}
+
+	result->uri_result = buf;
+    }
+}
+
+/* CLI dynamic choice handler */
+/* Get buddy id */
+static void get_buddy_id(pj_cli_dyn_choice_param *param)
+{
+    if (param->cnt < param->max_cnt) {	
+	pjsua_buddy_id ids[64];
+	int i = 0;
+	unsigned count = PJ_ARRAY_SIZE(ids);
+	char data_out[64];
+
+	pjsua_enum_buddies(ids, &count);
+	
+	if (count > 0) {
+	    for (i=0; i<(int)count; ++i) {
+		pjsua_buddy_info info;
+
+		if (pjsua_buddy_get_info(ids[i], &info) != PJ_SUCCESS)
+		    continue;
+
+		/* Fill buddy id */
+		pj_ansi_snprintf(data_out, sizeof(data_out), "%d", ids[i]+1);
+		pj_strdup2(param->pool, &param->choice[i].value, data_out);
+		pj_bzero(data_out, PJ_ARRAY_SIZE(data_out));
+    	    
+		/* Format & fill description */
+		pj_ansi_snprintf(data_out, 
+				sizeof(data_out),
+				"<%.*s>  %.*s", 		    
+				(int)info.status_text.slen,
+				info.status_text.ptr, 
+				(int)info.uri.slen,
+				info.uri.ptr);
+
+		pj_strdup2(param->pool, &param->choice[i].desc, data_out);		
+		if (++param->cnt >= (param->max_cnt-1))
+		    break;	
+	    }
+	}
+	if (param->arg_id == DYN_CHOICE_BUDDY_ID) {
+	    /* Add URL input option */
+	    pj_ansi_snprintf(data_out, sizeof(data_out), "URL");
+	    pj_strdup2(param->pool, &param->choice[i].value, data_out);
+	    pj_ansi_snprintf(data_out, sizeof(data_out), "An URL");
+	    pj_strdup2(param->pool, &param->choice[i].desc, data_out);
+	    ++param->cnt;
+	}
+    }
+}
+
+static void get_account_id(pj_cli_dyn_choice_param *param)
+{
+    if (param->cnt < param->max_cnt) {	
+	char buf[8];
+	char buf_out[80];
+	pjsua_acc_info info;
+
+	pjsua_acc_id acc_ids[16];
+	unsigned count = PJ_ARRAY_SIZE(acc_ids);
+	int i;    
+
+	pjsua_enum_accs(acc_ids, &count);
+        
+	for (i=0; i<(int)count; ++i) {	
+	    pj_bzero(&buf_out[0], PJ_ARRAY_SIZE(buf_out));
+
+	    pjsua_acc_get_info(acc_ids[i], &info);
+
+	    pj_ansi_snprintf(buf_out, 
+			     sizeof(buf_out),
+			     "%c%.*s", 
+			     (acc_ids[i]==current_acc?'*':' '),
+			     (int)info.acc_uri.slen, 
+			     info.acc_uri.ptr);
+
+	    pj_bzero(buf, sizeof(buf));
+	    pj_ansi_snprintf(buf, sizeof(buf), "%d", acc_ids[i]);
+	    pj_strdup2(param->pool, &param->choice[i].value, buf);
+	    pj_strdup2(param->pool, &param->choice[i].desc, buf_out);
+	    if (++param->cnt >= param->max_cnt)
+		break;	
+	}
+    }
+}
+
+static void get_media_port(pj_cli_dyn_choice_param *param)
+{
+    unsigned i, count;
+    pjsua_conf_port_id id[PJSUA_MAX_CONF_PORTS];
+
+    count = PJ_ARRAY_SIZE(id);
+    pjsua_enum_conf_ports(id, &count);
+
+    for (i=0; i<count; ++i) {
+	char slot_id[8];
+	char desc[256];
+	char txlist[256];
+	unsigned j;
+	pjsua_conf_port_info info;
+
+	pjsua_conf_get_port_info(id[i], &info);
+
+	pj_ansi_snprintf(slot_id, sizeof(slot_id), 
+			 "%d", info.slot_id);
+	pj_strdup2(param->pool, &param->choice[i].value, slot_id);
+
+	txlist[0] = '\0';
+	for (j=0; j<info.listener_cnt; ++j) {
+	    char s[10];
+	    pj_ansi_snprintf(s, sizeof(s), "#%d ", info.listeners[j]);
+	    pj_ansi_strcat(txlist, s);
+	}	
+
+	pj_ansi_snprintf(desc,  
+	       sizeof(desc),
+	       "[%2dKHz/%dms/%d] %20.*s  transmitting to: %s", 	       
+	       info.clock_rate/1000,
+	       info.samples_per_frame*1000/info.channel_count/info.clock_rate,
+	       info.channel_count,
+	       (int)info.name.slen, 
+	       info.name.ptr,
+	       txlist);
+
+	pj_strdup2(param->pool, &param->choice[i].desc, desc);	
+	if (++param->cnt >= param->max_cnt)
+	    break;	
+    }
+}
+
+static void get_audio_codec_id(pj_cli_dyn_choice_param *param)
+{
+    if (param->cnt < param->max_cnt) {	
+	pjsua_codec_info c[32];
+	unsigned i, count = PJ_ARRAY_SIZE(c);
+	char codec_id[64];
+	char desc[128];
+        
+	pjsua_enum_codecs(c, &count);
+	for (i=0; i<count; ++i) {	
+	    pj_ansi_snprintf(codec_id, sizeof(codec_id), 
+			     "%.*s", (int)c[i].codec_id.slen, 
+			     c[i].codec_id.ptr);
+
+	    pj_strdup2(param->pool, &param->choice[param->cnt].value, codec_id);
+
+	    pj_ansi_snprintf(desc, sizeof(desc), 
+			     "Audio, prio: %d%s%.*s", 
+			     c[i].priority, 
+			     c[i].desc.slen? " - ":"",
+			     (int)c[i].desc.slen,
+			     c[i].desc.ptr);
+
+	    pj_strdup2(param->pool, &param->choice[param->cnt].desc, desc);
+	    if (++param->cnt >= param->max_cnt)
+		break;	
+	}
+    }
+}
+
+#if PJSUA_HAS_VIDEO  
+static void get_video_stream_id(pj_cli_dyn_choice_param *param)
+{
+    if (param->cnt < param->max_cnt) {	
+	pjsua_call_info call_info;
+
+	if (current_call != PJSUA_INVALID_ID) {
+	    unsigned i;
+	    pjsua_call_get_info(current_call, &call_info);
+	    for (i=0; i<call_info.media_cnt; ++i) {
+		if (call_info.media[i].type == PJMEDIA_TYPE_VIDEO) {
+		    char med_idx[8];
+		    pj_ansi_snprintf(med_idx, sizeof(med_idx), "%d", 
+				     call_info.media[i].index);
+		    pj_strdup2(param->pool, &param->choice[i].value, med_idx);
+
+		    switch (call_info.media[i].status) {		    
+		    case PJSUA_CALL_MEDIA_NONE:
+			pj_strdup2(param->pool, &param->choice[i].desc, 
+				   "Status:None");
+			break;
+		    case PJSUA_CALL_MEDIA_ACTIVE:
+			pj_strdup2(param->pool, &param->choice[i].desc, 
+				   "Status:Active");
+			break;
+		    case PJSUA_CALL_MEDIA_LOCAL_HOLD:
+			pj_strdup2(param->pool, &param->choice[i].desc, 
+				   "Status:Local Hold");
+			break;
+		    case PJSUA_CALL_MEDIA_REMOTE_HOLD:
+			pj_strdup2(param->pool, &param->choice[i].desc, 
+				   "Status:Remote Hold");
+			break;
+		    case PJSUA_CALL_MEDIA_ERROR:
+			pj_strdup2(param->pool, &param->choice[i].desc, 
+				   "Status:Media Error");
+			break;
+		    }
+		    if (++param->cnt >= param->max_cnt)
+			break;	
+		}
+	    }
+	}
+    }
+}
+  
+static void get_video_dev_hint(pj_cli_dyn_choice_param *param, 
+			       pjmedia_vid_dev_info *vdi,
+			       unsigned vid_dev_id) 
+{
+    char desc[128];
+    char dev_id[8];
+    pj_ansi_snprintf(dev_id, sizeof(dev_id),
+	"%d", vid_dev_id);
+    pj_ansi_snprintf(desc, sizeof(desc), "%s [%s]", 
+	vdi->name, vdi->driver);
+
+    pj_strdup2(param->pool, &param->choice[param->cnt].value, 
+	       dev_id);
+    pj_strdup2(param->pool, &param->choice[param->cnt].desc, 
+	       desc);    
+}
+
+static void get_video_dev_id(pj_cli_dyn_choice_param *param, 
+			     pj_bool_t all,
+			     pj_bool_t capture)
+{
+    if (param->cnt < param->max_cnt) {	
+	unsigned i, count;
+	pjmedia_vid_dev_info vdi;
+	pj_status_t status;
+
+	count = pjsua_vid_dev_count();
+	if (count == 0) {	
+	    return;
+	} 
+
+	for (i=0; i<count; ++i) {
+	    status = pjsua_vid_dev_get_info(i, &vdi);
+	    if (status == PJ_SUCCESS) {
+		if ((all) ||
+		    ((capture) && (vdi.dir == PJMEDIA_DIR_CAPTURE)) ||
+		    ((!capture) && (vdi.dir == PJMEDIA_DIR_RENDER)))
+		{		
+		    get_video_dev_hint(param, &vdi, i);
+		    if (++param->cnt >= param->max_cnt)
+			break;	
+		} 
+	    }
+	}
+    }
+}
+
+static void get_video_codec_id(pj_cli_dyn_choice_param *param)
+{    
+    if (param->cnt < param->max_cnt) {	
+	pjsua_codec_info ci[32];
+	unsigned i, count = PJ_ARRAY_SIZE(ci);
+	char codec_id[64];
+	char desc[128];
+
+	pjsua_vid_enum_codecs(ci, &count);
+	for (i=0; i<count; ++i) {
+	    pjmedia_vid_codec_param cp;
+	    pjmedia_video_format_detail *vfd;
+	    pj_status_t status = PJ_SUCCESS;
+
+	    status = pjsua_vid_codec_get_param(&ci[i].codec_id, &cp);
+	    if (status != PJ_SUCCESS)
+		continue;
+
+	    vfd = pjmedia_format_get_video_format_detail(&cp.enc_fmt, PJ_TRUE);
+
+	    pj_ansi_snprintf(codec_id, sizeof(codec_id), 
+			     "%.*s", (int)ci[i].codec_id.slen, 
+			     ci[i].codec_id.ptr);
+
+	    pj_strdup2(param->pool, &param->choice[param->cnt].value, codec_id);
+
+	    pj_ansi_snprintf(desc, sizeof(desc), 
+	    		     "Video, p[%d], f[%.2f], b[%d/%d], s[%dx%d]", 
+	    		     ci[i].priority, 
+			     (vfd->fps.num*1.0/vfd->fps.denum),
+			     vfd->avg_bps/1000, vfd->max_bps/1000,
+			     vfd->size.w, vfd->size.h);
+
+	    pj_strdup2(param->pool, &param->choice[param->cnt].desc, desc);	
+	    if (++param->cnt >= param->max_cnt)
+		break;	
+	}
+    }
+}
+
+static void get_video_window_id(pj_cli_dyn_choice_param *param)
+{
+    if (param->cnt < param->max_cnt) {	
+	pjsua_vid_win_id wids[PJSUA_MAX_VID_WINS];
+	unsigned i, cnt = PJ_ARRAY_SIZE(wids);
+	char win_id[64];
+	char desc[128];
+
+	pjsua_vid_enum_wins(wids, &cnt);
+
+	for (i = 0; i < cnt; ++i) {
+	    pjsua_vid_win_info wi;
+
+	    pjsua_vid_win_get_info(wids[i], &wi);
+	    pj_ansi_snprintf(win_id, sizeof(win_id), "%d", wids[i]);
+	    pj_strdup2(param->pool, &param->choice[i].value, win_id);
+
+	    pj_ansi_snprintf(desc, sizeof(desc), 
+			     "Show:%c Pos(%d,%d)  Size(%dx%d)", 
+			     (wi.show?'Y':'N'), wi.pos.x, wi.pos.y,
+			     wi.size.w, wi.size.h);
+
+	    pj_strdup2(param->pool, &param->choice[i].desc, desc);	
+	    if (++param->cnt >= param->max_cnt)
+		break;	
+	}
+    }
+}
+
+static void get_call_id(pj_cli_dyn_choice_param *param)
+{
+    if (param->cnt < param->max_cnt) {	
+	char call_id[64];
+	char desc[128];
+	unsigned i, count;
+	pjsua_call_id ids[PJSUA_MAX_CALLS];
+	int call = current_call;
+
+	count = PJ_ARRAY_SIZE(ids);
+	pjsua_enum_calls(ids, &count);
+
+	if (count > 1) {
+	    for (i=0; i<count; ++i) {
+		pjsua_call_info call_info;
+
+		if (ids[i] == call)
+		    return;
+
+		pjsua_call_get_info(ids[i], &call_info);
+		pj_ansi_snprintf(call_id, sizeof(call_id), "%d", ids[i]);
+		pj_strdup2(param->pool, &param->choice[i].value, call_id);
+		pj_ansi_snprintf(desc, sizeof(desc), "%.*s [%.*s]", 
+		    (int)call_info.remote_info.slen,
+		    call_info.remote_info.ptr,
+		    (int)call_info.state_text.slen,
+		    call_info.state_text.ptr);
+		pj_strdup2(param->pool, &param->choice[i].desc, desc);
+		if (++param->cnt >= param->max_cnt)
+		    break;	
+
+	    }
+	}
+    }
+}
+
+#endif
+
+static void get_choice_value(pj_cli_dyn_choice_param *param)
+{
+    switch (param->arg_id) {
+    case DYN_CHOICE_BUDDY_ID:
+    case DYN_CHOICE_ADDED_BUDDY_ID:
+	get_buddy_id(param);
+	break;
+    case DYN_CHOICE_ACCOUNT_ID:
+	get_account_id(param);
+	break;
+    case DYN_CHOICE_MEDIA_PORT:
+	get_media_port(param);
+	break;
+    case DYN_CHOICE_AUDIO_CODEC_ID:
+	get_audio_codec_id(param);
+	break;
+#if PJSUA_HAS_VIDEO    
+    case DYN_CHOICE_CAP_DEV_ID:	
+    case DYN_CHOICE_REN_DEV_ID:
+    case DYN_CHOICE_VID_DEV_ID:
+	get_video_dev_id(param, 
+			 (param->arg_id==DYN_CHOICE_VID_DEV_ID),
+			 (param->arg_id==DYN_CHOICE_CAP_DEV_ID));
+	break;
+    case DYN_CHOICE_STREAM_ID:
+	get_video_stream_id(param);
+	break;
+    case DYN_CHOICE_VIDEO_CODEC_ID:
+	get_video_codec_id(param);
+	break;
+    case DYN_CHOICE_WIN_ID:
+	get_video_window_id(param);
+	break;
+    case DYN_CHOICE_CALL_ID:
+	get_call_id(param);
+	break;
+#endif
+    default:
+	param->cnt = 0;
+	break;
+    }
+}
+
+/* 
+ * CLI command handler
+ */
+
+/* Add account */
+static pj_status_t cmd_add_account(pj_cli_cmd_val *cval)
+{
+    pjsua_acc_config acc_cfg;
+    pj_status_t status;
+
+    pjsua_acc_config_default(&acc_cfg);
+    acc_cfg.id = cval->argv[1];
+    acc_cfg.reg_uri = cval->argv[2];
+    acc_cfg.cred_count = 1;
+    acc_cfg.cred_info[0].scheme = pj_str("Digest");
+    acc_cfg.cred_info[0].realm = cval->argv[3];
+    acc_cfg.cred_info[0].username = cval->argv[4];
+    acc_cfg.cred_info[0].data_type = 0;
+    acc_cfg.cred_info[0].data = cval->argv[5];
+
+    acc_cfg.rtp_cfg = app_config.rtp_cfg;
+    app_config_init_video(&acc_cfg);
+
+    status = pjsua_acc_add(&acc_cfg, PJ_TRUE, NULL);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Error adding new account", status);
+    }
+    
+    return status;
+}
+
+/* Delete account */
+static pj_status_t cmd_del_account(pj_cli_cmd_val *cval)
+{
+    char out_str[64];
+    unsigned str_len;
+
+    int i = my_atoi(cval->argv[1].ptr);
+
+    if (!pjsua_acc_is_valid(i)) {
+	pj_ansi_snprintf(out_str, sizeof(out_str), 
+		        "Invalid account id %d\n", i);
+	str_len = (unsigned)pj_ansi_strlen(out_str);
+	pj_cli_sess_write_msg(cval->sess, out_str, str_len);
+    } else {
+	pjsua_acc_del(i);
+	pj_ansi_snprintf(out_str, sizeof(out_str),
+			 "Account %d deleted\n", i);
+	str_len = (unsigned)pj_ansi_strlen(out_str);
+	pj_cli_sess_write_msg(cval->sess, out_str, str_len);
+    }
+    return PJ_SUCCESS;
+}
+
+/* Modify account */
+static pj_status_t cmd_mod_account(pj_cli_cmd_val *cval)
+{
+    PJ_UNUSED_ARG(cval);
+    return PJ_SUCCESS;
+}
+
+/* Register account */
+static pj_status_t cmd_reg_account()
+{    
+    pjsua_acc_set_registration(current_acc, PJ_TRUE);
+    return PJ_SUCCESS;
+}
+
+/* Unregister account */
+static pj_status_t cmd_unreg_account()
+{    
+    pjsua_acc_set_registration(current_acc, PJ_FALSE);
+    return PJ_SUCCESS;
+}
+
+/* Select account to be used for sending outgoing request */
+static pj_status_t cmd_next_account(pj_cli_cmd_val *cval)
+{
+    int i = my_atoi(cval->argv[1].ptr);
+    if (pjsua_acc_is_valid(i)) {
+	pjsua_acc_set_default(i);
+	PJ_LOG(3,(THIS_FILE, "Current account changed to %d", i));
+    } else {
+	PJ_LOG(3,(THIS_FILE, "Invalid account id %d", i));
+    }    
+    return PJ_SUCCESS;
+}
+
+/* Show account list */
+static pj_status_t cmd_show_account(pj_cli_cmd_val *cval)
+{
+    pjsua_acc_id acc_ids[16];
+    unsigned count = PJ_ARRAY_SIZE(acc_ids);
+    int i;
+    static const pj_str_t header = {"Account list:\n", 15};    
+
+    pjsua_enum_accs(acc_ids, &count);
+
+    pj_cli_sess_write_msg(cval->sess, header.ptr, header.slen);
+    for (i=0; i<(int)count; ++i) {
+	char acc_info[80];
+	char out_str[160];
+	pjsua_acc_info info;
+
+	pjsua_acc_get_info(acc_ids[i], &info);
+
+	if (!info.has_registration) {
+	    pj_ansi_snprintf(acc_info, sizeof(acc_info), "%.*s", 
+			     (int)info.status_text.slen,
+			     info.status_text.ptr);
+
+	} else {
+	    pj_ansi_snprintf(acc_info, sizeof(acc_info),
+			     "%d/%.*s (expires=%d)",
+			     info.status,
+			     (int)info.status_text.slen,
+			     info.status_text.ptr,
+			     info.expires);
+
+	}
+
+	pj_ansi_snprintf(out_str, sizeof(out_str), 
+			 " %c[%2d] %.*s: %s\n", 
+			 (acc_ids[i]==current_acc?'*':' '), acc_ids[i],  
+			 (int)info.acc_uri.slen, info.acc_uri.ptr, 
+			 acc_info);
+	pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));
+
+	pj_bzero(out_str, sizeof(out_str));
+	pj_ansi_snprintf(out_str, sizeof(out_str),
+			 "       Online status: %.*s\n", 
+			 (int)info.online_status_text.slen,
+			 info.online_status_text.ptr);
+
+	pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* Account command handler */
+pj_status_t cmd_account_handler(pj_cli_cmd_val *cval)
+{    
+    pj_status_t status = PJ_SUCCESS;
+
+    CHECK_PJSUA_RUNNING();
+
+    switch(pj_cli_get_cmd_id(cval->cmd)) {
+    case CMD_ACCOUNT_ADD:
+	status = cmd_add_account(cval);
+	break;
+    case CMD_ACCOUNT_DEL:
+	status = cmd_del_account(cval);
+	break;
+    case CMD_ACCOUNT_MOD:
+	status = cmd_mod_account(cval);
+	break;
+    case CMD_ACCOUNT_REG:
+	status = cmd_reg_account();
+	break;
+    case CMD_ACCOUNT_UNREG:
+	status = cmd_unreg_account();
+	break;
+    case CMD_ACCOUNT_NEXT:	
+    case CMD_ACCOUNT_PREV:
+	status = cmd_next_account(cval);	
+	break;
+    case CMD_ACCOUNT_SHOW:
+	status = cmd_show_account(cval);
+	break;
+    }    
+    return status;
+}
+
+/* Add buddy */
+static pj_status_t cmd_add_buddy(pj_cli_cmd_val *cval)
+{    
+    char out_str[80];
+    pjsua_buddy_config buddy_cfg;
+    pjsua_buddy_id buddy_id;
+    pj_status_t status = PJ_SUCCESS;
+    cval->argv[1].ptr[cval->argv[1].slen] = 0;
+
+    if (pjsua_verify_url(cval->argv[1].ptr) != PJ_SUCCESS) {
+	pj_ansi_snprintf(out_str, sizeof(out_str), 
+			 "Invalid URI '%s'\n", cval->argv[1].ptr);
+    } else {
+	pj_bzero(&buddy_cfg, sizeof(pjsua_buddy_config));
+
+	buddy_cfg.uri = pj_str(cval->argv[1].ptr);
+	buddy_cfg.subscribe = PJ_TRUE;
+
+	status = pjsua_buddy_add(&buddy_cfg, &buddy_id);
+	if (status == PJ_SUCCESS) {
+	    pj_ansi_snprintf(out_str, sizeof(out_str), 
+			      "New buddy '%s' added at index %d\n",
+			      cval->argv[1].ptr, buddy_id+1);
+	}   
+    }
+    pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));
+    return status;
+}
+
+/* Delete buddy */
+static pj_status_t cmd_del_buddy(pj_cli_cmd_val *cval)
+{    
+    int i = my_atoi(cval->argv[1].ptr) - 1;
+    char out_str[80];
+
+    if (!pjsua_buddy_is_valid(i)) {
+	pj_ansi_snprintf(out_str, sizeof(out_str), 
+			 "Invalid buddy id %d\n", i);	
+    } else {
+	pjsua_buddy_del(i);
+	pj_ansi_snprintf(out_str, sizeof(out_str), 
+			 "Buddy %d deleted\n", i);		
+    }
+    pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));
+    return PJ_SUCCESS;
+}
+
+/* Send IM */
+static pj_status_t cmd_send_im(pj_cli_cmd_val *cval)
+{    
+    int i = -1;    
+    struct input_result result;
+    char dest[64];
+    pj_str_t tmp = pj_str(dest);    
+
+    /* make compiler happy. */
+    char *uri = NULL;
+
+    pj_strncpy_with_null(&tmp, &cval->argv[1], sizeof(dest));
+    
+    /* input destination. */
+    get_input_url(tmp.ptr, tmp.slen, cval, &result);
+    if (result.nb_result != PJSUA_APP_NO_NB) {
+
+	if (result.nb_result == -1) {	    
+	    static const pj_str_t err_msg = {"you can't send broadcast im "
+					     "like that!\n", 40 };	    
+	    pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+	    return PJ_SUCCESS;
+	} else if (result.nb_result == 0) {
+	    i = current_call;
+	} else {
+	    pjsua_buddy_info binfo;
+	    pjsua_buddy_get_info(result.nb_result-1, &binfo);	    
+	    pj_strncpy_with_null(&tmp, &binfo.uri, sizeof(dest));
+	    uri = tmp.ptr;
+	}
+
+    } else if (result.uri_result) {
+	uri = result.uri_result;
+    }
+
+    /* send typing indication. */
+    if (i != -1)
+	pjsua_call_send_typing_ind(i, PJ_TRUE, NULL);
+    else {
+	pj_str_t tmp_uri = pj_str(uri);
+	pjsua_im_typing(current_acc, &tmp_uri, PJ_TRUE, NULL);
+    }
+
+    /* send the im */
+    if (i != -1)
+	pjsua_call_send_im(i, NULL, &cval->argv[2], NULL, NULL);
+    else {
+	pj_str_t tmp_uri = pj_str(uri);
+	pjsua_im_send(current_acc, &tmp_uri, NULL, &cval->argv[2], NULL, NULL);
+    }
+    return PJ_SUCCESS;
+}
+
+/* Subscribe/unsubscribe presence */
+static pj_status_t cmd_subs_pres(pj_cli_cmd_val *cval, pj_bool_t subscribe)
+{   
+    struct input_result result;    
+    char dest[64] = {0};
+    pj_str_t tmp = pj_str(dest);
+    
+    pj_strncpy_with_null(&tmp, &cval->argv[1], sizeof(dest));
+    get_input_url(tmp.ptr, tmp.slen, cval, &result);    
+    if (result.nb_result != PJSUA_APP_NO_NB) {
+	if (result.nb_result == -1) {
+	    int i, count;
+	    count = pjsua_get_buddy_count();
+	    for (i=0; i<count; ++i)
+		pjsua_buddy_subscribe_pres(i, subscribe);
+	} else if (result.nb_result == 0) {
+	    static const pj_str_t err_msg = {"Sorry, can only subscribe to "
+					     "buddy's presence, not from "
+					     "existing call\n", 71};
+	    pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+	} else {
+	    pjsua_buddy_subscribe_pres(result.nb_result-1, subscribe);
+	}
+
+    } else if (result.uri_result) {
+	static const pj_str_t err_msg = {"Sorry, can only subscribe to "
+					 "buddy's presence, not arbitrary "
+					 "URL (for now)\n", 76};
+	pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+    }
+    return PJ_SUCCESS;
+}
+
+/* Toggle online state */
+static pj_status_t cmd_toggle_state(pj_cli_cmd_val *cval)
+{    
+    char out_str[128];
+    pjsua_acc_info acc_info;
+
+    pjsua_acc_get_info(current_acc, &acc_info);
+    acc_info.online_status = !acc_info.online_status;
+    pjsua_acc_set_online_status(current_acc, acc_info.online_status);
+    pj_ansi_snprintf(out_str, sizeof(out_str), 
+		     "Setting %s online status to %s\n",
+		     acc_info.acc_uri.ptr,
+		    (acc_info.online_status?"online":"offline"));
+    pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));
+    return PJ_SUCCESS;
+}
+
+/* Set presence text */
+static pj_status_t cmd_set_presence_text(pj_cli_cmd_val *cval)
+{    
+    pjrpid_element elem;
+    int choice;
+    pj_bool_t online_status;
+
+    enum {
+	AVAILABLE, BUSY, OTP, IDLE, AWAY, BRB, OFFLINE, OPT_MAX
+    };
+
+    choice = pj_strtol(&cval->argv[1]) - 1;
+
+    pj_bzero(&elem, sizeof(elem));
+    elem.type = PJRPID_ELEMENT_TYPE_PERSON;
+
+    online_status = PJ_TRUE;
+
+    switch (choice) {
+    case AVAILABLE:
+	break;
+    case BUSY:
+	elem.activity = PJRPID_ACTIVITY_BUSY;
+	elem.note = pj_str("Busy");
+	break;
+    case OTP:
+	elem.activity = PJRPID_ACTIVITY_BUSY;
+	elem.note = pj_str("On the phone");
+	break;
+    case IDLE:
+	elem.activity = PJRPID_ACTIVITY_UNKNOWN;
+	elem.note = pj_str("Idle");
+	break;
+    case AWAY:
+	elem.activity = PJRPID_ACTIVITY_AWAY;
+	elem.note = pj_str("Away");
+	break;
+    case BRB:
+	elem.activity = PJRPID_ACTIVITY_UNKNOWN;
+	elem.note = pj_str("Be right back");
+	break;
+    case OFFLINE:
+	online_status = PJ_FALSE;
+	break;
+    }
+    pjsua_acc_set_online_status2(current_acc, online_status, &elem);
+    return PJ_SUCCESS;
+}
+
+/* Show buddy list */
+static pj_status_t cmd_show_buddy(pj_cli_cmd_val *cval)
+{        
+    pjsua_buddy_id ids[64];
+    int i;
+    unsigned count = PJ_ARRAY_SIZE(ids);
+    static const pj_str_t header = {"Buddy list:\n", 13};    
+    char out_str[64];
+
+    pj_cli_sess_write_msg(cval->sess, header.ptr, header.slen);
+
+    pjsua_enum_buddies(ids, &count);
+
+    if (count == 0) {
+	pj_ansi_snprintf(out_str, sizeof(out_str), " -none-\n");
+	pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));
+    } else {
+	for (i=0; i<(int)count; ++i) {	    
+	    pjsua_buddy_info info;
+	    pj_bzero(out_str, sizeof(out_str));
+
+	    if (pjsua_buddy_get_info(ids[i], &info) != PJ_SUCCESS)
+		continue;
+
+	    pj_ansi_snprintf(out_str, sizeof(out_str), 
+		    " [%2d] <%.*s>  %.*s\n", 
+		    ids[i]+1, 
+		    (int)info.status_text.slen,
+		    info.status_text.ptr, 
+		    (int)info.uri.slen,
+		    info.uri.ptr);
+
+	    pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));
+	}
+    }        
+    return PJ_SUCCESS;
+}
+
+/* Presence/buddy command handler */
+pj_status_t cmd_presence_handler(pj_cli_cmd_val *cval)
+{    
+    pj_status_t status = PJ_SUCCESS;
+
+    CHECK_PJSUA_RUNNING();
+
+    switch(pj_cli_get_cmd_id(cval->cmd)) {
+    case CMD_PRESENCE_ADD_BUDDY:
+	status = cmd_add_buddy(cval);
+	break;
+    case CMD_PRESENCE_DEL_BUDDY:
+	status = cmd_del_buddy(cval);
+	break;
+    case CMD_PRESENCE_SEND_IM:
+	status = cmd_send_im(cval);
+	break;
+    case CMD_PRESENCE_SUB:	
+    case CMD_PRESENCE_UNSUB:
+	status = cmd_subs_pres(cval, 
+		               pj_cli_get_cmd_id(cval->cmd)==CMD_PRESENCE_SUB);	
+	break;
+    case CMD_PRESENCE_TOG_STATE:
+	status = cmd_toggle_state(cval);
+	break;
+    case CMD_PRESENCE_TEXT:
+	status = cmd_set_presence_text(cval);
+	break;
+    case CMD_PRESENCE_LIST:
+	status = cmd_show_buddy(cval);
+	break;
+    }    
+
+    return status;
+}
+
+/* Show conference list */
+static pj_status_t cmd_media_list(pj_cli_cmd_val *cval)
+{
+    unsigned i, count;
+    pjsua_conf_port_id id[PJSUA_MAX_CONF_PORTS];
+    static const pj_str_t header = {"Conference ports:\n", 19};
+
+    pj_cli_sess_write_msg(cval->sess, header.ptr, header.slen);    
+
+    count = PJ_ARRAY_SIZE(id);
+    pjsua_enum_conf_ports(id, &count);
+
+    for (i=0; i<count; ++i) {
+	char out_str[128];
+	char txlist[16];
+	unsigned j;
+	pjsua_conf_port_info info;
+
+	pjsua_conf_get_port_info(id[i], &info);
+
+	pj_bzero(txlist, sizeof(txlist));
+	for (j=0; j<info.listener_cnt; ++j) {
+	    char s[10];
+	    pj_ansi_snprintf(s, sizeof(s), "#%d ", info.listeners[j]);
+	    pj_ansi_strcat(txlist, s);
+	}
+	pj_ansi_snprintf(out_str, 
+	       sizeof(out_str),
+	       "Port #%02d[%2dKHz/%dms/%d] %20.*s  transmitting to: %s\n", 
+	       info.slot_id, 
+	       info.clock_rate/1000,
+	       info.samples_per_frame*1000/info.channel_count/info.clock_rate,
+	       info.channel_count,
+	       (int)info.name.slen, 
+	       info.name.ptr,
+	       txlist);
+	pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));    
+    }    
+    return PJ_SUCCESS;
+}
+
+/* Conference connect/disconnect */
+static pj_status_t cmd_media_connect(pj_cli_cmd_val *cval, pj_bool_t connect)
+{
+    pj_status_t status;
+    
+    if (connect)
+	status = pjsua_conf_connect(pj_strtol(&cval->argv[1]), 
+				    pj_strtol(&cval->argv[2]));
+    else
+	status = pjsua_conf_disconnect(pj_strtol(&cval->argv[1]), 
+				       pj_strtol(&cval->argv[2]));
+
+    if (status == PJ_SUCCESS) {
+	static const pj_str_t success_msg = {"Success\n", 9};
+	pj_cli_sess_write_msg(cval->sess, success_msg.ptr, success_msg.slen);	
+    } else {
+	static const pj_str_t err_msg = {"ERROR!!\n", 9};
+	pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+    }
+    return status;
+}
+
+/* Adjust audio volume */
+static pj_status_t cmd_adjust_vol(pj_cli_cmd_val *cval)
+{
+    char buf[80];
+    float orig_level;
+    char *err;
+    char level_val[16] = {0};
+    pj_str_t tmp = pj_str(level_val);
+
+    /* Adjust mic level */
+    orig_level = app_config.mic_level;    
+    pj_strncpy_with_null(&tmp, &cval->argv[1], sizeof(level_val));
+    app_config.mic_level = (float)strtod(level_val, &err);
+    pjsua_conf_adjust_rx_level(0, app_config.mic_level);
+
+    pj_ansi_snprintf(buf, sizeof(buf),
+		     "Adjust mic level: [%4.1fx] -> [%4.1fx]\n", 
+		     orig_level, app_config.mic_level);
+
+    pj_cli_sess_write_msg(cval->sess, buf, pj_ansi_strlen(buf));
+
+    /* Adjust speaker level */
+    orig_level = app_config.speaker_level;        
+    pj_strncpy_with_null(&tmp, &cval->argv[2], sizeof(level_val));
+    app_config.speaker_level = (float)strtod(level_val, &err);
+    pjsua_conf_adjust_tx_level(0, app_config.speaker_level);
+
+    pj_ansi_snprintf(buf, sizeof(buf),
+		      "Adjust speaker level: [%4.1fx] -> [%4.1fx]\n", 
+		      orig_level, app_config.speaker_level);
+
+    pj_cli_sess_write_msg(cval->sess, buf, pj_ansi_strlen(buf));
+
+    return PJ_SUCCESS;
+}
+
+/* Set codec priority */
+static pj_status_t cmd_set_codec_prio(pj_cli_cmd_val *cval)
+{        
+    int new_prio;    
+    pj_status_t status;    
+
+    new_prio = pj_strtol(&cval->argv[2]);
+    if (new_prio < 0) 
+	new_prio = 0;
+    else if (new_prio > PJMEDIA_CODEC_PRIO_HIGHEST) 
+	new_prio = PJMEDIA_CODEC_PRIO_HIGHEST;
+
+    status = pjsua_codec_set_priority(&cval->argv[1], 
+				      (pj_uint8_t)new_prio);
+#if PJSUA_HAS_VIDEO
+    if (status != PJ_SUCCESS) {
+	status = pjsua_vid_codec_set_priority(&cval->argv[1], 
+					      (pj_uint8_t)new_prio);
+    }
+#endif
+    if (status != PJ_SUCCESS)
+	pjsua_perror(THIS_FILE, "Error setting codec priority", status);
+
+    return status;
+}
+
+/* Conference/media command handler */
+pj_status_t cmd_media_handler(pj_cli_cmd_val *cval)
+{
+    pj_status_t status = PJ_SUCCESS;
+
+    CHECK_PJSUA_RUNNING();
+
+    switch(pj_cli_get_cmd_id(cval->cmd)) {
+    case CMD_MEDIA_LIST:
+	status = cmd_media_list(cval);
+	break;
+    case CMD_MEDIA_CONF_CONNECT:
+    case CMD_MEDIA_CONF_DISCONNECT:
+	status = cmd_media_connect(cval, 
+		          pj_cli_get_cmd_id(cval->cmd)==CMD_MEDIA_CONF_CONNECT);	
+	break;
+    case CMD_MEDIA_ADJUST_VOL:	
+	status = cmd_adjust_vol(cval);
+	break;
+    case CMD_MEDIA_CODEC_PRIO:
+	status = cmd_set_codec_prio(cval);	
+	break;
+    case CMD_MEDIA_SPEAKER_TOGGLE:
+	{
+	    static int route = PJMEDIA_AUD_DEV_ROUTE_DEFAULT;
+	    status = pjsua_snd_get_setting(PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE,
+					   &route);
+	    if (status != PJ_SUCCESS) {
+		PJ_PERROR(2, (THIS_FILE, status,
+			      "Warning: unable to retrieve route setting"));
+	    }
+
+	    if (route == PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER)
+		route = PJMEDIA_AUD_DEV_ROUTE_DEFAULT;
+	    else
+		route = PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
+
+	    PJ_LOG(4,(THIS_FILE, "Setting output route to %s %s",
+		      (route==PJMEDIA_AUD_DEV_ROUTE_DEFAULT?
+				      "default" : "loudspeaker"),
+		      (status? "anyway" : "")));
+
+	    status = pjsua_snd_set_setting(PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE,
+					   &route, PJ_TRUE);
+	    PJ_PERROR(4,(THIS_FILE, status, "Result"));
+	}
+	break;
+    }    
+
+    return status;
+}
+
+/* Dump status */
+static pj_status_t cmd_stat_dump(pj_bool_t detail)
+{
+    pjsua_dump(detail);
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_show_config()
+{
+    char settings[2000];
+    int len;
+
+    len = write_settings(&app_config, settings, sizeof(settings));
+    if (len < 1)
+	PJ_LOG(1,(THIS_FILE, "Error: not enough buffer"));
+    else
+	PJ_LOG(3,(THIS_FILE, 
+		  "Dumping configuration (%d bytes):\n%s\n",
+		  len, settings));
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_write_config(pj_cli_cmd_val *cval)
+{
+    char settings[2000];
+    char buf[128] = {0};
+    int len;
+    pj_str_t tmp = pj_str(buf);
+
+    pj_strncpy_with_null(&tmp, &cval->argv[1], sizeof(buf));    
+
+    len = write_settings(&app_config, settings, sizeof(settings));
+    if (len < 1)
+	PJ_LOG(1,(THIS_FILE, "Error: not enough buffer"));
+    else {
+	pj_oshandle_t fd;
+	pj_status_t status;
+
+	status = pj_file_open(app_config.pool, buf, PJ_O_WRONLY, &fd);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Unable to open file", status);
+	} else {
+	    char out_str[256];
+	    pj_ssize_t size = len;
+	    pj_file_write(fd, settings, &size);
+	    pj_file_close(fd);
+
+	    pj_ansi_snprintf(out_str, sizeof(out_str),
+			     "Settings successfully written to '%s'\n", buf);
+
+	    pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* Status and config command handler */
+pj_status_t cmd_config_handler(pj_cli_cmd_val *cval)
+{
+    pj_status_t status = PJ_SUCCESS;
+
+    CHECK_PJSUA_RUNNING();
+
+    switch(pj_cli_get_cmd_id(cval->cmd)) {
+    case CMD_CONFIG_DUMP_STAT:
+	status = cmd_stat_dump(PJ_FALSE);
+	break;
+    case CMD_CONFIG_DUMP_DETAIL:
+	status = cmd_stat_dump(PJ_TRUE);
+	break;
+    case CMD_CONFIG_DUMP_CONF:
+	status = cmd_show_config();	
+	break;
+    case CMD_CONFIG_WRITE_SETTING:	
+	status = cmd_write_config(cval);
+	break;
+    }    
+
+    return status;
+}
+
+/* Make single call */
+static pj_status_t cmd_make_single_call(pj_cli_cmd_val *cval)
+{
+    struct input_result result;
+    char dest[64] = {0};
+    char out_str[128];
+    pj_str_t tmp = pj_str(dest);      
+
+    pj_strncpy_with_null(&tmp, &cval->argv[1], sizeof(dest));    
+
+    pj_ansi_snprintf(out_str, 
+		     sizeof(out_str), 
+		     "(You currently have %d calls)\n",
+		     pjsua_call_get_count());
+
+    pj_cli_sess_write_msg(cval->sess, out_str, pj_ansi_strlen(out_str));
+    
+    /* input destination. */
+    get_input_url(tmp.ptr, tmp.slen, cval, &result);    
+    if (result.nb_result != PJSUA_APP_NO_NB) {
+	pjsua_buddy_info binfo;
+	if (result.nb_result == -1 || result.nb_result == 0) {
+	    static const pj_str_t err_msg = 
+		    {"You can't do that with make call!\n", 35};
+	    pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+	    return PJ_SUCCESS;
+	} 	
+	pjsua_buddy_get_info(result.nb_result-1, &binfo);	    
+	pj_strncpy(&tmp, &binfo.uri, sizeof(dest));
+    } else if (result.uri_result) {
+	tmp = pj_str(result.uri_result);
+    } else {
+	tmp.slen = 0;
+    }
+
+    pjsua_msg_data_init(&msg_data);
+    TEST_MULTIPART(&msg_data);
+    pjsua_call_make_call(current_acc, &tmp, &call_opt, NULL, 
+			 &msg_data, &current_call);
+    return PJ_SUCCESS;
+}
+
+/* Make multi call */
+static pj_status_t cmd_make_multi_call(pj_cli_cmd_val *cval)
+{
+    struct input_result result;
+    char dest[64] = {0};    
+    char out_str[128];
+    int i, count;
+    pj_str_t tmp = pj_str(dest);
+
+    pj_ansi_snprintf(out_str, 
+		     sizeof(out_str), 
+		     "(You currently have %d calls)\n",
+		     pjsua_call_get_count());
+    
+    count = pj_strtol(&cval->argv[1]);
+    if (count < 1)
+	return PJ_SUCCESS;
+    
+    pj_strncpy_with_null(&tmp, &cval->argv[2], sizeof(dest));
+    
+    /* input destination. */
+    get_input_url(tmp.ptr, tmp.slen, cval, &result);    
+    if (result.nb_result != PJSUA_APP_NO_NB) {
+	pjsua_buddy_info binfo;
+	if (result.nb_result == -1 || result.nb_result == 0) {
+	    static const pj_str_t err_msg = 
+			    {"You can't do that with make call!\n", 35};
+	    pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+	    return PJ_SUCCESS;
+	} 	
+	pjsua_buddy_get_info(result.nb_result-1, &binfo);	    
+	pj_strncpy(&tmp, &binfo.uri, sizeof(dest));	
+    } else {
+	tmp = pj_str(result.uri_result);
+    } 
+
+    for (i=0; i<count; ++i) {
+	pj_status_t status;
+
+	status = pjsua_call_make_call(current_acc, &tmp, &call_opt, NULL,
+	    NULL, NULL);
+	if (status != PJ_SUCCESS)
+	    break;
+    }
+    return PJ_SUCCESS;
+}
+
+/* Answer call */
+static pj_status_t cmd_answer_call(pj_cli_cmd_val *cval)
+{
+    pjsua_call_info call_info;
+
+    if (current_call != PJSUA_INVALID_ID) {
+	pjsua_call_get_info(current_call, &call_info);
+    } else {
+	/* Make compiler happy */
+	call_info.role = PJSIP_ROLE_UAC;
+	call_info.state = PJSIP_INV_STATE_DISCONNECTED;
+    }
+
+    if (current_call == PJSUA_INVALID_ID || 
+	call_info.role != PJSIP_ROLE_UAS ||
+	call_info.state >= PJSIP_INV_STATE_CONNECTING)
+    {	
+	static const pj_str_t err_msg = {"No pending incoming call\n", 26};	  
+	pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+
+    } else {
+	int st_code;
+	char contact[120];
+	pj_str_t hname = { "Contact", 7 };
+	pj_str_t hvalue;	
+	pjsip_generic_string_hdr hcontact;	
+
+	st_code = pj_strtol(&cval->argv[1]);
+	if ((st_code < 100) || (st_code > 699))
+	    return PJ_SUCCESS;
+
+	pjsua_msg_data_init(&msg_data);
+
+	if (st_code/100 == 3) {
+	    if (cval->argc < 3) {
+		static const pj_str_t err_msg = {"Enter URL to be put "
+						 "in Contact\n",  32};
+		pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);		
+		return PJ_SUCCESS;
+	    }
+
+	    hvalue = pj_str(contact);
+	    pjsip_generic_string_hdr_init2(&hcontact, &hname, &hvalue);
+
+	    pj_list_push_back(&msg_data.hdr_list, &hcontact);
+	}
+
+	/*
+	* Must check again!
+	* Call may have been disconnected while we're waiting for 
+	* keyboard input.
+	*/
+	if (current_call == PJSUA_INVALID_ID) {
+	    static const pj_str_t err_msg = {"Call has been disconnected\n", 
+					     28};	    
+	    pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+	}
+
+	pjsua_call_answer2(current_call, &call_opt, st_code, NULL, &msg_data);
+    }
+    return PJ_SUCCESS;
+}
+
+/* Hangup call */
+static pj_status_t cmd_hangup_call(pj_cli_cmd_val *cval, pj_bool_t all)
+{
+    if (current_call == PJSUA_INVALID_ID) {
+	static const pj_str_t err_msg = {"No current call\n", 17};
+	pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+    } else {
+	if (all)
+	    pjsua_call_hangup_all();	    
+	else
+	    pjsua_call_hangup(current_call, 0, NULL, NULL);
+    }
+    return PJ_SUCCESS;
+}
+
+/* Hold call */
+static pj_status_t cmd_hold_call()
+{
+    if (current_call != PJSUA_INVALID_ID) {	
+	pjsua_call_set_hold(current_call, NULL);
+
+    } else {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    }
+    return PJ_SUCCESS;
+}
+
+/* Call reinvite */
+static pj_status_t cmd_call_reinvite()
+{
+    if (current_call != PJSUA_INVALID_ID) {
+	/*
+	 * re-INVITE
+	 */
+	call_opt.flag |= PJSUA_CALL_UNHOLD;
+	pjsua_call_reinvite2(current_call, &call_opt, NULL);
+
+    } else {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    }
+    return PJ_SUCCESS;
+}
+
+/* Send update */
+static pj_status_t cmd_call_update()
+{
+    if (current_call != PJSUA_INVALID_ID) {
+	pjsua_call_update2(current_call, &call_opt, NULL);
+    } else {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    }
+    return PJ_SUCCESS;
+}
+
+/* Select next call */
+static pj_status_t cmd_next_call(pj_bool_t next)
+{
+    /*
+     * Cycle next/prev dialog.
+     */
+    if (next) {
+	find_next_call();
+    } else {
+	find_prev_call();
+    }
+
+    if (current_call != PJSUA_INVALID_ID) {	
+	pjsua_call_info call_info;
+
+	pjsua_call_get_info(current_call, &call_info);
+	PJ_LOG(3,(THIS_FILE,"Current dialog: %.*s", 
+		  (int)call_info.remote_info.slen, 
+		  call_info.remote_info.ptr));
+
+    } else {
+	PJ_LOG(3,(THIS_FILE,"No current dialog"));
+    }
+    return PJ_SUCCESS;
+}
+
+/* Transfer call */
+static pj_status_t cmd_transfer_call(pj_cli_cmd_val *cval)
+{
+    if (current_call == PJSUA_INVALID_ID) {
+
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+
+    } else {
+	char out_str[64];
+	int call = current_call;
+	char dest[64] = {0};
+	pj_str_t tmp = pj_str(dest);
+	struct input_result result;
+	pjsip_generic_string_hdr refer_sub;
+	pj_str_t STR_REFER_SUB = { "Refer-Sub", 9 };
+	pj_str_t STR_FALSE = { "false", 5 };
+	pjsua_call_info ci;
+	
+	pj_strncpy_with_null(&tmp, &cval->argv[1], sizeof(dest));	
+
+	pjsua_call_get_info(current_call, &ci);
+	pj_ansi_snprintf(out_str, 
+			 sizeof(out_str), 
+			 "Transfering current call [%d] %.*s\n",
+			 current_call,
+			 (int)ci.remote_info.slen, 
+			 ci.remote_info.ptr);
+
+	get_input_url(tmp.ptr, tmp.slen, cval, &result);
+
+	/* Check if call is still there. */
+
+	if (call != current_call) {
+	    puts("Call has been disconnected");
+	    return PJ_SUCCESS;
+	}
+
+	pjsua_msg_data_init(&msg_data);
+	if (app_config.no_refersub) {
+	    /* Add Refer-Sub: false in outgoing REFER request */
+	    pjsip_generic_string_hdr_init2(&refer_sub, &STR_REFER_SUB,
+		&STR_FALSE);
+	    pj_list_push_back(&msg_data.hdr_list, &refer_sub);
+	}
+	if (result.nb_result != PJSUA_APP_NO_NB) {
+	    if (result.nb_result == -1 || result.nb_result == 0) {
+		static const pj_str_t err_msg = {"You can't do that with "
+						 "transfer call!\n", 39};
+
+		pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+	    } else {
+		pjsua_buddy_info binfo;
+		pjsua_buddy_get_info(result.nb_result-1, &binfo);
+		pjsua_call_xfer( current_call, &binfo.uri, &msg_data);
+	    }
+	} else if (result.uri_result) {
+	    pj_str_t tmp;
+	    tmp = pj_str(result.uri_result);
+	    pjsua_call_xfer( current_call, &tmp, &msg_data);
+	}
+    }	    
+    return PJ_SUCCESS;
+}
+
+/* Transfer call */
+static pj_status_t cmd_transfer_replace_call(pj_cli_cmd_val *cval)
+{    
+    if (current_call == -1) {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    } else {
+	int call = current_call;
+	int dst_call;
+	pjsip_generic_string_hdr refer_sub;
+	pj_str_t STR_REFER_SUB = { "Refer-Sub", 9 };
+	pj_str_t STR_FALSE = { "false", 5 };
+	pjsua_call_id ids[PJSUA_MAX_CALLS];	
+	pjsua_msg_data msg_data;
+	char buf[8] = {0};	
+	pj_str_t tmp = pj_str(buf);
+	unsigned count;	
+	static const pj_str_t err_invalid_num = 
+				    {"Invalid destination call number\n", 32 };
+	count = PJ_ARRAY_SIZE(ids);
+	pjsua_enum_calls(ids, &count);
+
+	if (count <= 1) {	    
+	    static const pj_str_t err_no_other_call = 
+				    {"There are no other calls\n", 25};
+
+	    pj_cli_sess_write_msg(cval->sess, err_no_other_call.ptr, 
+				  err_no_other_call.slen);
+	    return PJ_SUCCESS;
+	}
+
+	pj_strncpy_with_null(&tmp, &cval->argv[1], sizeof(buf));
+	dst_call = my_atoi(tmp.ptr);
+
+	/* Check if call is still there. */
+	if (call != current_call) {	    
+	    static pj_str_t err_call_dc = 
+				    {"Call has been disconnected\n", 27};
+
+	    pj_cli_sess_write_msg(cval->sess, err_call_dc.ptr, 
+				  err_call_dc.slen);
+	    return PJ_SUCCESS;
+	}
+
+	/* Check that destination call is valid. */
+	if (dst_call == call) {
+	    static pj_str_t err_same_num = 
+				    {"Destination call number must not be the "
+				     "same as the call being transfered\n", 74};
+
+	    pj_cli_sess_write_msg(cval->sess, err_same_num.ptr, 
+				  err_same_num.slen);
+	    return PJ_SUCCESS;
+	}
+
+	if (dst_call >= PJSUA_MAX_CALLS) {
+	    pj_cli_sess_write_msg(cval->sess, err_invalid_num.ptr, 
+				  err_invalid_num.slen);
+	    return PJ_SUCCESS;
+	}
+
+	if (!pjsua_call_is_active(dst_call)) {
+	    pj_cli_sess_write_msg(cval->sess, err_invalid_num.ptr, 
+				  err_invalid_num.slen);
+	    return PJ_SUCCESS;
+	}
+
+	pjsua_msg_data_init(&msg_data);
+	if (app_config.no_refersub) {
+	    /* Add Refer-Sub: false in outgoing REFER request */
+	    pjsip_generic_string_hdr_init2(&refer_sub, &STR_REFER_SUB, 
+					   &STR_FALSE);
+	    pj_list_push_back(&msg_data.hdr_list, &refer_sub);
+	}
+
+	pjsua_call_xfer_replaces(call, dst_call, 
+				 PJSUA_XFER_NO_REQUIRE_REPLACES, 
+				 &msg_data);
+    }
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_redirect_call(pj_cli_cmd_val *cval)
+{  
+    if (current_call == PJSUA_INVALID_ID) {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+	return PJ_SUCCESS;
+    }
+    if (!pjsua_call_is_active(current_call)) {
+	PJ_LOG(1,(THIS_FILE, "Call %d has gone", current_call));
+    } else {	
+	enum {
+	    ACCEPT_REPLACE, ACCEPT, REJECT, STOP
+	};
+	int choice = pj_strtol(&cval->argv[1]);
+
+	switch (choice) {
+	case ACCEPT_REPLACE:
+	    pjsua_call_process_redirect(current_call, 
+	    				PJSIP_REDIRECT_ACCEPT_REPLACE);	    
+	    break;
+	case ACCEPT:
+	    pjsua_call_process_redirect(current_call, PJSIP_REDIRECT_ACCEPT);
+	    break;
+	case REJECT:
+	    pjsua_call_process_redirect(current_call, PJSIP_REDIRECT_REJECT);
+	    break;
+	default:
+	    pjsua_call_process_redirect(current_call, PJSIP_REDIRECT_STOP);
+	    break;
+	}	
+    }
+    return PJ_SUCCESS;
+}
+
+/* Send DTMF (RFC2833) */
+static pj_status_t cmd_dtmf_2833(pj_cli_cmd_val *cval)
+{
+    if (current_call == PJSUA_INVALID_ID) {
+
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+
+    } else if (!pjsua_call_has_media(current_call)) {
+
+	PJ_LOG(3,(THIS_FILE, "Media is not established yet!"));
+
+    } else {	
+	int call = current_call;
+	pj_status_t status;
+
+	if (call != current_call) {
+	    static const pj_str_t err_msg = {"Call has been disconnected\n",
+					     28};
+	    pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+	    return PJ_SUCCESS;;
+	}
+	
+	status = pjsua_call_dial_dtmf(current_call, &cval->argv[1]);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Unable to send DTMF", status);
+	} else {
+	    static const pj_str_t msg = {"DTMF digits enqueued "
+					 "for transmission\n", 39};
+	    pj_cli_sess_write_msg(cval->sess, msg.ptr, msg.slen);
+	}
+    }
+    return PJ_SUCCESS;
+}
+
+/* Send DTMF with SIP Info */
+static pj_status_t cmd_call_info(pj_cli_cmd_val *cval)
+{
+    if (current_call == PJSUA_INVALID_ID) {
+
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+
+    } else {
+	const pj_str_t SIP_INFO = pj_str("INFO");	
+	int call = current_call;
+	int i;
+	pj_status_t status;
+
+	if (call != current_call) {
+	    static const pj_str_t err_msg = {"Call has been disconnected\n",
+					     28};
+	    pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+	    return PJ_SUCCESS;;
+	}
+	
+	for (i=0; i<cval->argv[1].slen; ++i) {
+	    char body[64];
+
+	    pjsua_msg_data_init(&msg_data);
+	    msg_data.content_type = pj_str("application/dtmf-relay");
+
+	    pj_ansi_snprintf(body, 
+			     sizeof(body),
+			     "Signal=%c\n"
+			     "Duration=160",
+			     cval->argv[1].ptr[i]);
+
+	    msg_data.msg_body = pj_str(body);
+
+	    status = pjsua_call_send_request(current_call, &SIP_INFO, 
+		&msg_data);
+	    if (status != PJ_SUCCESS) {
+		break;
+	    }
+	}
+    }
+    return PJ_SUCCESS;
+}
+
+/* Dump call quality */
+static pj_status_t cmd_call_quality()
+{
+    if (current_call != PJSUA_INVALID_ID) {
+	log_call_dump(current_call);
+    } else {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    }
+    return PJ_SUCCESS;
+}
+
+/* Send arbitrary request */
+static pj_status_t cmd_send_arbitrary(pj_cli_cmd_val *cval)
+{
+    if (pjsua_acc_get_count() == 0) {
+	static const pj_str_t err_msg = {"Sorry, need at least one "
+					 "account configured\n", 45};
+	pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);	
+    } else {
+	char *uri;
+	char dest[64] = {0};
+	pj_str_t tmp = pj_str(dest);	
+	struct input_result result;
+	static const pj_str_t header = {"Send arbitrary request to "
+					"remote host\n", 39};
+	
+	pj_cli_sess_write_msg(cval->sess, header.ptr, header.slen);	
+	
+	pj_strncpy_with_null(&tmp, &cval->argv[2], sizeof(dest));	
+	/* Input destination URI */
+	uri = NULL;
+	get_input_url(tmp.ptr, tmp.slen, cval, &result);
+	if (result.nb_result != PJSUA_APP_NO_NB) {
+	    if (result.nb_result == -1) {		
+		static const pj_str_t err_msg = {"Sorry you can't do that!\n",
+						 26};
+		pj_cli_sess_write_msg(cval->sess, err_msg.ptr, err_msg.slen);
+		return PJ_SUCCESS;
+	    } else if (result.nb_result == 0) {
+		uri = NULL;
+		if (current_call == PJSUA_INVALID_ID) {
+		    static const pj_str_t err_msg = {"No current call\n",
+						     17};
+		    pj_cli_sess_write_msg(cval->sess, err_msg.ptr,
+				          err_msg.slen);
+
+		    return PJ_SUCCESS;
+		}
+	    } else {
+		pjsua_buddy_info binfo;
+		pjsua_buddy_get_info(result.nb_result-1, &binfo);		
+		pj_strncpy_with_null(&tmp, &binfo.uri, sizeof(dest));
+		uri = tmp.ptr;
+	    }
+	} else if (result.uri_result) {
+	    uri = result.uri_result;
+	} else {
+	    return PJ_SUCCESS;;
+	}
+
+	if (uri) {
+	    char method[64] = {0};
+	    pj_str_t tmp_method = pj_str(method);	    
+	    pj_strncpy_with_null(&tmp_method, &cval->argv[1], sizeof(method));
+	    tmp = pj_str(uri);
+	    send_request(method, &tmp);
+	} else {
+	    /* If you send call control request using this method
+	    * (such requests includes BYE, CANCEL, etc.), it will
+	    * not go well with the call state, so don't do it
+	    * unless it's for testing.
+	    */	    
+	    pjsua_call_send_request(current_call, &cval->argv[1], NULL);
+	}    
+    }
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_show_current_call(pj_cli_cmd_val *cval)
+{
+    char out_str[128];
+    int i = pjsua_call_get_count();
+    pj_ansi_snprintf(out_str, sizeof(out_str),
+		     "You have %d active call%s\n", i, (i>1?"s":""));
+
+    pj_cli_sess_write_msg(cval->sess, out_str, 
+	pj_ansi_strlen(out_str));
+
+    if (current_call != PJSUA_INVALID_ID) {
+	pjsua_call_info ci;
+	if (pjsua_call_get_info(current_call, &ci)==PJ_SUCCESS) {	    
+	    pj_ansi_snprintf(out_str, sizeof(out_str), 
+		   "Current call id=%d to %.*s [%.*s]\n", current_call,
+		   (int)ci.remote_info.slen, ci.remote_info.ptr,
+		   (int)ci.state_text.slen, ci.state_text.ptr);
+
+	    pj_cli_sess_write_msg(cval->sess, out_str, 
+				  pj_ansi_strlen(out_str));
+	}
+    } 
+    return PJ_SUCCESS;
+}
+
+/* Call handler */
+pj_status_t cmd_call_handler(pj_cli_cmd_val *cval)
+{    
+    pj_status_t status = PJ_SUCCESS;
+    pj_cli_cmd_id cmd_id = pj_cli_get_cmd_id(cval->cmd);
+
+    CHECK_PJSUA_RUNNING();
+
+    switch(cmd_id) {
+    case CMD_CALL_NEW:
+	status = cmd_make_single_call(cval);
+	break;
+    case CMD_CALL_MULTI:
+	status = cmd_make_multi_call(cval);
+	break;
+    case CMD_CALL_ANSWER:
+	status = cmd_answer_call(cval);	
+	break;
+    case CMD_CALL_HANGUP:	
+    case CMD_CALL_HANGUP_ALL:	
+	status = cmd_hangup_call(cval, (cmd_id==CMD_CALL_HANGUP_ALL));
+	break;
+    case CMD_CALL_HOLD:	
+	status = cmd_hold_call();
+	break;
+    case CMD_CALL_REINVITE:	
+	status = cmd_call_reinvite();
+	break;
+    case CMD_CALL_UPDATE:	
+	status = cmd_call_update();
+	break;
+    case CMD_CALL_NEXT:			
+    case CMD_CALL_PREVIOUS:	
+	status = cmd_next_call(cmd_id==CMD_CALL_NEXT);	
+	break;
+    case CMD_CALL_TRANSFER:	
+	status = cmd_transfer_call(cval);
+	break;
+    case CMD_CALL_TRANSFER_REPLACE:	
+	status = cmd_transfer_replace_call(cval);
+	break;
+    case CMD_CALL_REDIRECT:
+	status = cmd_redirect_call(cval);
+	break;
+    case CMD_CALL_D2833:	
+	status = cmd_dtmf_2833(cval);
+	break;
+    case CMD_CALL_INFO:	
+	status = cmd_call_info(cval);
+	break;
+    case CMD_CALL_DUMP_Q:	
+	status = cmd_call_quality();
+	break;
+    case CMD_CALL_SEND_ARB:	
+	status = cmd_send_arbitrary(cval);
+	break;
+    case CMD_CALL_LIST:
+	status = cmd_show_current_call(cval);
+	break;
+    }    
+
+    return status;
+}
+
+#if PJSUA_HAS_VIDEO 
+static pj_status_t cmd_set_video_enable(pj_bool_t enabled)
+{    
+    app_config.vid.vid_cnt = (enabled ? 1 : 0);
+    PJ_LOG(3,(THIS_FILE, "Video will be %s in next offer/answer",
+	(enabled?"enabled":"disabled")));
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t modify_video_account(pjsua_acc_config *acc_cfg)
+{
+    pj_status_t status = pjsua_acc_modify(current_acc, acc_cfg);
+    if (status != PJ_SUCCESS)
+	PJ_PERROR(1,(THIS_FILE, status, "Error modifying account %d",
+		     current_acc));
+
+    return status;
+}
+
+static pj_status_t cmd_show_account_video()
+{
+    pjsua_acc_config acc_cfg;
+    pj_pool_t *pool = pjsua_pool_create("tmp-pjsua", 1000, 1000);
+    
+    pjsua_acc_get_config(current_acc, pool, &acc_cfg);
+    app_config_show_video(current_acc, &acc_cfg);
+    pj_pool_release(pool);
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_video_acc_handler(pj_cli_cmd_val *cval)
+{
+    pjsua_acc_config acc_cfg;
+    pj_cli_cmd_id cmd_id = pj_cli_get_cmd_id(cval->cmd);
+    pj_pool_t *pool = pjsua_pool_create("tmp-pjsua", 1000, 1000);
+
+    CHECK_PJSUA_RUNNING();
+
+    pjsua_acc_get_config(current_acc, pool, &acc_cfg);
+
+    switch(cmd_id) {
+    case CMD_VIDEO_ACC_AUTORX:	
+    case CMD_VIDEO_ACC_AUTOTX:	
+	{
+	    int on = (pj_ansi_strnicmp(cval->argv[1].ptr, "On", 2)==0);
+       	
+	    if (cmd_id == CMD_VIDEO_ACC_AUTORX)
+		acc_cfg.vid_in_auto_show = on;
+	    else
+		acc_cfg.vid_out_auto_transmit = on;
+	}
+	break;
+    case CMD_VIDEO_ACC_CAP_ID:		
+    case CMD_VIDEO_ACC_REN_ID:
+	{
+	    int dev = pj_strtol(&cval->argv[1]);	    	    
+
+	    if (cmd_id == CMD_VIDEO_ACC_CAP_ID)
+		acc_cfg.vid_cap_dev = dev;
+	    else 
+		acc_cfg.vid_rend_dev = dev;		
+	}	
+	break;
+    }
+    modify_video_account(&acc_cfg);
+    pj_pool_release(pool);
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_add_vid_strm()
+{
+    return pjsua_call_set_vid_strm(current_call,
+				   PJSUA_CALL_VID_STRM_ADD, NULL);
+}
+
+static pj_status_t cmd_enable_vid_rx(pj_cli_cmd_val *cval)
+{
+    pjsua_call_vid_strm_op_param param;    
+    pjsua_stream_info si;    
+    pj_status_t status = PJ_SUCCESS;
+    pj_bool_t on = (pj_ansi_strnicmp(cval->argv[1].ptr, "On", 2) == 0);
+
+    pjsua_call_vid_strm_op_param_default(&param);    
+
+    param.med_idx = pj_strtol(&cval->argv[2]); 
+    if (pjsua_call_get_stream_info(current_call, param.med_idx, &si) ||
+	si.type != PJMEDIA_TYPE_VIDEO)
+    {
+	PJ_PERROR(1,(THIS_FILE, PJ_EINVAL, "Invalid stream"));
+	return status;
+    }
+
+    if (on) param.dir = (si.info.vid.dir | PJMEDIA_DIR_DECODING);
+    else param.dir = (si.info.vid.dir & PJMEDIA_DIR_ENCODING);
+
+    status = pjsua_call_set_vid_strm(current_call,
+				     PJSUA_CALL_VID_STRM_CHANGE_DIR,
+				     &param);
+    return status;
+}
+
+static pj_status_t cmd_enable_vid_tx(pj_cli_cmd_val *cval)
+{
+    pjsua_call_vid_strm_op_param param;    
+    pj_status_t status = PJ_SUCCESS;
+    pj_bool_t on = (pj_ansi_strnicmp(cval->argv[1].ptr, "On", 2) == 0);    
+    
+    pjsua_call_vid_strm_op op = on? PJSUA_CALL_VID_STRM_START_TRANSMIT :
+				PJSUA_CALL_VID_STRM_STOP_TRANSMIT;
+
+    pjsua_call_vid_strm_op_param_default(&param);
+    
+    param.med_idx = pj_strtol(&cval->argv[2]);
+
+    status = pjsua_call_set_vid_strm(current_call, op, &param);    
+    return status;
+}
+
+static pj_status_t cmd_enable_vid_stream(pj_cli_cmd_val *cval, 
+					   pj_bool_t enable)
+{    
+    pjsua_call_vid_strm_op_param param;    
+    pjsua_call_vid_strm_op op = enable? PJSUA_CALL_VID_STRM_CHANGE_DIR :
+				PJSUA_CALL_VID_STRM_REMOVE;
+
+    pjsua_call_vid_strm_op_param_default(&param);
+
+    param.med_idx = cval->argc > 1 ? pj_strtol(&cval->argv[1]) : -1;
+    param.dir = PJMEDIA_DIR_ENCODING_DECODING;
+    return pjsua_call_set_vid_strm(current_call, op, &param);    
+}
+
+static pj_status_t cmd_set_cap_dev_id(pj_cli_cmd_val *cval)
+{
+    pjsua_call_vid_strm_op_param param;
+
+    pjsua_call_vid_strm_op_param_default(&param);
+    param.med_idx = cval->argc > 1? pj_strtol(&cval->argv[1]) : -1;
+    param.cap_dev = cval->argc > 2? pj_strtol(&cval->argv[2]) : 
+				    PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+
+    return pjsua_call_set_vid_strm(current_call,
+				   PJSUA_CALL_VID_STRM_CHANGE_CAP_DEV,
+				   &param);
+}
+
+static pj_status_t cmd_list_vid_dev()
+{
+    vid_list_devs();
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_vid_device_refresh()
+{
+    pjmedia_vid_dev_refresh();
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_vid_device_preview(pj_cli_cmd_val *cval)
+{        
+    int dev_id = pj_strtol(&cval->argv[2]);    
+    pj_bool_t on = (pj_ansi_strnicmp(cval->argv[1].ptr, "On", 2) == 0);          
+
+    if (on) {
+	pjsua_vid_preview_param param;
+
+	pjsua_vid_preview_param_default(&param);
+	param.wnd_flags = PJMEDIA_VID_DEV_WND_BORDER |
+	    PJMEDIA_VID_DEV_WND_RESIZABLE;
+	pjsua_vid_preview_start(dev_id, &param);
+	arrange_window(pjsua_vid_preview_get_win(dev_id));
+    } else {
+	pjsua_vid_win_id wid;
+	wid = pjsua_vid_preview_get_win(dev_id);
+	if (wid != PJSUA_INVALID_ID) {
+	    /* Preview window hiding once it is stopped is
+	    * responsibility of app */
+	    pjsua_vid_win_set_show(wid, PJ_FALSE);
+	    pjsua_vid_preview_stop(dev_id);
+	}
+    }    
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_vid_codec_list()
+{    
+    pjsua_codec_info ci[PJMEDIA_CODEC_MGR_MAX_CODECS];
+    unsigned count = PJ_ARRAY_SIZE(ci);
+    pj_status_t status = pjsua_vid_enum_codecs(ci, &count);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(1,(THIS_FILE, status, "Error enumerating codecs"));
+    } else {
+	unsigned i;
+	PJ_LOG(3,(THIS_FILE, "Found %d video codecs:", count));
+	PJ_LOG(3,(THIS_FILE, "codec id      prio  fps    bw(kbps)   size"));
+	PJ_LOG(3,(THIS_FILE, "------------------------------------------"));
+	for (i=0; i<count; ++i) {
+	    pjmedia_vid_codec_param cp;
+	    pjmedia_video_format_detail *vfd;
+
+	    status = pjsua_vid_codec_get_param(&ci[i].codec_id, &cp);
+	    if (status != PJ_SUCCESS)
+		continue;
+
+	    vfd = pjmedia_format_get_video_format_detail(&cp.enc_fmt,
+		PJ_TRUE);
+	    PJ_LOG(3,(THIS_FILE, "%.*s%.*s %3d %7.2f  %4d/%4d  %dx%d", 
+		(int)ci[i].codec_id.slen, ci[i].codec_id.ptr,
+		13-(int)ci[i].codec_id.slen, "                ",
+		ci[i].priority,
+		(vfd->fps.num*1.0/vfd->fps.denum),
+		vfd->avg_bps/1000, vfd->max_bps/1000,
+		vfd->size.w, vfd->size.h));
+	}
+    }
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_set_vid_codec_prio(pj_cli_cmd_val *cval)
+{    
+    int prio = pj_strtol(&cval->argv[2]);
+    pj_status_t status;
+        
+    status = pjsua_vid_codec_set_priority(&cval->argv[1], (pj_uint8_t)prio);
+    if (status != PJ_SUCCESS)
+	PJ_PERROR(1,(THIS_FILE, status, "Set codec priority error"));
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_set_vid_codec_fps(pj_cli_cmd_val *cval)
+{    
+    pjmedia_vid_codec_param cp;
+    int M, N;    
+    pj_status_t status;
+
+    M = pj_strtol(&cval->argv[2]);
+    N = pj_strtol(&cval->argv[3]);
+    status = pjsua_vid_codec_get_param(&cval->argv[1], &cp);
+    if (status == PJ_SUCCESS) {
+	cp.enc_fmt.det.vid.fps.num = M;
+	cp.enc_fmt.det.vid.fps.denum = N;
+	status = pjsua_vid_codec_set_param(&cval->argv[1], &cp);
+    }
+    if (status != PJ_SUCCESS)
+	PJ_PERROR(1,(THIS_FILE, status, "Set codec framerate error"));
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_set_vid_codec_bitrate(pj_cli_cmd_val *cval)
+{    
+    pjmedia_vid_codec_param cp;    
+    int M, N;
+    pj_status_t status;
+
+    M = pj_strtol(&cval->argv[2]);
+    N = pj_strtol(&cval->argv[3]);
+    status = pjsua_vid_codec_get_param(&cval->argv[1], &cp);
+    if (status == PJ_SUCCESS) {
+	cp.enc_fmt.det.vid.avg_bps = M * 1000;
+	cp.enc_fmt.det.vid.max_bps = N * 1000;
+	status = pjsua_vid_codec_set_param(&cval->argv[1], &cp);
+    }
+    if (status != PJ_SUCCESS)
+	PJ_PERROR(1,(THIS_FILE, status, "Set codec bitrate error"));
+
+    return status;
+}
+
+static pj_status_t cmd_set_vid_codec_size(pj_cli_cmd_val *cval)
+{
+    pjmedia_vid_codec_param cp;    
+    int M, N;
+    pj_status_t status;
+
+    M = pj_strtol(&cval->argv[2]);
+    N = pj_strtol(&cval->argv[3]);
+    status = pjsua_vid_codec_get_param(&cval->argv[1], &cp);
+    if (status == PJ_SUCCESS) {
+	cp.enc_fmt.det.vid.size.w = M;
+	cp.enc_fmt.det.vid.size.h = N;
+	status = pjsua_vid_codec_set_param(&cval->argv[1], &cp);
+    }
+    if (status != PJ_SUCCESS)
+	PJ_PERROR(1,(THIS_FILE, status, "Set codec size error"));
+
+    return status;
+}
+
+static pj_status_t cmd_vid_win_list()
+{
+    pjsua_vid_win_id wids[PJSUA_MAX_VID_WINS];
+    unsigned i, cnt = PJ_ARRAY_SIZE(wids);
+
+    pjsua_vid_enum_wins(wids, &cnt);
+
+    PJ_LOG(3,(THIS_FILE, "Found %d video windows:", cnt));
+    PJ_LOG(3,(THIS_FILE, "WID show    pos       size"));
+    PJ_LOG(3,(THIS_FILE, "------------------------------"));
+    for (i = 0; i < cnt; ++i) {
+	pjsua_vid_win_info wi;
+	pjsua_vid_win_get_info(wids[i], &wi);
+	PJ_LOG(3,(THIS_FILE, "%3d   %c  (%d,%d)  %dx%d",
+	    wids[i], (wi.show?'Y':'N'), wi.pos.x, wi.pos.y,
+	    wi.size.w, wi.size.h));
+    }
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_arrange_vid_win()
+{
+    arrange_window(PJSUA_INVALID_ID);
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_show_vid_win(pj_cli_cmd_val *cval, pj_bool_t show)
+{            
+    pjsua_vid_win_id wid = pj_strtol(&cval->argv[1]);
+    return pjsua_vid_win_set_show(wid, show);
+}
+
+static pj_status_t cmd_move_vid_win(pj_cli_cmd_val *cval)
+{
+    pjsua_vid_win_id wid = pj_strtol(&cval->argv[1]);
+    pjmedia_coord pos;
+
+    pos.x = pj_strtol(&cval->argv[2]);
+    pos.y = pj_strtol(&cval->argv[3]);
+    return pjsua_vid_win_set_pos(wid, &pos);
+}
+
+static pj_status_t cmd_resize_vid_win(pj_cli_cmd_val *cval)
+{
+    pjsua_vid_win_id wid = pj_strtol(&cval->argv[1]);
+    pjmedia_rect_size size;
+
+    size.w = pj_strtol(&cval->argv[2]);
+    size.h = pj_strtol(&cval->argv[3]);
+    return pjsua_vid_win_set_size(wid, &size);
+}
+
+/* Video handler */
+static pj_status_t cmd_video_handler(pj_cli_cmd_val *cval)
+{    
+    pj_status_t status = PJ_SUCCESS;
+    pj_cli_cmd_id cmd_id = pj_cli_get_cmd_id(cval->cmd);    
+
+    CHECK_PJSUA_RUNNING();
+
+    switch(cmd_id) {
+    case CMD_VIDEO_ENABLE:
+	status = cmd_set_video_enable(PJ_TRUE);
+	break;
+    case CMD_VIDEO_DISABLE:
+	status = cmd_set_video_enable(PJ_FALSE);
+	break;
+    case CMD_VIDEO_ACC_SHOW:
+	status = cmd_show_account_video();
+	break;
+    case CMD_VIDEO_ACC_AUTORX:
+    case CMD_VIDEO_ACC_AUTOTX:
+    case CMD_VIDEO_ACC_CAP_ID:
+    case CMD_VIDEO_ACC_REN_ID:
+	status = cmd_video_acc_handler(cval);
+	break;
+    case CMD_VIDEO_CALL_ADD:
+	status = cmd_add_vid_strm();
+	break;
+    case CMD_VIDEO_CALL_RX:
+	status = cmd_enable_vid_rx(cval);
+	break;
+    case CMD_VIDEO_CALL_TX:
+	status = cmd_enable_vid_tx(cval);
+	break;
+    case CMD_VIDEO_CALL_ENABLE:
+    case CMD_VIDEO_CALL_DISABLE:
+	status = cmd_enable_vid_stream(cval, (cmd_id==CMD_VIDEO_CALL_ENABLE));
+	break;
+    case CMD_VIDEO_CALL_CAP:
+	status = cmd_set_cap_dev_id(cval);
+	break;
+    case CMD_VIDEO_DEVICE_LIST:
+	status = cmd_list_vid_dev();
+	break;
+    case CMD_VIDEO_DEVICE_REFRESH:
+	status = cmd_vid_device_refresh();
+	break;
+    case CMD_VIDEO_DEVICE_PREVIEW:
+	status = cmd_vid_device_preview(cval);
+	break;
+    case CMD_VIDEO_CODEC_LIST:
+	status = cmd_vid_codec_list();
+	break;
+    case CMD_VIDEO_CODEC_PRIO:
+	status = cmd_set_vid_codec_prio(cval);
+	break;
+    case CMD_VIDEO_CODEC_FPS:
+	status = cmd_set_vid_codec_fps(cval);
+	break;
+    case CMD_VIDEO_CODEC_BITRATE:
+	status = cmd_set_vid_codec_bitrate(cval);
+	break;
+    case CMD_VIDEO_CODEC_SIZE:
+	status = cmd_set_vid_codec_size(cval);
+	break;
+    case CMD_VIDEO_WIN_LIST:
+	status = cmd_vid_win_list();
+	break;
+    case CMD_VIDEO_WIN_ARRANGE:
+	status = cmd_arrange_vid_win();
+	break;
+    case CMD_VIDEO_WIN_SHOW:	
+    case CMD_VIDEO_WIN_HIDE:
+	status = cmd_show_vid_win(cval, (cmd_id==CMD_VIDEO_WIN_SHOW));
+	break;
+    case CMD_VIDEO_WIN_MOVE:
+	status = cmd_move_vid_win(cval);
+	break;
+    case CMD_VIDEO_WIN_RESIZE:
+	status = cmd_resize_vid_win(cval);
+	break;
+    }    
+
+    return status;
+}
+#endif
+
+/* Other command handler */
+static pj_status_t cmd_sleep_handler(pj_cli_cmd_val *cval)
+{    
+    int delay;
+
+    delay = pj_strtoul(&cval->argv[1]);
+    if (delay < 0) delay = 0;
+    pj_thread_sleep(delay);    
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_network_handler(pj_cli_cmd_val *cval)
+{
+    pj_status_t status = PJ_SUCCESS;
+    PJ_UNUSED_ARG(cval);
+
+    CHECK_PJSUA_RUNNING();
+    
+    status = pjsua_detect_nat_type();
+    if (status != PJ_SUCCESS)
+	pjsua_perror(THIS_FILE, "Error", status);
+
+    return status;
+}
+
+static pj_status_t cmd_quit_handler(pj_cli_cmd_val *cval)
+{
+    PJ_LOG(3,(THIS_FILE, "Quitting app.."));
+    pj_cli_quit(cval->sess->fe->cli, cval->sess, PJ_FALSE);
+
+    /* Invoke CLI stop callback (defined in pjsua_app.c) */
+    cli_on_stopped(PJ_FALSE, 0, NULL);
+
+    return PJ_SUCCESS;
+}
+
+/* 
+ * Syntax error handler for parser. 
+ */
+static void on_syntax_error(pj_scanner *scanner)
+{
+    PJ_UNUSED_ARG(scanner);
+    PJ_THROW(PJ_EINVAL);
+}
+
+/* 
+ * This method will parse buffer string info array of argument string
+ * @argc On input, maximum array size of argument. On output, number of argument 
+ * parsed
+ * @argv Array of argument string
+ */
+static pj_status_t get_options(pj_str_t *options, unsigned *argc,
+			       pj_str_t argv[])
+{
+    pj_scanner scanner;
+    unsigned max_argc = *argc;
+    
+    PJ_USE_EXCEPTION;
+
+    if (!options)
+	return PJ_SUCCESS;
+
+    pj_scan_init(&scanner, options->ptr, options->slen, PJ_SCAN_AUTOSKIP_WS, 
+		 &on_syntax_error);
+    PJ_TRY {
+	*argc = 0;
+	while (!pj_scan_is_eof(&scanner) && (max_argc > *argc)) {
+	    pj_str_t str;
+	    
+	    pj_scan_get_until_chr(&scanner, " \t\r\n", &str);
+	    argv[*argc] = str;
+	    ++(*argc);
+	}
+    }
+    PJ_CATCH_ANY {
+	pj_scan_fini(&scanner);	
+	return PJ_GET_EXCEPTION();
+    }
+    PJ_END;
+    return PJ_SUCCESS;
+}
+
+static pj_status_t cmd_restart_handler(pj_cli_cmd_val *cval)
+{
+    enum { MAX_ARGC = 64 };
+    int i;
+    unsigned argc = 1;
+    static char argv_buffer[PJ_CLI_MAX_CMDBUF];
+    static char *argv[MAX_ARGC] = {NULL};
+    char *pbuf = argv_buffer;
+
+    PJ_LOG(3,(THIS_FILE, "Restarting app.."));
+    pj_cli_quit(cval->sess->fe->cli, cval->sess, PJ_TRUE);
+
+    /** Get the pjsua option **/       
+    for (i=1; i < cval->argc; i++) {
+	pj_str_t argvst[MAX_ARGC];
+	unsigned j, ac;
+
+	ac = MAX_ARGC - argc;
+	get_options(&cval->argv[i], &ac, argvst);
+	for (j = 0; j < ac; j++) {
+	    pj_ansi_strncpy(pbuf, argvst[j].ptr, argvst[j].slen);
+	    pbuf[argvst[j].slen] = '\0';
+	    argv[argc + j] = pbuf;
+	    pbuf += argvst[j].slen + 1;
+	}
+	argc += ac;
+    }
+
+    /* Invoke CLI stop callback (defined in pjsua_app.c) */
+    cli_on_stopped(PJ_TRUE, argc, (char**)argv);
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t add_call_command(pj_cli_t *cli)
+{  
+    char* call_command = 
+	"<CMD name='call' id='100' desc='Call related commands'>"
+	"  <CMD name='new' id='1001' desc='Make a new call/INVITE'>"
+	"    <ARG name='buddy_id' type='choice' id='9901' validate='0' "
+	"     desc='Buddy Id'>"
+	"      <CHOICE value='-1' desc='All buddies'/>"
+	"      <CHOICE value='0' desc='Current dialog'/>"
+	"    </ARG>"
+	"  </CMD>"
+	"  <CMD name='multi' id='1002' desc='Make multiple calls'>"
+	"    <ARG name='number_of_calls' type='int' desc='Number of calls'/>"
+	"    <ARG name='buddy_id' type='choice' id='9901' validate='0' "
+	"     desc='Buddy Id'>"
+	"      <CHOICE value='-1' desc='All buddies'/>"
+	"      <CHOICE value='0' desc='Current dialog'/>"
+	"    </ARG>"
+	"  </CMD>"
+	"  <CMD name='answer' id='1003' desc='Answer call'>"
+	"    <ARG name='code' type='int' desc='Answer code'/>"
+	"    <ARG name='new_url' type='string' optional='1' "
+	"     desc='New URL(for 3xx resp)'/>"
+	"  </CMD>"
+	"  <CMD name='hangup' id='1004' sc='g' desc='Hangup call'/>"
+	"  <CMD name='hangup_all' id='1005' sc='hA' desc='Hangup all call'/>"
+	"  <CMD name='hold' id='1006' sc='H' desc='Hold call'/>"
+	"  <CMD name='reinvite' id='1007' sc='v' "
+	"   desc='Re-invite (release hold)'/>"
+	"  <CMD name='update' id='1008' sc='U' desc='Send Update request'/>"
+	"  <CMD name='next' id='1009' sc=']' desc='Select next call'/>"
+	"  <CMD name='previous' id='1010' sc='[' desc='Select previous call'/>"
+	"  <CMD name='transfer' id='1011' sc='x' desc='Transfer call'>"
+	"    <ARG name='buddy_id' type='choice' id='9901' validate='0' "
+	"     desc='Buddy Id'>"
+	"      <CHOICE value='-1' desc='All buddies'/>"
+	"      <CHOICE value='0' desc='Current dialog'/>"
+	"    </ARG>"
+	"  </CMD>"
+	"  <CMD name='transfer_replaces' id='1012' sc='X' "
+	"   desc='Transfer replace call'>"
+	"    <ARG name='call_id' type='choice' id='9911' desc='Call Id'/>"	
+	"  </CMD>"
+	"  <CMD name='redirect' id='1013' sc='R' desc='Redirect call'>"
+	"    <ARG name='redirect_option' type='choice' desc='Redirect option'>"
+	"      <CHOICE value='0' desc='Redirect accept replace'/>"
+	"      <CHOICE value='1' desc='Redirect accept'/>"
+	"      <CHOICE value='2' desc='Redirect reject'/>"
+	"      <CHOICE value='3' desc='Redirect stop'/>"
+	"    </ARG>"
+	"  </CMD>"
+	"  <CMD name='d_2833' id='1014' sc='#' desc='Send DTMF (RFC 2833)'>"
+	"    <ARG name='dtmf_to_send' type='string' "
+	"     desc='DTMF String to send'/>"
+	"  </CMD>"
+	"  <CMD name='d_info' id='1015' sc='*' desc='Send DTMF with SIP INFO'>"
+	"    <ARG name='dtmf_to_send' type='string' "
+	"     desc='DTMF String to send'/>"
+	"  </CMD>"
+	"  <CMD name='dump_q' id='1016' sc='dq' desc='Dump (call) quality'/>"
+	"  <CMD name='send_arb' id='1017' sc='S' desc='Send arbitrary request'>"
+	"    <ARG name='request_method' type='string' desc='Request method'/>"
+	"    <ARG name='buddy_id' type='choice' id='9901' validate='0' "
+	"     desc='Buddy Id'>"
+	"      <CHOICE value='-1' desc='All buddies'/>"
+	"      <CHOICE value='0' desc='Current dialog'/>"
+	"    </ARG>"
+	"  </CMD>"
+	"  <CMD name='list' id='1018' desc='Show current call'/>"
+	"</CMD>";
+
+    pj_str_t xml = pj_str(call_command);
+    return pj_cli_add_cmd_from_xml(cli, NULL, 
+				   &xml, cmd_call_handler,
+				   NULL, get_choice_value);
+}
+
+static pj_status_t add_presence_command(pj_cli_t *cli)
+{
+    char* presence_command =
+	"<CMD name='im' id='200' desc='IM and Presence Commands'>"
+	"  <CMD name='add_b' id='2001' sc='+b' desc='Add buddy'>"
+	"    <ARG name='buddy_uri' type='string' desc='Buddy URI'/>"
+	"  </CMD>"
+	"  <CMD name='del_b' id='2002' sc='-b' desc='Delete buddy'>"
+	"    <ARG name='added_buddy_id' type='choice' id='9912' "
+	"     desc='Buddy ID'/>"
+	"  </CMD>"
+	"  <CMD name='send_im' id='2003' sc='i' desc='Send IM'>"
+	"    <ARG name='buddy_id' type='choice' id='9901' validate='0' "
+	"     desc='Buddy Id'>"
+	"      <CHOICE value='-1' desc='All buddies'/>"
+	"      <CHOICE value='0' desc='Current dialog'/>"
+	"    </ARG>"
+	"    <ARG name='message_content' type='string' desc='Message Content'/>"
+	"  </CMD>"
+	"  <CMD name='sub_pre' id='2004' desc='Subscribe presence'>"
+	"    <ARG name='buddy_id' type='choice' id='9901' validate='0' "
+	"     desc='Buddy Id'>"
+	"      <CHOICE value='-1' desc='All buddies'/>"
+	"      <CHOICE value='0' desc='Current dialog'/>"
+	"    </ARG>"
+	"  </CMD>"
+	"  <CMD name='unsub_pre' id='2005' desc='Unsubscribe Presence'>"
+	"    <ARG name='buddy_id' type='choice' id='9901' validate='0' "
+	"     desc='Buddy Id'>"
+	"      <CHOICE value='-1' desc='All buddies'/>"
+	"      <CHOICE value='0' desc='Current dialog'/>"
+	"    </ARG>"
+	"  </CMD>"
+	"  <CMD name='tog_state' id='2006' desc='Toggle online state'/>"
+	"  <CMD name='pre_text' id='2007' sc='T' "
+	"   desc='Specify custom presence text'>"
+	"    <ARG name='online_state' type='choice' desc='Online state'>"
+	"      <CHOICE value='1' desc='Available'/>"
+	"      <CHOICE value='2' desc='Busy'/>"
+	"      <CHOICE value='3' desc='On The Phone'/>"
+	"      <CHOICE value='4' desc='Idle'/>"
+	"      <CHOICE value='5' desc='Away'/>"
+	"      <CHOICE value='6' desc='Be Right Back'/>"
+	"      <CHOICE value='7' desc='Offline'/>"
+	"    </ARG>"
+	"  </CMD>"
+	"  <CMD name='bud_list' id='2008' sc='bl' desc='Show buddy list'/>"
+	"</CMD>";
+
+    pj_str_t xml = pj_str(presence_command);
+
+    return pj_cli_add_cmd_from_xml(cli, NULL, 
+				   &xml, cmd_presence_handler, 
+				   NULL, get_choice_value);
+}
+
+static pj_status_t add_account_command(pj_cli_t *cli)
+{
+    char* account_command = 
+	"<CMD name='acc' id='300' desc='Account commands'>"
+	"  <CMD name='add' id='3001' sc='+a' desc='Add new account'>"
+	"    <ARG name='sip_url' type='string' desc='Your SIP URL'/>"
+	"    <ARG name='registrar_url' type='string' "
+	"     desc='URL of the registrar'/>"
+	"    <ARG name='auth_realm' type='string' desc='Auth realm'/>"
+	"    <ARG name='auth_username' type='string' desc='Auth username'/>"
+	"    <ARG name='auth_password' type='string' desc='Auth password'/>"
+	"  </CMD>"
+	"  <CMD name='del' id='3002' sc='-a' desc='Delete account'>"
+	"    <ARG name='account_id' type='choice' id='9902' desc='Account Id'/>"
+	"  </CMD>"
+	"  <CMD name='mod' id='3003' sc='!a' desc='Modify account'>"
+	"    <ARG name='account_id' type='choice' id='9902' desc='Account Id'/>"
+	"    <ARG name='sip_url' type='string' desc='Your SIP URL'/>"
+	"    <ARG name='registrar_url' type='string' "
+	"     desc='URL of the registrar'/>"
+	"    <ARG name='auth_realm' type='string' desc='Auth realm'/>"
+	"    <ARG name='auth_username' type='string' desc='Auth username'/>"
+	"    <ARG name='auth_password' type='string' desc='Auth password'/>"
+	"  </CMD>"
+	"  <CMD name='reg' id='3004' sc='rr' "
+	"   desc='Send (Refresh) Register request to register'/>"
+	"  <CMD name='unreg' id='3005' sc='ru' "
+	"   desc='Send Register request to unregister'/>"
+	"  <CMD name='next' id='3006' sc='<' "
+	"   desc='Select the next account for sending outgoing requests'>"
+	"    <ARG name='account_id' type='choice' id='9902' desc='Account Id'/>"
+	"  </CMD>"
+	"  <CMD name='prev' id='3007' sc='>' "
+	"   desc='Select the previous account for sending outgoing requests'>"
+	"    <ARG name='account_id' type='choice' id='9902' desc='Account Id'/>"
+	"  </CMD>"
+	"  <CMD name='show' id='3008' sc='l' desc='Show account list'/>"
+	"</CMD>";
+
+    pj_str_t xml = pj_str(account_command);
+    return pj_cli_add_cmd_from_xml(cli, NULL, 
+				   &xml, cmd_account_handler, 
+				   NULL, get_choice_value);
+}
+
+static pj_status_t add_media_command(pj_cli_t *cli)
+{
+    char* media_command = 
+	"<CMD name='audio' id='400' desc='Conference and Media commands'>"
+	"  <CMD name='list' id='4001' sc='cl' desc='Show conference list'/>"
+	"  <CMD name='conf_con' id='4002' sc='cc' desc='Conference connect'>"
+	"    <ARG name='source_port' type='choice' id='9903' "
+	"     desc='Source Port'/>"
+	"    <ARG name='destination_port' type='choice' id='9903' "
+	"     desc='Destination Port'/>"
+	"  </CMD>"
+	"  <CMD name='conf_dis' id='4003' sc='cd' desc='Conference disconnect'>"
+	"    <ARG name='source_port' type='choice' id='9903' "
+	"     desc='Source Port'/>"
+	"    <ARG name='destination_port' type='choice' id='9903' "
+	"     desc='Destination Port'/>"
+	"  </CMD>"
+	"  <CMD name='adjust_vol' id='4004' sc='V' desc='Adjust volume'>"
+	"    <ARG name='mic_level' type='int' desc='Mic Level'/>"
+	"    <ARG name='speaker_port' type='int' desc='Speaker Level'/>"
+	"  </CMD>"
+	"  <CMD name='speakertog' id='4006' desc='Toggle audio output route' />"
+	"  <CMD name='codec_prio' id='4005' sc='Cp' "
+	"   desc='Arrange codec priorities'>"
+	"    <ARG name='codec_id' type='choice' id='9904' desc='Codec Id'/>"
+	"    <ARG name='priority' type='int' desc='Codec Priority'/>"
+	"  </CMD>"
+	"</CMD>";
+
+    pj_str_t xml = pj_str(media_command);
+    return pj_cli_add_cmd_from_xml(cli, NULL, 
+				   &xml, cmd_media_handler, 
+				   NULL, get_choice_value);
+}
+
+static pj_status_t add_config_command(pj_cli_t *cli)
+{
+    char* config_command = 
+	"<CMD name='stat' id='500' desc='Status and config commands'>"
+	"  <CMD name='dump_stat' id='5001' sc='ds' desc='Dump status'/>"
+	"  <CMD name='dump_detail' id='5002' sc='dd' "
+	"   desc='Dump detail status'/>"
+	"  <CMD name='dump_conf' id='5003' sc='dc' "
+	"   desc='Dump configuration to screen'/>"
+	"  <CMD name='write_setting' id='5004' sc='f' "
+	"   desc='Write current configuration file'>"
+	"    <ARG name='output_file' type='string' desc='Output filename'/>"
+	"  </CMD>"
+	"</CMD>";
+
+    pj_str_t xml = pj_str(config_command);
+    return pj_cli_add_cmd_from_xml(cli, NULL, 
+				   &xml, cmd_config_handler,
+				   NULL, get_choice_value);
+}
+
+#if PJSUA_HAS_VIDEO    
+static pj_status_t add_video_command(pj_cli_t *cli)
+{
+    char* video_command =
+	"<CMD name='video' id='600' desc='Video commands'>"
+	"  <CMD name='enable' id='6001' desc='Enable video'/>"
+	"  <CMD name='disable' id='6002' desc='Disable video'/>"
+	"  <CMD name='acc' id='6003' desc='Video setting for current account'>"
+	"    <CMD name='show' id='60031' "
+	"     desc='Show video setting for current account'/>"
+	"    <CMD name='autorx' id='60032' sc='ar' "
+	"     desc='Automatically show incoming video'>"
+	"      <ARG name='enable_option' type='choice' "
+	"       desc='Enable/Disable option'>"
+	"        <CHOICE value='On' desc='Enable'/>"
+	"        <CHOICE value='Off' desc='Disable'/>"
+	"      </ARG>"
+	"    </CMD>"
+	"    <CMD name='autotx' id='60033' sc='at' "
+	"     desc='Automatically offer video'>"
+	"      <ARG name='enable_option' type='choice' "
+	"       desc='Enable/Disable option'>"
+	"        <CHOICE value='On' desc='Enable'/>"
+	"        <CHOICE value='Off' desc='Disable'/>"
+	"      </ARG>"
+	"    </CMD>"
+	"    <CMD name='cap_id' id='60034' sc='ci' "
+	"     desc='Set default capture device for current account'>"
+	"      <ARG name='cap_dev_id' type='choice' id='9905' "
+	"       desc='Capture device Id'/>"
+	"    </CMD>"
+	"    <CMD name='ren_id' id='60035' sc='ri' "
+	"     desc='Set default renderer device for current account'>"
+	"      <ARG name='ren_dev_id' type='choice' id='9906' "
+	"       desc='Renderer device Id'/>"
+	"    </CMD>"
+	"  </CMD>"
+	"  <CMD name='call' id='6004' sc='vcl' "
+	"   desc='Video call commands/settings'>"
+	"    <CMD name='rx' id='60041' "
+	"     desc='Enable/disable video RX for stream in curr call'>"
+	"      <ARG name='enable_option' type='choice' "
+	"       desc='Enable/Disable option'>"
+	"        <CHOICE value='On' desc='Enable'/>"
+	"        <CHOICE value='Off' desc='Disable'/>"
+	"      </ARG>"
+	"      <ARG name='stream_id' type='choice' id='9908' desc='Stream Id'/>"
+	"    </CMD>"
+	"    <CMD name='tx' id='60042' "
+	"     desc='Enable/disable video TX for stream in curr call'>"
+	"      <ARG name='enable_option' type='choice' "
+	"       desc='Enable/Disable option'>"
+	"        <CHOICE value='On' desc='Enable'/>"
+	"        <CHOICE value='Off' desc='Disable'/>"
+	"      </ARG>"
+	"      <ARG name='stream_id' type='choice' id='9908' desc='Stream Id'/>"
+	"    </CMD>"
+	"    <CMD name='add' id='60043' "
+	"     desc='Add video stream for current call'/>"
+	"    <CMD name='enable' id='60044' "
+	"     desc='Enable stream #N in current call'>"
+	"      <ARG name='stream_id' type='choice' id='9908' optional='1' "
+	"       desc='Stream Id'/>"
+	"    </CMD>"
+	"    <CMD name='disable' id='60045' "
+	"     desc='Disable stream #N in current call'>"
+	"      <ARG name='stream_id' type='choice' id='9908' optional='1' "
+	"       desc='Stream Id'/>"
+	"    </CMD>"
+	"    <CMD name='cap' id='60046' "
+	"     desc='Set capture dev ID for stream #N in current call'>"
+	"      <ARG name='stream_id' type='choice' id='9908' desc='Stream Id'/>"
+	"      <ARG name='cap_device_id' type='choice' id='9905' "
+	"       desc='Device Id'/>"
+	"    </CMD>"
+	"  </CMD>"
+	"  <CMD name='device' id='6005' sc='vv' desc='Video device commands'>"
+	"    <CMD name='list' id='60051' desc='Show all video devices'/>"
+	"    <CMD name='refresh' id='60052' desc='Refresh video device list'/>"
+	"    <CMD name='prev' id='60053' "
+	"     desc='Enable/disable preview for specified device ID'>"
+	"      <ARG name='enable_option' type='choice' "
+	"       desc='Enable/Disable option'>"
+	"        <CHOICE value='On' desc='Enable'/>"
+	"        <CHOICE value='Off' desc='Disable'/>"
+	"      </ARG>"
+	"      <ARG name='device_id' type='choice' id='9907' "
+	"       desc='Video Device Id'/>"
+	"    </CMD>"
+	"  </CMD>"
+	"  <CMD name='codec' id='6006' desc='Video codec commands'>"
+	"    <CMD name='list' id='60061' desc='Show video codec list'/>"
+	"    <CMD name='prio' id='60062' desc='Set video codec priority'>"
+	"      <ARG name='codec_id' type='choice' id='9909' desc='Codec Id'/>"
+	"      <ARG name='priority' type='int' desc='Priority'/>"
+	"    </CMD>"
+	"    <CMD name='fps' id='60063' desc='Set video codec framerate'>"
+	"      <ARG name='codec_id' type='choice' id='9909' desc='Codec Id'/>"
+	"      <ARG name='num' type='int' desc='Numerator'/>"
+	"      <ARG name='denum' type='int' desc='Denumerator'/>"
+	"    </CMD>"
+	"    <CMD name='bitrate' id='60064' desc='Set video codec bitrate'>"
+	"      <ARG name='codec_id' type='choice' id='9909' desc='Codec Id'/>"
+	"      <ARG name='avg' type='int' desc='Average bps'/>"
+	"      <ARG name='max' type='int' desc='Maximum bps'/>"
+	"    </CMD>"
+	"    <CMD name='size' id='60065' desc='Set codec ID size/resolution'>"
+	"      <ARG name='codec_id' type='choice' id='9909' desc='Codec Id'/>"
+	"      <ARG name='width' type='int' desc='Width'/>"
+	"      <ARG name='height' type='int' desc='Height'/>"
+	"    </CMD>"
+	"  </CMD>"
+	"  <CMD name='win' id='6007' desc='Video windows settings/commands'>"
+	"    <CMD name='list' id='60071' desc='List all active video windows'/>"
+	"    <CMD name='arrange' id='60072' desc='Auto arrange windows'/>"
+	"    <CMD name='show' id='60073' desc='Show specific windows'>"
+	"      <ARG name='window_id' type='choice' id='9910' "
+	"       desc='Windows Id'/>"
+	"    </CMD>"
+	"    <CMD name='hide' id='60074' desc='Hide specific windows'>"
+	"      <ARG name='window_id' type='choice' id='9910' "
+	"       desc='Windows Id'/>"
+	"    </CMD>"
+	"    <CMD name='move' id='60075' desc='Move window position'>"
+	"      <ARG name='window_id' type='choice' id='9910' "
+	"       desc='Windows Id'/>"
+	"      <ARG name='x' type='int' desc='Horizontal position'/>"
+	"      <ARG name='y' type='int' desc='Vertical position'/>"
+	"    </CMD>"
+	"    <CMD name='resize' id='60076' "
+	"     desc='Resize window to specific width/height'>"
+	"      <ARG name='window_id' type='choice' id='9910' "
+	"       desc='Windows Id'/>"
+	"      <ARG name='width' type='int' desc='Width'/>"
+	"      <ARG name='height' type='int' desc='Height'/>"
+	"    </CMD>"
+	"  </CMD>"
+	"</CMD>";
+
+    pj_str_t xml = pj_str(video_command);
+    return pj_cli_add_cmd_from_xml(cli, NULL, 
+				   &xml, cmd_video_handler, 
+				   NULL, get_choice_value);
+}
+#endif
+
+static pj_status_t add_other_command(pj_cli_t *cli)
+{
+    char* sleep_command =
+	"<CMD name='sleep' id='700' desc='Suspend keyboard input'>"
+	"  <ARG name='msec' type='int' desc='Millisecond'/>"
+	"</CMD>";
+
+    char* network_command =
+	"<CMD name='network' id='900' desc='Detect network type'/>";
+
+    char* shutdown_command =
+	"<CMD name='shutdown' id='110' desc='Shutdown application'/>";
+
+    char* restart_command =
+	"<CMD name='restart' id='120' desc='Restart application'>"
+	"  <ARG name='options1' type='string' desc='Options' optional='1'/>"
+	"  <ARG name='options2' type='string' desc='Options' optional='1'/>"
+	"  <ARG name='options3' type='string' desc='Options' optional='1'/>"
+	"  <ARG name='options4' type='string' desc='Options' optional='1'/>"
+	"</CMD>";
+
+    pj_status_t status;
+    pj_str_t sleep_xml = pj_str(sleep_command);    
+    pj_str_t network_xml = pj_str(network_command);
+    pj_str_t shutdown_xml = pj_str(shutdown_command);
+    pj_str_t restart_xml = pj_str(restart_command);
+
+    status = pj_cli_add_cmd_from_xml(cli, NULL, 
+				     &sleep_xml, cmd_sleep_handler, 
+				     NULL, NULL);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = pj_cli_add_cmd_from_xml(cli, NULL, 
+				     &network_xml, cmd_network_handler, 
+				     NULL, NULL);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = pj_cli_add_cmd_from_xml(cli, NULL, 
+				     &shutdown_xml, cmd_quit_handler, 
+				     NULL, NULL);
+
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = pj_cli_add_cmd_from_xml(cli, NULL, 
+				     &restart_xml, cmd_restart_handler, 
+				     NULL, NULL);
+
+    return status;
+}
+
+pj_status_t cli_setup_command(pj_cli_t *cli)
+{
+    pj_status_t status;
+
+    status = add_call_command(cli);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = add_presence_command(cli);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = add_account_command(cli);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = add_media_command(cli);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = add_config_command(cli);
+    if (status != PJ_SUCCESS)
+	return status;
+
+#if PJSUA_HAS_VIDEO    
+    status = add_video_command(cli);
+    if (status != PJ_SUCCESS)
+	return status;
+#endif
+
+    status = add_other_command(cli);
+
+    return status;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_common.c b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_common.c
new file mode 100644
index 0000000..e95d765
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_common.c
@@ -0,0 +1,355 @@
+/* $Id: pjsua_app_common.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 "pjsua_app_common.h"
+
+#define THIS_FILE	"pjsua_app_common.c"
+
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+#   define SOME_BUF_SIZE	(1024 * 10)
+#else
+#   define SOME_BUF_SIZE	(1024 * 3)
+#endif
+
+static char some_buf[SOME_BUF_SIZE];
+
+/** Variable definition **/
+int		    stdout_refresh = -1;
+pj_bool_t	    stdout_refresh_quit = PJ_FALSE;
+pjsua_call_id	    current_call = PJSUA_INVALID_ID;
+pjsua_app_config    app_config;
+pjsua_call_setting  call_opt;
+pjsua_msg_data	    msg_data;
+
+int my_atoi(const char *cs)
+{
+    pj_str_t s;
+
+    pj_cstr(&s, cs);
+    if (cs[0] == '-') {
+	s.ptr++, s.slen--;
+	return 0 - (int)pj_strtoul(&s);
+    } else if (cs[0] == '+') {
+	s.ptr++, s.slen--;
+	return pj_strtoul(&s);
+    } else {
+	return pj_strtoul(&s);
+    }
+}
+
+/*
+ * Find next call when current call is disconnected or when user
+ * press ']'
+ */
+pj_bool_t find_next_call()
+{
+    int i, max;
+
+    max = pjsua_call_get_max_count();
+    for (i=current_call+1; i<max; ++i) {
+	if (pjsua_call_is_active(i)) {
+	    current_call = i;
+	    return PJ_TRUE;
+	}
+    }
+
+    for (i=0; i<current_call; ++i) {
+	if (pjsua_call_is_active(i)) {
+	    current_call = i;
+	    return PJ_TRUE;
+	}
+    }
+
+    current_call = PJSUA_INVALID_ID;
+    return PJ_FALSE;
+}
+
+pj_bool_t find_prev_call()
+{
+    int i, max;
+
+    max = pjsua_call_get_max_count();
+    for (i=current_call-1; i>=0; --i) {
+	if (pjsua_call_is_active(i)) {
+	    current_call = i;
+	    return PJ_TRUE;
+	}
+    }
+
+    for (i=max-1; i>current_call; --i) {
+	if (pjsua_call_is_active(i)) {
+	    current_call = i;
+	    return PJ_TRUE;
+	}
+    }
+
+    current_call = PJSUA_INVALID_ID;
+    return PJ_FALSE;
+}
+
+/*
+ * Send arbitrary request to remote host
+ */
+void send_request(char *cstr_method, const pj_str_t *dst_uri)
+{
+    pj_str_t str_method;
+    pjsip_method method;
+    pjsip_tx_data *tdata;
+    pjsip_endpoint *endpt;
+    pj_status_t status;
+
+    endpt = pjsua_get_pjsip_endpt();
+
+    str_method = pj_str(cstr_method);
+    pjsip_method_init_np(&method, &str_method);
+
+    status = pjsua_acc_create_request(current_acc, &method, dst_uri, &tdata);
+
+    status = pjsip_endpt_send_request(endpt, tdata, -1, NULL, NULL);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Unable to send request", status);
+	return;
+    }
+}
+
+/*
+ * Print log of call states. Since call states may be too long for logger,
+ * printing it is a bit tricky, it should be printed part by part as long 
+ * as the logger can accept.
+ */
+void log_call_dump(int call_id) 
+{
+    unsigned call_dump_len;
+    unsigned part_len;
+    unsigned part_idx;
+    unsigned log_decor;
+
+    pjsua_call_dump(call_id, PJ_TRUE, some_buf, sizeof(some_buf), "  ");
+    call_dump_len = (unsigned)strlen(some_buf);
+
+    log_decor = pj_log_get_decor();
+    pj_log_set_decor(log_decor & ~(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_CR));
+    PJ_LOG(3,(THIS_FILE, "\n"));
+    pj_log_set_decor(0);
+
+    part_idx = 0;
+    part_len = PJ_LOG_MAX_SIZE-80;
+    while (part_idx < call_dump_len) {
+	char p_orig, *p;
+
+	p = &some_buf[part_idx];
+	if (part_idx + part_len > call_dump_len)
+	    part_len = call_dump_len - part_idx;
+	p_orig = p[part_len];
+	p[part_len] = '\0';
+	PJ_LOG(3,(THIS_FILE, "%s", p));
+	p[part_len] = p_orig;
+	part_idx += part_len;
+    }
+    pj_log_set_decor(log_decor);
+}
+
+#ifdef PJSUA_HAS_VIDEO
+void app_config_init_video(pjsua_acc_config *acc_cfg)
+{
+    acc_cfg->vid_in_auto_show = app_config.vid.in_auto_show;
+    acc_cfg->vid_out_auto_transmit = app_config.vid.out_auto_transmit;
+    /* Note that normally GUI application will prefer a borderless
+     * window.
+     */
+    acc_cfg->vid_wnd_flags = PJMEDIA_VID_DEV_WND_BORDER |
+                             PJMEDIA_VID_DEV_WND_RESIZABLE;
+    acc_cfg->vid_cap_dev = app_config.vid.vcapture_dev;
+    acc_cfg->vid_rend_dev = app_config.vid.vrender_dev;
+
+    if (app_config.avi_auto_play &&
+	app_config.avi_def_idx != PJSUA_INVALID_ID &&
+	app_config.avi[app_config.avi_def_idx].dev_id != PJMEDIA_VID_INVALID_DEV)
+    {
+	acc_cfg->vid_cap_dev = app_config.avi[app_config.avi_def_idx].dev_id;
+    }
+}
+#else
+void app_config_init_video(pjsua_acc_config *acc_cfg)
+{
+    PJ_UNUSED_ARG(acc_cfg);
+}
+#endif
+
+#ifdef HAVE_MULTIPART_TEST
+  /*
+   * Enable multipart in msg_data and add a dummy body into the
+   * multipart bodies.
+   */
+  void add_multipart(pjsua_msg_data *msg_data)
+  {
+      static pjsip_multipart_part *alt_part;
+
+      if (!alt_part) {
+	  pj_str_t type, subtype, content;
+
+	  alt_part = pjsip_multipart_create_part(app_config.pool);
+
+	  type = pj_str("text");
+	  subtype = pj_str("plain");
+	  content = pj_str("Sample text body of a multipart bodies");
+	  alt_part->body = pjsip_msg_body_create(app_config.pool, &type,
+						 &subtype, &content);
+      }
+
+      msg_data->multipart_ctype.type = pj_str("multipart");
+      msg_data->multipart_ctype.subtype = pj_str("mixed");
+      pj_list_push_back(&msg_data->multipart_parts, alt_part);
+  }
+#endif
+
+/* arrange windows. arg:
+ *   -1:    arrange all windows
+ *   != -1: arrange only this window id
+ */
+void arrange_window(pjsua_vid_win_id wid)
+{
+#if PJSUA_HAS_VIDEO
+    pjmedia_coord pos;
+    int i, last;
+
+    pos.x = 0;
+    pos.y = 10;
+    last = (wid == PJSUA_INVALID_ID) ? PJSUA_MAX_VID_WINS : wid;
+
+    for (i=0; i<last; ++i) {
+	pjsua_vid_win_info wi;
+	pj_status_t status;
+
+	status = pjsua_vid_win_get_info(i, &wi);
+	if (status != PJ_SUCCESS)
+	    continue;
+
+	if (wid == PJSUA_INVALID_ID)
+	    pjsua_vid_win_set_pos(i, &pos);
+
+	if (wi.show)
+	    pos.y += wi.size.h;
+    }
+
+    if (wid != PJSUA_INVALID_ID)
+	pjsua_vid_win_set_pos(wid, &pos);
+#else
+    PJ_UNUSED_ARG(wid);
+#endif
+}
+
+
+#if PJSUA_HAS_VIDEO
+void vid_print_dev(int id, const pjmedia_vid_dev_info *vdi, const char *title)
+{
+    char capnames[120];
+    char formats[120];
+    const char *dirname;
+    unsigned i;
+
+    if (vdi->dir == PJMEDIA_DIR_CAPTURE_RENDER) {
+	dirname = "capture, render";
+    } else if (vdi->dir == PJMEDIA_DIR_CAPTURE) {
+	dirname = "capture";
+    } else {
+	dirname = "render";
+    }
+
+
+    capnames[0] = '\0';
+    for (i=0; i<sizeof(int)*8 && (1 << i) < PJMEDIA_VID_DEV_CAP_MAX; ++i) {
+	if (vdi->caps & (1 << i)) {
+	    const char *capname = pjmedia_vid_dev_cap_name(1 << i, NULL);
+	    if (capname) {
+		if (*capnames)
+		    strcat(capnames, ", ");
+		strncat(capnames, capname,
+		        sizeof(capnames)-strlen(capnames)-1);
+	    }
+	}
+    }
+
+    formats[0] = '\0';
+    for (i=0; i<vdi->fmt_cnt; ++i) {
+	const pjmedia_video_format_info *vfi =
+		pjmedia_get_video_format_info(NULL, vdi->fmt[i].id);
+	if (vfi) {
+	    if (*formats)
+		strcat(formats, ", ");
+	    strncat(formats, vfi->name, sizeof(formats)-strlen(formats)-1);
+	}
+    }
+
+    PJ_LOG(3,(THIS_FILE, "%3d %s [%s][%s] %s", id, vdi->name, vdi->driver,
+	      dirname, title));
+    PJ_LOG(3,(THIS_FILE, "    Supported capabilities: %s", capnames));
+    PJ_LOG(3,(THIS_FILE, "    Supported formats: %s", formats));
+}
+
+void vid_list_devs()
+{
+    unsigned i, count;
+    pjmedia_vid_dev_info vdi;
+    pj_status_t status;
+
+    PJ_LOG(3,(THIS_FILE, "Video device list:"));
+    count = pjsua_vid_dev_count();
+    if (count == 0) {
+	PJ_LOG(3,(THIS_FILE, " - no device detected -"));
+	return;
+    } else {
+	PJ_LOG(3,(THIS_FILE, "%d device(s) detected:", count));
+    }
+
+    status = pjsua_vid_dev_get_info(PJMEDIA_VID_DEFAULT_RENDER_DEV, &vdi);
+    if (status == PJ_SUCCESS)
+	vid_print_dev(PJMEDIA_VID_DEFAULT_RENDER_DEV, &vdi,
+	              "(default renderer device)");
+
+    status = pjsua_vid_dev_get_info(PJMEDIA_VID_DEFAULT_CAPTURE_DEV, &vdi);
+    if (status == PJ_SUCCESS)
+	vid_print_dev(PJMEDIA_VID_DEFAULT_CAPTURE_DEV, &vdi,
+	              "(default capture device)");
+
+    for (i=0; i<count; ++i) {
+	status = pjsua_vid_dev_get_info(i, &vdi);
+	if (status == PJ_SUCCESS)
+	    vid_print_dev(i, &vdi, "");
+    }
+}
+
+void app_config_show_video(int acc_id, const pjsua_acc_config *acc_cfg)
+{
+    PJ_LOG(3,(THIS_FILE,
+	      "Account %d:\n"
+	      "  RX auto show:     %d\n"
+	      "  TX auto transmit: %d\n"
+	      "  Capture dev:      %d\n"
+	      "  Render dev:       %d",
+	      acc_id,
+	      acc_cfg->vid_in_auto_show,
+	      acc_cfg->vid_out_auto_transmit,
+	      acc_cfg->vid_cap_dev,
+	      acc_cfg->vid_rend_dev));
+}
+
+
+#endif
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_common.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_common.h
new file mode 100644
index 0000000..996ed06
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_common.h
@@ -0,0 +1,226 @@
+/* $Id: pjsua_app_common.h 4489 2013-04-23 07:53:25Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 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 __PJSUA_APP_COMMON_H__
+#define __PJSUA_APP_COMMON_H__
+
+#include <pjsua-lib/pjsua.h>
+
+PJ_BEGIN_DECL
+
+#define current_acc	pjsua_acc_get_default()
+
+#define PJSUA_APP_NO_LIMIT_DURATION	(int)0x7FFFFFFF
+#define PJSUA_APP_MAX_AVI		4
+#define PJSUA_APP_NO_NB			-2
+
+typedef struct input_result
+{
+    int	  nb_result;
+    char *uri_result;
+} input_result;
+
+/* Call specific data */
+typedef struct app_call_data
+{
+    pj_timer_entry	    timer;
+    pj_bool_t		    ringback_on;
+    pj_bool_t		    ring_on;
+} app_call_data;
+
+/* Video settings */
+typedef struct app_vid
+{
+    unsigned		    vid_cnt;
+    int			    vcapture_dev;
+    int			    vrender_dev;
+    pj_bool_t		    in_auto_show;
+    pj_bool_t		    out_auto_transmit;
+} app_vid;
+
+/* Enumeration of CLI frontends */
+typedef enum {
+    CLI_FE_CONSOLE	    = 1,
+    CLI_FE_TELNET	    = 2
+} CLI_FE;
+
+/** CLI config **/
+typedef struct cli_cfg_t
+{
+    /** Bitmask of CLI_FE **/
+    int			    cli_fe;
+    pj_cli_cfg		    cfg;
+    pj_cli_telnet_cfg	    telnet_cfg;
+    pj_cli_console_cfg	    console_cfg;
+} cli_cfg_t;
+
+/* Pjsua application data */
+typedef struct pjsua_app_config
+{
+    pjsua_config	    cfg;
+    pjsua_logging_config    log_cfg;
+    pjsua_media_config	    media_cfg;
+    pj_bool_t		    no_refersub;
+    pj_bool_t		    ipv6;
+    pj_bool_t		    enable_qos;
+    pj_bool_t		    no_tcp;
+    pj_bool_t		    no_udp;
+    pj_bool_t		    use_tls;
+    pjsua_transport_config  udp_cfg;
+    pjsua_transport_config  rtp_cfg;
+    pjsip_redirect_op	    redir_op;
+
+    unsigned		    acc_cnt;
+    pjsua_acc_config	    acc_cfg[PJSUA_MAX_ACC];
+
+    unsigned		    buddy_cnt;
+    pjsua_buddy_config	    buddy_cfg[PJSUA_MAX_BUDDIES];
+
+    app_call_data	    call_data[PJSUA_MAX_CALLS];
+
+    pj_pool_t		   *pool;
+    /* Compatibility with older pjsua */
+
+    unsigned		    codec_cnt;
+    pj_str_t		    codec_arg[32];
+    unsigned		    codec_dis_cnt;
+    pj_str_t                codec_dis[32];
+    pj_bool_t		    null_audio;
+    unsigned		    wav_count;
+    pj_str_t		    wav_files[32];
+    unsigned		    tone_count;
+    pjmedia_tone_desc	    tones[32];
+    pjsua_conf_port_id	    tone_slots[32];
+    pjsua_player_id	    wav_id;
+    pjsua_conf_port_id	    wav_port;
+    pj_bool_t		    auto_play;
+    pj_bool_t		    auto_play_hangup;
+    pj_timer_entry	    auto_hangup_timer;
+    pj_bool_t		    auto_loop;
+    pj_bool_t		    auto_conf;
+    pj_str_t		    rec_file;
+    pj_bool_t		    auto_rec;
+    pjsua_recorder_id	    rec_id;
+    pjsua_conf_port_id	    rec_port;
+    unsigned		    auto_answer;
+    unsigned		    duration;
+
+#ifdef STEREO_DEMO
+    pjmedia_snd_port	   *snd;
+    pjmedia_port	   *sc, *sc_ch1;
+    pjsua_conf_port_id	    sc_ch1_slot;
+#endif
+
+    float		    mic_level,
+			    speaker_level;
+
+    int			    capture_dev, playback_dev;
+    unsigned		    capture_lat, playback_lat;
+
+    pj_bool_t		    no_tones;
+    int			    ringback_slot;
+    int			    ringback_cnt;
+    pjmedia_port	   *ringback_port;
+    int			    ring_slot;
+    int			    ring_cnt;
+    pjmedia_port	   *ring_port;
+
+    app_vid		    vid;
+    unsigned		    aud_cnt;
+
+    /* AVI to play */
+    unsigned                avi_cnt;
+    struct {
+	pj_str_t		path;
+	pjmedia_vid_dev_index	dev_id;
+	pjsua_conf_port_id	slot;
+    } avi[PJSUA_APP_MAX_AVI];
+    pj_bool_t               avi_auto_play;
+    int			    avi_def_idx;
+
+    /* CLI setting */
+    pj_bool_t		    use_cli;
+    cli_cfg_t		    cli_cfg;
+} pjsua_app_config;
+
+/** Extern variable declaration **/
+extern pjsua_call_id	    current_call;
+extern pjsua_app_config	    app_config;
+extern int		    stdout_refresh;
+extern pj_bool_t	    stdout_refresh_quit;
+extern pjsua_call_setting   call_opt;
+extern pjsua_msg_data	    msg_data;
+extern pj_bool_t	    app_running;
+
+int my_atoi(const char *cs);
+pj_bool_t find_next_call();
+pj_bool_t find_prev_call();
+void send_request(char *cstr_method, const pj_str_t *dst_uri);
+void log_call_dump(int call_id);
+int write_settings(pjsua_app_config *cfg, char *buf, pj_size_t max);
+void app_config_init_video(pjsua_acc_config *acc_cfg);
+void arrange_window(pjsua_vid_win_id wid);
+
+/** Defined in pjsua_cli_cmd.c **/
+pj_bool_t is_cli_inited();
+
+/** Defined in pjsua_config.c **/
+/** This is to load the configuration **/
+pj_status_t load_config(int argc, char **argv, pj_str_t *uri_arg);
+
+/** Pjsua app callback **/
+/** This callback is called when CLI is started. **/
+void cli_on_started(pj_status_t status);
+
+/** This callback is called when "shutdown"/"restart" command is invoked **/
+void cli_on_stopped(pj_bool_t restart, int argc, char **argv);
+
+/** This callback is called when "quit"/"restart" command is invoked **/
+void legacy_on_stopped(pj_bool_t restart);
+
+/** Pjsua cli method **/
+pj_status_t cli_init();
+pj_status_t cli_main(pj_bool_t wait_telnet_cli);
+void cli_destroy();
+void cli_get_info(char *info, pj_size_t size); 
+
+/** Legacy method **/
+void legacy_main();
+
+#if PJSUA_HAS_VIDEO
+void vid_print_dev(int id, const pjmedia_vid_dev_info *vdi, const char *title);
+void vid_list_devs();
+void app_config_show_video(int acc_id, const pjsua_acc_config *acc_cfg);
+#endif
+
+#ifdef HAVE_MULTIPART_TEST
+    /*
+    * Enable multipart in msg_data and add a dummy body into the
+    * multipart bodies.
+    */
+    void add_multipart(pjsua_msg_data *msg_data);
+#  define TEST_MULTIPART(msg_data)	add_multipart(msg_data)
+#else
+#  define TEST_MULTIPART(msg_data)
+#endif
+
+
+PJ_END_DECL
+    
+#endif	/* __PJSUA_APP_COMMON_H__ */
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_config.c b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_config.c
new file mode 100644
index 0000000..ce06d49
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_config.c
@@ -0,0 +1,2180 @@
+/* $Id: pjsua_app_config.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 "pjsua_app_common.h"
+
+#define THIS_FILE	"pjsua_app_config.c"
+
+#define MAX_APP_OPTIONS 128
+
+char   *stdout_refresh_text = "STDOUT_REFRESH";
+
+/* Show usage */
+static void usage(void)
+{
+    puts  ("Usage:");
+    puts  ("  pjsua [options] [SIP URL to call]");
+    puts  ("");
+    puts  ("General options:");
+    puts  ("  --config-file=file  Read the config/arguments from file.");
+    puts  ("  --help              Display this help screen");
+    puts  ("  --version           Display version info");
+    puts  ("");
+    puts  ("Logging options:");
+    puts  ("  --log-file=fname    Log to filename (default stderr)");
+    puts  ("  --log-level=N       Set log max level to N (0(none) to 6(trace)) (default=5)");
+    puts  ("  --app-log-level=N   Set log max level for stdout display (default=4)");
+    puts  ("  --log-append        Append instead of overwrite existing log file.\n");
+    puts  ("  --color             Use colorful logging (default yes on Win32)");
+    puts  ("  --no-color          Disable colorful logging");
+    puts  ("  --light-bg          Use dark colors for light background (default is dark bg)");
+    puts  ("  --no-stderr         Disable stderr");
+
+    puts  ("");
+    puts  ("SIP Account options:");
+    puts  ("  --registrar=url     Set the URL of registrar server");
+    puts  ("  --id=url            Set the URL of local ID (used in From header)");
+    puts  ("  --realm=string      Set realm");
+    puts  ("  --username=string   Set authentication username");
+    puts  ("  --password=string   Set authentication password");
+    puts  ("  --contact=url       Optionally override the Contact information");
+    puts  ("  --contact-params=S  Append the specified parameters S in Contact header");
+    puts  ("  --contact-uri-params=S  Append the specified parameters S in Contact URI");
+    puts  ("  --proxy=url         Optional URL of proxy server to visit");
+    puts  ("                      May be specified multiple times");
+    printf("  --reg-timeout=SEC   Optional registration interval (default %d)\n",
+	    PJSUA_REG_INTERVAL);
+    printf("  --rereg-delay=SEC   Optional auto retry registration interval (default %d)\n",
+	    PJSUA_REG_RETRY_INTERVAL);
+    puts  ("  --reg-use-proxy=N   Control the use of proxy settings in REGISTER.");
+    puts  ("                      0=no proxy, 1=outbound only, 2=acc only, 3=all (default)");
+    puts  ("  --publish           Send presence PUBLISH for this account");
+    puts  ("  --mwi               Subscribe to message summary/waiting indication");
+    puts  ("  --use-ims           Enable 3GPP/IMS related settings on this account");
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    puts  ("  --use-srtp=N        Use SRTP?  0:disabled, 1:optional, 2:mandatory,");
+    puts  ("                      3:optional by duplicating media offer (def:0)");
+    puts  ("  --srtp-secure=N     SRTP require secure SIP? 0:no, 1:tls, 2:sips (def:1)");
+#endif
+    puts  ("  --use-100rel        Require reliable provisional response (100rel)");
+    puts  ("  --use-timer=N       Use SIP session timers? (default=1)");
+    puts  ("                      0:inactive, 1:optional, 2:mandatory, 3:always");
+    printf("  --timer-se=N        Session timers expiration period, in secs (def:%d)\n",
+	    PJSIP_SESS_TIMER_DEF_SE);
+    puts  ("  --timer-min-se=N    Session timers minimum expiration period, in secs (def:90)");
+    puts  ("  --outb-rid=string   Set SIP outbound reg-id (default:1)");
+    puts  ("  --auto-update-nat=N Where N is 0 or 1 to enable/disable SIP traversal behind");
+    puts  ("                      symmetric NAT (default 1)");
+    puts  ("  --disable-stun      Disable STUN for this account");
+    puts  ("  --next-cred         Add another credentials");
+    puts  ("");
+    puts  ("SIP Account Control:");
+    puts  ("  --next-account      Add more account");
+    puts  ("");
+    puts  ("Transport Options:");
+#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
+    puts  ("  --ipv6              Use IPv6 instead for SIP and media.");
+#endif
+    puts  ("  --set-qos           Enable QoS tagging for SIP and media.");
+    puts  ("  --local-port=port   Set TCP/UDP port. This implicitly enables both ");
+    puts  ("                      TCP and UDP transports on the specified port, unless");
+    puts  ("                      if TCP or UDP is disabled.");
+    puts  ("  --ip-addr=IP        Use the specifed address as SIP and RTP addresses.");
+    puts  ("                      (Hint: the IP may be the public IP of the NAT/router)");
+    puts  ("  --bound-addr=IP     Bind transports to this IP interface");
+    puts  ("  --no-tcp            Disable TCP transport.");
+    puts  ("  --no-udp            Disable UDP transport.");
+    puts  ("  --nameserver=NS     Add the specified nameserver to enable SRV resolution");
+    puts  ("                      This option can be specified multiple times.");
+    puts  ("  --outbound=url      Set the URL of global outbound proxy server");
+    puts  ("                      May be specified multiple times");
+    puts  ("  --stun-srv=FORMAT   Set STUN server host or domain. This option may be");
+    puts  ("                      specified more than once. FORMAT is hostdom[:PORT]");
+
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
+    puts  ("");
+    puts  ("TLS Options:");
+    puts  ("  --use-tls           Enable TLS transport (default=no)");
+    puts  ("  --tls-ca-file       Specify TLS CA file (default=none)");
+    puts  ("  --tls-cert-file     Specify TLS certificate file (default=none)");
+    puts  ("  --tls-privkey-file  Specify TLS private key file (default=none)");
+    puts  ("  --tls-password      Specify TLS password to private key file (default=none)");
+    puts  ("  --tls-verify-server Verify server's certificate (default=no)");
+    puts  ("  --tls-verify-client Verify client's certificate (default=no)");
+    puts  ("  --tls-neg-timeout   Specify TLS negotiation timeout (default=no)");
+    puts  ("  --tls-srv-name      Specify TLS server name for multihosting server");
+    puts  ("  --tls-cipher        Specify prefered TLS cipher (optional).");
+    puts  ("                      May be specified multiple times");
+#endif
+
+    puts  ("");
+    puts  ("Audio Options:");
+    puts  ("  --add-codec=name    Manually add codec (default is to enable all)");
+    puts  ("  --dis-codec=name    Disable codec (can be specified multiple times)");
+    puts  ("  --clock-rate=N      Override conference bridge clock rate");
+    puts  ("  --snd-clock-rate=N  Override sound device clock rate");
+    puts  ("  --stereo            Audio device and conference bridge opened in stereo mode");
+    puts  ("  --null-audio        Use NULL audio device");
+    puts  ("  --play-file=file    Register WAV file in conference bridge.");
+    puts  ("                      This can be specified multiple times.");
+    puts  ("  --play-tone=FORMAT  Register tone to the conference bridge.");
+    puts  ("                      FORMAT is 'F1,F2,ON,OFF', where F1,F2 are");
+    puts  ("                      frequencies, and ON,OFF=on/off duration in msec.");
+    puts  ("                      This can be specified multiple times.");
+    puts  ("  --auto-play         Automatically play the file (to incoming calls only)");
+    puts  ("  --auto-loop         Automatically loop incoming RTP to outgoing RTP");
+    puts  ("  --auto-conf         Automatically put calls in conference with others");
+    puts  ("  --rec-file=file     Open file recorder (extension can be .wav or .mp3");
+    puts  ("  --auto-rec          Automatically record conversation");
+    puts  ("  --quality=N         Specify media quality (0-10, default=6)");
+    puts  ("  --ptime=MSEC        Override codec ptime to MSEC (default=specific)");
+    puts  ("  --no-vad            Disable VAD/silence detector (default=vad enabled)");
+    puts  ("  --ec-tail=MSEC      Set echo canceller tail length (default=256)");
+    puts  ("  --ec-opt=OPT        Select echo canceller algorithm (0=default, ");
+    puts  ("                        1=speex, 2=suppressor)");
+    puts  ("  --ilbc-mode=MODE    Set iLBC codec mode (20 or 30, default is 30)");
+    puts  ("  --capture-dev=id    Audio capture device ID (default=-1)");
+    puts  ("  --playback-dev=id   Audio playback device ID (default=-1)");
+    puts  ("  --capture-lat=N     Audio capture latency, in ms (default=100)");
+    puts  ("  --playback-lat=N    Audio playback latency, in ms (default=100)");
+    puts  ("  --snd-auto-close=N  Auto close audio device when idle for N secs (default=1)");
+    puts  ("                      Specify N=-1 to disable this feature.");
+    puts  ("                      Specify N=0 for instant close when unused.");
+    puts  ("  --no-tones          Disable audible tones");
+    puts  ("  --jb-max-size       Specify jitter buffer maximum size, in frames (default=-1)");
+    puts  ("  --extra-audio       Add one more audio stream");
+
+#if PJSUA_HAS_VIDEO
+    puts  ("");
+    puts  ("Video Options:");
+    puts  ("  --video             Enable video");
+    puts  ("  --vcapture-dev=id   Video capture device ID (default=-1)");
+    puts  ("  --vrender-dev=id    Video render device ID (default=-2)");
+    puts  ("  --play-avi=FILE     Load this AVI as virtual capture device");
+    puts  ("  --auto-play-avi     Automatically play the AVI media to call");
+#endif
+
+    puts  ("");
+    puts  ("Media Transport Options:");
+    puts  ("  --use-ice           Enable ICE (default:no)");
+    puts  ("  --ice-regular       Use ICE regular nomination (default: aggressive)");
+    puts  ("  --ice-max-hosts=N   Set maximum number of ICE host candidates");
+    puts  ("  --ice-no-rtcp       Disable RTCP component in ICE (default: no)");
+    puts  ("  --rtp-port=N        Base port to try for RTP (default=4000)");
+    puts  ("  --rx-drop-pct=PCT   Drop PCT percent of RX RTP (for pkt lost sim, default: 0)");
+    puts  ("  --tx-drop-pct=PCT   Drop PCT percent of TX RTP (for pkt lost sim, default: 0)");
+    puts  ("  --use-turn          Enable TURN relay with ICE (default:no)");
+    puts  ("  --turn-srv          Domain or host name of TURN server (\"NAME:PORT\" format)");
+    puts  ("  --turn-tcp          Use TCP connection to TURN server (default no)");
+    puts  ("  --turn-user         TURN username");
+    puts  ("  --turn-passwd       TURN password");
+
+    puts  ("");
+    puts  ("Buddy List (can be more than one):");
+    puts  ("  --add-buddy url     Add the specified URL to the buddy list.");
+    puts  ("");
+    puts  ("User Agent options:");
+    puts  ("  --auto-answer=code  Automatically answer incoming calls with code (e.g. 200)");
+    puts  ("  --max-calls=N       Maximum number of concurrent calls (default:4, max:255)");
+    puts  ("  --thread-cnt=N      Number of worker threads (default:1)");
+    puts  ("  --duration=SEC      Set maximum call duration (default:no limit)");
+    puts  ("  --norefersub        Suppress event subscription when transfering calls");
+    puts  ("  --use-compact-form  Minimize SIP message size");
+    puts  ("  --no-force-lr       Allow strict-route to be used (i.e. do not force lr)");
+    puts  ("  --accept-redirect=N Specify how to handle call redirect (3xx) response.");
+    puts  ("                      0: reject, 1: follow automatically,");
+    puts  ("                      2: follow + replace To header (default), 3: ask");
+
+    puts  ("");
+    puts  ("CLI options:");
+    puts  ("  --use-cli           Use CLI as user interface");
+    puts  ("  --cli-telnet-port=N CLI telnet port");
+    puts  ("  --no-cli-console    Disable CLI console");
+    puts  ("");
+
+    puts  ("");
+    puts  ("When URL is specified, pjsua will immediately initiate call to that URL");
+    puts  ("");
+
+    fflush(stdout);
+}
+
+/*
+ * Read command arguments from config file.
+ */
+static int read_config_file(pj_pool_t *pool, const char *filename, 
+			    int *app_argc, char ***app_argv)
+{
+    int i;
+    FILE *fhnd;
+    char line[200];
+    int argc = 0;
+    char **argv;
+    enum { MAX_ARGS = 128 };
+
+    /* Allocate MAX_ARGS+1 (argv needs to be terminated with NULL argument) */
+    argv = pj_pool_calloc(pool, MAX_ARGS+1, sizeof(char*));
+    argv[argc++] = *app_argv[0];
+
+    /* Open config file. */
+    fhnd = fopen(filename, "rt");
+    if (!fhnd) {
+	PJ_LOG(1,(THIS_FILE, "Unable to open config file %s", filename));
+	fflush(stdout);
+	return -1;
+    }
+
+    /* Scan tokens in the file. */
+    while (argc < MAX_ARGS && !feof(fhnd)) {
+	char  *token;
+	char  *p;
+	const char *whitespace = " \t\r\n";
+	char  cDelimiter;
+	pj_size_t   len;
+	int token_len;
+	
+	pj_bzero(line, sizeof(line));
+	if (fgets(line, sizeof(line), fhnd) == NULL) break;
+	
+	// Trim ending newlines
+	len = strlen(line);
+	if (line[len-1]=='\n')
+	    line[--len] = '\0';
+	if (line[len-1]=='\r')
+	    line[--len] = '\0';
+
+	if (len==0) continue;
+
+	for (p = line; *p != '\0' && argc < MAX_ARGS; p++) {
+	    // first, scan whitespaces
+	    while (*p != '\0' && strchr(whitespace, *p) != NULL) p++;
+
+	    if (*p == '\0')		    // are we done yet?
+		break;
+	    
+	    if (*p == '"' || *p == '\'') {    // is token a quoted string
+		cDelimiter = *p++;	    // save quote delimiter
+		token = p;
+		
+		while (*p != '\0' && *p != cDelimiter) p++;
+		
+		if (*p == '\0')		// found end of the line, but,
+		    cDelimiter = '\0';	// didn't find a matching quote
+
+	    } else {			// token's not a quoted string
+		token = p;
+		
+		while (*p != '\0' && strchr(whitespace, *p) == NULL) p++;
+		
+		cDelimiter = *p;
+	    }
+	    
+	    *p = '\0';
+	    token_len = (int)(p-token);
+	    
+	    if (token_len > 0) {
+		if (*token == '#')
+		    break;  // ignore remainder of line
+		
+		argv[argc] = pj_pool_alloc(pool, token_len + 1);
+		pj_memcpy(argv[argc], token, token_len + 1);
+		++argc;
+	    }
+	    
+	    *p = cDelimiter;
+	}
+    }
+
+    /* Copy arguments from command line */
+    for (i=1; i<*app_argc && argc < MAX_ARGS; ++i)
+	argv[argc++] = (*app_argv)[i];
+
+    if (argc == MAX_ARGS && (i!=*app_argc || !feof(fhnd))) {
+	PJ_LOG(1,(THIS_FILE, 
+		  "Too many arguments specified in cmd line/config file"));
+	fflush(stdout);
+	fclose(fhnd);
+	return -1;
+    }
+
+    fclose(fhnd);
+
+    /* Assign the new command line back to the original command line. */
+    *app_argc = argc;
+    *app_argv = argv;
+    return 0;
+}
+
+/* Parse arguments. */
+static pj_status_t parse_args(int argc, char *argv[], 			      
+			      pj_str_t *uri_to_call)
+{
+    int c;
+    int option_index;
+    pjsua_app_config *cfg = &app_config;
+    enum { OPT_CONFIG_FILE=127, OPT_LOG_FILE, OPT_LOG_LEVEL, OPT_APP_LOG_LEVEL, 
+	   OPT_LOG_APPEND, OPT_COLOR, OPT_NO_COLOR, OPT_LIGHT_BG, OPT_NO_STDERR,
+	   OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO, OPT_SND_AUTO_CLOSE,
+	   OPT_LOCAL_PORT, OPT_IP_ADDR, OPT_PROXY, OPT_OUTBOUND_PROXY, 
+	   OPT_REGISTRAR, OPT_REG_TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT,
+	   OPT_BOUND_ADDR, OPT_CONTACT_PARAMS, OPT_CONTACT_URI_PARAMS,
+	   OPT_100REL, OPT_USE_IMS, OPT_REALM, OPT_USERNAME, OPT_PASSWORD,
+	   OPT_REG_RETRY_INTERVAL, OPT_REG_USE_PROXY,
+	   OPT_MWI, OPT_NAMESERVER, OPT_STUN_SRV, OPT_OUTB_RID,
+	   OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE,
+	   OPT_AUTO_ANSWER, OPT_AUTO_PLAY, OPT_AUTO_PLAY_HANGUP, OPT_AUTO_LOOP,
+	   OPT_AUTO_CONF, OPT_CLOCK_RATE, OPT_SND_CLOCK_RATE, OPT_STEREO,
+	   OPT_USE_ICE, OPT_ICE_REGULAR, OPT_USE_SRTP, OPT_SRTP_SECURE,
+	   OPT_USE_TURN, OPT_ICE_MAX_HOSTS, OPT_ICE_NO_RTCP, OPT_TURN_SRV, 
+	   OPT_TURN_TCP, OPT_TURN_USER, OPT_TURN_PASSWD,
+	   OPT_PLAY_FILE, OPT_PLAY_TONE, OPT_RTP_PORT, OPT_ADD_CODEC, 
+	   OPT_ILBC_MODE, OPT_REC_FILE, OPT_AUTO_REC,
+	   OPT_COMPLEXITY, OPT_QUALITY, OPT_PTIME, OPT_NO_VAD,
+	   OPT_RX_DROP_PCT, OPT_TX_DROP_PCT, OPT_EC_TAIL, OPT_EC_OPT,
+	   OPT_NEXT_ACCOUNT, OPT_NEXT_CRED, OPT_MAX_CALLS, 
+	   OPT_DURATION, OPT_NO_TCP, OPT_NO_UDP, OPT_THREAD_CNT,
+	   OPT_NOREFERSUB, OPT_ACCEPT_REDIRECT,
+	   OPT_USE_TLS, OPT_TLS_CA_FILE, OPT_TLS_CERT_FILE, OPT_TLS_PRIV_FILE,
+	   OPT_TLS_PASSWORD, OPT_TLS_VERIFY_SERVER, OPT_TLS_VERIFY_CLIENT,
+	   OPT_TLS_NEG_TIMEOUT, OPT_TLS_CIPHER,
+	   OPT_CAPTURE_DEV, OPT_PLAYBACK_DEV,
+	   OPT_CAPTURE_LAT, OPT_PLAYBACK_LAT, OPT_NO_TONES, OPT_JB_MAX_SIZE,
+	   OPT_STDOUT_REFRESH, OPT_STDOUT_REFRESH_TEXT, OPT_IPV6, OPT_QOS,
+#ifdef _IONBF
+	   OPT_STDOUT_NO_BUF,
+#endif
+	   OPT_AUTO_UPDATE_NAT,OPT_USE_COMPACT_FORM,OPT_DIS_CODEC,
+	   OPT_DISABLE_STUN, OPT_NO_FORCE_LR,
+	   OPT_TIMER, OPT_TIMER_SE, OPT_TIMER_MIN_SE,
+	   OPT_VIDEO, OPT_EXTRA_AUDIO,
+	   OPT_VCAPTURE_DEV, OPT_VRENDER_DEV, OPT_PLAY_AVI, OPT_AUTO_PLAY_AVI,
+	   OPT_USE_CLI, OPT_CLI_TELNET_PORT, OPT_DISABLE_CLI_CONSOLE
+    };
+    struct pj_getopt_option long_options[] = {
+	{ "config-file",1, 0, OPT_CONFIG_FILE},
+	{ "log-file",	1, 0, OPT_LOG_FILE},
+	{ "log-level",	1, 0, OPT_LOG_LEVEL},
+	{ "app-log-level",1,0,OPT_APP_LOG_LEVEL},
+	{ "log-append", 0, 0, OPT_LOG_APPEND},
+	{ "color",	0, 0, OPT_COLOR},
+	{ "no-color",	0, 0, OPT_NO_COLOR},
+	{ "light-bg",		0, 0, OPT_LIGHT_BG},
+	{ "no-stderr",  0, 0, OPT_NO_STDERR},
+	{ "help",	0, 0, OPT_HELP},
+	{ "version",	0, 0, OPT_VERSION},
+	{ "clock-rate",	1, 0, OPT_CLOCK_RATE},
+	{ "snd-clock-rate",	1, 0, OPT_SND_CLOCK_RATE},
+	{ "stereo",	0, 0, OPT_STEREO},
+	{ "null-audio", 0, 0, OPT_NULL_AUDIO},
+	{ "local-port", 1, 0, OPT_LOCAL_PORT},
+	{ "ip-addr",	1, 0, OPT_IP_ADDR},
+	{ "bound-addr", 1, 0, OPT_BOUND_ADDR},
+	{ "no-tcp",     0, 0, OPT_NO_TCP},
+	{ "no-udp",     0, 0, OPT_NO_UDP},
+	{ "norefersub", 0, 0, OPT_NOREFERSUB},
+	{ "proxy",	1, 0, OPT_PROXY},
+	{ "outbound",	1, 0, OPT_OUTBOUND_PROXY},
+	{ "registrar",	1, 0, OPT_REGISTRAR},
+	{ "reg-timeout",1, 0, OPT_REG_TIMEOUT},
+	{ "publish",    0, 0, OPT_PUBLISH},
+	{ "mwi",	0, 0, OPT_MWI},
+	{ "use-100rel", 0, 0, OPT_100REL},
+	{ "use-ims",    0, 0, OPT_USE_IMS},
+	{ "id",		1, 0, OPT_ID},
+	{ "contact",	1, 0, OPT_CONTACT},
+	{ "contact-params",1,0, OPT_CONTACT_PARAMS},
+	{ "contact-uri-params",1,0, OPT_CONTACT_URI_PARAMS},
+	{ "auto-update-nat",	1, 0, OPT_AUTO_UPDATE_NAT},
+	{ "disable-stun",0,0, OPT_DISABLE_STUN},
+        { "use-compact-form",	0, 0, OPT_USE_COMPACT_FORM},
+	{ "accept-redirect", 1, 0, OPT_ACCEPT_REDIRECT},
+	{ "no-force-lr",0, 0, OPT_NO_FORCE_LR},
+	{ "realm",	1, 0, OPT_REALM},
+	{ "username",	1, 0, OPT_USERNAME},
+	{ "password",	1, 0, OPT_PASSWORD},
+	{ "rereg-delay",1, 0, OPT_REG_RETRY_INTERVAL},
+	{ "reg-use-proxy", 1, 0, OPT_REG_USE_PROXY},
+	{ "nameserver", 1, 0, OPT_NAMESERVER},
+	{ "stun-srv",   1, 0, OPT_STUN_SRV},
+	{ "add-buddy",  1, 0, OPT_ADD_BUDDY},
+	{ "offer-x-ms-msg",0,0,OPT_OFFER_X_MS_MSG},
+	{ "no-presence", 0, 0, OPT_NO_PRESENCE},
+	{ "auto-answer",1, 0, OPT_AUTO_ANSWER},
+	{ "auto-play",  0, 0, OPT_AUTO_PLAY},
+	{ "auto-play-hangup",0, 0, OPT_AUTO_PLAY_HANGUP},
+	{ "auto-rec",   0, 0, OPT_AUTO_REC},
+	{ "auto-loop",  0, 0, OPT_AUTO_LOOP},
+	{ "auto-conf",  0, 0, OPT_AUTO_CONF},
+	{ "play-file",  1, 0, OPT_PLAY_FILE},
+	{ "play-tone",  1, 0, OPT_PLAY_TONE},
+	{ "rec-file",   1, 0, OPT_REC_FILE},
+	{ "rtp-port",	1, 0, OPT_RTP_PORT},
+
+	{ "use-ice",    0, 0, OPT_USE_ICE},
+	{ "ice-regular",0, 0, OPT_ICE_REGULAR},
+	{ "use-turn",	0, 0, OPT_USE_TURN},
+	{ "ice-max-hosts",1, 0, OPT_ICE_MAX_HOSTS},
+	{ "ice-no-rtcp",0, 0, OPT_ICE_NO_RTCP},
+	{ "turn-srv",	1, 0, OPT_TURN_SRV},
+	{ "turn-tcp",	0, 0, OPT_TURN_TCP},
+	{ "turn-user",	1, 0, OPT_TURN_USER},
+	{ "turn-passwd",1, 0, OPT_TURN_PASSWD},
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+	{ "use-srtp",   1, 0, OPT_USE_SRTP},
+	{ "srtp-secure",1, 0, OPT_SRTP_SECURE},
+#endif
+	{ "add-codec",  1, 0, OPT_ADD_CODEC},
+	{ "dis-codec",  1, 0, OPT_DIS_CODEC},
+	{ "complexity",	1, 0, OPT_COMPLEXITY},
+	{ "quality",	1, 0, OPT_QUALITY},
+	{ "ptime",      1, 0, OPT_PTIME},
+	{ "no-vad",     0, 0, OPT_NO_VAD},
+	{ "ec-tail",    1, 0, OPT_EC_TAIL},
+	{ "ec-opt",	1, 0, OPT_EC_OPT},
+	{ "ilbc-mode",	1, 0, OPT_ILBC_MODE},
+	{ "rx-drop-pct",1, 0, OPT_RX_DROP_PCT},
+	{ "tx-drop-pct",1, 0, OPT_TX_DROP_PCT},
+	{ "next-account",0,0, OPT_NEXT_ACCOUNT},
+	{ "next-cred",	0, 0, OPT_NEXT_CRED},
+	{ "max-calls",	1, 0, OPT_MAX_CALLS},
+	{ "duration",	1, 0, OPT_DURATION},
+	{ "thread-cnt",	1, 0, OPT_THREAD_CNT},
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
+	{ "use-tls",	0, 0, OPT_USE_TLS}, 
+	{ "tls-ca-file",1, 0, OPT_TLS_CA_FILE},
+	{ "tls-cert-file",1,0, OPT_TLS_CERT_FILE}, 
+	{ "tls-privkey-file",1,0, OPT_TLS_PRIV_FILE},
+	{ "tls-password",1,0, OPT_TLS_PASSWORD},
+	{ "tls-verify-server", 0, 0, OPT_TLS_VERIFY_SERVER},
+	{ "tls-verify-client", 0, 0, OPT_TLS_VERIFY_CLIENT},
+	{ "tls-neg-timeout", 1, 0, OPT_TLS_NEG_TIMEOUT},
+	{ "tls-cipher", 1, 0, OPT_TLS_CIPHER},
+#endif
+	{ "capture-dev",    1, 0, OPT_CAPTURE_DEV},
+	{ "playback-dev",   1, 0, OPT_PLAYBACK_DEV},
+	{ "capture-lat",    1, 0, OPT_CAPTURE_LAT},
+	{ "playback-lat",   1, 0, OPT_PLAYBACK_LAT},
+	{ "stdout-refresh", 1, 0, OPT_STDOUT_REFRESH},
+	{ "stdout-refresh-text", 1, 0, OPT_STDOUT_REFRESH_TEXT},
+#ifdef _IONBF
+	{ "stdout-no-buf",  0, 0, OPT_STDOUT_NO_BUF },
+#endif
+	{ "snd-auto-close", 1, 0, OPT_SND_AUTO_CLOSE},
+	{ "no-tones",    0, 0, OPT_NO_TONES},
+	{ "jb-max-size", 1, 0, OPT_JB_MAX_SIZE},
+#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
+	{ "ipv6",	 0, 0, OPT_IPV6},
+#endif
+	{ "set-qos",	 0, 0, OPT_QOS},
+	{ "use-timer",  1, 0, OPT_TIMER},
+	{ "timer-se",   1, 0, OPT_TIMER_SE},
+	{ "timer-min-se", 1, 0, OPT_TIMER_MIN_SE},
+	{ "outb-rid",	1, 0, OPT_OUTB_RID},
+	{ "video",	0, 0, OPT_VIDEO},
+	{ "extra-audio",0, 0, OPT_EXTRA_AUDIO},
+	{ "vcapture-dev", 1, 0, OPT_VCAPTURE_DEV},
+	{ "vrender-dev",  1, 0, OPT_VRENDER_DEV},
+	{ "play-avi",	1, 0, OPT_PLAY_AVI},
+	{ "auto-play-avi", 0, 0, OPT_AUTO_PLAY_AVI},
+	{ "use-cli",	0, 0, OPT_USE_CLI},
+	{ "cli-telnet-port", 1, 0, OPT_CLI_TELNET_PORT},
+	{ "no-cli-console", 0, 0, OPT_DISABLE_CLI_CONSOLE},
+	{ NULL, 0, 0, 0}
+    };
+    pj_status_t status;
+    pjsua_acc_config *cur_acc;
+    char *config_file = NULL;
+    unsigned i;
+
+    /* Run pj_getopt once to see if user specifies config file to read. */ 
+    pj_optind = 0;
+    while ((c=pj_getopt_long(argc, argv, "", long_options, 
+			     &option_index)) != -1) 
+    {
+	switch (c) {
+	case OPT_CONFIG_FILE:
+	    config_file = pj_optarg;
+	    break;
+	}
+	if (config_file)
+	    break;
+    }
+
+    if (config_file) {
+	status = read_config_file(cfg->pool, config_file, &argc, &argv);
+	if (status != 0)
+	    return status;
+    }
+
+    cfg->acc_cnt = 0;
+    cur_acc = cfg->acc_cfg;
+
+
+    /* Reinitialize and re-run pj_getopt again, possibly with new arguments
+     * read from config file.
+     */
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc,argv, "", long_options,&option_index))!=-1) {
+	pj_str_t tmp;
+	long lval;
+
+	switch (c) {
+
+	case OPT_CONFIG_FILE:
+	    /* Ignore as this has been processed before */
+	    break;
+	
+	case OPT_LOG_FILE:
+	    cfg->log_cfg.log_filename = pj_str(pj_optarg);
+	    break;
+
+	case OPT_LOG_LEVEL:
+	    c = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    if (c < 0 || c > 6) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: expecting integer value 0-6 "
+			  "for --log-level"));
+		return PJ_EINVAL;
+	    }
+	    cfg->log_cfg.level = c;
+	    pj_log_set_level( c );
+	    break;
+
+	case OPT_APP_LOG_LEVEL:
+	    cfg->log_cfg.console_level = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    if (cfg->log_cfg.console_level < 0 || cfg->log_cfg.console_level > 6) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: expecting integer value 0-6 "
+			  "for --app-log-level"));
+		return PJ_EINVAL;
+	    }
+	    break;
+
+	case OPT_LOG_APPEND:
+	    cfg->log_cfg.log_file_flags |= PJ_O_APPEND;
+	    break;
+
+	case OPT_COLOR:
+	    cfg->log_cfg.decor |= PJ_LOG_HAS_COLOR;
+	    break;
+
+	case OPT_NO_COLOR:
+	    cfg->log_cfg.decor &= ~PJ_LOG_HAS_COLOR;
+	    break;
+
+	case OPT_LIGHT_BG:
+	    pj_log_set_color(1, PJ_TERM_COLOR_R);
+	    pj_log_set_color(2, PJ_TERM_COLOR_R | PJ_TERM_COLOR_G);
+	    pj_log_set_color(3, PJ_TERM_COLOR_B | PJ_TERM_COLOR_G);
+	    pj_log_set_color(4, 0);
+	    pj_log_set_color(5, 0);
+	    pj_log_set_color(77, 0);
+	    break;
+
+	case OPT_NO_STDERR:
+#if !defined(PJ_WIN32_WINCE) || PJ_WIN32_WINCE==0
+	    freopen("/dev/null", "w", stderr);
+#endif
+	    break;
+
+	case OPT_HELP:
+	    usage();
+	    return PJ_EINVAL;
+
+	case OPT_VERSION:   /* version */
+	    pj_dump_config();
+	    return PJ_EINVAL;
+
+	case OPT_NULL_AUDIO:
+	    cfg->null_audio = PJ_TRUE;
+	    break;
+
+	case OPT_CLOCK_RATE:
+	    lval = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    if (lval < 8000 || lval > 192000) {
+		PJ_LOG(1,(THIS_FILE, "Error: expecting value between "
+				     "8000-192000 for conference clock rate"));
+		return PJ_EINVAL;
+	    }
+	    cfg->media_cfg.clock_rate = lval; 
+	    break;
+
+	case OPT_SND_CLOCK_RATE:
+	    lval = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    if (lval < 8000 || lval > 192000) {
+		PJ_LOG(1,(THIS_FILE, "Error: expecting value between "
+				     "8000-192000 for sound device clock rate"));
+		return PJ_EINVAL;
+	    }
+	    cfg->media_cfg.snd_clock_rate = lval; 
+	    break;
+
+	case OPT_STEREO:
+	    cfg->media_cfg.channel_count = 2;
+	    break;
+
+	case OPT_LOCAL_PORT:   /* local-port */
+	    lval = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    if (lval < 0 || lval > 65535) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: expecting integer value for "
+			  "--local-port"));
+		return PJ_EINVAL;
+	    }
+	    cfg->udp_cfg.port = (pj_uint16_t)lval;
+	    break;
+
+	case OPT_IP_ADDR: /* ip-addr */
+	    cfg->udp_cfg.public_addr = pj_str(pj_optarg);
+	    cfg->rtp_cfg.public_addr = pj_str(pj_optarg);
+	    break;
+
+	case OPT_BOUND_ADDR: /* bound-addr */
+	    cfg->udp_cfg.bound_addr = pj_str(pj_optarg);
+	    cfg->rtp_cfg.bound_addr = pj_str(pj_optarg);
+	    break;
+
+	case OPT_NO_UDP: /* no-udp */
+	    if (cfg->no_tcp && !cfg->use_tls) {
+	      PJ_LOG(1,(THIS_FILE,"Error: cannot disable both TCP and UDP"));
+	      return PJ_EINVAL;
+	    }
+
+	    cfg->no_udp = PJ_TRUE;
+	    break;
+
+	case OPT_NOREFERSUB: /* norefersub */
+	    cfg->no_refersub = PJ_TRUE;
+	    break;
+
+	case OPT_NO_TCP: /* no-tcp */
+	    if (cfg->no_udp && !cfg->use_tls) {
+	      PJ_LOG(1,(THIS_FILE,"Error: cannot disable both TCP and UDP"));
+	      return PJ_EINVAL;
+	    }
+
+	    cfg->no_tcp = PJ_TRUE;
+	    break;
+
+	case OPT_PROXY:   /* proxy */
+	    if (pjsua_verify_sip_url(pj_optarg) != 0) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: invalid SIP URL '%s' "
+			  "in proxy argument", pj_optarg));
+		return PJ_EINVAL;
+	    }
+	    cur_acc->proxy[cur_acc->proxy_cnt++] = pj_str(pj_optarg);
+	    break;
+
+	case OPT_OUTBOUND_PROXY:   /* outbound proxy */
+	    if (pjsua_verify_sip_url(pj_optarg) != 0) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: invalid SIP URL '%s' "
+			  "in outbound proxy argument", pj_optarg));
+		return PJ_EINVAL;
+	    }
+	    cfg->cfg.outbound_proxy[cfg->cfg.outbound_proxy_cnt++] = pj_str(pj_optarg);
+	    break;
+
+	case OPT_REGISTRAR:   /* registrar */
+	    if (pjsua_verify_sip_url(pj_optarg) != 0) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: invalid SIP URL '%s' in "
+			  "registrar argument", pj_optarg));
+		return PJ_EINVAL;
+	    }
+	    cur_acc->reg_uri = pj_str(pj_optarg);
+	    break;
+
+	case OPT_REG_TIMEOUT:   /* reg-timeout */
+	    cur_acc->reg_timeout = pj_strtoul(pj_cstr(&tmp,pj_optarg));
+	    if (cur_acc->reg_timeout < 1 || cur_acc->reg_timeout > 3600) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: invalid value for --reg-timeout "
+			  "(expecting 1-3600)"));
+		return PJ_EINVAL;
+	    }
+	    break;
+
+	case OPT_PUBLISH:   /* publish */
+	    cur_acc->publish_enabled = PJ_TRUE;
+	    break;
+
+	case OPT_MWI:	/* mwi */
+	    cur_acc->mwi_enabled = PJ_TRUE;
+	    break;
+
+	case OPT_100REL: /** 100rel */
+	    cur_acc->require_100rel = PJSUA_100REL_MANDATORY;
+	    cfg->cfg.require_100rel = PJSUA_100REL_MANDATORY;
+	    break;
+
+	case OPT_TIMER: /** session timer */
+	    lval = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    if (lval < 0 || lval > 3) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: expecting integer value 0-3 for --use-timer"));
+		return PJ_EINVAL;
+	    }
+	    cur_acc->use_timer = lval;
+	    cfg->cfg.use_timer = lval;
+	    break;
+
+	case OPT_TIMER_SE: /** session timer session expiration */
+	    cur_acc->timer_setting.sess_expires = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    if (cur_acc->timer_setting.sess_expires < 90) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: invalid value for --timer-se "
+			  "(expecting higher than 90)"));
+		return PJ_EINVAL;
+	    }
+	    cfg->cfg.timer_setting.sess_expires = cur_acc->timer_setting.sess_expires;
+	    break;
+
+	case OPT_TIMER_MIN_SE: /** session timer minimum session expiration */
+	    cur_acc->timer_setting.min_se = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    if (cur_acc->timer_setting.min_se < 90) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: invalid value for --timer-min-se "
+			  "(expecting higher than 90)"));
+		return PJ_EINVAL;
+	    }
+	    cfg->cfg.timer_setting.min_se = cur_acc->timer_setting.min_se;
+	    break;
+
+	case OPT_OUTB_RID: /* Outbound reg-id */
+	    cur_acc->rfc5626_reg_id = pj_str(pj_optarg);
+	    break;
+
+	case OPT_USE_IMS: /* Activate IMS settings */
+	    cur_acc->auth_pref.initial_auth = PJ_TRUE;
+	    break;
+
+	case OPT_ID:   /* id */
+	    if (pjsua_verify_url(pj_optarg) != 0) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: invalid SIP URL '%s' "
+			  "in local id argument", pj_optarg));
+		return PJ_EINVAL;
+	    }
+	    cur_acc->id = pj_str(pj_optarg);
+	    break;
+
+	case OPT_CONTACT:   /* contact */
+	    if (pjsua_verify_sip_url(pj_optarg) != 0) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: invalid SIP URL '%s' "
+			  "in contact argument", pj_optarg));
+		return PJ_EINVAL;
+	    }
+	    cur_acc->force_contact = pj_str(pj_optarg);
+	    break;
+
+	case OPT_CONTACT_PARAMS:
+	    cur_acc->contact_params = pj_str(pj_optarg);
+	    break;
+
+	case OPT_CONTACT_URI_PARAMS:
+	    cur_acc->contact_uri_params = pj_str(pj_optarg);
+	    break;
+
+	case OPT_AUTO_UPDATE_NAT:   /* OPT_AUTO_UPDATE_NAT */
+            cur_acc->allow_contact_rewrite  = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    break;
+
+	case OPT_DISABLE_STUN:
+	    cur_acc->sip_stun_use = PJSUA_STUN_USE_DISABLED;
+	    cur_acc->media_stun_use = PJSUA_STUN_USE_DISABLED;
+	    break;
+
+	case OPT_USE_COMPACT_FORM:
+	    /* enable compact form - from Ticket #342 */
+            {
+		extern pj_bool_t pjsip_use_compact_form;
+		extern pj_bool_t pjsip_include_allow_hdr_in_dlg;
+		extern pj_bool_t pjmedia_add_rtpmap_for_static_pt;
+
+		pjsip_use_compact_form = PJ_TRUE;
+		/* do not transmit Allow header */
+		pjsip_include_allow_hdr_in_dlg = PJ_FALSE;
+		/* Do not include rtpmap for static payload types (<96) */
+		pjmedia_add_rtpmap_for_static_pt = PJ_FALSE;
+            }
+	    break;
+
+	case OPT_ACCEPT_REDIRECT:
+	    cfg->redir_op = my_atoi(pj_optarg);
+	    if (cfg->redir_op<0 || cfg->redir_op>PJSIP_REDIRECT_STOP) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: accept-redirect value '%s' ", pj_optarg));
+		return PJ_EINVAL;
+	    }
+	    break;
+
+	case OPT_NO_FORCE_LR:
+	    cfg->cfg.force_lr = PJ_FALSE;
+	    break;
+
+	case OPT_NEXT_ACCOUNT: /* Add more account. */
+	    cfg->acc_cnt++;
+	    cur_acc = &cfg->acc_cfg[cfg->acc_cnt];
+	    break;
+
+	case OPT_USERNAME:   /* Default authentication user */
+	    cur_acc->cred_info[cur_acc->cred_count].username = pj_str(pj_optarg);
+	    cur_acc->cred_info[cur_acc->cred_count].scheme = pj_str("Digest");
+	    break;
+
+	case OPT_REALM:	    /* Default authentication realm. */
+	    cur_acc->cred_info[cur_acc->cred_count].realm = pj_str(pj_optarg);
+	    break;
+
+	case OPT_PASSWORD:   /* authentication password */
+	    cur_acc->cred_info[cur_acc->cred_count].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
+	    cur_acc->cred_info[cur_acc->cred_count].data = pj_str(pj_optarg);
+#if PJSIP_HAS_DIGEST_AKA_AUTH
+	    cur_acc->cred_info[cur_acc->cred_count].data_type |= PJSIP_CRED_DATA_EXT_AKA;
+	    cur_acc->cred_info[cur_acc->cred_count].ext.aka.k = pj_str(pj_optarg);
+	    cur_acc->cred_info[cur_acc->cred_count].ext.aka.cb = &pjsip_auth_create_aka_response;
+#endif
+	    break;
+
+	case OPT_REG_RETRY_INTERVAL:
+	    cur_acc->reg_retry_interval = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    break;
+
+	case OPT_REG_USE_PROXY:
+	    cur_acc->reg_use_proxy = (unsigned)pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    if (cur_acc->reg_use_proxy > 3) {
+		PJ_LOG(1,(THIS_FILE, "Error: invalid --reg-use-proxy value '%s'",
+			  pj_optarg));
+		return PJ_EINVAL;
+	    }
+	    break;
+
+	case OPT_NEXT_CRED: /* next credential */
+	    cur_acc->cred_count++;
+	    break;
+
+	case OPT_NAMESERVER: /* nameserver */
+	    cfg->cfg.nameserver[cfg->cfg.nameserver_count++] = pj_str(pj_optarg);
+	    if (cfg->cfg.nameserver_count > PJ_ARRAY_SIZE(cfg->cfg.nameserver)) {
+		PJ_LOG(1,(THIS_FILE, "Error: too many nameservers"));
+		return PJ_ETOOMANY;
+	    }
+	    break;
+
+	case OPT_STUN_SRV:   /* STUN server */
+	    cfg->cfg.stun_host = pj_str(pj_optarg);
+	    if (cfg->cfg.stun_srv_cnt==PJ_ARRAY_SIZE(cfg->cfg.stun_srv)) {
+		PJ_LOG(1,(THIS_FILE, "Error: too many STUN servers"));
+		return PJ_ETOOMANY;
+	    }
+	    cfg->cfg.stun_srv[cfg->cfg.stun_srv_cnt++] = pj_str(pj_optarg);
+	    break;
+
+	case OPT_ADD_BUDDY: /* Add to buddy list. */
+	    if (pjsua_verify_url(pj_optarg) != 0) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: invalid URL '%s' in "
+			  "--add-buddy option", pj_optarg));
+		return -1;
+	    }
+	    if (cfg->buddy_cnt == PJ_ARRAY_SIZE(cfg->buddy_cfg)) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: too many buddies in buddy list."));
+		return -1;
+	    }
+	    cfg->buddy_cfg[cfg->buddy_cnt].uri = pj_str(pj_optarg);
+	    cfg->buddy_cnt++;
+	    break;
+
+	case OPT_AUTO_PLAY:
+	    cfg->auto_play = 1;
+	    break;
+
+	case OPT_AUTO_PLAY_HANGUP:
+	    cfg->auto_play_hangup = 1;
+	    break;
+
+	case OPT_AUTO_REC:
+	    cfg->auto_rec = 1;
+	    break;
+
+	case OPT_AUTO_LOOP:
+	    cfg->auto_loop = 1;
+	    break;
+
+	case OPT_AUTO_CONF:
+	    cfg->auto_conf = 1;
+	    break;
+
+	case OPT_PLAY_FILE:
+	    cfg->wav_files[cfg->wav_count++] = pj_str(pj_optarg);
+	    break;
+
+	case OPT_PLAY_TONE:
+	    {
+		int f1, f2, on, off;
+		int n;
+
+		n = sscanf(pj_optarg, "%d,%d,%d,%d", &f1, &f2, &on, &off);
+		if (n != 4) {
+		    puts("Expecting f1,f2,on,off in --play-tone");
+		    return -1;
+		}
+
+		cfg->tones[cfg->tone_count].freq1 = (short)f1;
+		cfg->tones[cfg->tone_count].freq2 = (short)f2;
+		cfg->tones[cfg->tone_count].on_msec = (short)on;
+		cfg->tones[cfg->tone_count].off_msec = (short)off;
+		++cfg->tone_count;
+	    }
+	    break;
+
+	case OPT_REC_FILE:
+	    cfg->rec_file = pj_str(pj_optarg);
+	    break;
+
+	case OPT_USE_ICE:
+	    cfg->media_cfg.enable_ice =
+		    cur_acc->ice_cfg.enable_ice = PJ_TRUE;
+	    break;
+
+	case OPT_ICE_REGULAR:
+	    cfg->media_cfg.ice_opt.aggressive =
+		    cur_acc->ice_cfg.ice_opt.aggressive = PJ_FALSE;
+	    break;
+
+	case OPT_USE_TURN:
+	    cfg->media_cfg.enable_turn =
+		    cur_acc->turn_cfg.enable_turn = PJ_TRUE;
+	    break;
+
+	case OPT_ICE_MAX_HOSTS:
+	    cfg->media_cfg.ice_max_host_cands =
+		    cur_acc->ice_cfg.ice_max_host_cands = my_atoi(pj_optarg);
+	    break;
+
+	case OPT_ICE_NO_RTCP:
+	    cfg->media_cfg.ice_no_rtcp =
+		    cur_acc->ice_cfg.ice_no_rtcp = PJ_TRUE;
+	    break;
+
+	case OPT_TURN_SRV:
+	    cfg->media_cfg.turn_server =
+		    cur_acc->turn_cfg.turn_server = pj_str(pj_optarg);
+	    break;
+
+	case OPT_TURN_TCP:
+	    cfg->media_cfg.turn_conn_type =
+		    cur_acc->turn_cfg.turn_conn_type = PJ_TURN_TP_TCP;
+	    break;
+
+	case OPT_TURN_USER:
+	    cfg->media_cfg.turn_auth_cred.type =
+		    cur_acc->turn_cfg.turn_auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
+	    cfg->media_cfg.turn_auth_cred.data.static_cred.realm =
+		    cur_acc->turn_cfg.turn_auth_cred.data.static_cred.realm = pj_str("*");
+	    cfg->media_cfg.turn_auth_cred.data.static_cred.username =
+		    cur_acc->turn_cfg.turn_auth_cred.data.static_cred.username = pj_str(pj_optarg);
+	    break;
+
+	case OPT_TURN_PASSWD:
+	    cfg->media_cfg.turn_auth_cred.data.static_cred.data_type =
+		    cur_acc->turn_cfg.turn_auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
+	    cfg->media_cfg.turn_auth_cred.data.static_cred.data =
+		    cur_acc->turn_cfg.turn_auth_cred.data.static_cred.data = pj_str(pj_optarg);
+	    break;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+	case OPT_USE_SRTP:
+	    app_config.cfg.use_srtp = my_atoi(pj_optarg);
+	    if (!pj_isdigit(*pj_optarg) || app_config.cfg.use_srtp > 3) {
+		PJ_LOG(1,(THIS_FILE, "Invalid value for --use-srtp option"));
+		return -1;
+	    }
+	    if ((int)app_config.cfg.use_srtp == 3) {
+		/* SRTP optional mode with duplicated media offer */
+		app_config.cfg.use_srtp = PJMEDIA_SRTP_OPTIONAL;
+		app_config.cfg.srtp_optional_dup_offer = PJ_TRUE;
+		cur_acc->srtp_optional_dup_offer = PJ_TRUE;
+	    }
+	    cur_acc->use_srtp = app_config.cfg.use_srtp;
+	    break;
+	case OPT_SRTP_SECURE:
+	    app_config.cfg.srtp_secure_signaling = my_atoi(pj_optarg);
+	    if (!pj_isdigit(*pj_optarg) || 
+		app_config.cfg.srtp_secure_signaling > 2) 
+	    {
+		PJ_LOG(1,(THIS_FILE, "Invalid value for --srtp-secure option"));
+		return -1;
+	    }
+	    cur_acc->srtp_secure_signaling = app_config.cfg.srtp_secure_signaling;
+	    break;
+#endif
+
+	case OPT_RTP_PORT:
+	    cfg->rtp_cfg.port = my_atoi(pj_optarg);
+	    if (cfg->rtp_cfg.port == 0) {
+		enum { START_PORT=4000 };
+		unsigned range;
+
+		range = (65535-START_PORT-PJSUA_MAX_CALLS*2);
+		cfg->rtp_cfg.port = START_PORT + 
+				    ((pj_rand() % range) & 0xFFFE);
+	    }
+
+	    if (cfg->rtp_cfg.port < 1 || cfg->rtp_cfg.port > 65535) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: rtp-port argument value "
+			  "(expecting 1-65535"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_DIS_CODEC:
+            cfg->codec_dis[cfg->codec_dis_cnt++] = pj_str(pj_optarg);
+	    break;
+
+	case OPT_ADD_CODEC:
+	    cfg->codec_arg[cfg->codec_cnt++] = pj_str(pj_optarg);
+	    break;
+
+	/* These options were no longer valid after new pjsua */
+	/*
+	case OPT_COMPLEXITY:
+	    cfg->complexity = my_atoi(pj_optarg);
+	    if (cfg->complexity < 0 || cfg->complexity > 10) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --complexity (expecting 0-10"));
+		return -1;
+	    }
+	    break;
+	*/
+
+	case OPT_DURATION:
+	    cfg->duration = my_atoi(pj_optarg);
+	    break;
+
+	case OPT_THREAD_CNT:
+	    cfg->cfg.thread_cnt = my_atoi(pj_optarg);
+	    if (cfg->cfg.thread_cnt > 128) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --thread-cnt option"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_PTIME:
+	    cfg->media_cfg.ptime = my_atoi(pj_optarg);
+	    if (cfg->media_cfg.ptime < 10 || cfg->media_cfg.ptime > 1000) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --ptime option"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_NO_VAD:
+	    cfg->media_cfg.no_vad = PJ_TRUE;
+	    break;
+
+	case OPT_EC_TAIL:
+	    cfg->media_cfg.ec_tail_len = my_atoi(pj_optarg);
+	    if (cfg->media_cfg.ec_tail_len > 1000) {
+		PJ_LOG(1,(THIS_FILE, "I think the ec-tail length setting "
+			  "is too big"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_EC_OPT:
+	    cfg->media_cfg.ec_options = my_atoi(pj_optarg);
+	    break;
+
+	case OPT_QUALITY:
+	    cfg->media_cfg.quality = my_atoi(pj_optarg);
+	    if (cfg->media_cfg.quality < 0 || cfg->media_cfg.quality > 10) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --quality (expecting 0-10"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_ILBC_MODE:
+	    cfg->media_cfg.ilbc_mode = my_atoi(pj_optarg);
+	    if (cfg->media_cfg.ilbc_mode!=20 && cfg->media_cfg.ilbc_mode!=30) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --ilbc-mode (expecting 20 or 30"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_RX_DROP_PCT:
+	    cfg->media_cfg.rx_drop_pct = my_atoi(pj_optarg);
+	    if (cfg->media_cfg.rx_drop_pct > 100) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --rx-drop-pct (expecting <= 100"));
+		return -1;
+	    }
+	    break;
+	    
+	case OPT_TX_DROP_PCT:
+	    cfg->media_cfg.tx_drop_pct = my_atoi(pj_optarg);
+	    if (cfg->media_cfg.tx_drop_pct > 100) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid --tx-drop-pct (expecting <= 100"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_AUTO_ANSWER:
+	    cfg->auto_answer = my_atoi(pj_optarg);
+	    if (cfg->auto_answer < 100 || cfg->auto_answer > 699) {
+		PJ_LOG(1,(THIS_FILE,
+			  "Error: invalid code in --auto-answer "
+			  "(expecting 100-699"));
+		return -1;
+	    }
+	    break;
+
+	case OPT_MAX_CALLS:
+	    cfg->cfg.max_calls = my_atoi(pj_optarg);
+	    if (cfg->cfg.max_calls < 1 || cfg->cfg.max_calls > PJSUA_MAX_CALLS) {
+		PJ_LOG(1,(THIS_FILE,"Error: maximum call setting exceeds "
+				    "compile time limit (PJSUA_MAX_CALLS=%d)",
+			  PJSUA_MAX_CALLS));
+		return -1;
+	    }
+	    break;
+
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
+	case OPT_USE_TLS:
+	    cfg->use_tls = PJ_TRUE;
+	    break;
+	    
+	case OPT_TLS_CA_FILE:
+	    cfg->udp_cfg.tls_setting.ca_list_file = pj_str(pj_optarg);
+	    break;
+	    
+	case OPT_TLS_CERT_FILE:
+	    cfg->udp_cfg.tls_setting.cert_file = pj_str(pj_optarg);
+	    break;
+	    
+	case OPT_TLS_PRIV_FILE:
+	    cfg->udp_cfg.tls_setting.privkey_file = pj_str(pj_optarg);
+	    break;
+
+	case OPT_TLS_PASSWORD:
+	    cfg->udp_cfg.tls_setting.password = pj_str(pj_optarg);
+	    break;
+
+	case OPT_TLS_VERIFY_SERVER:
+	    cfg->udp_cfg.tls_setting.verify_server = PJ_TRUE;
+	    break;
+
+	case OPT_TLS_VERIFY_CLIENT:
+	    cfg->udp_cfg.tls_setting.verify_client = PJ_TRUE;
+	    cfg->udp_cfg.tls_setting.require_client_cert = PJ_TRUE;
+	    break;
+
+	case OPT_TLS_NEG_TIMEOUT:
+	    cfg->udp_cfg.tls_setting.timeout.sec = atoi(pj_optarg);
+	    break;
+
+	case OPT_TLS_CIPHER:
+	    {
+		pj_ssl_cipher cipher;
+
+		if (pj_ansi_strnicmp(pj_optarg, "0x", 2) == 0) {
+		    pj_str_t cipher_st = pj_str(pj_optarg + 2);
+		    cipher = pj_strtoul2(&cipher_st, NULL, 16);
+		} else {
+		    cipher = atoi(pj_optarg);
+		}
+
+		if (pj_ssl_cipher_is_supported(cipher)) {
+		    static pj_ssl_cipher tls_ciphers[128];
+
+		    tls_ciphers[cfg->udp_cfg.tls_setting.ciphers_num++] = cipher;
+		    cfg->udp_cfg.tls_setting.ciphers = tls_ciphers;
+		} else {
+		    pj_ssl_cipher ciphers[128];
+		    unsigned j, ciphers_cnt;
+
+		    ciphers_cnt = PJ_ARRAY_SIZE(ciphers);
+		    pj_ssl_cipher_get_availables(ciphers, &ciphers_cnt);
+		    
+		    PJ_LOG(1,(THIS_FILE, "Cipher \"%s\" is not supported by "
+					 "TLS/SSL backend.", pj_optarg));
+		    printf("Available TLS/SSL ciphers (%d):\n", ciphers_cnt);
+		    for (j=0; j<ciphers_cnt; ++j)
+			printf("- 0x%06X: %s\n", ciphers[j], pj_ssl_cipher_name(ciphers[j]));
+		    return -1;
+		}
+	    }
+ 	    break;
+#endif /* PJSIP_HAS_TLS_TRANSPORT */
+
+	case OPT_CAPTURE_DEV:
+	    cfg->capture_dev = atoi(pj_optarg);
+	    break;
+
+	case OPT_PLAYBACK_DEV:
+	    cfg->playback_dev = atoi(pj_optarg);
+	    break;
+
+	case OPT_STDOUT_REFRESH:
+	    stdout_refresh = atoi(pj_optarg);
+	    break;
+
+	case OPT_STDOUT_REFRESH_TEXT:
+	    stdout_refresh_text = pj_optarg;
+	    break;
+
+#ifdef _IONBF
+	case OPT_STDOUT_NO_BUF:
+	    setvbuf(stdout, NULL, _IONBF, 0);
+	    break;
+#endif
+
+	case OPT_CAPTURE_LAT:
+	    cfg->capture_lat = atoi(pj_optarg);
+	    break;
+
+	case OPT_PLAYBACK_LAT:
+	    cfg->playback_lat = atoi(pj_optarg);
+	    break;
+
+	case OPT_SND_AUTO_CLOSE:
+	    cfg->media_cfg.snd_auto_close_time = atoi(pj_optarg);
+	    break;
+
+	case OPT_NO_TONES:
+	    cfg->no_tones = PJ_TRUE;
+	    break;
+
+	case OPT_JB_MAX_SIZE:
+	    cfg->media_cfg.jb_max = atoi(pj_optarg);
+	    break;
+
+#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
+	case OPT_IPV6:
+	    cfg->ipv6 = PJ_TRUE;
+	    break;
+#endif
+	case OPT_QOS:
+	    cfg->enable_qos = PJ_TRUE;
+	    /* Set RTP traffic type to Voice */
+	    cfg->rtp_cfg.qos_type = PJ_QOS_TYPE_VOICE;
+	    /* Directly apply DSCP value to SIP traffic. Say lets
+	     * set it to CS3 (DSCP 011000). Note that this will not 
+	     * work on all platforms.
+	     */
+	    cfg->udp_cfg.qos_params.flags = PJ_QOS_PARAM_HAS_DSCP;
+	    cfg->udp_cfg.qos_params.dscp_val = 0x18;
+	    break;
+	case OPT_VIDEO:
+	    cfg->vid.vid_cnt = 1;
+	    cfg->vid.in_auto_show = PJ_TRUE;
+	    cfg->vid.out_auto_transmit = PJ_TRUE;
+	    break;
+	case OPT_EXTRA_AUDIO:
+	    cfg->aud_cnt++;
+	    break;
+
+	case OPT_VCAPTURE_DEV:
+	    cfg->vid.vcapture_dev = atoi(pj_optarg);
+	    cur_acc->vid_cap_dev = cfg->vid.vcapture_dev;
+	    break;
+
+	case OPT_VRENDER_DEV:
+	    cfg->vid.vrender_dev = atoi(pj_optarg);
+	    cur_acc->vid_rend_dev = cfg->vid.vrender_dev;
+	    break;
+
+	case OPT_PLAY_AVI:
+	    if (app_config.avi_cnt >= PJSUA_APP_MAX_AVI) {
+		PJ_LOG(1,(THIS_FILE, "Too many AVIs"));
+		return -1;
+	    }
+	    app_config.avi[app_config.avi_cnt++].path = pj_str(pj_optarg);
+	    break;
+
+	case OPT_AUTO_PLAY_AVI:
+	    app_config.avi_auto_play = PJ_TRUE;
+	    break;
+
+	case OPT_USE_CLI:
+	    cfg->use_cli = PJ_TRUE;
+	    break;
+
+	case OPT_CLI_TELNET_PORT:
+	    cfg->cli_cfg.telnet_cfg.port = (pj_uint16_t)atoi(pj_optarg);
+	    cfg->cli_cfg.cli_fe |= CLI_FE_TELNET;
+	    break;
+
+	case OPT_DISABLE_CLI_CONSOLE:
+	    cfg->cli_cfg.cli_fe &= (~CLI_FE_CONSOLE);
+	    break;
+
+	default:
+	    PJ_LOG(1,(THIS_FILE, 
+		      "Argument \"%s\" is not valid. Use --help to see help",
+		      argv[pj_optind-1]));
+	    return -1;
+	}
+    }
+
+    if (pj_optind != argc) {
+	pj_str_t uri_arg;
+
+	if (pjsua_verify_url(argv[pj_optind]) != PJ_SUCCESS) {
+	    PJ_LOG(1,(THIS_FILE, "Invalid SIP URI %s", argv[pj_optind]));
+	    return -1;
+	}
+	uri_arg = pj_str(argv[pj_optind]);
+	if (uri_to_call)
+	    *uri_to_call = uri_arg;
+	pj_optind++;
+
+	/* Add URI to call to buddy list if it's not already there */
+	for (i=0; i<cfg->buddy_cnt; ++i) {
+	    if (pj_stricmp(&cfg->buddy_cfg[i].uri, &uri_arg)==0)
+		break;
+	}
+	if (i == cfg->buddy_cnt && cfg->buddy_cnt < PJSUA_MAX_BUDDIES) {
+	    cfg->buddy_cfg[cfg->buddy_cnt++].uri = uri_arg;
+	}
+
+    } else {
+	if (uri_to_call)
+	    uri_to_call->slen = 0;
+    }
+
+    if (pj_optind != argc) {
+	PJ_LOG(1,(THIS_FILE, "Error: unknown options %s", argv[pj_optind]));
+	return PJ_EINVAL;
+    }
+
+    if (cfg->acc_cfg[cfg->acc_cnt].id.slen)
+	cfg->acc_cnt++;
+
+    for (i=0; i<cfg->acc_cnt; ++i) {
+	pjsua_acc_config *acfg = &cfg->acc_cfg[i];
+
+	if (acfg->cred_info[acfg->cred_count].username.slen)
+	{
+	    acfg->cred_count++;
+	}
+
+	if (acfg->ice_cfg.enable_ice) {
+	    acfg->ice_cfg_use = PJSUA_ICE_CONFIG_USE_CUSTOM;
+	}
+	if (acfg->turn_cfg.enable_turn) {
+	    acfg->turn_cfg_use = PJSUA_TURN_CONFIG_USE_CUSTOM;
+	}
+
+	/* When IMS mode is enabled for the account, verify that settings
+	 * are okay.
+	 */
+	/* For now we check if IMS mode is activated by looking if
+	 * initial_auth is set.
+	 */
+	if (acfg->auth_pref.initial_auth && acfg->cred_count) {
+	    /* Realm must point to the real domain */
+	    if (*acfg->cred_info[0].realm.ptr=='*') {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: cannot use '*' as realm with IMS"));
+		return PJ_EINVAL;
+	    }
+
+	    /* Username for authentication must be in a@b format */
+	    if (strchr(acfg->cred_info[0].username.ptr, '@')==0) {
+		PJ_LOG(1,(THIS_FILE, 
+			  "Error: Username for authentication must "
+			  "be in user@domain format with IMS"));
+		return PJ_EINVAL;
+	    }
+	}
+    }
+    return PJ_SUCCESS;
+}
+
+/* Set default config. */
+static void default_config()
+{
+    char tmp[80];
+    unsigned i;
+    pjsua_app_config *cfg = &app_config;
+
+    pjsua_config_default(&cfg->cfg);
+    pj_ansi_sprintf(tmp, "PJSUA v%s %s", pj_get_version(),
+		    pj_get_sys_info()->info.ptr);
+    pj_strdup2_with_null(app_config.pool, &cfg->cfg.user_agent, tmp);
+
+    pjsua_logging_config_default(&cfg->log_cfg);
+    pjsua_media_config_default(&cfg->media_cfg);
+    pjsua_transport_config_default(&cfg->udp_cfg);
+    cfg->udp_cfg.port = 5060;
+    pjsua_transport_config_default(&cfg->rtp_cfg);
+    cfg->rtp_cfg.port = 4000;
+    cfg->redir_op = PJSIP_REDIRECT_ACCEPT_REPLACE;
+    cfg->duration = PJSUA_APP_NO_LIMIT_DURATION;
+    cfg->wav_id = PJSUA_INVALID_ID;
+    cfg->rec_id = PJSUA_INVALID_ID;
+    cfg->wav_port = PJSUA_INVALID_ID;
+    cfg->rec_port = PJSUA_INVALID_ID;
+    cfg->mic_level = cfg->speaker_level = 1.0;
+    cfg->capture_dev = PJSUA_INVALID_ID;
+    cfg->playback_dev = PJSUA_INVALID_ID;
+    cfg->capture_lat = PJMEDIA_SND_DEFAULT_REC_LATENCY;
+    cfg->playback_lat = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;
+    cfg->ringback_slot = PJSUA_INVALID_ID;
+    cfg->ring_slot = PJSUA_INVALID_ID;
+
+    for (i=0; i<PJ_ARRAY_SIZE(cfg->acc_cfg); ++i)
+	pjsua_acc_config_default(&cfg->acc_cfg[i]);
+
+    for (i=0; i<PJ_ARRAY_SIZE(cfg->buddy_cfg); ++i)
+	pjsua_buddy_config_default(&cfg->buddy_cfg[i]);
+    
+    cfg->vid.vcapture_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+    cfg->vid.vrender_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV;
+    cfg->aud_cnt = 1;
+
+    cfg->avi_def_idx = PJSUA_INVALID_ID;
+
+    cfg->use_cli = PJ_FALSE;
+    cfg->cli_cfg.cli_fe = CLI_FE_CONSOLE;
+    cfg->cli_cfg.telnet_cfg.port = 0;
+}
+
+static pj_status_t parse_config(int argc, char *argv[], pj_str_t *uri_arg)
+{
+    pj_status_t status;
+
+    /* Initialize default config */
+    default_config();
+
+    /* Parse the arguments */
+    status = parse_args(argc, argv, uri_arg);
+    return status;
+}
+
+pj_status_t load_config(int argc,
+			char **argv,
+			pj_str_t *uri_arg)
+{
+    pj_status_t status;
+    pj_bool_t use_cli = PJ_FALSE;
+    int cli_fe = 0;
+    pj_uint16_t cli_telnet_port = 0;
+
+    /** CLI options are not changable **/
+    if (app_running) {
+	use_cli = app_config.use_cli;
+	cli_fe = app_config.cli_cfg.cli_fe;
+	cli_telnet_port = app_config.cli_cfg.telnet_cfg.port;
+    }
+
+    status = parse_config(argc, argv, uri_arg);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    if (app_running) {    
+	app_config.use_cli = use_cli;
+	app_config.cli_cfg.cli_fe = cli_fe;
+	app_config.cli_cfg.telnet_cfg.port = cli_telnet_port;
+    }
+
+    return status;
+}
+
+/*
+ * Save account settings
+ */
+static void write_account_settings(int acc_index, pj_str_t *result)
+{
+    unsigned i;
+    char line[128];
+    pjsua_acc_config *acc_cfg = &app_config.acc_cfg[acc_index];
+
+
+    pj_ansi_sprintf(line, "\n#\n# Account %d:\n#\n", acc_index);
+    pj_strcat2(result, line);
+
+
+    /* Identity */
+    if (acc_cfg->id.slen) {
+	pj_ansi_sprintf(line, "--id %.*s\n",
+			(int)acc_cfg->id.slen,
+			acc_cfg->id.ptr);
+	pj_strcat2(result, line);
+    }
+
+    /* Registrar server */
+    if (acc_cfg->reg_uri.slen) {
+	pj_ansi_sprintf(line, "--registrar %.*s\n",
+			      (int)acc_cfg->reg_uri.slen,
+			      acc_cfg->reg_uri.ptr);
+	pj_strcat2(result, line);
+
+	pj_ansi_sprintf(line, "--reg-timeout %u\n",
+			      acc_cfg->reg_timeout);
+	pj_strcat2(result, line);
+    }
+
+    /* Contact */
+    if (acc_cfg->force_contact.slen) {
+	pj_ansi_sprintf(line, "--contact %.*s\n",
+			(int)acc_cfg->force_contact.slen,
+			acc_cfg->force_contact.ptr);
+	pj_strcat2(result, line);
+    }
+
+    /* Contact header parameters */
+    if (acc_cfg->contact_params.slen) {
+	pj_ansi_sprintf(line, "--contact-params %.*s\n",
+			(int)acc_cfg->contact_params.slen,
+			acc_cfg->contact_params.ptr);
+	pj_strcat2(result, line);
+    }
+
+    /* Contact URI parameters */
+    if (acc_cfg->contact_uri_params.slen) {
+	pj_ansi_sprintf(line, "--contact-uri-params %.*s\n",
+			(int)acc_cfg->contact_uri_params.slen,
+			acc_cfg->contact_uri_params.ptr);
+	pj_strcat2(result, line);
+    }
+
+    /*  */
+    if (acc_cfg->allow_contact_rewrite!=1)
+    {
+	pj_ansi_sprintf(line, "--auto-update-nat %i\n",
+			(int)acc_cfg->allow_contact_rewrite);
+	pj_strcat2(result, line);
+    }
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    /* SRTP */
+    if (acc_cfg->use_srtp) {
+	int use_srtp = (int)acc_cfg->use_srtp;
+	if (use_srtp == PJMEDIA_SRTP_OPTIONAL &&
+	    acc_cfg->srtp_optional_dup_offer)
+	{
+	    use_srtp = 3;
+	}
+	pj_ansi_sprintf(line, "--use-srtp %i\n", use_srtp);
+	pj_strcat2(result, line);
+    }
+    if (acc_cfg->srtp_secure_signaling !=
+	PJSUA_DEFAULT_SRTP_SECURE_SIGNALING)
+    {
+	pj_ansi_sprintf(line, "--srtp-secure %d\n",
+			acc_cfg->srtp_secure_signaling);
+	pj_strcat2(result, line);
+    }
+#endif
+
+    /* Proxy */
+    for (i=0; i<acc_cfg->proxy_cnt; ++i) {
+	pj_ansi_sprintf(line, "--proxy %.*s\n",
+			      (int)acc_cfg->proxy[i].slen,
+			      acc_cfg->proxy[i].ptr);
+	pj_strcat2(result, line);
+    }
+
+    /* Credentials */
+    for (i=0; i<acc_cfg->cred_count; ++i) {
+	if (acc_cfg->cred_info[i].realm.slen) {
+	    pj_ansi_sprintf(line, "--realm %.*s\n",
+				  (int)acc_cfg->cred_info[i].realm.slen,
+				  acc_cfg->cred_info[i].realm.ptr);
+	    pj_strcat2(result, line);
+	}
+
+	if (acc_cfg->cred_info[i].username.slen) {
+	    pj_ansi_sprintf(line, "--username %.*s\n",
+				  (int)acc_cfg->cred_info[i].username.slen,
+				  acc_cfg->cred_info[i].username.ptr);
+	    pj_strcat2(result, line);
+	}
+
+	if (acc_cfg->cred_info[i].data.slen) {
+	    pj_ansi_sprintf(line, "--password %.*s\n",
+				  (int)acc_cfg->cred_info[i].data.slen,
+				  acc_cfg->cred_info[i].data.ptr);
+	    pj_strcat2(result, line);
+	}
+
+	if (i != acc_cfg->cred_count - 1)
+	    pj_strcat2(result, "--next-cred\n");
+    }
+
+    /* reg-use-proxy */
+    if (acc_cfg->reg_use_proxy != 3) {
+	pj_ansi_sprintf(line, "--reg-use-proxy %d\n",
+			      acc_cfg->reg_use_proxy);
+	pj_strcat2(result, line);
+    }
+
+    /* rereg-delay */
+    if (acc_cfg->reg_retry_interval != PJSUA_REG_RETRY_INTERVAL) {
+	pj_ansi_sprintf(line, "--rereg-delay %d\n",
+		              acc_cfg->reg_retry_interval);
+	pj_strcat2(result, line);
+    }
+
+    /* 100rel extension */
+    if (acc_cfg->require_100rel) {
+	pj_strcat2(result, "--use-100rel\n");
+    }
+
+    /* Session Timer extension */
+    if (acc_cfg->use_timer) {
+	pj_ansi_sprintf(line, "--use-timer %d\n",
+			      acc_cfg->use_timer);
+	pj_strcat2(result, line);
+    }
+    if (acc_cfg->timer_setting.min_se != 90) {
+	pj_ansi_sprintf(line, "--timer-min-se %d\n",
+			      acc_cfg->timer_setting.min_se);
+	pj_strcat2(result, line);
+    }
+    if (acc_cfg->timer_setting.sess_expires != PJSIP_SESS_TIMER_DEF_SE) {
+	pj_ansi_sprintf(line, "--timer-se %d\n",
+			      acc_cfg->timer_setting.sess_expires);
+	pj_strcat2(result, line);
+    }
+
+    /* Publish */
+    if (acc_cfg->publish_enabled)
+	pj_strcat2(result, "--publish\n");
+
+    /* MWI */
+    if (acc_cfg->mwi_enabled)
+	pj_strcat2(result, "--mwi\n");
+
+    if (acc_cfg->sip_stun_use != PJSUA_STUN_USE_DEFAULT ||
+	acc_cfg->media_stun_use != PJSUA_STUN_USE_DEFAULT)
+    {
+	pj_strcat2(result, "--disable-stun\n");
+    }
+
+    /* Media Transport*/
+    if (acc_cfg->ice_cfg.enable_ice)
+	pj_strcat2(result, "--use-ice\n");
+
+    if (acc_cfg->ice_cfg.ice_opt.aggressive == PJ_FALSE)
+	pj_strcat2(result, "--ice-regular\n");
+
+    if (acc_cfg->turn_cfg.enable_turn)
+	pj_strcat2(result, "--use-turn\n");
+
+    if (acc_cfg->ice_cfg.ice_max_host_cands >= 0) {
+	pj_ansi_sprintf(line, "--ice_max_host_cands %d\n",
+	                acc_cfg->ice_cfg.ice_max_host_cands);
+	pj_strcat2(result, line);
+    }
+
+    if (acc_cfg->ice_cfg.ice_no_rtcp)
+	pj_strcat2(result, "--ice-no-rtcp\n");
+
+    if (acc_cfg->turn_cfg.turn_server.slen) {
+	pj_ansi_sprintf(line, "--turn-srv %.*s\n",
+			(int)acc_cfg->turn_cfg.turn_server.slen,
+			acc_cfg->turn_cfg.turn_server.ptr);
+	pj_strcat2(result, line);
+    }
+
+    if (acc_cfg->turn_cfg.turn_conn_type == PJ_TURN_TP_TCP)
+	pj_strcat2(result, "--turn-tcp\n");
+
+    if (acc_cfg->turn_cfg.turn_auth_cred.data.static_cred.username.slen) {
+	pj_ansi_sprintf(line, "--turn-user %.*s\n",
+			(int)acc_cfg->turn_cfg.turn_auth_cred.data.static_cred.username.slen,
+			acc_cfg->turn_cfg.turn_auth_cred.data.static_cred.username.ptr);
+	pj_strcat2(result, line);
+    }
+
+    if (acc_cfg->turn_cfg.turn_auth_cred.data.static_cred.data.slen) {
+	pj_ansi_sprintf(line, "--turn-passwd %.*s\n",
+			(int)acc_cfg->turn_cfg.turn_auth_cred.data.static_cred.data.slen,
+			acc_cfg->turn_cfg.turn_auth_cred.data.static_cred.data.ptr);
+	pj_strcat2(result, line);
+    }
+}
+
+/*
+ * Write settings.
+ */
+int write_settings(pjsua_app_config *config, char *buf, pj_size_t max)
+{
+    unsigned acc_index;
+    unsigned i;
+    pj_str_t cfg;
+    char line[128];
+    extern pj_bool_t pjsip_use_compact_form;
+
+    PJ_UNUSED_ARG(max);
+
+    cfg.ptr = buf;
+    cfg.slen = 0;
+
+    /* Logging. */
+    pj_strcat2(&cfg, "#\n# Logging options:\n#\n");
+    pj_ansi_sprintf(line, "--log-level %d\n",
+		    config->log_cfg.level);
+    pj_strcat2(&cfg, line);
+
+    pj_ansi_sprintf(line, "--app-log-level %d\n",
+		    config->log_cfg.console_level);
+    pj_strcat2(&cfg, line);
+
+    if (config->log_cfg.log_filename.slen) {
+	pj_ansi_sprintf(line, "--log-file %.*s\n",
+			(int)config->log_cfg.log_filename.slen,
+			config->log_cfg.log_filename.ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+    if (config->log_cfg.log_file_flags & PJ_O_APPEND) {
+	pj_strcat2(&cfg, "--log-append\n");
+    }
+
+    /* Save account settings. */
+    for (acc_index=0; acc_index < config->acc_cnt; ++acc_index) {
+
+	write_account_settings(acc_index, &cfg);
+
+	if (acc_index < config->acc_cnt-1)
+	    pj_strcat2(&cfg, "--next-account\n");
+    }
+
+    pj_strcat2(&cfg, "\n#\n# Network settings:\n#\n");
+
+    /* Nameservers */
+    for (i=0; i<config->cfg.nameserver_count; ++i) {
+	pj_ansi_sprintf(line, "--nameserver %.*s\n",
+			      (int)config->cfg.nameserver[i].slen,
+			      config->cfg.nameserver[i].ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* Outbound proxy */
+    for (i=0; i<config->cfg.outbound_proxy_cnt; ++i) {
+	pj_ansi_sprintf(line, "--outbound %.*s\n",
+			      (int)config->cfg.outbound_proxy[i].slen,
+			      config->cfg.outbound_proxy[i].ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* Transport options */
+    if (config->ipv6) {
+	pj_strcat2(&cfg, "--ipv6\n");
+    }
+    if (config->enable_qos) {
+	pj_strcat2(&cfg, "--set-qos\n");
+    }
+
+    /* UDP Transport. */
+    pj_ansi_sprintf(line, "--local-port %d\n", config->udp_cfg.port);
+    pj_strcat2(&cfg, line);
+
+    /* IP address, if any. */
+    if (config->udp_cfg.public_addr.slen) {
+	pj_ansi_sprintf(line, "--ip-addr %.*s\n",
+			(int)config->udp_cfg.public_addr.slen,
+			config->udp_cfg.public_addr.ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* Bound IP address, if any. */
+    if (config->udp_cfg.bound_addr.slen) {
+	pj_ansi_sprintf(line, "--bound-addr %.*s\n",
+			(int)config->udp_cfg.bound_addr.slen,
+			config->udp_cfg.bound_addr.ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* No TCP ? */
+    if (config->no_tcp) {
+	pj_strcat2(&cfg, "--no-tcp\n");
+    }
+
+    /* No UDP ? */
+    if (config->no_udp) {
+	pj_strcat2(&cfg, "--no-udp\n");
+    }
+
+    /* STUN */
+    for (i=0; i<config->cfg.stun_srv_cnt; ++i) {
+	pj_ansi_sprintf(line, "--stun-srv %.*s\n",
+			(int)config->cfg.stun_srv[i].slen,
+			config->cfg.stun_srv[i].ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
+    /* TLS */
+    if (config->use_tls)
+	pj_strcat2(&cfg, "--use-tls\n");
+    if (config->udp_cfg.tls_setting.ca_list_file.slen) {
+	pj_ansi_sprintf(line, "--tls-ca-file %.*s\n",
+			(int)config->udp_cfg.tls_setting.ca_list_file.slen,
+			config->udp_cfg.tls_setting.ca_list_file.ptr);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->udp_cfg.tls_setting.cert_file.slen) {
+	pj_ansi_sprintf(line, "--tls-cert-file %.*s\n",
+			(int)config->udp_cfg.tls_setting.cert_file.slen,
+			config->udp_cfg.tls_setting.cert_file.ptr);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->udp_cfg.tls_setting.privkey_file.slen) {
+	pj_ansi_sprintf(line, "--tls-privkey-file %.*s\n",
+			(int)config->udp_cfg.tls_setting.privkey_file.slen,
+			config->udp_cfg.tls_setting.privkey_file.ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+    if (config->udp_cfg.tls_setting.password.slen) {
+	pj_ansi_sprintf(line, "--tls-password %.*s\n",
+			(int)config->udp_cfg.tls_setting.password.slen,
+			config->udp_cfg.tls_setting.password.ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+    if (config->udp_cfg.tls_setting.verify_server)
+	pj_strcat2(&cfg, "--tls-verify-server\n");
+
+    if (config->udp_cfg.tls_setting.verify_client)
+	pj_strcat2(&cfg, "--tls-verify-client\n");
+
+    if (config->udp_cfg.tls_setting.timeout.sec) {
+	pj_ansi_sprintf(line, "--tls-neg-timeout %d\n",
+			(int)config->udp_cfg.tls_setting.timeout.sec);
+	pj_strcat2(&cfg, line);
+    }
+
+    for (i=0; i<config->udp_cfg.tls_setting.ciphers_num; ++i) {
+	pj_ansi_sprintf(line, "--tls-cipher 0x%06X # %s\n",
+			config->udp_cfg.tls_setting.ciphers[i],
+			pj_ssl_cipher_name(config->udp_cfg.tls_setting.ciphers[i]));
+	pj_strcat2(&cfg, line);
+    }
+#endif
+
+    pj_strcat2(&cfg, "\n#\n# Media settings:\n#\n");
+
+    /* Video & extra audio */
+    for (i=0; i<config->vid.vid_cnt; ++i) {
+	pj_strcat2(&cfg, "--video\n");
+    }
+    for (i=1; i<config->aud_cnt; ++i) {
+	pj_strcat2(&cfg, "--extra-audio\n");
+    }
+
+    /* SRTP */
+#if PJMEDIA_HAS_SRTP
+    if (app_config.cfg.use_srtp != PJSUA_DEFAULT_USE_SRTP) {
+	int use_srtp = (int)app_config.cfg.use_srtp;
+	if (use_srtp == PJMEDIA_SRTP_OPTIONAL &&
+	    app_config.cfg.srtp_optional_dup_offer)
+	{
+	    use_srtp = 3;
+	}
+	pj_ansi_sprintf(line, "--use-srtp %d\n", use_srtp);
+	pj_strcat2(&cfg, line);
+    }
+    if (app_config.cfg.srtp_secure_signaling !=
+	PJSUA_DEFAULT_SRTP_SECURE_SIGNALING)
+    {
+	pj_ansi_sprintf(line, "--srtp-secure %d\n",
+			app_config.cfg.srtp_secure_signaling);
+	pj_strcat2(&cfg, line);
+    }
+#endif
+
+    /* Media */
+    if (config->null_audio)
+	pj_strcat2(&cfg, "--null-audio\n");
+    if (config->auto_play)
+	pj_strcat2(&cfg, "--auto-play\n");
+    if (config->auto_loop)
+	pj_strcat2(&cfg, "--auto-loop\n");
+    if (config->auto_conf)
+	pj_strcat2(&cfg, "--auto-conf\n");
+    for (i=0; i<config->wav_count; ++i) {
+	pj_ansi_sprintf(line, "--play-file %s\n",
+			config->wav_files[i].ptr);
+	pj_strcat2(&cfg, line);
+    }
+    for (i=0; i<config->tone_count; ++i) {
+	pj_ansi_sprintf(line, "--play-tone %d,%d,%d,%d\n",
+			config->tones[i].freq1, config->tones[i].freq2,
+			config->tones[i].on_msec, config->tones[i].off_msec);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->rec_file.slen) {
+	pj_ansi_sprintf(line, "--rec-file %s\n",
+			config->rec_file.ptr);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->auto_rec)
+	pj_strcat2(&cfg, "--auto-rec\n");
+    if (config->capture_dev != PJSUA_INVALID_ID) {
+	pj_ansi_sprintf(line, "--capture-dev %d\n", config->capture_dev);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->playback_dev != PJSUA_INVALID_ID) {
+	pj_ansi_sprintf(line, "--playback-dev %d\n", config->playback_dev);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->media_cfg.snd_auto_close_time != -1) {
+	pj_ansi_sprintf(line, "--snd-auto-close %d\n",
+			config->media_cfg.snd_auto_close_time);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->no_tones) {
+	pj_strcat2(&cfg, "--no-tones\n");
+    }
+    if (config->media_cfg.jb_max != -1) {
+	pj_ansi_sprintf(line, "--jb-max-size %d\n",
+			config->media_cfg.jb_max);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* Sound device latency */
+    if (config->capture_lat != PJMEDIA_SND_DEFAULT_REC_LATENCY) {
+	pj_ansi_sprintf(line, "--capture-lat %d\n", config->capture_lat);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->playback_lat != PJMEDIA_SND_DEFAULT_PLAY_LATENCY) {
+	pj_ansi_sprintf(line, "--playback-lat %d\n", config->playback_lat);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* Media clock rate. */
+    if (config->media_cfg.clock_rate != PJSUA_DEFAULT_CLOCK_RATE) {
+	pj_ansi_sprintf(line, "--clock-rate %d\n",
+			config->media_cfg.clock_rate);
+	pj_strcat2(&cfg, line);
+    } else {
+	pj_ansi_sprintf(line, "#using default --clock-rate %d\n",
+			config->media_cfg.clock_rate);
+	pj_strcat2(&cfg, line);
+    }
+
+    if (config->media_cfg.snd_clock_rate &&
+	config->media_cfg.snd_clock_rate != config->media_cfg.clock_rate)
+    {
+	pj_ansi_sprintf(line, "--snd-clock-rate %d\n",
+			config->media_cfg.snd_clock_rate);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* Stereo mode. */
+    if (config->media_cfg.channel_count == 2) {
+	pj_ansi_sprintf(line, "--stereo\n");
+	pj_strcat2(&cfg, line);
+    }
+
+    /* quality */
+    if (config->media_cfg.quality != PJSUA_DEFAULT_CODEC_QUALITY) {
+	pj_ansi_sprintf(line, "--quality %d\n",
+			config->media_cfg.quality);
+	pj_strcat2(&cfg, line);
+    } else {
+	pj_ansi_sprintf(line, "#using default --quality %d\n",
+			config->media_cfg.quality);
+	pj_strcat2(&cfg, line);
+    }
+
+    if (config->vid.vcapture_dev != PJMEDIA_VID_DEFAULT_CAPTURE_DEV) {
+	pj_ansi_sprintf(line, "--vcapture-dev %d\n", config->vid.vcapture_dev);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->vid.vrender_dev != PJMEDIA_VID_DEFAULT_RENDER_DEV) {
+	pj_ansi_sprintf(line, "--vrender-dev %d\n", config->vid.vrender_dev);
+	pj_strcat2(&cfg, line);
+    }
+    for (i=0; i<config->avi_cnt; ++i) {
+	pj_ansi_sprintf(line, "--play-avi %s\n", config->avi[i].path.ptr);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->avi_auto_play) {
+	pj_ansi_sprintf(line, "--auto-play-avi\n");
+	pj_strcat2(&cfg, line);
+    }
+
+    /* ptime */
+    if (config->media_cfg.ptime) {
+	pj_ansi_sprintf(line, "--ptime %d\n",
+			config->media_cfg.ptime);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* no-vad */
+    if (config->media_cfg.no_vad) {
+	pj_strcat2(&cfg, "--no-vad\n");
+    }
+
+    /* ec-tail */
+    if (config->media_cfg.ec_tail_len != PJSUA_DEFAULT_EC_TAIL_LEN) {
+	pj_ansi_sprintf(line, "--ec-tail %d\n",
+			config->media_cfg.ec_tail_len);
+	pj_strcat2(&cfg, line);
+    } else {
+	pj_ansi_sprintf(line, "#using default --ec-tail %d\n",
+			config->media_cfg.ec_tail_len);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* ec-opt */
+    if (config->media_cfg.ec_options != 0) {
+	pj_ansi_sprintf(line, "--ec-opt %d\n",
+			config->media_cfg.ec_options);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* ilbc-mode */
+    if (config->media_cfg.ilbc_mode != PJSUA_DEFAULT_ILBC_MODE) {
+	pj_ansi_sprintf(line, "--ilbc-mode %d\n",
+			config->media_cfg.ilbc_mode);
+	pj_strcat2(&cfg, line);
+    } else {
+	pj_ansi_sprintf(line, "#using default --ilbc-mode %d\n",
+			config->media_cfg.ilbc_mode);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* RTP drop */
+    if (config->media_cfg.tx_drop_pct) {
+	pj_ansi_sprintf(line, "--tx-drop-pct %d\n",
+			config->media_cfg.tx_drop_pct);
+	pj_strcat2(&cfg, line);
+
+    }
+    if (config->media_cfg.rx_drop_pct) {
+	pj_ansi_sprintf(line, "--rx-drop-pct %d\n",
+			config->media_cfg.rx_drop_pct);
+	pj_strcat2(&cfg, line);
+
+    }
+
+    /* Start RTP port. */
+    pj_ansi_sprintf(line, "--rtp-port %d\n",
+		    config->rtp_cfg.port);
+    pj_strcat2(&cfg, line);
+
+    /* Disable codec */
+    for (i=0; i<config->codec_dis_cnt; ++i) {
+	pj_ansi_sprintf(line, "--dis-codec %s\n",
+		    config->codec_dis[i].ptr);
+	pj_strcat2(&cfg, line);
+    }
+    /* Add codec. */
+    for (i=0; i<config->codec_cnt; ++i) {
+	pj_ansi_sprintf(line, "--add-codec %s\n",
+		    config->codec_arg[i].ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+    pj_strcat2(&cfg, "\n#\n# User agent:\n#\n");
+
+    /* Auto-answer. */
+    if (config->auto_answer != 0) {
+	pj_ansi_sprintf(line, "--auto-answer %d\n",
+			config->auto_answer);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* accept-redirect */
+    if (config->redir_op != PJSIP_REDIRECT_ACCEPT_REPLACE) {
+	pj_ansi_sprintf(line, "--accept-redirect %d\n",
+			config->redir_op);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* Max calls. */
+    pj_ansi_sprintf(line, "--max-calls %d\n",
+		    config->cfg.max_calls);
+    pj_strcat2(&cfg, line);
+
+    /* Uas-duration. */
+    if (config->duration != PJSUA_APP_NO_LIMIT_DURATION) {
+	pj_ansi_sprintf(line, "--duration %d\n",
+			config->duration);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* norefersub ? */
+    if (config->no_refersub) {
+	pj_strcat2(&cfg, "--norefersub\n");
+    }
+
+    if (pjsip_use_compact_form)
+    {
+	pj_strcat2(&cfg, "--use-compact-form\n");
+    }
+
+    if (!config->cfg.force_lr) {
+	pj_strcat2(&cfg, "--no-force-lr\n");
+    }
+
+    pj_strcat2(&cfg, "\n#\n# Buddies:\n#\n");
+
+    /* Add buddies. */
+    for (i=0; i<config->buddy_cnt; ++i) {
+	pj_ansi_sprintf(line, "--add-buddy %.*s\n",
+			      (int)config->buddy_cfg[i].uri.slen,
+			      config->buddy_cfg[i].uri.ptr);
+	pj_strcat2(&cfg, line);
+    }
+
+    /* SIP extensions. */
+    pj_strcat2(&cfg, "\n#\n# SIP extensions:\n#\n");
+    /* 100rel extension */
+    if (config->cfg.require_100rel) {
+	pj_strcat2(&cfg, "--use-100rel\n");
+    }
+    /* Session Timer extension */
+    if (config->cfg.use_timer) {
+	pj_ansi_sprintf(line, "--use-timer %d\n",
+			      config->cfg.use_timer);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->cfg.timer_setting.min_se != 90) {
+	pj_ansi_sprintf(line, "--timer-min-se %d\n",
+			      config->cfg.timer_setting.min_se);
+	pj_strcat2(&cfg, line);
+    }
+    if (config->cfg.timer_setting.sess_expires != PJSIP_SESS_TIMER_DEF_SE) {
+	pj_ansi_sprintf(line, "--timer-se %d\n",
+			      config->cfg.timer_setting.sess_expires);
+	pj_strcat2(&cfg, line);
+    }
+
+    *(cfg.ptr + cfg.slen) = '\0';
+    return (int)cfg.slen;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_config.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_config.h
new file mode 100644
index 0000000..216757f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_config.h
@@ -0,0 +1,48 @@
+/* $Id: pjsua_app_config.h 4492 2013-04-23 10:59:52Z nanang $ */
+/*
+ * Copyright (C) 2008-2013 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 __PJSUA_APP_CONFIG_H__
+#define __PJSUA_APP_CONFIG_H__
+
+#include <pjlib.h>
+
+/* This file defines the default app config. It's used by pjsua
+ * *mobile* version only. If you're porting pjsua to new mobile
+ * platform, you should only include this file once in one of
+ * your source file.
+ */
+const char *pjsua_app_def_argv[] = { "pjsua",
+				     "--use-cli",
+				     "--no-cli-console",
+#if defined(PJ_SYMBIAN) && PJ_SYMBIAN
+				     /* Can't reuse address on E52 */
+				     "--cli-telnet-port=0",
+#else
+				     "--cli-telnet-port=2323",
+#endif
+				     "--quality=4",
+#if defined(PJ_CONFIG_BB10) && PJ_CONFIG_BB10
+			             "--add-buddy=sip:169.254.0.2",
+#endif
+			             NULL };
+
+#define pjsua_app_def_argc (PJ_ARRAY_SIZE(pjsua_app_def_argv)-1)
+
+
+#endif	/* __PJSUA_APP_CONFIG_H__ */
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_legacy.c b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_legacy.c
new file mode 100644
index 0000000..a77e1bf
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/pjsua_app_legacy.c
@@ -0,0 +1,1933 @@
+/* $Id: pjsua_app_legacy.c 4710 2014-01-22 10:51:49Z bennylp $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 <pjsua-lib/pjsua.h>
+#include "pjsua_app_common.h"
+
+#define THIS_FILE	"pjsua_app_legacy.c"
+
+static pj_bool_t	cmd_echo;
+
+/*
+ * Print buddy list.
+ */
+static void print_buddy_list()
+{
+    pjsua_buddy_id ids[64];
+    int i;
+    unsigned count = PJ_ARRAY_SIZE(ids);
+
+    puts("Buddy list:");
+
+    pjsua_enum_buddies(ids, &count);
+
+    if (count == 0)
+	puts(" -none-");
+    else {
+	for (i=0; i<(int)count; ++i) {
+	    pjsua_buddy_info info;
+
+	    if (pjsua_buddy_get_info(ids[i], &info) != PJ_SUCCESS)
+		continue;
+
+	    printf(" [%2d] <%.*s>  %.*s\n", 
+		    ids[i]+1, 
+		    (int)info.status_text.slen,
+		    info.status_text.ptr, 
+		    (int)info.uri.slen,
+		    info.uri.ptr);
+	}
+    }
+    puts("");
+}
+
+/*
+ * Input URL.
+ */
+static void ui_input_url(const char *title, char *buf, pj_size_t len, 
+			 input_result *result)
+{
+    result->nb_result = PJSUA_APP_NO_NB;
+    result->uri_result = NULL;
+
+    print_buddy_list();
+
+    printf("Choices:\n"
+	   "   0         For current dialog.\n"
+	   "  -1         All %d buddies in buddy list\n"
+	   "  [1 -%2d]    Select from buddy list\n"
+	   "  URL        An URL\n"
+	   "  <Enter>    Empty input (or 'q') to cancel\n"
+	   , pjsua_get_buddy_count(), pjsua_get_buddy_count());
+    printf("%s: ", title);
+
+    fflush(stdout);
+    if (fgets(buf, (int)len, stdin) == NULL)
+	return;
+    len = strlen(buf);
+
+    /* Left trim */
+    while (pj_isspace(*buf)) {
+	++buf;
+	--len;
+    }
+
+    /* Remove trailing newlines */
+    while (len && (buf[len-1] == '\r' || buf[len-1] == '\n'))
+	buf[--len] = '\0';
+
+    if (len == 0 || buf[0]=='q')
+	return;
+
+    if (pj_isdigit(*buf) || *buf=='-') {
+	
+	unsigned i;
+	
+	if (*buf=='-')
+	    i = 1;
+	else
+	    i = 0;
+
+	for (; i<len; ++i) {
+	    if (!pj_isdigit(buf[i])) {
+		puts("Invalid input");
+		return;
+	    }
+	}
+
+	result->nb_result = my_atoi(buf);
+
+	if (result->nb_result >= 0 && 
+	    result->nb_result <= (int)pjsua_get_buddy_count()) 
+	{
+	    return;
+	}
+	if (result->nb_result == -1)
+	    return;
+
+	puts("Invalid input");
+	result->nb_result = PJSUA_APP_NO_NB;
+	return;
+
+    } else {
+	pj_status_t status;
+
+	if ((status=pjsua_verify_url(buf)) != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Invalid URL", status);
+	    return;
+	}
+
+	result->uri_result = buf;
+    }
+}
+
+static pj_bool_t simple_input(const char *title, char *buf, pj_size_t len)
+{
+    char *p;
+
+    printf("%s (empty to cancel): ", title); fflush(stdout);
+    if (fgets(buf, (int)len, stdin) == NULL)
+	return PJ_FALSE;
+
+    /* Remove trailing newlines. */
+    for (p=buf; ; ++p) {
+	if (*p=='\r' || *p=='\n') *p='\0';
+	else if (!*p) break;
+    }
+
+    if (!*buf)
+	return PJ_FALSE;
+    
+    return PJ_TRUE;
+}
+
+/*
+ * Print account status.
+ */
+static void print_acc_status(int acc_id)
+{
+    char buf[80];
+    pjsua_acc_info info;
+
+    pjsua_acc_get_info(acc_id, &info);
+
+    if (!info.has_registration) {
+	pj_ansi_snprintf(buf, sizeof(buf), "%.*s", 
+			 (int)info.status_text.slen,
+			 info.status_text.ptr);
+
+    } else {
+	pj_ansi_snprintf(buf, sizeof(buf),
+			 "%d/%.*s (expires=%d)",
+			 info.status,
+			 (int)info.status_text.slen,
+			 info.status_text.ptr,
+			 info.expires);
+
+    }
+
+    printf(" %c[%2d] %.*s: %s\n", (acc_id==current_acc?'*':' '),
+	   acc_id,  (int)info.acc_uri.slen, info.acc_uri.ptr, buf);
+    printf("       Online status: %.*s\n", 
+	(int)info.online_status_text.slen,
+	info.online_status_text.ptr);
+}
+
+/*
+ * Show a bit of help.
+ */
+static void keystroke_help()
+{
+    pjsua_acc_id acc_ids[16];
+    unsigned count = PJ_ARRAY_SIZE(acc_ids);
+    int i;
+
+    printf(">>>>\n");
+
+    pjsua_enum_accs(acc_ids, &count);
+
+    printf("Account list:\n");
+    for (i=0; i<(int)count; ++i)
+	print_acc_status(acc_ids[i]);
+
+    print_buddy_list();
+    
+    //puts("Commands:");
+    puts("+=============================================================================+");
+    puts("|       Call Commands:         |   Buddy, IM & Presence:  |     Account:      |");
+    puts("|                              |                          |                   |");
+    puts("|  m  Make new call            | +b  Add new buddy       .| +a  Add new accnt |");
+    puts("|  M  Make multiple calls      | -b  Delete buddy         | -a  Delete accnt. |");
+    puts("|  a  Answer call              |  i  Send IM              | !a  Modify accnt. |");
+    puts("|  h  Hangup call  (ha=all)    |  s  Subscribe presence   | rr  (Re-)register |");
+    puts("|  H  Hold call                |  u  Unsubscribe presence | ru  Unregister    |");
+    puts("|  v  re-inVite (release hold) |  t  ToGgle Online status |  >  Cycle next ac.|");
+    puts("|  U  send UPDATE              |  T  Set online status    |  <  Cycle prev ac.|");
+    puts("| ],[ Select next/prev call    +--------------------------+-------------------+");
+    puts("|  x  Xfer call                |      Media Commands:     |  Status & Config: |");
+    puts("|  X  Xfer with Replaces       |                          |                   |");
+    puts("|  #  Send RFC 2833 DTMF       | cl  List ports           |  d  Dump status   |");
+    puts("|  *  Send DTMF with INFO      | cc  Connect port         | dd  Dump detailed |");
+    puts("| dq  Dump curr. call quality  | cd  Disconnect port      | dc  Dump config   |");
+    puts("|                              |  V  Adjust audio Volume  |  f  Save config   |");
+    puts("|  S  Send arbitrary REQUEST   | Cp  Codec priorities     |                   |");
+    puts("+-----------------------------------------------------------------------------+");
+#if PJSUA_HAS_VIDEO
+    puts("| Video: \"vid help\" for more info                                             |");
+    puts("+-----------------------------------------------------------------------------+");
+#endif
+    puts("|  q  QUIT   L  ReLoad   sleep MS   echo [0|1|txt]     n: detect NAT type     |");
+    puts("+=============================================================================+");
+
+    i = pjsua_call_get_count();
+    printf("You have %d active call%s\n", i, (i>1?"s":""));
+
+    if (current_call != PJSUA_INVALID_ID) {
+	pjsua_call_info ci;
+	if (pjsua_call_get_info(current_call, &ci)==PJ_SUCCESS)
+	    printf("Current call id=%d to %.*s [%.*s]\n", current_call,
+		   (int)ci.remote_info.slen, ci.remote_info.ptr,
+		   (int)ci.state_text.slen, ci.state_text.ptr);
+    }
+}
+
+/* Help screen for video */
+#if PJSUA_HAS_VIDEO
+static void vid_show_help()
+{
+    pj_bool_t vid_enabled = (app_config.vid.vid_cnt > 0);
+
+    puts("+=============================================================================+");
+    puts("|                            Video commands:                                  |");
+    puts("|                                                                             |");
+    puts("| vid help                  Show this help screen                             |");
+    puts("| vid enable|disable        Enable or disable video in next offer/answer      |");
+    puts("| vid acc show              Show current account video settings               |");
+    puts("| vid acc autorx on|off     Automatically show incoming video on/off          |");
+    puts("| vid acc autotx on|off     Automatically offer video on/off                  |");
+    puts("| vid acc cap ID            Set default capture device for current acc        |");
+    puts("| vid acc rend ID           Set default renderer device for current acc       |");
+    puts("| vid call rx on|off N      Enable/disable video RX for stream N in curr call |");
+    puts("| vid call tx on|off N      Enable/disable video TX for stream N in curr call |");
+    puts("| vid call add              Add video stream for current call                 |");
+    puts("| vid call enable|disable N Enable/disable stream #N in current call          |");
+    puts("| vid call cap N ID         Set capture dev ID for stream #N in current call  |");
+    puts("| vid dev list              List all video devices                            |");
+    puts("| vid dev refresh           Refresh video device list                         |");
+    puts("| vid dev prev on|off ID    Enable/disable preview for specified device ID    |");
+    puts("| vid codec list            List video codecs                                 |");
+    puts("| vid codec prio ID PRIO    Set codec ID priority to PRIO                     |");
+    puts("| vid codec fps ID NUM DEN  Set codec ID framerate to (NUM/DEN) fps           |");
+    puts("| vid codec bw ID AVG MAX   Set codec ID bitrate to AVG & MAX kbps            |");
+    puts("| vid codec size ID W H     Set codec ID size/resolution to W x H             |");
+    puts("| vid win list              List all active video windows                     |");
+    puts("| vid win arrange           Auto arrange windows                              |");
+    puts("| vid win show|hide ID      Show/hide the specified video window ID           |");
+    puts("| vid win move ID X Y       Move window ID to position X,Y                    |");
+    puts("| vid win resize ID w h     Resize window ID to the specified width, height   |");
+    puts("+=============================================================================+");
+    printf("| Video will be %s in the next offer/answer %s                            |\n",
+	   (vid_enabled? "enabled" : "disabled"), (vid_enabled? " " : ""));
+    puts("+=============================================================================+");
+}
+
+static void vid_handle_menu(char *menuin)
+{
+    char *argv[8];
+    int argc = 0;
+
+    /* Tokenize */
+    argv[argc] = strtok(menuin, " \t\r\n");
+    while (argv[argc] && *argv[argc]) {
+	argc++;
+	argv[argc] = strtok(NULL, " \t\r\n");
+    }
+
+    if (argc == 1 || strcmp(argv[1], "help")==0) {
+	vid_show_help();
+    } else if (argc == 2 && (strcmp(argv[1], "enable")==0 ||
+			     strcmp(argv[1], "disable")==0))
+    {
+	pj_bool_t enabled = (strcmp(argv[1], "enable")==0);
+	app_config.vid.vid_cnt = (enabled ? 1 : 0);
+	PJ_LOG(3,(THIS_FILE, "Video will be %s in next offer/answer",
+		  (enabled?"enabled":"disabled")));
+    } else if (strcmp(argv[1], "acc")==0) {
+	pjsua_acc_config acc_cfg;
+	pj_bool_t changed = PJ_FALSE;
+	pj_pool_t *tmp_pool = pjsua_pool_create("tmp-pjsua", 1000, 1000);
+
+	pjsua_acc_get_config(current_acc, tmp_pool, &acc_cfg);
+
+	if (argc == 3 && strcmp(argv[2], "show")==0) {
+	    app_config_show_video(current_acc, &acc_cfg);
+	} else if (argc == 4 && strcmp(argv[2], "autorx")==0) {
+	    int on = (strcmp(argv[3], "on")==0);
+	    acc_cfg.vid_in_auto_show = on;
+	    changed = PJ_TRUE;
+	} else if (argc == 4 && strcmp(argv[2], "autotx")==0) {
+	    int on = (strcmp(argv[3], "on")==0);
+	    acc_cfg.vid_out_auto_transmit = on;
+	    changed = PJ_TRUE;
+	} else if (argc == 4 && strcmp(argv[2], "cap")==0) {
+	    int dev = atoi(argv[3]);
+	    acc_cfg.vid_cap_dev = dev;
+	    changed = PJ_TRUE;
+	} else if (argc == 4 && strcmp(argv[2], "rend")==0) {
+	    int dev = atoi(argv[3]);
+	    acc_cfg.vid_rend_dev = dev;
+	    changed = PJ_TRUE;
+	} else {
+	    pj_pool_release(tmp_pool);
+	    goto on_error;
+	}
+
+	if (changed) {
+	    pj_status_t status = pjsua_acc_modify(current_acc, &acc_cfg);
+	    if (status != PJ_SUCCESS)
+		PJ_PERROR(1,(THIS_FILE, status, "Error modifying account %d",
+			     current_acc));
+	}
+	pj_pool_release(tmp_pool);
+
+    } else if (strcmp(argv[1], "call")==0) {
+	pjsua_call_vid_strm_op_param param;
+	pj_status_t status = PJ_SUCCESS;
+
+	pjsua_call_vid_strm_op_param_default(&param);
+
+	if (argc == 5 && strcmp(argv[2], "rx")==0) {
+	    pjsua_stream_info si;
+	    pj_bool_t on = (strcmp(argv[3], "on") == 0);
+
+	    param.med_idx = atoi(argv[4]);
+	    if (pjsua_call_get_stream_info(current_call, param.med_idx, &si) ||
+		si.type != PJMEDIA_TYPE_VIDEO)
+	    {
+		PJ_PERROR(1,(THIS_FILE, PJ_EINVAL, "Invalid stream"));
+		return;
+	    }
+
+	    if (on) param.dir = (si.info.vid.dir | PJMEDIA_DIR_DECODING);
+	    else param.dir = (si.info.vid.dir & PJMEDIA_DIR_ENCODING);
+
+	    status = pjsua_call_set_vid_strm(current_call,
+	                                     PJSUA_CALL_VID_STRM_CHANGE_DIR,
+	                                     &param);
+	}
+	else if (argc == 5 && strcmp(argv[2], "tx")==0) {
+	    pj_bool_t on = (strcmp(argv[3], "on") == 0);
+	    pjsua_call_vid_strm_op op = on? PJSUA_CALL_VID_STRM_START_TRANSMIT :
+					    PJSUA_CALL_VID_STRM_STOP_TRANSMIT;
+
+	    param.med_idx = atoi(argv[4]);
+
+	    status = pjsua_call_set_vid_strm(current_call, op, &param);
+	}
+	else if (argc == 3 && strcmp(argv[2], "add")==0) {
+	    status = pjsua_call_set_vid_strm(current_call,
+	                                     PJSUA_CALL_VID_STRM_ADD, NULL);
+	}
+	else if (argc >= 3 && 
+		 (strcmp(argv[2], "disable")==0 || strcmp(argv[2], "enable")==0))
+	{
+	    pj_bool_t enable = (strcmp(argv[2], "enable") == 0);
+	    pjsua_call_vid_strm_op op = enable? PJSUA_CALL_VID_STRM_CHANGE_DIR :
+						PJSUA_CALL_VID_STRM_REMOVE;
+
+	    param.med_idx = argc >= 4? atoi(argv[3]) : -1;
+	    param.dir = PJMEDIA_DIR_ENCODING_DECODING;
+	    status = pjsua_call_set_vid_strm(current_call, op, &param);
+	}
+	else if (argc >= 3 && strcmp(argv[2], "cap")==0) {
+	    param.med_idx = argc >= 4? atoi(argv[3]) : -1;
+	    param.cap_dev = argc >= 5? atoi(argv[4]) : PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+	    status = pjsua_call_set_vid_strm(current_call,
+	                                     PJSUA_CALL_VID_STRM_CHANGE_CAP_DEV,
+	                                     &param);
+	} else
+	    goto on_error;
+
+	if (status != PJ_SUCCESS) {
+	    PJ_PERROR(1,(THIS_FILE, status, "Error modifying video stream"));
+	}
+
+    } else if (argc >= 3 && strcmp(argv[1], "dev")==0) {
+	if (strcmp(argv[2], "list")==0) {
+	    vid_list_devs();
+	} else if (strcmp(argv[2], "refresh")==0) {
+	    pjmedia_vid_dev_refresh();
+	} else if (strcmp(argv[2], "prev")==0) {
+	    if (argc != 5) {
+		goto on_error;
+	    } else {
+		pj_bool_t on = (strcmp(argv[3], "on") == 0);
+		int dev_id = atoi(argv[4]);
+		if (on) {
+                    pjsua_vid_preview_param param;
+
+                    pjsua_vid_preview_param_default(&param);
+                    param.wnd_flags = PJMEDIA_VID_DEV_WND_BORDER |
+                                      PJMEDIA_VID_DEV_WND_RESIZABLE;
+		    pjsua_vid_preview_start(dev_id, &param);
+		    arrange_window(pjsua_vid_preview_get_win(dev_id));
+		} else {
+		    pjsua_vid_win_id wid;
+		    wid = pjsua_vid_preview_get_win(dev_id);
+		    if (wid != PJSUA_INVALID_ID) {
+			/* Preview window hiding once it is stopped is
+			 * responsibility of app */
+			pjsua_vid_win_set_show(wid, PJ_FALSE);
+			pjsua_vid_preview_stop(dev_id);
+		    }
+		}
+	    }
+	} else
+	    goto on_error;
+    } else if (strcmp(argv[1], "win")==0) {
+	pj_status_t status = PJ_SUCCESS;
+
+	if (argc==3 && strcmp(argv[2], "list")==0) {
+	    pjsua_vid_win_id wids[PJSUA_MAX_VID_WINS];
+	    unsigned i, cnt = PJ_ARRAY_SIZE(wids);
+
+	    pjsua_vid_enum_wins(wids, &cnt);
+
+	    PJ_LOG(3,(THIS_FILE, "Found %d video windows:", cnt));
+	    PJ_LOG(3,(THIS_FILE, "WID show    pos       size"));
+	    PJ_LOG(3,(THIS_FILE, "------------------------------"));
+	    for (i = 0; i < cnt; ++i) {
+		pjsua_vid_win_info wi;
+		pjsua_vid_win_get_info(wids[i], &wi);
+		PJ_LOG(3,(THIS_FILE, "%3d   %c  (%d,%d)  %dx%d",
+			  wids[i], (wi.show?'Y':'N'), wi.pos.x, wi.pos.y,
+			  wi.size.w, wi.size.h));
+	    }
+	} else if (argc==4 && (strcmp(argv[2], "show")==0 ||
+			       strcmp(argv[2], "hide")==0))
+	{
+	    pj_bool_t show = (strcmp(argv[2], "show")==0);
+	    pjsua_vid_win_id wid = atoi(argv[3]);
+	    status = pjsua_vid_win_set_show(wid, show);
+	} else if (argc==6 && strcmp(argv[2], "move")==0) {
+	    pjsua_vid_win_id wid = atoi(argv[3]);
+	    pjmedia_coord pos;
+
+	    pos.x = atoi(argv[4]);
+	    pos.y = atoi(argv[5]);
+	    status = pjsua_vid_win_set_pos(wid, &pos);
+	} else if (argc==6 && strcmp(argv[2], "resize")==0) {
+	    pjsua_vid_win_id wid = atoi(argv[3]);
+	    pjmedia_rect_size size;
+
+	    size.w = atoi(argv[4]);
+	    size.h = atoi(argv[5]);
+	    status = pjsua_vid_win_set_size(wid, &size);
+	} else if (argc==3 && strcmp(argv[2], "arrange")==0) {
+	    arrange_window(PJSUA_INVALID_ID);
+	} else
+	    goto on_error;
+
+	if (status != PJ_SUCCESS) {
+	    PJ_PERROR(1,(THIS_FILE, status, "Window operation error"));
+	}
+
+    } else if (strcmp(argv[1], "codec")==0) {
+	pjsua_codec_info ci[PJMEDIA_CODEC_MGR_MAX_CODECS];
+	unsigned count = PJ_ARRAY_SIZE(ci);
+	pj_status_t status;
+
+	if (argc==3 && strcmp(argv[2], "list")==0) {
+	    status = pjsua_vid_enum_codecs(ci, &count);
+	    if (status != PJ_SUCCESS) {
+		PJ_PERROR(1,(THIS_FILE, status, "Error enumerating codecs"));
+	    } else {
+		unsigned i;
+		PJ_LOG(3,(THIS_FILE, "Found %d video codecs:", count));
+		PJ_LOG(3,(THIS_FILE, "codec id      prio  fps    bw(kbps)   size"));
+		PJ_LOG(3,(THIS_FILE, "------------------------------------------"));
+		for (i=0; i<count; ++i) {
+		    pjmedia_vid_codec_param cp;
+		    pjmedia_video_format_detail *vfd;
+
+		    status = pjsua_vid_codec_get_param(&ci[i].codec_id, &cp);
+		    if (status != PJ_SUCCESS)
+			continue;
+
+		    vfd = pjmedia_format_get_video_format_detail(&cp.enc_fmt,
+								 PJ_TRUE);
+		    PJ_LOG(3,(THIS_FILE, "%.*s%.*s %3d %7.2f  %4d/%4d  %dx%d", 
+			      (int)ci[i].codec_id.slen, ci[i].codec_id.ptr,
+			      13-(int)ci[i].codec_id.slen, "                ",
+			      ci[i].priority,
+			      (vfd->fps.num*1.0/vfd->fps.denum),
+			      vfd->avg_bps/1000, vfd->max_bps/1000,
+			      vfd->size.w, vfd->size.h));
+		}
+	    }
+	} else if (argc==5 && strcmp(argv[2], "prio")==0) {
+	    pj_str_t cid;
+	    int prio;
+	    cid = pj_str(argv[3]);
+	    prio = atoi(argv[4]);
+	    status = pjsua_vid_codec_set_priority(&cid, (pj_uint8_t)prio);
+	    if (status != PJ_SUCCESS)
+		PJ_PERROR(1,(THIS_FILE, status, "Set codec priority error"));
+	} else if (argc==6 && strcmp(argv[2], "fps")==0) {
+	    pjmedia_vid_codec_param cp;
+	    pj_str_t cid;
+	    int M, N;
+	    cid = pj_str(argv[3]);
+	    M = atoi(argv[4]);
+	    N = atoi(argv[5]);
+	    status = pjsua_vid_codec_get_param(&cid, &cp);
+	    if (status == PJ_SUCCESS) {
+		cp.enc_fmt.det.vid.fps.num = M;
+		cp.enc_fmt.det.vid.fps.denum = N;
+		status = pjsua_vid_codec_set_param(&cid, &cp);
+	    }
+	    if (status != PJ_SUCCESS)
+		PJ_PERROR(1,(THIS_FILE, status, "Set codec framerate error"));
+	} else if (argc==6 && strcmp(argv[2], "bw")==0) {
+	    pjmedia_vid_codec_param cp;
+	    pj_str_t cid;
+	    int M, N;
+	    cid = pj_str(argv[3]);
+	    M = atoi(argv[4]);
+	    N = atoi(argv[5]);
+	    status = pjsua_vid_codec_get_param(&cid, &cp);
+	    if (status == PJ_SUCCESS) {
+		cp.enc_fmt.det.vid.avg_bps = M * 1000;
+		cp.enc_fmt.det.vid.max_bps = N * 1000;
+		status = pjsua_vid_codec_set_param(&cid, &cp);
+	    }
+	    if (status != PJ_SUCCESS)
+		PJ_PERROR(1,(THIS_FILE, status, "Set codec bitrate error"));
+	} else if (argc==6 && strcmp(argv[2], "size")==0) {
+	    pjmedia_vid_codec_param cp;
+	    pj_str_t cid;
+	    int M, N;
+	    cid = pj_str(argv[3]);
+	    M = atoi(argv[4]);
+	    N = atoi(argv[5]);
+	    status = pjsua_vid_codec_get_param(&cid, &cp);
+	    if (status == PJ_SUCCESS) {
+		cp.enc_fmt.det.vid.size.w = M;
+		cp.enc_fmt.det.vid.size.h = N;
+		status = pjsua_vid_codec_set_param(&cid, &cp);
+	    }
+	    if (status != PJ_SUCCESS)
+		PJ_PERROR(1,(THIS_FILE, status, "Set codec size error"));
+	} else
+	    goto on_error;
+    } else
+	goto on_error;
+
+    return;
+
+on_error:
+    PJ_LOG(1,(THIS_FILE, "Invalid command, use 'vid help'"));
+}
+
+#endif /* PJSUA_HAS_VIDEO */
+
+/** UI Command **/
+static void ui_make_new_call()
+{    
+    char buf[128];
+    pjsua_msg_data msg_data;
+    input_result result;
+    pj_str_t tmp;
+
+    printf("(You currently have %d calls)\n", pjsua_call_get_count());
+    
+    ui_input_url("Make call", buf, sizeof(buf), &result);
+    if (result.nb_result != PJSUA_APP_NO_NB) {
+
+	if (result.nb_result == -1 || result.nb_result == 0) {
+	    puts("You can't do that with make call!");
+	    return;
+	} else {
+	    pjsua_buddy_info binfo;
+	    pjsua_buddy_get_info(result.nb_result-1, &binfo);
+	    tmp.ptr = buf;
+	    pj_strncpy(&tmp, &binfo.uri, sizeof(buf));
+	}
+
+    } else if (result.uri_result) {
+	tmp = pj_str(result.uri_result);
+    } else {
+	tmp.slen = 0;
+    }
+
+    pjsua_msg_data_init(&msg_data);
+    TEST_MULTIPART(&msg_data);
+    pjsua_call_make_call(current_acc, &tmp, &call_opt, NULL, 
+			 &msg_data, &current_call);
+}
+
+static void ui_make_multi_call()
+{
+    char menuin[32];
+    int count;
+    char buf[128];
+    input_result result;
+    pj_str_t tmp;
+    int i;
+
+    printf("(You currently have %d calls)\n", pjsua_call_get_count());
+
+    if (!simple_input("Number of calls", menuin, sizeof(menuin)))
+	return;
+
+    count = my_atoi(menuin);
+    if (count < 1)
+	return;
+
+    ui_input_url("Make call", buf, sizeof(buf), &result);
+    if (result.nb_result != PJSUA_APP_NO_NB) {
+	pjsua_buddy_info binfo;
+	if (result.nb_result == -1 || result.nb_result == 0) {
+	    puts("You can't do that with make call!");
+	    return;
+	}
+	pjsua_buddy_get_info(result.nb_result-1, &binfo);
+	tmp.ptr = buf;
+	pj_strncpy(&tmp, &binfo.uri, sizeof(buf));
+    } else {
+	tmp = pj_str(result.uri_result);
+    }
+
+    for (i=0; i<my_atoi(menuin); ++i) {
+	pj_status_t status;
+
+	status = pjsua_call_make_call(current_acc, &tmp, &call_opt, NULL,
+	    NULL, NULL);
+	if (status != PJ_SUCCESS)
+	    break;
+    }
+}
+
+static void ui_detect_nat_type()
+{
+    int i = pjsua_detect_nat_type();
+    if (i != PJ_SUCCESS)
+	pjsua_perror(THIS_FILE, "Error", i);
+}
+
+static void ui_send_instant_message()
+{
+    char *uri = NULL;
+    /* i is for call index to send message, if any */
+    int i = -1;
+    input_result result;
+    char buf[128];
+    char text[128];
+    pj_str_t tmp;
+
+    /* Input destination. */
+    ui_input_url("Send IM to", buf, sizeof(buf), &result);
+    if (result.nb_result != PJSUA_APP_NO_NB) {
+
+	if (result.nb_result == -1) {
+	    puts("You can't send broadcast IM like that!");
+	    return;
+
+	} else if (result.nb_result == 0) {
+	    i = current_call;
+	} else {
+	    pjsua_buddy_info binfo;
+	    pjsua_buddy_get_info(result.nb_result-1, &binfo);
+	    tmp.ptr = buf;
+	    pj_strncpy_with_null(&tmp, &binfo.uri, sizeof(buf));
+	    uri = buf;
+	}
+
+    } else if (result.uri_result) {
+	uri = result.uri_result;
+    }
+
+
+    /* Send typing indication. */
+    if (i != -1)
+	pjsua_call_send_typing_ind(i, PJ_TRUE, NULL);
+    else {
+	pj_str_t tmp_uri = pj_str(uri);
+	pjsua_im_typing(current_acc, &tmp_uri, PJ_TRUE, NULL);
+    }
+
+    /* Input the IM . */
+    if (!simple_input("Message", text, sizeof(text))) {
+	/*
+	* Cancelled.
+	* Send typing notification too, saying we're not typing.
+	*/
+	if (i != -1)
+	    pjsua_call_send_typing_ind(i, PJ_FALSE, NULL);
+	else {
+	    pj_str_t tmp_uri = pj_str(uri);
+	    pjsua_im_typing(current_acc, &tmp_uri, PJ_FALSE, NULL);
+	}
+	return;
+    }
+
+    tmp = pj_str(text);
+
+    /* Send the IM */
+    if (i != -1)
+	pjsua_call_send_im(i, NULL, &tmp, NULL, NULL);
+    else {
+	pj_str_t tmp_uri = pj_str(uri);
+	pjsua_im_send(current_acc, &tmp_uri, NULL, &tmp, NULL, NULL);
+    }
+}
+
+static void ui_answer_call()
+{
+    pjsua_call_info call_info;
+    char buf[128];
+    pjsua_msg_data msg_data;
+
+    if (current_call != -1) {
+	pjsua_call_get_info(current_call, &call_info);
+    } else {
+	/* Make compiler happy */
+	call_info.role = PJSIP_ROLE_UAC;
+	call_info.state = PJSIP_INV_STATE_DISCONNECTED;
+    }
+
+    if (current_call == -1 || 
+	call_info.role != PJSIP_ROLE_UAS ||
+	call_info.state >= PJSIP_INV_STATE_CONNECTING)
+    {
+	puts("No pending incoming call");
+	fflush(stdout);
+	return;
+
+    } else {
+	int st_code;
+	char contact[120];
+	pj_str_t hname = { "Contact", 7 };
+	pj_str_t hvalue;
+	pjsip_generic_string_hdr hcontact;
+
+	if (!simple_input("Answer with code (100-699)", buf, sizeof(buf)))
+	    return;
+
+	st_code = my_atoi(buf);
+	if (st_code < 100)
+	    return;
+
+	pjsua_msg_data_init(&msg_data);
+
+	if (st_code/100 == 3) {
+	    if (!simple_input("Enter URL to be put in Contact", 
+		contact, sizeof(contact)))
+		return;
+	    hvalue = pj_str(contact);
+	    pjsip_generic_string_hdr_init2(&hcontact, &hname, &hvalue);
+
+	    pj_list_push_back(&msg_data.hdr_list, &hcontact);
+	}
+
+	/*
+	* Must check again!
+	* Call may have been disconnected while we're waiting for 
+	* keyboard input.
+	*/
+	if (current_call == -1) {
+	    puts("Call has been disconnected");
+	    fflush(stdout);
+	    return;
+	}
+
+	pjsua_call_answer2(current_call, &call_opt, st_code, NULL, &msg_data);
+    }    
+}
+
+static void ui_hangup_call(char menuin[])
+{
+    if (current_call == -1) {
+	puts("No current call");
+	fflush(stdout);
+	return;
+
+    } else if (menuin[1] == 'a') {
+	/* Hangup all calls */
+	pjsua_call_hangup_all();
+    } else {
+	/* Hangup current calls */
+	pjsua_call_hangup(current_call, 0, NULL, NULL);
+    }
+}
+
+static void ui_cycle_dialog(char menuin[])
+{
+    if (menuin[0] == ']') {
+	find_next_call();
+
+    } else {
+	find_prev_call();
+    }
+
+    if (current_call != -1) {
+	pjsua_call_info call_info;
+
+	pjsua_call_get_info(current_call, &call_info);
+	PJ_LOG(3,(THIS_FILE,"Current dialog: %.*s", 
+	    (int)call_info.remote_info.slen, 
+	    call_info.remote_info.ptr));
+
+    } else {
+	PJ_LOG(3,(THIS_FILE,"No current dialog"));
+    }
+}
+
+static void ui_cycle_account()
+{
+    int i;
+    char buf[128];
+
+    if (!simple_input("Enter account ID to select", buf, sizeof(buf)))
+	return;
+
+    i = my_atoi(buf);
+    if (pjsua_acc_is_valid(i)) {
+	pjsua_acc_set_default(i);
+	PJ_LOG(3,(THIS_FILE, "Current account changed to %d", i));
+    } else {
+	PJ_LOG(3,(THIS_FILE, "Invalid account id %d", i));
+    }
+}
+
+static void ui_add_buddy()
+{
+    char buf[128];
+    pjsua_buddy_config buddy_cfg;
+    pjsua_buddy_id buddy_id;
+    pj_status_t status;
+
+    if (!simple_input("Enter buddy's URI:", buf, sizeof(buf)))
+	return;
+
+    if (pjsua_verify_url(buf) != PJ_SUCCESS) {
+	printf("Invalid URI '%s'\n", buf);
+	return;
+    }
+
+    pj_bzero(&buddy_cfg, sizeof(pjsua_buddy_config));
+
+    buddy_cfg.uri = pj_str(buf);
+    buddy_cfg.subscribe = PJ_TRUE;
+
+    status = pjsua_buddy_add(&buddy_cfg, &buddy_id);
+    if (status == PJ_SUCCESS) {
+	printf("New buddy '%s' added at index %d\n",
+	    buf, buddy_id+1);
+    }
+}
+
+static void ui_add_account(pjsua_transport_config *rtp_cfg)
+{
+    char id[80], registrar[80], realm[80], uname[80], passwd[30];
+    pjsua_acc_config acc_cfg;
+    pj_status_t status;
+
+    if (!simple_input("Your SIP URL:", id, sizeof(id)))
+	return;
+    if (!simple_input("URL of the registrar:", registrar, sizeof(registrar)))
+	return;
+    if (!simple_input("Auth Realm:", realm, sizeof(realm)))
+	return;
+    if (!simple_input("Auth Username:", uname, sizeof(uname)))
+	return;
+    if (!simple_input("Auth Password:", passwd, sizeof(passwd)))
+	return;
+
+    pjsua_acc_config_default(&acc_cfg);
+    acc_cfg.id = pj_str(id);
+    acc_cfg.reg_uri = pj_str(registrar);
+    acc_cfg.cred_count = 1;
+    acc_cfg.cred_info[0].scheme = pj_str("Digest");
+    acc_cfg.cred_info[0].realm = pj_str(realm);
+    acc_cfg.cred_info[0].username = pj_str(uname);
+    acc_cfg.cred_info[0].data_type = 0;
+    acc_cfg.cred_info[0].data = pj_str(passwd);
+
+    acc_cfg.rtp_cfg = *rtp_cfg;    
+    app_config_init_video(&acc_cfg);
+
+    status = pjsua_acc_add(&acc_cfg, PJ_TRUE, NULL);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Error adding new account", status);
+    }
+}
+
+static void ui_delete_buddy()
+{
+    char buf[128];
+    int i;
+
+    if (!simple_input("Enter buddy ID to delete", buf, sizeof(buf)))
+	return;
+
+    i = my_atoi(buf) - 1;
+
+    if (!pjsua_buddy_is_valid(i)) {
+	printf("Invalid buddy id %d\n", i);
+    } else {
+	pjsua_buddy_del(i);
+	printf("Buddy %d deleted\n", i);
+    }
+}
+
+static void ui_delete_account()
+{
+    char buf[128];
+    int i;
+
+    if (!simple_input("Enter account ID to delete", buf, sizeof(buf)))
+	return;
+
+    i = my_atoi(buf);
+
+    if (!pjsua_acc_is_valid(i)) {
+	printf("Invalid account id %d\n", i);
+    } else {
+	pjsua_acc_del(i);
+	printf("Account %d deleted\n", i);
+    }
+}
+
+static void ui_call_hold()
+{
+    if (current_call != -1) {		
+	pjsua_call_set_hold(current_call, NULL);
+    } else {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    }
+}
+
+static void ui_call_reinvite()
+{
+    call_opt.flag |= PJSUA_CALL_UNHOLD;
+    pjsua_call_reinvite2(current_call, &call_opt, NULL);
+}
+
+static void ui_send_update()
+{
+    if (current_call != -1) {		
+	pjsua_call_update2(current_call, &call_opt, NULL);
+    } else {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    }
+}
+
+/*
+ * Change codec priorities.
+ */
+static void ui_manage_codec_prio()
+{
+    pjsua_codec_info c[32];
+    unsigned i, count = PJ_ARRAY_SIZE(c);
+    char input[32];
+    char *codec, *prio;
+    pj_str_t id;
+    int new_prio;
+    pj_status_t status;
+
+    printf("List of audio codecs:\n");
+    pjsua_enum_codecs(c, &count);
+    for (i=0; i<count; ++i) {
+	printf("  %d\t%.*s\n", c[i].priority, (int)c[i].codec_id.slen,
+			       c[i].codec_id.ptr);
+    }
+
+#if PJSUA_HAS_VIDEO
+    puts("");
+    printf("List of video codecs:\n");
+    pjsua_vid_enum_codecs(c, &count);
+    for (i=0; i<count; ++i) {
+	printf("  %d\t%.*s%s%.*s\n", c[i].priority,
+				     (int)c[i].codec_id.slen,
+				     c[i].codec_id.ptr,
+				     c[i].desc.slen? " - ":"",
+				     (int)c[i].desc.slen,
+				     c[i].desc.ptr);
+    }
+#endif
+
+    puts("");
+    puts("Enter codec id and its new priority (e.g. \"speex/16000 200\", "
+	 """\"H263 200\"),");
+    puts("or empty to cancel.");
+
+    printf("Codec name (\"*\" for all) and priority: ");
+    if (fgets(input, sizeof(input), stdin) == NULL)
+	return;
+    if (input[0]=='\r' || input[0]=='\n') {
+	puts("Done");
+	return;
+    }
+
+    codec = strtok(input, " \t\r\n");
+    prio = strtok(NULL, " \r\n");
+
+    if (!codec || !prio) {
+	puts("Invalid input");
+	return;
+    }
+
+    new_prio = atoi(prio);
+    if (new_prio < 0) 
+	new_prio = 0;
+    else if (new_prio > PJMEDIA_CODEC_PRIO_HIGHEST) 
+	new_prio = PJMEDIA_CODEC_PRIO_HIGHEST;
+
+    status = pjsua_codec_set_priority(pj_cstr(&id, codec), 
+				      (pj_uint8_t)new_prio);
+#if PJSUA_HAS_VIDEO
+    if (status != PJ_SUCCESS) {
+	status = pjsua_vid_codec_set_priority(pj_cstr(&id, codec), 
+					      (pj_uint8_t)new_prio);
+    }
+#endif
+    if (status != PJ_SUCCESS)
+	pjsua_perror(THIS_FILE, "Error setting codec priority", status);
+}
+
+static void ui_call_transfer(pj_bool_t no_refersub)
+{
+    if (current_call == -1) {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    } else {
+	int call = current_call;
+	char buf[128];
+	pjsip_generic_string_hdr refer_sub;
+	pj_str_t STR_REFER_SUB = { "Refer-Sub", 9 };
+	pj_str_t STR_FALSE = { "false", 5 };
+	pjsua_call_info ci;
+	input_result result;
+	pjsua_msg_data msg_data;
+
+	pjsua_call_get_info(current_call, &ci);
+	printf("Transfering current call [%d] %.*s\n", current_call,
+	       (int)ci.remote_info.slen, ci.remote_info.ptr);
+
+	ui_input_url("Transfer to URL", buf, sizeof(buf), &result);
+
+	/* Check if call is still there. */
+
+	if (call != current_call) {
+	    puts("Call has been disconnected");
+	    return;
+	}
+
+	pjsua_msg_data_init(&msg_data);
+	if (no_refersub) {
+	    /* Add Refer-Sub: false in outgoing REFER request */
+	    pjsip_generic_string_hdr_init2(&refer_sub, &STR_REFER_SUB,
+		&STR_FALSE);
+	    pj_list_push_back(&msg_data.hdr_list, &refer_sub);
+	}
+	if (result.nb_result != PJSUA_APP_NO_NB) {
+	    if (result.nb_result == -1 || result.nb_result == 0)
+		puts("You can't do that with transfer call!");
+	    else {
+		pjsua_buddy_info binfo;
+		pjsua_buddy_get_info(result.nb_result-1, &binfo);
+		pjsua_call_xfer( current_call, &binfo.uri, &msg_data);
+	    }
+
+	} else if (result.uri_result) {
+	    pj_str_t tmp;
+	    tmp = pj_str(result.uri_result);
+	    pjsua_call_xfer( current_call, &tmp, &msg_data);
+	}
+    }
+}
+
+static void ui_call_transfer_replaces(pj_bool_t no_refersub)
+{        
+    if (current_call == -1) {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    } else {
+	int call = current_call;
+	int dst_call;
+	pjsip_generic_string_hdr refer_sub;
+	pj_str_t STR_REFER_SUB = { "Refer-Sub", 9 };
+	pj_str_t STR_FALSE = { "false", 5 };
+	pjsua_call_id ids[PJSUA_MAX_CALLS];
+	pjsua_call_info ci;
+	pjsua_msg_data msg_data;
+	char buf[128];
+	unsigned i, count;
+
+	count = PJ_ARRAY_SIZE(ids);
+	pjsua_enum_calls(ids, &count);
+
+	if (count <= 1) {
+	    puts("There are no other calls");
+	    return;
+	}
+
+	pjsua_call_get_info(current_call, &ci);
+	printf("Transfer call [%d] %.*s to one of the following:\n",
+	       current_call,
+	       (int)ci.remote_info.slen, ci.remote_info.ptr);
+
+	for (i=0; i<count; ++i) {
+	    pjsua_call_info call_info;
+
+	    if (ids[i] == call)
+		continue;
+
+	    pjsua_call_get_info(ids[i], &call_info);
+	    printf("%d  %.*s [%.*s]\n",
+		ids[i],
+		(int)call_info.remote_info.slen,
+		call_info.remote_info.ptr,
+		(int)call_info.state_text.slen,
+		call_info.state_text.ptr);
+	}
+
+	if (!simple_input("Enter call number to be replaced", buf, sizeof(buf)))
+	    return;
+
+	dst_call = my_atoi(buf);
+
+	/* Check if call is still there. */
+
+	if (call != current_call) {
+	    puts("Call has been disconnected");
+	    return;
+	}
+
+	/* Check that destination call is valid. */
+	if (dst_call == call) {
+	    puts("Destination call number must not be the same "
+		"as the call being transfered");
+	    return;
+	}
+	if (dst_call >= PJSUA_MAX_CALLS) {
+	    puts("Invalid destination call number");
+	    return;
+	}
+	if (!pjsua_call_is_active(dst_call)) {
+	    puts("Invalid destination call number");
+	    return;
+	}
+
+	pjsua_msg_data_init(&msg_data);
+	if (no_refersub) {
+	    /* Add Refer-Sub: false in outgoing REFER request */
+	    pjsip_generic_string_hdr_init2(&refer_sub, &STR_REFER_SUB, 
+					   &STR_FALSE);
+	    pj_list_push_back(&msg_data.hdr_list, &refer_sub);
+	}
+
+	pjsua_call_xfer_replaces(call, dst_call, 
+				 PJSUA_XFER_NO_REQUIRE_REPLACES, 
+				 &msg_data);
+    }
+}
+
+static void ui_send_dtmf_2833()
+{
+    if (current_call == -1) {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    } else if (!pjsua_call_has_media(current_call)) {
+	PJ_LOG(3,(THIS_FILE, "Media is not established yet!"));
+    } else {
+	pj_str_t digits;
+	int call = current_call;
+	pj_status_t status;
+	char buf[128];
+
+	if (!simple_input("DTMF strings to send (0-9*#A-B)", buf, 
+	    sizeof(buf)))
+	{
+	    return;
+	}
+
+	if (call != current_call) {
+	    puts("Call has been disconnected");
+	    return;
+	}
+
+	digits = pj_str(buf);
+	status = pjsua_call_dial_dtmf(current_call, &digits);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Unable to send DTMF", status);
+	} else {
+	    puts("DTMF digits enqueued for transmission");
+	}
+    }
+}
+
+static void ui_send_dtmf_info()
+{
+    if (current_call == -1) {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    } else {
+	const pj_str_t SIP_INFO = pj_str("INFO");
+	pj_str_t digits;
+	int call = current_call;
+	int i;
+	pj_status_t status;
+	char buf[128];
+
+	if (!simple_input("DTMF strings to send (0-9*#A-B)", buf, 
+	    sizeof(buf)))
+	{
+	    return;
+	}
+
+	if (call != current_call) {
+	    puts("Call has been disconnected");
+	    return;
+	}
+
+	digits = pj_str(buf);
+	for (i=0; i<digits.slen; ++i) {
+	    char body[80];
+	    pjsua_msg_data msg_data;
+
+	    pjsua_msg_data_init(&msg_data);
+	    msg_data.content_type = pj_str("application/dtmf-relay");
+
+	    pj_ansi_snprintf(body, sizeof(body),
+		"Signal=%c\r\n"
+		"Duration=160",
+		buf[i]);
+	    msg_data.msg_body = pj_str(body);
+
+	    status = pjsua_call_send_request(current_call, &SIP_INFO, 
+		&msg_data);
+	    if (status != PJ_SUCCESS) {
+		return;
+	    }
+	}
+    }
+}
+
+static void ui_send_arbitrary_request()
+{
+    char text[128];
+    char buf[128];
+    char *uri;
+    input_result result;
+    pj_str_t tmp;
+
+    if (pjsua_acc_get_count() == 0) {
+	puts("Sorry, need at least one account configured");
+	return;
+    }
+
+    puts("Send arbitrary request to remote host");
+
+    /* Input METHOD */
+    if (!simple_input("Request method:",text,sizeof(text)))
+	return;
+
+    /* Input destination URI */
+    uri = NULL;
+    ui_input_url("Destination URI", buf, sizeof(buf), &result);
+    if (result.nb_result != PJSUA_APP_NO_NB) {
+
+	if (result.nb_result == -1) {
+	    puts("Sorry you can't do that!");
+	    return;
+	} else if (result.nb_result == 0) {
+	    uri = NULL;
+	    if (current_call == PJSUA_INVALID_ID) {
+		puts("No current call");
+		return;
+	    }
+	} else {	    
+	    pjsua_buddy_info binfo;
+	    pjsua_buddy_get_info(result.nb_result-1, &binfo);
+	    tmp.ptr = buf;
+	    pj_strncpy_with_null(&tmp, &binfo.uri, sizeof(buf));
+	    uri = buf;
+	}
+
+    } else if (result.uri_result) {
+	uri = result.uri_result;
+    } else {
+	return;
+    }
+
+    if (uri) {
+	tmp = pj_str(uri);
+	send_request(text, &tmp);
+    } else {
+	/* If you send call control request using this method
+	* (such requests includes BYE, CANCEL, etc.), it will
+	* not go well with the call state, so don't do it
+	* unless it's for testing.
+	*/
+	pj_str_t method = pj_str(text);
+	pjsua_call_send_request(current_call, &method, NULL);
+    }	    
+}
+
+static void ui_echo(char menuin[])
+{
+    if (pj_ansi_strnicmp(menuin, "echo", 4)==0) {
+	pj_str_t tmp;
+
+	tmp.ptr = menuin+5;
+	tmp.slen = pj_ansi_strlen(menuin)-6;
+
+	if (tmp.slen < 1) {
+	    puts("Usage: echo [0|1]");
+	    return;
+	}
+	cmd_echo = *tmp.ptr != '0' || tmp.slen!=1;
+    }
+}
+
+static void ui_sleep(char menuin[])
+{
+    if (pj_ansi_strnicmp(menuin, "sleep", 5)==0) {
+	pj_str_t tmp;
+	int delay;
+
+	tmp.ptr = menuin+6;
+	tmp.slen = pj_ansi_strlen(menuin)-7;
+
+	if (tmp.slen < 1) {
+	    puts("Usage: sleep MSEC");
+	    return;
+	}
+
+	delay = pj_strtoul(&tmp);
+	if (delay < 0) delay = 0;
+	pj_thread_sleep(delay);		
+    }
+}
+
+static void ui_subscribe(char menuin[])
+{
+    char buf[128];
+    input_result result;
+
+    ui_input_url("(un)Subscribe presence of", buf, sizeof(buf), &result);
+    if (result.nb_result != PJSUA_APP_NO_NB) {
+	if (result.nb_result == -1) {
+	    int i, count;
+	    count = pjsua_get_buddy_count();
+	    for (i=0; i<count; ++i)
+		pjsua_buddy_subscribe_pres(i, menuin[0]=='s');
+	} else if (result.nb_result == 0) {
+	    puts("Sorry, can only subscribe to buddy's presence, "
+		"not from existing call");
+	} else {
+	    pjsua_buddy_subscribe_pres(result.nb_result-1, (menuin[0]=='s'));
+	}
+
+    } else if (result.uri_result) {
+	puts("Sorry, can only subscribe to buddy's presence, "
+	    "not arbitrary URL (for now)");
+    }
+}
+
+static void ui_register(char menuin[])
+{
+    switch (menuin[1]) {
+    case 'r':
+	/*
+	* Re-Register.
+	*/
+	pjsua_acc_set_registration(current_acc, PJ_TRUE);
+	break;
+    case 'u':
+	/*
+	* Unregister
+	*/
+	pjsua_acc_set_registration(current_acc, PJ_FALSE);
+	break;
+    }
+}
+
+static void ui_toggle_state()
+{
+    pjsua_acc_info acc_info;
+
+    pjsua_acc_get_info(current_acc, &acc_info);
+    acc_info.online_status = !acc_info.online_status;
+    pjsua_acc_set_online_status(current_acc, acc_info.online_status);
+    printf("Setting %s online status to %s\n",
+	   acc_info.acc_uri.ptr,
+	   (acc_info.online_status?"online":"offline"));
+}
+
+/*
+ * Change extended online status.
+ */
+static void ui_change_online_status()
+{
+    char menuin[32];
+    pj_bool_t online_status;
+    pjrpid_element elem;
+    int i, choice;
+
+    enum {
+	AVAILABLE, BUSY, OTP, IDLE, AWAY, BRB, OFFLINE, OPT_MAX
+    };
+
+    struct opt {
+	int id;
+	char *name;
+    } opts[] = {
+	{ AVAILABLE, "Available" },
+	{ BUSY, "Busy"},
+	{ OTP, "On the phone"},
+	{ IDLE, "Idle"},
+	{ AWAY, "Away"},
+	{ BRB, "Be right back"},
+	{ OFFLINE, "Offline"}
+    };
+
+    printf("\n"
+	   "Choices:\n");
+    for (i=0; i<PJ_ARRAY_SIZE(opts); ++i) {
+	printf("  %d  %s\n", opts[i].id+1, opts[i].name);
+    }
+
+    if (!simple_input("Select status", menuin, sizeof(menuin)))
+	return;
+
+    choice = atoi(menuin) - 1;
+    if (choice < 0 || choice >= OPT_MAX) {
+	puts("Invalid selection");
+	return;
+    }
+
+    pj_bzero(&elem, sizeof(elem));
+    elem.type = PJRPID_ELEMENT_TYPE_PERSON;
+
+    online_status = PJ_TRUE;
+
+    switch (choice) {
+    case AVAILABLE:
+	break;
+    case BUSY:
+	elem.activity = PJRPID_ACTIVITY_BUSY;
+	elem.note = pj_str("Busy");
+	break;
+    case OTP:
+	elem.activity = PJRPID_ACTIVITY_BUSY;
+	elem.note = pj_str("On the phone");
+	break;
+    case IDLE:
+	elem.activity = PJRPID_ACTIVITY_UNKNOWN;
+	elem.note = pj_str("Idle");
+	break;
+    case AWAY:
+	elem.activity = PJRPID_ACTIVITY_AWAY;
+	elem.note = pj_str("Away");
+	break;
+    case BRB:
+	elem.activity = PJRPID_ACTIVITY_UNKNOWN;
+	elem.note = pj_str("Be right back");
+	break;
+    case OFFLINE:
+	online_status = PJ_FALSE;
+	break;
+    }
+
+    pjsua_acc_set_online_status2(current_acc, online_status, &elem);
+}
+
+/*
+ * List the ports in conference bridge
+ */
+static void ui_conf_list()
+{
+    unsigned i, count;
+    pjsua_conf_port_id id[PJSUA_MAX_CALLS];
+
+    printf("Conference ports:\n");
+
+    count = PJ_ARRAY_SIZE(id);
+    pjsua_enum_conf_ports(id, &count);
+
+    for (i=0; i<count; ++i) {
+	char txlist[PJSUA_MAX_CALLS*4+10];
+	unsigned j;
+	pjsua_conf_port_info info;
+
+	pjsua_conf_get_port_info(id[i], &info);
+
+	txlist[0] = '\0';
+	for (j=0; j<info.listener_cnt; ++j) {
+	    char s[10];
+	    pj_ansi_snprintf(s, sizeof(s), "#%d ", info.listeners[j]);
+	    pj_ansi_strcat(txlist, s);
+	}
+	printf("Port #%02d[%2dKHz/%dms/%d] %20.*s  transmitting to: %s\n", 
+	       info.slot_id, 
+	       info.clock_rate/1000,
+	       info.samples_per_frame*1000/info.channel_count/info.clock_rate,
+	       info.channel_count,
+	       (int)info.name.slen, 
+	       info.name.ptr,
+	       txlist);
+
+    }
+    puts("");
+}
+
+static void ui_conf_connect(char menuin[])
+{
+    char tmp[10], src_port[10], dst_port[10];
+    pj_status_t status;
+    int cnt;
+    const char *src_title, *dst_title;
+
+    cnt = sscanf(menuin, "%s %s %s", tmp, src_port, dst_port);
+
+    if (cnt != 3) {
+	ui_conf_list();
+
+	src_title = (menuin[1]=='c'? "Connect src port #":
+				     "Disconnect src port #");
+	dst_title = (menuin[1]=='c'? "To dst port #":"From dst port #");
+
+	if (!simple_input(src_title, src_port, sizeof(src_port)))
+	    return;
+
+	if (!simple_input(dst_title, dst_port, sizeof(dst_port)))
+	    return;
+    }
+
+    if (menuin[1]=='c') {
+	status = pjsua_conf_connect(my_atoi(src_port), my_atoi(dst_port));
+    } else {
+	status = pjsua_conf_disconnect(my_atoi(src_port), my_atoi(dst_port));
+    }
+    if (status == PJ_SUCCESS) {
+	puts("Success");
+    } else {
+	puts("ERROR!!");
+    }
+}
+
+static void ui_adjust_volume()
+{
+    char buf[128];
+    char text[128];
+    sprintf(buf, "Adjust mic level: [%4.1fx] ", app_config.mic_level);
+    if (simple_input(buf,text,sizeof(text))) {
+	char *err;
+	app_config.mic_level = (float)strtod(text, &err);
+	pjsua_conf_adjust_rx_level(0, app_config.mic_level);
+    }
+    sprintf(buf, "Adjust speaker level: [%4.1fx] ", app_config.speaker_level);
+    if (simple_input(buf,text,sizeof(text))) {
+	char *err;
+	app_config.speaker_level = (float)strtod(text, &err);
+	pjsua_conf_adjust_tx_level(0, app_config.speaker_level);
+    }
+}
+
+static void ui_dump_call_quality()
+{
+    if (current_call != PJSUA_INVALID_ID) {
+	log_call_dump(current_call);
+    } else {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    }
+}
+
+static void ui_dump_configuration()
+{
+    char settings[2000];
+    int len;
+
+    len = write_settings(&app_config, settings, sizeof(settings));
+    if (len < 1)
+	PJ_LOG(1,(THIS_FILE, "Error: not enough buffer"));
+    else
+	PJ_LOG(3,(THIS_FILE, "Dumping configuration (%d bytes):\n%s\n",	
+		  len, settings));	
+}
+
+static void ui_write_settings()
+{
+    char settings[2000];
+    int len;
+    char buf[128];
+
+    len = write_settings(&app_config, settings, sizeof(settings));
+    if (len < 1)
+	PJ_LOG(1,(THIS_FILE, "Error: not enough buffer"));
+    else {
+	pj_oshandle_t fd;
+	pj_status_t status;
+
+	status = pj_file_open(app_config.pool, buf, PJ_O_WRONLY, &fd);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Unable to open file", status);
+	} else {
+	    pj_ssize_t size = len;
+	    pj_file_write(fd, settings, &size);
+	    pj_file_close(fd);
+
+	    printf("Settings successfully written to '%s'\n", buf);
+	}
+    }
+}
+
+/*
+ * Dump application states.
+ */
+static void ui_app_dump(pj_bool_t detail)
+{
+    pjsua_dump(detail);
+}
+
+static void ui_call_redirect(char menuin[])
+{
+    if (current_call == PJSUA_INVALID_ID) {
+	PJ_LOG(3,(THIS_FILE, "No current call"));
+    } else {
+	if (!pjsua_call_is_active(current_call)) {
+	    PJ_LOG(1,(THIS_FILE, "Call %d has gone", current_call));
+	} else if (menuin[1] == 'a') {
+	    pjsua_call_process_redirect(current_call, 
+		PJSIP_REDIRECT_ACCEPT_REPLACE);
+	} else if (menuin[1] == 'A') {
+	    pjsua_call_process_redirect(current_call, 
+		PJSIP_REDIRECT_ACCEPT);
+	} else if (menuin[1] == 'r') {
+	    pjsua_call_process_redirect(current_call,
+		PJSIP_REDIRECT_REJECT);
+	} else {
+	    pjsua_call_process_redirect(current_call,
+		PJSIP_REDIRECT_STOP);
+	}
+    }
+}
+
+/*
+ * Main "user interface" loop.
+ */
+void legacy_main()
+{    
+    char menuin[80];    
+    char buf[128];    
+
+    keystroke_help();
+
+    for (;;) {
+
+	printf(">>> ");
+	fflush(stdout);
+
+	if (fgets(menuin, sizeof(menuin), stdin) == NULL) {
+	    /* 
+	     * Be friendly to users who redirect commands into
+	     * program, when file ends, resume with kbd.
+	     * If exit is desired end script with q for quit
+	     */
+ 	    /* Reopen stdin/stdout/stderr to /dev/console */
+#if ((defined(PJ_WIN32) && PJ_WIN32!=0) || \
+     (defined(PJ_WIN64) && PJ_WIN64!=0)) && \
+  (!defined(PJ_WIN32_WINCE) || PJ_WIN32_WINCE==0)
+	    if (freopen ("CONIN$", "r", stdin) == NULL) {
+#else
+	    if (1) {
+#endif
+		puts("Cannot switch back to console from file redirection");
+		menuin[0] = 'q';
+		menuin[1] = '\0';
+	    } else {
+		puts("Switched back to console from file redirection");
+		continue;
+	    }
+	}
+
+	if (cmd_echo) {
+	    printf("%s", menuin);
+	}
+
+	/* Update call setting */
+	pjsua_call_setting_default(&call_opt);
+	call_opt.aud_cnt = app_config.aud_cnt;
+	call_opt.vid_cnt = app_config.vid.vid_cnt;
+
+	switch (menuin[0]) {
+
+	case 'm':
+	    /* Make call! : */
+	    ui_make_new_call();
+	    break;
+
+	case 'M':
+	    /* Make multiple calls! : */
+	    ui_make_multi_call();
+	    break;
+
+	case 'n':
+	    ui_detect_nat_type();
+	    break;
+
+	case 'i':
+	    /* Send instant messaeg */
+	    ui_send_instant_message();
+	    break;
+
+	case 'a':
+	    ui_answer_call();
+	    break;
+
+	case 'h':
+	    ui_hangup_call(menuin);
+	    break;
+
+	case ']':
+	case '[':
+	    /*
+	     * Cycle next/prev dialog.
+	     */
+	    ui_cycle_dialog(menuin);
+	    break;
+
+	case '>':
+	case '<':
+	    ui_cycle_account();
+	    break;
+
+	case '+':
+	    if (menuin[1] == 'b') {
+		ui_add_buddy();
+	    } else if (menuin[1] == 'a') {
+		ui_add_account(&app_config.rtp_cfg);
+	    } else {
+		printf("Invalid input %s\n", menuin);
+	    }
+	    break;
+
+	case '-':
+	    if (menuin[1] == 'b') {
+		ui_delete_buddy();
+	    } else if (menuin[1] == 'a') {
+		ui_delete_account();
+	    } else {
+		printf("Invalid input %s\n", menuin);
+	    }
+	    break;
+
+	case 'H':
+	    /*
+	     * Hold call.
+	     */
+	    ui_call_hold();
+	    break;
+
+	case 'v':	    
+#if PJSUA_HAS_VIDEO
+	    if (menuin[1]=='i' && menuin[2]=='d' && menuin[3]==' ') {
+		vid_handle_menu(menuin);
+	    } else
+#endif
+	    if (current_call != -1) {
+		/*
+		 * re-INVITE
+		 */
+		ui_call_reinvite();
+	    } else {
+		PJ_LOG(3,(THIS_FILE, "No current call"));
+	    }
+	    break;
+
+	case 'U':
+	    /*
+	     * Send UPDATE
+	     */
+	    ui_send_update();
+	    break;
+
+	case 'C':
+	    if (menuin[1] == 'p') {
+		ui_manage_codec_prio();
+	    }
+	    break;
+
+	case 'x':
+	    /*
+	     * Transfer call.
+	     */
+	    ui_call_transfer(app_config.no_refersub);
+	    break;
+
+	case 'X':
+	    /*
+	     * Transfer call with replaces.
+	     */
+	    ui_call_transfer_replaces(app_config.no_refersub);
+	    break;
+
+	case '#':
+	    /*
+	     * Send DTMF strings.
+	     */
+	    ui_send_dtmf_2833();
+	    break;
+
+	case '*':
+	    /* Send DTMF with INFO */
+	    ui_send_dtmf_info();
+	    break;
+
+	case 'S':
+	    /*
+	     * Send arbitrary request
+	     */
+	    ui_send_arbitrary_request();
+	    break;
+
+	case 'e':
+	    ui_echo(menuin);
+	    break;
+
+	case 's':
+	    if (pj_ansi_strnicmp(menuin, "sleep", 5)==0) {
+		ui_sleep(menuin);
+		break;
+	    }
+	    /* Continue below */
+
+	case 'u':
+	    /*
+	     * Subscribe/unsubscribe presence.
+	     */
+	    ui_subscribe(menuin);
+	    break;
+
+	case 'r':
+	    ui_register(menuin);
+	    break;
+	    
+	case 't':
+	    ui_toggle_state();
+	    break;
+
+	case 'T':
+	    ui_change_online_status();
+	    break;
+
+	case 'c':
+	    switch (menuin[1]) {
+	    case 'l':
+		ui_conf_list();
+		break;
+	    case 'c':
+	    case 'd':
+		ui_conf_connect(menuin);
+		break;
+	    }
+	    break;
+
+	case 'V':
+	    /* Adjust audio volume */	    
+	    ui_adjust_volume();
+	    break;
+
+	case 'd':
+	    if (menuin[1] == 'c') {
+		ui_dump_configuration();	
+	    } else if (menuin[1] == 'q') {
+		ui_dump_call_quality();
+	    } else {		
+		ui_app_dump(menuin[1]=='d');
+	    }
+	    break;
+
+	case 'f':
+	    if (simple_input("Enter output filename", buf, sizeof(buf))) {
+		ui_write_settings();		
+	    }
+	    break;
+
+	case 'L':   /* Restart */
+	case 'q':
+	    legacy_on_stopped(menuin[0]=='L');
+	    goto on_exit;
+
+	case 'R':	    
+	    ui_call_redirect(menuin);
+	    break;
+
+	default:
+	    if (menuin[0] != '\n' && menuin[0] != '\r') {
+		printf("Invalid input %s", menuin);
+	    }
+	    keystroke_help();
+	    break;
+	}
+    }
+
+on_exit:
+    ;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/application.uidesign b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/application.uidesign
new file mode 100644
index 0000000..f2bf30e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/application.uidesign
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<designerData version="1.1.0">
+  <componentManifest>
+    <manifestEntry id="com.nokia.sdt.series60.CAknApplication" version="1.1.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.NonLayoutBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CommonBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CAknDocument" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CAknViewAppUi" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CAknAppUi" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CAknAppUiBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.DesignTimeContainer" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.StatusPane" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.ControlBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.StatusPaneCaption" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.StatusPaneTitleBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CBA" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CBABase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.AvkonViewReference" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.DesignReference" version="1.0.0"/>
+  </componentManifest>
+  <property id="com.nokia.sdt.symbian.dm.RESOURCE_DIRECTORY_ID">data</property>
+  <property id="com.nokia.sdt.component.symbian.version">3.2.0</property>
+  <property id="com.nokia.sdt.component.symbian.vendor">com.nokia.series60</property>
+  <property id="com.nokia.sdt.symbian.dm.COMPONENT_PROVIDER">com.nokia.sdt.component.symbian.Symbian-Provider</property>
+  <property id="com.nokia.sdt.symbian.dm.INCLUDE_DIRECTORY_ID">inc</property>
+  <property id="com.nokia.sdt.symbian.dm.ROOT_CONTAINER">pjsuaAppUi</property>
+  <property id="com.nokia.sdt.symbian.dm.SOURCE_DIRECTORY_ID">src</property>
+  <property id="com.nokia.sdt.symbian.dm.ROOT_APPLICATION_NAME">pjsua</property>
+  <property id="com.nokia.sdt.symbian.dm.SOURCEGEN_PROVIDER">com.nokia.sdt.sourcegen.Symbian-Provider</property>
+  <property id="com.nokia.sdt.symbian.dm.BUILD_DIRECTORY_ID">group</property>
+  <component id="com.nokia.sdt.series60.CAknApplication">
+    <property id="className">CpjsuaApplication</property>
+    <property id="documentBase">pjsua</property>
+    <property id="name">pjsuaApplication</property>
+    <property id="uid">0xE44C2D02</property>
+    <component id="com.nokia.sdt.series60.CAknDocument">
+      <property id="className">CpjsuaDocument</property>
+      <property id="name">pjsuaDocument</property>
+      <component id="com.nokia.sdt.series60.CAknViewAppUi">
+        <property id="initialDesign" type="componentRef">aknViewReference1</property>
+        <property id="className">CpjsuaAppUi</property>
+        <compoundProperty id="location">
+          <property id="x">51</property>
+          <property id="y">44</property>
+        </compoundProperty>
+        <property id="name">pjsuaAppUi</property>
+        <compoundProperty id="size">
+          <property id="width">240</property>
+          <property id="height">320</property>
+        </compoundProperty>
+        <component id="com.nokia.sdt.series60.StatusPane">
+          <compoundProperty id="location">
+            <property id="x">20</property>
+          </compoundProperty>
+          <property id="name">statusPane</property>
+          <compoundProperty id="size">
+            <property id="width">204</property>
+            <property id="height">63</property>
+          </compoundProperty>
+          <component id="com.nokia.sdt.series60.StatusPaneCaption">
+            <property id="shortCaption" type="i18n">STR_pjsuaApplication_5</property>
+            <compoundProperty id="location">
+              <property id="x">56</property>
+            </compoundProperty>
+            <property id="longCaption" type="i18n">STR_pjsuaApplication_4</property>
+            <property id="name">caption</property>
+            <compoundProperty id="size">
+              <property id="width">148</property>
+              <property id="height">43</property>
+            </compoundProperty>
+          </component>
+        </component>
+        <component id="com.nokia.sdt.series60.CBA">
+          <compoundProperty id="location">
+            <property id="y">288</property>
+          </compoundProperty>
+          <compoundProperty id="info">
+            <property id="leftText" type="i18n">STR_pjsuaApplication_1</property>
+            <property id="rightText" type="i18n">STR_pjsuaApplication_2</property>
+            <property id="middleText" type="i18n">STR_pjsuaApplication_3</property>
+            <property id="leftId"></property>
+            <property id="rightId">EAknSoftkeyBack</property>
+            <property id="type">R_AVKON_SOFTKEYS_EXIT</property>
+          </compoundProperty>
+          <property id="name">controlPane</property>
+          <compoundProperty id="size">
+            <property id="width">240</property>
+            <property id="height">32</property>
+          </compoundProperty>
+        </component>
+        <component id="com.nokia.sdt.series60.AvkonViewReference">
+          <property id="filePath">pjsuaContainer.uidesign</property>
+          <compoundProperty id="tabImage"/>
+          <property id="baseName">pjsuaContainer</property>
+          <property id="name">aknViewReference1</property>
+        </component>
+      </component>
+    </component>
+  </component>
+  <stringBundle>
+    <stringTable language="LANG_English">
+      <string id="STR_pjsuaApplication_1"/>
+      <string id="STR_pjsuaApplication_2"/>
+      <string id="STR_pjsuaApplication_3"/>
+      <string id="STR_pjsuaApplication_4">pjsua</string>
+      <string id="STR_pjsuaApplication_5">pjsua</string>
+    </stringTable>
+  </stringBundle>
+  <macroTable/>
+  <sourceMappingState>
+    <resourceMappings>
+      <resourceMapping instanceName="pjsuaAppUi">r_application_pjsua_app_ui</resourceMapping>
+      <resourceMapping instanceName="statusPane">r_application_status_pane</resourceMapping>
+      <resourceMapping instanceName="pjsuaAppUi" rsrcId="localisable_app_info">r_localisable_app_info</resourceMapping>
+      <resourceMapping instanceName="aknViewReference1" rsrcId="tabText">r_application_akn_view_reference1</resourceMapping>
+    </resourceMappings>
+    <enumMappings>
+      <enumMapping instanceName="aknViewReference1" propertyId="" nameAlgorithm="com.nokia.sdt.component.symbian.NAME_ALG_VIEW_UID">EPjsuaContainerViewId</enumMapping>
+    </enumMappings>
+    <arrayMappings/>
+  </sourceMappingState>
+  <generatedFiles>
+    <file>src/pjsuaapplication.cpp</file>
+    <file>src/pjsuacontainerview.cpp</file>
+    <file>src/pjsuadocument.cpp</file>
+    <file>inc/pjsuadocument.h</file>
+    <file>inc/pjsuacontainerview.h</file>
+    <file>inc/pjsuaappui.h</file>
+    <file>inc/pjsuaapplication.h</file>
+    <file>src/pjsuaappui.cpp</file>
+    <file>data/pjsua.rss</file>
+    <file>data/pjsuacontainer.rssi</file>
+    <file>inc/pjsua.hrh</file>
+    <file>data/pjsua.loc</file>
+    <file>data/pjsua.l01</file>
+    <file>data/pjsuacontainer.loc</file>
+    <file>data/pjsuacontainer.l01</file>
+  </generatedFiles>
+</designerData>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua.l01 b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua.l01
new file mode 100644
index 0000000..a3855bc
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua.l01
@@ -0,0 +1,14 @@
+/*
+========================================================================
+ Name        : pjsua.l01
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+// localized strings for language: UK English (01)
+#define STR_pjsuaApplication_4 "pjsua"
+#define STR_pjsuaApplication_5 "pjsua"
+#define STR_pjsuaApplication_1 ""
+#define STR_pjsuaApplication_2 ""
+#define STR_pjsuaApplication_3 ""
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua.loc b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua.loc
new file mode 100644
index 0000000..c48d6c1
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua.loc
@@ -0,0 +1,11 @@
+/*
+========================================================================
+ Name        : pjsua.loc
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+#ifdef LANGUAGE_01
+#include "pjsua.l01"
+#endif
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua.rss b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua.rss
new file mode 100644
index 0000000..4003177
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua.rss
@@ -0,0 +1,46 @@
+/*
+========================================================================
+ Name        : pjsua.rss
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+NAME PJSU
+
+#include <avkon.rsg>
+#include <avkon.rh>
+#include <eikon.rh>
+#include <appinfo.rh>
+#include "pjsua.hrh"
+#include "pjsua.loc"
+
+RESOURCE RSS_SIGNATURE
+	{
+	}
+RESOURCE TBUF
+	{
+	buf = "pjsua";
+	}
+RESOURCE EIK_APP_INFO r_application_pjsua_app_ui
+	{
+	cba = R_AVKON_SOFTKEYS_EXIT;
+	status_pane = r_application_status_pane;
+	}
+RESOURCE STATUS_PANE_APP_MODEL r_application_status_pane
+	{
+	}
+RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info
+	{
+	short_caption = STR_pjsuaApplication_5;
+	caption_and_icon = CAPTION_AND_ICON_INFO
+		{
+		caption = STR_pjsuaApplication_4;
+		number_of_icons = 0;
+		};
+	}
+RESOURCE TBUF r_application_akn_view_reference1
+	{
+	}
+
+#include "pjsuaContainer.rssi"
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsuaContainer.l01 b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsuaContainer.l01
new file mode 100644
index 0000000..792282d
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsuaContainer.l01
@@ -0,0 +1,14 @@
+/*
+========================================================================
+ Name        : pjsuaContainer.l01
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+// localized strings for language: UK English (01)
+#define STR_pjsuaContainerView_2 ""
+#define STR_pjsuaContainerView_3 ""
+#define STR_pjsuaContainerView_4 "pjsuaContainer"
+#define STR_pjsuaContainerView_1 ""
+#define STR_pjsuaContainerView_5 "Please wait.."
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsuaContainer.loc b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsuaContainer.loc
new file mode 100644
index 0000000..119c15b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsuaContainer.loc
@@ -0,0 +1,11 @@
+/*
+========================================================================
+ Name        : pjsuaContainer.loc
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+#ifdef LANGUAGE_01
+#include "pjsuaContainer.l01"
+#endif
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsuaContainer.rssi b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsuaContainer.rssi
new file mode 100644
index 0000000..03fc197
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsuaContainer.rssi
@@ -0,0 +1,28 @@
+#include "pjsuaContainer.loc"
+
+RESOURCE AVKON_VIEW r_pjsua_container_pjsua_container_view
+	{
+	cba = R_AVKON_SOFTKEYS_EXIT;
+	toolbar = 0;
+	}
+RESOURCE STATUS_PANE_APP_MODEL r_pjsua_container_status_pane
+	{
+	panes =
+		{
+		SPANE_PANE
+			{
+			id = EEikStatusPaneUidTitle;
+			type = EAknCtTitlePane;
+			resource = r_pjsua_container_title_resource;
+			}
+		};
+	}
+RESOURCE TITLE_PANE r_pjsua_container_title_resource
+	{
+	txt = STR_pjsuaContainerView_4;
+	}
+RESOURCE LABEL r_pjsua_container_label1
+	{
+	txt = STR_pjsuaContainerView_5;
+	horiz_align = EEikLabelAlignHCenter;
+	}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua_reg.loc b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua_reg.loc
new file mode 100644
index 0000000..0299c09
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua_reg.loc
@@ -0,0 +1,11 @@
+//  LOCALISATION STRINGS
+
+// Caption string for app.
+#define qtn_caption_string "pjsua"
+
+// Short caption string for app.
+#define qtn_short_caption_string "HW"
+
+#define qtn_loc_resource_file_1 "\\resource\\apps\\pjsua"
+
+// End of File
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua_reg.rss b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua_reg.rss
new file mode 100644
index 0000000..e91a00b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/data/pjsua_reg.rss
@@ -0,0 +1,21 @@
+
+#include <eikon.rh>
+#include <avkon.rsg>
+#include <avkon.rh>
+#include <appinfo.rh>
+#include "pjsua_reg.loc"
+#include <pjsua.rsg>
+
+UID2 KUidAppRegistrationResourceFile
+UID3 0xE44C2D02
+
+RESOURCE APP_REGISTRATION_INFO
+	{
+	app_file="pjsua";
+	localisable_resource_file =  qtn_loc_resource_file_1;
+	localisable_resource_id = R_LOCALISABLE_APP_INFO;
+
+	embeddability=KAppNotEmbeddable;
+	newfile=KAppDoesNotSupportNewFile;
+	}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/list_icon.bmp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/list_icon.bmp
new file mode 100644
index 0000000..a874fea
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/list_icon.bmp
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/list_icon_mask.bmp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/list_icon_mask.bmp
new file mode 100644
index 0000000..e320527
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/list_icon_mask.bmp
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/mark_icon.bmp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/mark_icon.bmp
new file mode 100644
index 0000000..35571e2
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/mark_icon.bmp
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/mark_icon_mask.bmp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/mark_icon_mask.bmp
new file mode 100644
index 0000000..dc8744b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/mark_icon_mask.bmp
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/pjsua.bmp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/pjsua.bmp
new file mode 100644
index 0000000..c6c2027
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/pjsua.bmp
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/qgn_menu_pjsua.svg b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/qgn_menu_pjsua.svg
new file mode 100644
index 0000000..47da6d7
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/gfx/qgn_menu_pjsua.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">

+<svg baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 88 87.999">

+<g>

+<g>

+<g>

+<g>

+<rect fill="none" width="88" height="87.999"/>

+</g>

+</g>

+<g>

+<linearGradient id="XMLID_7_" gradientUnits="userSpaceOnUse" x1="12.3042" y1="18.3799" x2="63.4113" y2="79.287">

+<stop offset="0" style="stop-color:#B3DDFF"/>

+<stop offset="0.8146" style="stop-color:#084296"/>

+<stop offset="1" style="stop-color:#084296"/>

+</linearGradient>

+<path fill="url(#XMLID_7_)" d="M32.135,7.415L14.363,17.432v23.167c0,0,8.926,15.351,10.468,18.001       c-2.386,1.704-15.44,11.03-15.44,11.03l21.613,12.652c0,0,12.907-9.85,14.71-11.226c1.979,1.109,16.231,9.101,16.231,9.101       l16.664-15.132c0,0-14.066-6.929-16.888-8.318c1.467-3.01,10.531-21.604,10.531-21.604l-22.298-9.59       c0,0-1.486,3.173-2.093,4.467c-2.046-0.88-6.573-2.826-6.573-2.826s-3.713,2.463-5.696,3.778       c-0.327-0.744-0.542-1.233-0.657-1.495c0.007-0.824,0.213-23.72,0.213-23.72L32.135,7.415z"/>

+<linearGradient id="XMLID_8_" gradientUnits="userSpaceOnUse" x1="40.8276" y1="52.1914" x2="16.1997" y2="21.1353">

+<stop offset="0" style="stop-color:#5AA7E0"/>

+<stop offset="1" style="stop-color:#3366CC"/>

+</linearGradient>

+<polygon fill="url(#XMLID_8_)" points="59.051,57.621 69.536,36.111 50.944,28.115 48.852,32.581 41.493,29.418 34.719,33.911        32.932,29.849 33.117,9.157 16.363,18.601 16.363,40.06 27.476,59.169 13.064,69.463 30.856,79.879 45.546,68.669        61.667,77.708 75.089,65.521 "/>

+<linearGradient id="XMLID_9_" gradientUnits="userSpaceOnUse" x1="60.585" y1="31.876" x2="53.8582" y2="45.1125">

+<stop offset="0" style="stop-color:#5AA7E0"/>

+<stop offset="1" style="stop-color:#3366CC"/>

+</linearGradient>

+<polygon fill="url(#XMLID_9_)" points="41.26,48.783 50.944,28.115 69.536,36.111 59.051,57.621 "/>

+<polygon fill="#0046B7" points="16.363,40.06 27.476,59.169 41.26,48.783 32.932,29.849 "/>

+<polygon fill="#3366CC" points="16.363,40.06 16.363,18.601 33.117,9.157 32.932,29.849 "/>

+<polygon fill="#CFECFF" points="26.696,39.23 41.493,29.418 59.523,37.168 45.546,47.954 "/>

+<path fill="#5AA7E0" d="M41.954,55.286"/>

+<polygon fill="#3366CC" points="26.696,39.23 27.476,59.169 45.546,68.669 45.546,47.954 "/>

+<polygon fill="#5AA7E0" points="13.064,69.463 27.476,59.169 45.546,68.669 30.856,79.879 "/>

+<linearGradient id="XMLID_10_" gradientUnits="userSpaceOnUse" x1="29.2085" y1="63.6836" x2="48.7102" y2="56.1976">

+<stop offset="0" style="stop-color:#5AA7E0"/>

+<stop offset="0.0056" style="stop-color:#5AA7E0"/>

+<stop offset="0.85" style="stop-color:#3366CC"/>

+<stop offset="1" style="stop-color:#3366CC"/>

+</linearGradient>

+<polygon fill="url(#XMLID_10_)" points="43.423,46.971 27.476,59.169 45.546,68.669 45.546,47.954 "/>

+<polygon fill="#0046B7" points="45.546,47.954 45.546,68.669 59.051,57.621 59.523,37.168 "/>

+<linearGradient id="XMLID_11_" gradientUnits="userSpaceOnUse" x1="45.3936" y1="59.5186" x2="59.0508" y2="59.5186">

+<stop offset="0" style="stop-color:#0046B7"/>

+<stop offset="1" style="stop-color:#3366CC"/>

+</linearGradient>

+<polygon fill="url(#XMLID_11_)" points="45.394,50.368 45.546,68.669 59.051,57.621 "/>

+<linearGradient id="XMLID_12_" gradientUnits="userSpaceOnUse" x1="60.8945" y1="68.6807" x2="57.2953" y2="58.792">

+<stop offset="0" style="stop-color:#5AA7E0"/>

+<stop offset="0.4101" style="stop-color:#5AA7E0"/>

+<stop offset="1" style="stop-color:#3366CC"/>

+</linearGradient>

+<polygon fill="url(#XMLID_12_)" points="61.667,77.708 45.546,68.669 59.051,57.621 75.089,65.521 "/>

+</g>

+</g>

+</g>

+</svg>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/ABLD.BAT b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/ABLD.BAT
new file mode 100644
index 0000000..70c8b68
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/ABLD.BAT
@@ -0,0 +1,15 @@
+@ECHO OFF
+
+REM Bldmake-generated batch file - ABLD.BAT
+REM ** DO NOT EDIT **
+
+perl -S ABLD.PL "\Users\Teluu\pjsip\trunk\pjsip-apps\src\pjsua\symbian\group\\" %1 %2 %3 %4 %5 %6 %7 %8 %9
+if errorlevel==1 goto CheckPerl
+goto End
+
+:CheckPerl
+perl -v >NUL
+if errorlevel==1 echo Is Perl, version 5.003_07 or later, installed?
+goto End
+
+:End
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/bld.inf b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/bld.inf
new file mode 100644
index 0000000..ba36d31
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/bld.inf
@@ -0,0 +1,26 @@
+
+PRJ_PLATFORMS
+WINSCW ARMV5 GCCE
+
+
+#ifdef SBSV2
+
+PRJ_EXTENSIONS
+	
+	START EXTENSION s60/mifconv
+	OPTION TARGETFILE pjsua_0xE44C2D02.mif
+	OPTION HEADERFILE pjsua_0xE44C2D02.mbg
+	OPTION SOURCEDIR ../gfx
+	OPTION SOURCES -c32 qgn_menu_pjsua
+	END
+
+#else
+
+PRJ_MMPFILES
+
+	gnumakefile pjsua_icons.mk
+
+#endif
+
+PRJ_MMPFILES
+pjsua.mmp
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/pjsua.mmp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/pjsua.mmp
new file mode 100644
index 0000000..a65981a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/pjsua.mmp
@@ -0,0 +1,105 @@
+// These part may be overwritten by automated test
+// =BEGIN
+#define SND_HAS_APS	0
+#define SND_HAS_VAS	0
+#define SND_HAS_MDA	1
+// =END
+
+TARGET			pjsua.exe
+UID			0x100039CE 0xE44C2D02
+VENDORID	  	0
+TARGETTYPE		exe
+EPOCSTACKSIZE	 	0x5000
+
+SYSTEMINCLUDE 		\epoc32\include \epoc32\include\variant \epoc32\include\ecom
+USERINCLUDE	   	..\inc ..\data
+
+SOURCEPATH		..\data
+START RESOURCE		pjsua.rss
+HEADER
+TARGETPATH 		resource\apps
+END //RESOURCE
+
+START RESOURCE		pjsua_reg.rss
+TARGETPATH 	  	\private\10003a3f\apps
+END //RESOURCE
+
+LIBRARY			euser.lib apparc.lib cone.lib eikcore.lib avkon.lib
+LIBRARY			commonengine.lib efsrv.lib estor.lib eikcoctl.lib eikdlg.lib 
+LIBRARY			eikctl.lib bafl.lib fbscli.lib aknnotify.lib aknicon.lib
+LIBRARY			etext.lib gdi.lib egul.lib insock.lib
+LIBRARY			ecom.lib InetProtUtil.lib http.lib esock.lib
+
+LANG 				01
+
+START BITMAP pjsua.mbm
+	HEADER
+	TARGETPATH \resource\apps
+	SOURCEPATH ..\gfx
+	SOURCE c12,1 list_icon.bmp list_icon_mask.bmp
+	SOURCE c24 pjsua.bmp
+END
+
+SOURCEPATH		..\src
+
+#ifdef ENABLE_ABIV2_MODE
+DEBUGGABLE_UDEBONLY
+#endif
+
+SOURCE pjsuaContainer.cpp PjsuaContainerView.cpp pjsuaApplication.cpp pjsuaDocument.cpp pjsuaAppUi.cpp
+
+
+/* PJSIP library dependencies */
+
+MACRO			PJ_M_I386=1
+MACRO			PJ_SYMBIAN=1
+
+SYSTEMINCLUDE		..\..\..\..\..\pjlib\include
+SYSTEMINCLUDE		..\..\..\..\..\pjlib-util\include
+SYSTEMINCLUDE		..\..\..\..\..\pjnath\include
+SYSTEMINCLUDE		..\..\..\..\..\pjmedia\include
+SYSTEMINCLUDE		..\..\..\..\..\pjsip\include
+
+SYSTEMINCLUDE		\epoc32\include\libc
+
+LIBRARY			estlib.lib charconv.lib hal.lib
+
+STATICLIBRARY		pjsua_lib.lib
+STATICLIBRARY		pjsip_ua.lib pjsip_simple.lib pjsip.lib
+STATICLIBRARY		libgsmcodec.lib libspeexcodec.lib 
+STATICLIBRARY		libg7221codec.lib libpassthroughcodec.lib
+STATICLIBRARY		pjmedia.lib
+STATICLIBRARY		pjmedia_audiodev.lib
+STATICLIBRARY		pjsdp.lib
+STATICLIBRARY		pjnath.lib
+STATICLIBRARY		pjlib_util.lib pjlib.lib
+STATICLIBRARY		libsrtp.lib
+STATICLIBRARY		libresample.lib
+
+/* Sound device (APS/VAS/MDA) library & capability settings */
+#if SND_HAS_APS
+	LIBRARY		APSSession2.lib
+#endif
+
+#if SND_HAS_VAS
+	LIBRARY		VoIPAudioIntfc.lib		
+#endif
+
+#if SND_HAS_MDA
+	LIBRARY 	mediaclientaudiostream.lib
+	LIBRARY 	mediaclientaudioinputstream.lib
+#endif
+
+#if SND_HAS_APS || SND_HAS_VAS
+	CAPABILITY	NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment MultimediaDD
+#else
+	CAPABILITY	NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment
+#endif
+
+
+/* PJSUA APP */
+
+SOURCEPATH		..\..
+
+SOURCE 			pjsua_app_cli.c pjsua_app_legacy.c
+SOURCE 			pjsua_app.c pjsua_app_common.c pjsua_app_config.c
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/pjsua_icons.mk b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/pjsua_icons.mk
new file mode 100644
index 0000000..525ba21
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/group/pjsua_icons.mk
@@ -0,0 +1,75 @@
+# ============================================================================
+#  Name	 : Icons_aif_scalable_dc.mk
+#  Part of  : pjsua
+#
+#  Description:
+# 
+# ============================================================================
+
+
+ifeq (WINS,$(findstring WINS, $(PLATFORM)))
+ZDIR=$(EPOCROOT)epoc32\release\$(PLATFORM)\$(CFG)\Z
+else
+ZDIR=$(EPOCROOT)epoc32\data\z
+endif
+
+
+# ----------------------------------------------------------------------------
+# TODO: Configure these
+# ----------------------------------------------------------------------------
+
+TARGETDIR=$(ZDIR)\resource\apps
+ICONTARGETFILENAME=$(TARGETDIR)\pjsua_aif.mif
+HEADERDIR=$(EPOCROOT)epoc32\include
+HEADERFILENAME=$(HEADERDIR)\pjsua_aif.mbg
+
+ICONDIR=..\gfx
+
+do_nothing :
+	@rem do_nothing
+
+MAKMAKE : do_nothing
+
+BLD : do_nothing
+
+CLEAN :
+	@echo ...Deleting $(ICONTARGETFILENAME)
+	del /q /f $(ICONTARGETFILENAME)
+
+LIB : do_nothing
+
+CLEANLIB : do_nothing
+
+# ----------------------------------------------------------------------------
+# TODO: Configure these.
+#
+# NOTE 1: DO NOT DEFINE MASK FILE NAMES! They are included automatically by
+# MifConv if the mask detph is defined.
+#
+# NOTE 2: Usually, source paths should not be included in the bitmap
+# definitions. MifConv searches for the icons in all icon directories in a
+# predefined order, which is currently \s60\icons, \s60\bitmaps2.
+# The directory \s60\icons is included in the search only if the feature flag
+# __SCALABLE_ICONS is defined.
+# ----------------------------------------------------------------------------
+# NOTE: if you have JUSTINTIME enabled for your S60 3rd FP1 or newer SDK
+# and this command crashes, consider adding "/X" to the command line.
+# See <http://forum.nokia.com/document/Forum_Nokia_Technical_Library_v1_35/contents/FNTL/Build_process_fails_at_mif_file_creation_in_S60_3rd_Ed_FP1_SDK.htm>
+# ----------------------------------------------------------------------------
+
+RESOURCE : $(ICONTARGETFILENAME)
+
+$(ICONTARGETFILENAME) : $(ICONDIR)\qgn_menu_pjsua.svg
+	mifconv $(ICONTARGETFILENAME) \
+		/H$(HEADERFILENAME) \
+		/c32,8 $(ICONDIR)\qgn_menu_pjsua.svg
+		
+FREEZE : do_nothing
+
+SAVESPACE : do_nothing
+
+RELEASABLES :
+	@echo $(ICONTARGETFILENAME)
+
+FINAL : do_nothing
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/PjsuaContainerView.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/PjsuaContainerView.h
new file mode 100644
index 0000000..22b3ed8
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/PjsuaContainerView.h
@@ -0,0 +1,94 @@
+/*
+========================================================================
+ Name        : PjsuaContainerView.h
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+#ifndef PJSUACONTAINERVIEW_H
+#define PJSUACONTAINERVIEW_H
+
+// [[[ begin generated region: do not modify [Generated Includes]
+#include <aknview.h>
+// ]]] end generated region [Generated Includes]
+
+
+// [[[ begin [Event Handler Includes]
+// ]]] end [Event Handler Includes]
+
+// [[[ begin generated region: do not modify [Generated Constants]
+// ]]] end generated region [Generated Constants]
+
+// [[[ begin generated region: do not modify [Generated Forward Declarations]
+class CPjsuaContainer;
+// ]]] end generated region [Generated Forward Declarations]
+
+/**
+ * Avkon view class for pjsuaContainerView. It is register with the view server
+ * by the AppUi. It owns the container control.
+ * @class	CpjsuaContainerView pjsuaContainerView.h
+ */						
+			
+class CpjsuaContainerView : public CAknView
+	{
+	
+	
+	// [[[ begin [Public Section]
+public:
+	// constructors and destructor
+	CpjsuaContainerView();
+	static CpjsuaContainerView* NewL();
+	static CpjsuaContainerView* NewLC();        
+	void ConstructL();
+	virtual ~CpjsuaContainerView();
+						
+	// from base class CAknView
+	TUid Id() const;
+	void HandleCommandL( TInt aCommand );
+	
+	// [[[ begin generated region: do not modify [Generated Methods]
+	CPjsuaContainer* CreateContainerL();
+	// ]]] end generated region [Generated Methods]
+	
+	// ]]] end [Public Section]
+	
+	void PutMessage( const char *msg );
+	
+	// [[[ begin [Protected Section]
+protected:
+	// from base class CAknView
+	void DoActivateL(
+		const TVwsViewId& aPrevViewId,
+		TUid aCustomMessageId,
+		const TDesC8& aCustomMessage );
+	void DoDeactivate();
+	void HandleStatusPaneSizeChange();
+	
+	// [[[ begin generated region: do not modify [Overridden Methods]
+	// ]]] end generated region [Overridden Methods]
+	
+	
+	// [[[ begin [User Handlers]
+	// ]]] end [User Handlers]
+	
+	// ]]] end [Protected Section]
+	
+	
+	// [[[ begin [Private Section]
+private:
+	void SetupStatusPaneL();
+	void CleanupStatusPane();
+	
+	// [[[ begin generated region: do not modify [Generated Instance Variables]
+	CPjsuaContainer* iPjsuaContainer;
+	// ]]] end generated region [Generated Instance Variables]
+	
+	// [[[ begin generated region: do not modify [Generated Methods]
+	// ]]] end generated region [Generated Methods]
+	
+	// ]]] end [Private Section]
+	
+	};
+
+#endif // PJSUACONTAINERVIEW_H
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsua.hrh b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsua.hrh
new file mode 100644
index 0000000..ba27f50
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsua.hrh
@@ -0,0 +1,12 @@
+/*
+========================================================================
+ Name        : pjsua.hrh
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+enum TpjsuaViewUids
+	{
+	EPjsuaContainerViewId = 1
+	};
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsua.pan b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsua.pan
new file mode 100644
index 0000000..e33dbd5
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsua.pan
@@ -0,0 +1,18 @@
+
+#ifndef PJSUA_PAN_H
+#define PJSUA_PAN_H
+
+/** pjsua application panic codes */
+enum TpjsuaPanics
+	{
+	EpjsuaUi = 1
+	// add further panics here
+	};
+
+inline void Panic(TpjsuaPanics aReason)
+	{
+	_LIT(applicationName,"pjsua");
+	User::Panic(applicationName, aReason);
+	}
+
+#endif // PJSUA_PAN_H
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaAppUi.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaAppUi.h
new file mode 100644
index 0000000..8bfd244
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaAppUi.h
@@ -0,0 +1,70 @@
+/*
+========================================================================
+ Name        : pjsuaAppUi.h
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+#ifndef PJSUAAPPUI_H
+#define PJSUAAPPUI_H
+
+// [[[ begin generated region: do not modify [Generated Includes]
+#include <aknviewappui.h>
+// ]]] end generated region [Generated Includes]
+
+
+// [[[ begin generated region: do not modify [Generated Forward Declarations]
+class CpjsuaContainerView;
+// ]]] end generated region [Generated Forward Declarations]
+
+/**
+ * @class	CpjsuaAppUi pjsuaAppUi.h
+ * @brief The AppUi class handles application-wide aspects of the user interface, including
+ *        view management and the default menu, control pane, and status pane.
+ */
+class CpjsuaAppUi : public CAknViewAppUi
+	{
+public: 
+	// constructor and destructor
+	CpjsuaAppUi();
+	virtual ~CpjsuaAppUi();
+	void ConstructL();
+
+public:
+	// from CCoeAppUi
+	TKeyResponse HandleKeyEventL(
+				const TKeyEvent& aKeyEvent,
+				TEventCode aType );
+
+	// from CEikAppUi
+	void HandleCommandL( TInt aCommand );
+	void HandleResourceChangeL( TInt aType );
+
+	// from CAknAppUi
+	void HandleViewDeactivation( 
+			const TVwsViewId& aViewIdToBeDeactivated, 
+			const TVwsViewId& aNewlyActivatedViewId );
+
+private:
+	void InitializeContainersL();
+	// [[[ begin generated region: do not modify [Generated Methods]
+public: 
+	// ]]] end generated region [Generated Methods]
+	
+	void PutMsg(const char *msg);
+	
+	// [[[ begin generated region: do not modify [Generated Instance Variables]
+private: 
+	CpjsuaContainerView* iPjsuaContainerView;
+	// ]]] end generated region [Generated Instance Variables]
+	
+	
+	// [[[ begin [User Handlers]
+protected: 
+	// ]]] end [User Handlers]
+	void PrepareToExit();
+
+	};
+
+#endif // PJSUAAPPUI_H			
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaApplication.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaApplication.h
new file mode 100644
index 0000000..eef6e3f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaApplication.h
@@ -0,0 +1,35 @@
+/*
+========================================================================
+ Name        : pjsuaApplication.h
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+#ifndef PJSUAAPPLICATION_H
+#define PJSUAAPPLICATION_H
+
+// [[[ begin generated region: do not modify [Generated Includes]
+#include <aknapp.h>
+// ]]] end generated region [Generated Includes]
+
+// [[[ begin generated region: do not modify [Generated Constants]
+const TUid KUidpjsuaApplication = { 0xE44C2D02 };
+// ]]] end generated region [Generated Constants]
+
+/**
+ *
+ * @class	CpjsuaApplication pjsuaApplication.h
+ * @brief	A CAknApplication-derived class is required by the S60 application 
+ *          framework. It is subclassed to create the application's document 
+ *          object.
+ */
+class CpjsuaApplication : public CAknApplication
+	{
+private:
+	TUid AppDllUid() const;
+	CApaDocument* CreateDocumentL();
+	
+	};
+			
+#endif // PJSUAAPPLICATION_H		
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaContainer.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaContainer.h
new file mode 100644
index 0000000..2ee1475
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaContainer.h
@@ -0,0 +1,112 @@
+/*
+========================================================================
+ Name        : pjsuaContainer.h
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+#ifndef PJSUACONTAINER_H
+#define PJSUACONTAINER_H
+
+// [[[ begin generated region: do not modify [Generated Includes]
+#include <coecntrl.h>		
+// ]]] end generated region [Generated Includes]
+
+
+// [[[ begin [Event Handler Includes]
+// ]]] end [Event Handler Includes]
+
+// [[[ begin generated region: do not modify [Generated Forward Declarations]
+class MEikCommandObserver;		
+class CEikImage;
+class CEikLabel;
+// ]]] end generated region [Generated Forward Declarations]
+
+/**
+ * Container class for pjsuaContainer
+ * 
+ * @class	CPjsuaContainer pjsuaContainer.h
+ */
+class CPjsuaContainer : public CCoeControl
+	{
+public:
+	// constructors and destructor
+	CPjsuaContainer();
+	static CPjsuaContainer* NewL( 
+		const TRect& aRect, 
+		const CCoeControl* aParent, 
+		MEikCommandObserver* aCommandObserver );
+	static CPjsuaContainer* NewLC( 
+		const TRect& aRect, 
+		const CCoeControl* aParent, 
+		MEikCommandObserver* aCommandObserver );
+	void ConstructL( 
+		const TRect& aRect, 
+		const CCoeControl* aParent, 
+		MEikCommandObserver* aCommandObserver );
+	virtual ~CPjsuaContainer();
+
+public:
+	// from base class CCoeControl
+	TInt CountComponentControls() const;
+	CCoeControl* ComponentControl( TInt aIndex ) const;
+	TKeyResponse OfferKeyEventL( 
+			const TKeyEvent& aKeyEvent, 
+			TEventCode aType );
+	void HandleResourceChange( TInt aType );
+	
+protected:
+	// from base class CCoeControl
+	void SizeChanged();
+
+private:
+	// from base class CCoeControl
+	void Draw( const TRect& aRect ) const;
+
+private:
+	void InitializeControlsL();
+	void LayoutControls();
+	CCoeControl* iFocusControl;
+	MEikCommandObserver* iCommandObserver;
+	// [[[ begin generated region: do not modify [Generated Methods]
+public: 
+	// ]]] end generated region [Generated Methods]
+	
+	void PutMessageL( const char* msg );
+	// [[[ begin generated region: do not modify [Generated Type Declarations]
+public: 
+	// ]]] end generated region [Generated Type Declarations]
+	
+	// [[[ begin generated region: do not modify [Generated Instance Variables]
+private: 
+	CEikImage* iImage1;
+	CEikLabel* iLabel1;
+	// ]]] end generated region [Generated Instance Variables]
+	
+	
+	// [[[ begin [Overridden Methods]
+protected: 
+	// ]]] end [Overridden Methods]
+	
+	
+	// [[[ begin [User Handlers]
+protected: 
+	// ]]] end [User Handlers]
+	
+public: 
+	enum TControls
+		{
+		// [[[ begin generated region: do not modify [Generated Contents]
+		EImage1,
+		ELabel1,
+		
+		// ]]] end generated region [Generated Contents]
+		
+		// add any user-defined entries here...
+		
+		ELastControl
+		};
+	};
+				
+#endif // PJSUACONTAINER_H
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaDocument.h b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaDocument.h
new file mode 100644
index 0000000..be5deff
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/inc/pjsuaDocument.h
@@ -0,0 +1,36 @@
+/*
+========================================================================
+ Name        : pjsuaDocument.h
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+#ifndef PJSUADOCUMENT_H
+#define PJSUADOCUMENT_H
+
+#include <akndoc.h>
+		
+class CEikAppUi;
+
+/**
+* @class	CpjsuaDocument pjsuaDocument.h
+* @brief	A CAknDocument-derived class is required by the S60 application 
+*           framework. It is responsible for creating the AppUi object. 
+*/
+class CpjsuaDocument : public CAknDocument
+	{
+public: 
+	// constructor
+	static CpjsuaDocument* NewL( CEikApplication& aApp );
+
+private: 
+	// constructors
+	CpjsuaDocument( CEikApplication& aApp );
+	void ConstructL();
+	
+public: 
+	// from base class CEikDocument
+	CEikAppUi* CreateAppUiL();
+	};
+#endif // PJSUADOCUMENT_H
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/pjsuaContainer.uidesign b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/pjsuaContainer.uidesign
new file mode 100644
index 0000000..e50fd6d
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/pjsuaContainer.uidesign
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<designerData version="1.1.0">
+  <componentManifest>
+    <manifestEntry id="com.nokia.sdt.series60.CAknView" version="1.2.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.DesignTimeContainer" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CommonBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.StatusPane" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.ControlBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.StatusPaneTitle" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.StatusPaneTitleBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CBA" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CBABase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CCoeControl" version="1.2.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.ContainerBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CEikImage" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.symbian.CEikAlignedBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CCoeControlBase" version="1.0.0"/>
+    <manifestEntry id="com.nokia.sdt.series60.CEikLabel" version="1.0.0"/>
+  </componentManifest>
+  <property id="com.nokia.sdt.symbian.dm.RESOURCE_DIRECTORY_ID">data</property>
+  <property id="com.nokia.sdt.component.symbian.version">3.2.0</property>
+  <property id="com.nokia.sdt.component.symbian.vendor">com.nokia.series60</property>
+  <property id="com.nokia.sdt.symbian.dm.COMPONENT_PROVIDER">com.nokia.sdt.component.symbian.Symbian-Provider</property>
+  <property id="com.nokia.sdt.symbian.dm.INCLUDE_DIRECTORY_ID">inc</property>
+  <property id="com.nokia.sdt.symbian.dm.SOURCE_DIRECTORY_ID">src</property>
+  <property id="com.nokia.sdt.symbian.dm.SOURCEGEN_PROVIDER">com.nokia.sdt.sourcegen.Symbian-Provider</property>
+  <property id="com.nokia.sdt.symbian.dm.BUILD_DIRECTORY_ID">group</property>
+  <component id="com.nokia.sdt.series60.CAknView">
+    <property id="className">CpjsuaContainerView</property>
+    <compoundProperty id="location">
+      <property id="x">51</property>
+      <property id="y">44</property>
+    </compoundProperty>
+    <property id="name">pjsuaContainerView</property>
+    <compoundProperty id="size">
+      <property id="width">240</property>
+      <property id="height">320</property>
+    </compoundProperty>
+    <component id="com.nokia.sdt.series60.StatusPane">
+      <compoundProperty id="location">
+        <property id="x">20</property>
+      </compoundProperty>
+      <property id="name">statusPane</property>
+      <compoundProperty id="size">
+        <property id="width">204</property>
+        <property id="height">63</property>
+      </compoundProperty>
+      <component id="com.nokia.sdt.series60.StatusPaneTitle">
+        <compoundProperty id="location">
+          <property id="x">56</property>
+        </compoundProperty>
+        <property id="name">title</property>
+        <property id="titleText" type="i18n">STR_pjsuaContainerView_4</property>
+        <compoundProperty id="size">
+          <property id="width">148</property>
+          <property id="height">43</property>
+        </compoundProperty>
+        <compoundProperty id="image"/>
+      </component>
+    </component>
+    <component id="com.nokia.sdt.series60.CBA">
+      <compoundProperty id="location">
+        <property id="y">288</property>
+      </compoundProperty>
+      <compoundProperty id="info">
+        <property id="leftText" type="i18n">STR_pjsuaContainerView_1</property>
+        <property id="rightText" type="i18n">STR_pjsuaContainerView_2</property>
+        <property id="middleText" type="i18n">STR_pjsuaContainerView_3</property>
+        <property id="leftId"></property>
+        <property id="rightId">EAknSoftkeyBack</property>
+        <property id="type">R_AVKON_SOFTKEYS_EXIT</property>
+      </compoundProperty>
+      <property id="name">controlPane</property>
+      <compoundProperty id="size">
+        <property id="width">240</property>
+        <property id="height">32</property>
+      </compoundProperty>
+    </component>
+    <component id="com.nokia.sdt.series60.CCoeControl">
+      <property id="backColor">0,0,0</property>
+      <compoundProperty id="location">
+        <property id="y">66</property>
+      </compoundProperty>
+      <property id="className">CPjsuaContainer</property>
+      <property id="name">pjsuaContainer</property>
+      <compoundProperty id="size">
+        <property id="width">240</property>
+        <property id="height">222</property>
+      </compoundProperty>
+      <component id="com.nokia.sdt.series60.CEikImage">
+        <compoundProperty id="location">
+          <property id="x">0</property>
+          <property id="y">0</property>
+        </compoundProperty>
+        <property id="name">image1</property>
+        <compoundProperty id="size">
+          <property id="width">99</property>
+          <property id="height">111</property>
+        </compoundProperty>
+        <compoundProperty id="image">
+          <property id="bmpfile">\resource\apps\pjsua.mbm</property>
+          <property id="bmpid">EMbmPjsuaPjsua</property>
+        </compoundProperty>
+      </component>
+      <component id="com.nokia.sdt.series60.CEikLabel">
+        <compoundProperty id="location">
+          <property id="y">196</property>
+        </compoundProperty>
+        <property id="name">label1</property>
+        <property id="text" type="i18n">STR_pjsuaContainerView_5</property>
+        <compoundProperty id="size">
+          <property id="width">241</property>
+          <property id="height">27</property>
+        </compoundProperty>
+      </component>
+    </component>
+  </component>
+  <stringBundle>
+    <stringTable language="LANG_English">
+      <string id="STR_pjsuaContainerView_1"/>
+      <string id="STR_pjsuaContainerView_2"/>
+      <string id="STR_pjsuaContainerView_3"/>
+      <string id="STR_pjsuaContainerView_4">pjsuaContainer</string>
+      <string id="STR_pjsuaContainerView_5">Please wait..</string>
+    </stringTable>
+  </stringBundle>
+  <macroTable/>
+  <sourceMappingState>
+    <resourceMappings>
+      <resourceMapping instanceName="pjsuaContainerView">r_pjsua_container_pjsua_container_view</resourceMapping>
+      <resourceMapping instanceName="statusPane">r_pjsua_container_status_pane</resourceMapping>
+      <resourceMapping instanceName="label1">r_pjsua_container_label1</resourceMapping>
+      <resourceMapping instanceName="title">r_pjsua_container_title_resource</resourceMapping>
+    </resourceMappings>
+    <enumMappings>
+      <enumMapping instanceName="label1" propertyId="font">EEikLabelFontNormal</enumMapping>
+      <enumMapping instanceName="pjsuaContainerView" propertyId="" nameAlgorithm="com.nokia.sdt.component.symbian.NAME_ALG_VIEW_UID">EPjsuaContainerViewId</enumMapping>
+      <enumMapping instanceName="label1" propertyId="alignment">EEikLabelAlignHCenter</enumMapping>
+      <enumMapping instanceName="title" propertyId="" nameAlgorithm="com.nokia.sdt.component.symbian.NAME_ALG_STATUS_PANE_ID">EEikStatusPaneUidTitle</enumMapping>
+      <enumMapping instanceName="title" propertyId="" nameAlgorithm="com.nokia.sdt.component.symbian.NAME_ALG_CONTROL_TYPE">EAknCtTitlePane</enumMapping>
+    </enumMappings>
+    <arrayMappings/>
+  </sourceMappingState>
+  <generatedFiles>
+    <file>src/pjsuacontainer.cpp</file>
+    <file>src/pjsuacontainerview.cpp</file>
+    <file>inc/pjsuacontainer.h</file>
+    <file>inc/pjsuacontainerview.h</file>
+    <file>data/pjsua.rss</file>
+    <file>data/pjsuacontainer.rssi</file>
+    <file>inc/pjsua.hrh</file>
+    <file>data/pjsua.loc</file>
+    <file>data/pjsua.l01</file>
+    <file>data/pjsuacontainer.loc</file>
+    <file>data/pjsuacontainer.l01</file>
+  </generatedFiles>
+</designerData>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/sis/backup_registration.xml b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/sis/backup_registration.xml
new file mode 100644
index 0000000..7f7f2d0
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/sis/backup_registration.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" standalone="yes"?>
+<backup_registration>
+  <system_backup/>
+  <restore requires_reboot = "no"/>
+</backup_registration>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/sis/pjsua.pkg b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/sis/pjsua.pkg
new file mode 100644
index 0000000..5b25277
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/sis/pjsua.pkg
@@ -0,0 +1,36 @@
+; pjsua.pkg
+; This is an auto-generated PKG file by Carbide.
+; This file uses variables specific to Carbide builds that will not work
+; on command-line builds. If you want to use this generated PKG file from the
+; command-line tools you will need to modify the variables with the appropriate
+; values: $(EPOCROOT), $(PLATFORM), $(TARGET)
+; Also, the resource file entries should be changed to match the language
+; used in the build. For example, if building for LANGUAGE_01, change the file
+; extensions .rsc to .r01.
+;
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"pjsua"},(0xE44C2D02),1,0,0
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Supports Series 60 v 3.0
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+;Files to install
+;You should change the source paths to match that of your environment
+;<source> <destination>
+"$(EPOCROOT)Epoc32\release\$(PLATFORM)\$(TARGET)\pjsua.exe"		-"!:\sys\bin\pjsua.exe"
+"$(EPOCROOT)Epoc32\data\z\resource\apps\pjsua.r01"		-"!:\resource\apps\pjsua.r01"
+"$(EPOCROOT)Epoc32\data\z\private\10003a3f\apps\pjsua_reg.r01"	-"!:\private\10003a3f\import\apps\pjsua_reg.r01"
+"$(EPOCROOT)epoc32\data\z\resource\apps\pjsua_aif.mif" -"!:\resource\apps\pjsua_aif.mif"
+"$(EPOCROOT)epoc32\data\z\resource\apps\pjsua.mbm" -"!:\resource\apps\pjsua.mbm"
+; Add any installation notes if applicable
+;"pjsua.txt"					  -"!:\private\0xE44C2D02\pjsua.txt"
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/PjsuaContainerView.cpp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/PjsuaContainerView.cpp
new file mode 100644
index 0000000..8595260
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/PjsuaContainerView.cpp
@@ -0,0 +1,261 @@
+/*
+========================================================================
+ Name        : PjsuaContainerView.cpp
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+// [[[ begin generated region: do not modify [Generated System Includes]
+#include <aknviewappui.h>
+#include <eikmenub.h>
+#include <avkon.hrh>
+#include <barsread.h>
+#include <eikimage.h>
+#include <eikenv.h>
+#include <stringloader.h>
+#include <eiklabel.h>
+#include <akncontext.h>
+#include <akntitle.h>
+#include <eikbtgpc.h>
+#include <pjsua.rsg>
+// ]]] end generated region [Generated System Includes]
+
+// [[[ begin generated region: do not modify [Generated User Includes]
+
+#include "pjsua.hrh"
+#include "pjsuaContainerView.h"
+#include "pjsuaContainer.h"
+// ]]] end generated region [Generated User Includes]
+
+// [[[ begin generated region: do not modify [Generated Constants]
+// ]]] end generated region [Generated Constants]
+
+/**
+ * First phase of Symbian two-phase construction. Should not contain any
+ * code that could leave.
+ */
+CpjsuaContainerView::CpjsuaContainerView()
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	iPjsuaContainer = NULL;
+	// ]]] end generated region [Generated Contents]
+	
+	}
+
+/** 
+ * The view's destructor removes the container from the control
+ * stack and destroys it.
+ */
+CpjsuaContainerView::~CpjsuaContainerView()
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	delete iPjsuaContainer;
+	iPjsuaContainer = NULL;
+	// ]]] end generated region [Generated Contents]
+	
+	}
+
+/**
+ * Symbian two-phase constructor.
+ * This creates an instance then calls the second-phase constructor
+ * without leaving the instance on the cleanup stack.
+ * @return new instance of CpjsuaContainerView
+ */
+CpjsuaContainerView* CpjsuaContainerView::NewL()
+	{
+	CpjsuaContainerView* self = CpjsuaContainerView::NewLC();
+	CleanupStack::Pop( self );
+	return self;
+	}
+
+/**
+ * Symbian two-phase constructor.
+ * This creates an instance, pushes it on the cleanup stack,
+ * then calls the second-phase constructor.
+ * @return new instance of CpjsuaContainerView
+ */
+CpjsuaContainerView* CpjsuaContainerView::NewLC()
+	{
+	CpjsuaContainerView* self = new ( ELeave ) CpjsuaContainerView();
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	return self;
+	}
+
+
+/**
+ * Second-phase constructor for view.  
+ * Initialize contents from resource.
+ */ 
+void CpjsuaContainerView::ConstructL()
+	{
+	// [[[ begin generated region: do not modify [Generated Code]
+	BaseConstructL( R_PJSUA_CONTAINER_PJSUA_CONTAINER_VIEW );
+				
+	// ]]] end generated region [Generated Code]
+	
+	// add your own initialization code here
+	}
+
+/**
+ * @return The UID for this view
+ */
+TUid CpjsuaContainerView::Id() const
+	{
+	return TUid::Uid( EPjsuaContainerViewId );
+	}
+
+/**
+ * Handle a command for this view (override)
+ * @param aCommand command id to be handled
+ */
+void CpjsuaContainerView::HandleCommandL( TInt aCommand )
+	{
+	// [[[ begin generated region: do not modify [Generated Code]
+	TBool commandHandled = EFalse;
+	switch ( aCommand )
+		{	// code to dispatch to the AknView's menu and CBA commands is generated here
+		default:
+			break;
+		}
+	
+		
+	if ( !commandHandled ) 
+		{
+	
+		if ( aCommand == EAknSoftkeyBack )
+			{
+			AppUi()->HandleCommandL( EEikCmdExit );
+			}
+	
+		}
+	// ]]] end generated region [Generated Code]
+	
+	}
+
+/**
+ *	Handles user actions during activation of the view, 
+ *	such as initializing the content.
+ */
+void CpjsuaContainerView::DoActivateL( 
+		const TVwsViewId& /*aPrevViewId*/,
+		TUid /*aCustomMessageId*/,
+		const TDesC8& /*aCustomMessage*/ )
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	SetupStatusPaneL();
+	
+				
+				
+	
+	if ( iPjsuaContainer == NULL )
+		{
+		iPjsuaContainer = CreateContainerL();
+		iPjsuaContainer->SetMopParent( this );
+		AppUi()->AddToStackL( *this, iPjsuaContainer );
+		} 
+	// ]]] end generated region [Generated Contents]
+	
+	}
+
+/**
+ */
+void CpjsuaContainerView::DoDeactivate()
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	CleanupStatusPane();
+	
+	if ( iPjsuaContainer != NULL )
+		{
+		AppUi()->RemoveFromViewStack( *this, iPjsuaContainer );
+		delete iPjsuaContainer;
+		iPjsuaContainer = NULL;
+		}
+	// ]]] end generated region [Generated Contents]
+	
+	}
+
+/** 
+ * Handle status pane size change for this view (override)
+ */
+void CpjsuaContainerView::HandleStatusPaneSizeChange()
+	{
+	CAknView::HandleStatusPaneSizeChange();
+	
+	// this may fail, but we're not able to propagate exceptions here
+	TVwsViewId view;
+	AppUi()->GetActiveViewId( view );
+	if ( view.iViewUid == Id() )
+		{
+		TInt result;
+		TRAP( result, SetupStatusPaneL() );
+		}
+
+	// Hide menu
+	Cba()->MakeVisible(EFalse);
+	
+	//PutMessage("HandleStatusPaneSizeChange()");
+	
+	// [[[ begin generated region: do not modify [Generated Code]
+	// ]]] end generated region [Generated Code]
+	
+	}
+
+// [[[ begin generated function: do not modify
+void CpjsuaContainerView::SetupStatusPaneL()
+	{
+	// reset the context pane
+	TUid contextPaneUid = TUid::Uid( EEikStatusPaneUidContext );
+	CEikStatusPaneBase::TPaneCapabilities subPaneContext = 
+		StatusPane()->PaneCapabilities( contextPaneUid );
+	if ( subPaneContext.IsPresent() && subPaneContext.IsAppOwned() )
+		{
+		CAknContextPane* context = static_cast< CAknContextPane* > ( 
+			StatusPane()->ControlL( contextPaneUid ) );
+		context->SetPictureToDefaultL();
+		}
+	
+	// setup the title pane
+	TUid titlePaneUid = TUid::Uid( EEikStatusPaneUidTitle );
+	CEikStatusPaneBase::TPaneCapabilities subPaneTitle = 
+		StatusPane()->PaneCapabilities( titlePaneUid );
+	if ( subPaneTitle.IsPresent() && subPaneTitle.IsAppOwned() )
+		{
+		CAknTitlePane* title = static_cast< CAknTitlePane* >( 
+			StatusPane()->ControlL( titlePaneUid ) );
+		TResourceReader reader;
+		iEikonEnv->CreateResourceReaderLC( reader, R_PJSUA_CONTAINER_TITLE_RESOURCE );
+		title->SetFromResourceL( reader );
+		CleanupStack::PopAndDestroy(); // reader internal state
+		}
+				
+	}
+
+// ]]] end generated function
+
+// [[[ begin generated function: do not modify
+void CpjsuaContainerView::CleanupStatusPane()
+	{
+	}
+
+// ]]] end generated function
+
+/**
+ *	Creates the top-level container for the view.  You may modify this method's
+ *	contents and the CPjsuaContainer::NewL() signature as needed to initialize the
+ *	container, but the signature for this method is fixed.
+ *	@return new initialized instance of CPjsuaContainer
+ */
+CPjsuaContainer* CpjsuaContainerView::CreateContainerL()
+	{
+	return CPjsuaContainer::NewL( ClientRect(), NULL, this );
+	}
+
+void CpjsuaContainerView::PutMessage( const char *msg )
+{
+	if (!iPjsuaContainer)
+	    return;
+
+	TRAPD(result, iPjsuaContainer->PutMessageL(msg));
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaAppUi.cpp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaAppUi.cpp
new file mode 100644
index 0000000..74b8c42
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaAppUi.cpp
@@ -0,0 +1,370 @@
+/*
+========================================================================
+ Name        : pjsuaAppUi.cpp
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+// [[[ begin generated region: do not modify [Generated System Includes]
+#include <eikmenub.h>
+#include <akncontext.h>
+#include <akntitle.h>
+#include <pjsua.rsg>
+// ]]] end generated region [Generated System Includes]
+
+// [[[ begin generated region: do not modify [Generated User Includes]
+#include "pjsuaAppUi.h"
+#include "pjsua.hrh"
+#include "pjsuaContainerView.h"
+// ]]] end generated region [Generated User Includes]
+
+// [[[ begin generated region: do not modify [Generated Constants]
+// ]]] end generated region [Generated Constants]
+
+#include "../../pjsua_app.h"
+#include "../../pjsua_app_config.h"
+
+/* Global vars */
+static CpjsuaAppUi *appui = NULL;
+static pj_ioqueue_t *app_ioqueue = NULL;
+static int start_argc = 0;
+static char **start_argv = NULL;
+
+static pj_status_t InitSymbSocket();
+static void DestroySymbSocket();
+
+/* Helper funtions to init/restart/destroy the pjsua */
+static void PjsuaInitL();
+static void PjsuaDestroyL();
+
+/* pjsua app callbacks */
+static void PjsuaOnStarted(pj_status_t status, const char* title);
+static void PjsuaOnStopped(pj_bool_t restart, int argc, char** argv);
+static void PjsuaOnConfig(pjsua_app_config *cfg);
+
+/* Helper class to schedule function execution */
+class MyTimer : public CActive 
+{
+public:
+    typedef void (*timer_func)();
+    
+public:
+    static MyTimer* NewL(int ms, timer_func f) {
+	MyTimer *self = new MyTimer(f);
+	CleanupStack::PushL(self);
+	self->ConstructL(ms);
+	CleanupStack::Pop(self);
+	return self;
+    }
+    
+    MyTimer(timer_func f) : CActive(EPriorityStandard), func(f) {}
+    ~MyTimer() {
+	Cancel();
+	rtimer.Close();
+    }
+    
+    virtual void RunL() { (*func)(); delete this; }
+    virtual void DoCancel() { rtimer.Cancel(); }
+
+private:	
+    RTimer rtimer;
+    timer_func func;
+    
+    void ConstructL(int ms) {
+	rtimer.CreateLocal();
+	CActiveScheduler::Add(this);
+	rtimer.After(iStatus, ms * 1000);
+	SetActive();
+    }
+};
+
+/**
+ * Construct the CpjsuaAppUi instance
+ */ 
+CpjsuaAppUi::CpjsuaAppUi()
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	// ]]] end generated region [Generated Contents]
+	
+	}
+
+/** 
+ * The appui's destructor removes the container from the control
+ * stack and destroys it.
+ */
+CpjsuaAppUi::~CpjsuaAppUi()
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	// ]]] end generated region [Generated Contents]
+	
+	}
+
+// [[[ begin generated function: do not modify
+void CpjsuaAppUi::InitializeContainersL()
+	{
+	iPjsuaContainerView = CpjsuaContainerView::NewL();
+	AddViewL( iPjsuaContainerView );
+	SetDefaultViewL( *iPjsuaContainerView );
+	}
+// ]]] end generated function
+
+/**
+ * Handle a command for this appui (override)
+ * @param aCommand command id to be handled
+ */
+void CpjsuaAppUi::HandleCommandL( TInt aCommand )
+	{
+	// [[[ begin generated region: do not modify [Generated Code]
+	TBool commandHandled = EFalse;
+	switch ( aCommand )
+		{ // code to dispatch to the AppUi's menu and CBA commands is generated here
+		default:
+			break;
+		}
+	
+		
+	if ( !commandHandled ) 
+		{
+		if ( aCommand == EAknSoftkeyExit || aCommand == EEikCmdExit )
+			{
+			Exit();
+			}
+		}
+	// ]]] end generated region [Generated Code]
+	
+	}
+
+/** 
+ * Override of the HandleResourceChangeL virtual function
+ */
+void CpjsuaAppUi::HandleResourceChangeL( TInt aType )
+	{
+	CAknViewAppUi::HandleResourceChangeL( aType );
+	// [[[ begin generated region: do not modify [Generated Code]
+	// ]]] end generated region [Generated Code]
+	
+	}
+				
+/** 
+ * Override of the HandleKeyEventL virtual function
+ * @return EKeyWasConsumed if event was handled, EKeyWasNotConsumed if not
+ * @param aKeyEvent 
+ * @param aType 
+ */
+TKeyResponse CpjsuaAppUi::HandleKeyEventL(
+		const TKeyEvent& aKeyEvent,
+		TEventCode aType )
+	{
+	// The inherited HandleKeyEventL is private and cannot be called
+	// [[[ begin generated region: do not modify [Generated Contents]
+	// ]]] end generated region [Generated Contents]
+
+	// Left or right softkey pressed
+	if (aType==EEventKeyDown && 
+	    (aKeyEvent.iScanCode == EStdKeyDevice0 || 
+	     aKeyEvent.iScanCode == EStdKeyDevice1))    
+	{
+	    Cba()->MakeVisible(ETrue);
+	} else {
+	    Cba()->MakeVisible(EFalse);   
+	}
+
+	return EKeyWasNotConsumed;
+	}
+
+/** 
+ * Override of the HandleViewDeactivation virtual function
+ *
+ * @param aViewIdToBeDeactivated 
+ * @param aNewlyActivatedViewId 
+ */
+void CpjsuaAppUi::HandleViewDeactivation( 
+		const TVwsViewId& aViewIdToBeDeactivated, 
+		const TVwsViewId& aNewlyActivatedViewId )
+	{
+	CAknViewAppUi::HandleViewDeactivation( 
+			aViewIdToBeDeactivated, 
+			aNewlyActivatedViewId );
+	// [[[ begin generated region: do not modify [Generated Contents]
+	// ]]] end generated region [Generated Contents]
+	
+	}
+
+/**
+ * @brief Completes the second phase of Symbian object construction. 
+ * Put initialization code that could leave here. 
+ */ 
+void CpjsuaAppUi::ConstructL()
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	
+	BaseConstructL( EAknEnableSkin  | 
+					 EAknEnableMSK ); 
+	InitializeContainersL();
+	// ]]] end generated region [Generated Contents]
+	
+	// Save pointer to this AppUi
+	appui = this;
+	
+	// Full screen
+	StatusPane()->MakeVisible(EFalse);
+	Cba()->MakeVisible(EFalse);
+
+	if (InitSymbSocket() != PJ_SUCCESS) {
+	    PutMsg("Failed to initialize Symbian network param.");
+	} else {	
+	    start_argc = pjsua_app_def_argc;
+	    start_argv = (char**)pjsua_app_def_argv;
+
+	    // Schedule Lib Init
+	    MyTimer::NewL(100, &PjsuaInitL);
+	}
+	
+	}
+
+/* Called by Symbian GUI framework when app is about to exit */
+void CpjsuaAppUi::PrepareToExit()
+{
+    TRAPD(result, PjsuaDestroyL());
+    DestroySymbSocket();
+    CloseSTDLIB();
+    CAknViewAppUi::PrepareToExit();
+}
+
+/* Print message on screen */
+void CpjsuaAppUi::PutMsg(const char *msg)
+{
+    iPjsuaContainerView->PutMessage(msg);
+}
+
+#include <es_sock.h>
+
+static RSocketServ aSocketServer;
+static RConnection aConn;
+
+/* Called when pjsua is started */
+void PjsuaOnStarted(pj_status_t status, const char* title)
+{
+    char err_msg[128];
+
+    if (status != PJ_SUCCESS || title == NULL) {
+	char err_str[PJ_ERR_MSG_SIZE];
+	pj_strerror(status, err_str, sizeof(err_str));
+	pj_ansi_snprintf(err_msg, sizeof(err_msg), "%s: %s",
+			 (title?title:"App start error"), err_str);
+	title = err_msg;
+    }
+
+    appui->PutMsg(title);
+}
+
+/* Called when pjsua is stopped */
+void PjsuaOnStopped(pj_bool_t restart, int argc, char** argv)
+{
+    if (restart) {
+	start_argc = argc;
+	start_argv = argv;
+
+	// Schedule Lib Init
+	MyTimer::NewL(100, &PjsuaInitL);
+    } else {
+	/* Destroy & quit GUI, e.g: clean up window, resources  */
+	appui->Exit();
+    }
+}
+
+/* Called before pjsua initializing config.
+ * We need to override some settings here.
+ */
+void PjsuaOnConfig(pjsua_app_config *cfg)
+{
+    /* Disable threading */
+    cfg->cfg.thread_cnt = 0;
+    cfg->cfg.thread_cnt = 0;
+    cfg->media_cfg.thread_cnt = 0;
+    cfg->media_cfg.has_ioqueue = PJ_FALSE;
+
+    /* Create ioqueue for telnet CLI */
+    if (app_ioqueue ==  NULL) {
+	pj_ioqueue_create(cfg->pool, 0, &app_ioqueue);
+    }
+    cfg->cli_cfg.telnet_cfg.ioqueue = app_ioqueue; 
+}
+
+// Set Symbian OS parameters in pjlib.
+// This must be done before pj_init() is called.
+pj_status_t InitSymbSocket()
+{
+    pj_symbianos_params sym_params;
+    TInt err;
+    
+    // Initialize RSocketServ
+    if ((err=aSocketServer.Connect(32)) != KErrNone) {
+	return PJ_STATUS_FROM_OS(err);
+    }
+    
+    // Open up a connection
+    if ((err=aConn.Open(aSocketServer)) != KErrNone) {
+	aSocketServer.Close();
+	return PJ_STATUS_FROM_OS(err);
+    }
+    if ((err=aConn.Start()) != KErrNone) {
+	aConn.Close();
+	aSocketServer.Close();
+	return PJ_STATUS_FROM_OS(err);
+    }
+    
+    pj_bzero(&sym_params, sizeof(sym_params));
+    sym_params.rsocketserv = &aSocketServer;
+    sym_params.rconnection = &aConn;
+    pj_symbianos_set_params(&sym_params);
+    
+    return PJ_SUCCESS;
+}
+
+
+void DestroySymbSocket()
+{
+    aConn.Close();
+    aSocketServer.Close();
+}
+
+
+void PjsuaInitL()
+{
+    pjsua_app_cfg_t app_cfg;
+    pj_status_t status;
+    
+    PjsuaDestroyL();
+    
+    pj_bzero(&app_cfg, sizeof(app_cfg));
+    app_cfg.argc = start_argc;
+    app_cfg.argv = start_argv;
+    app_cfg.on_started = &PjsuaOnStarted;
+    app_cfg.on_stopped = &PjsuaOnStopped;
+    app_cfg.on_config_init = &PjsuaOnConfig;
+
+    appui->PutMsg("Initializing..");
+    status = pjsua_app_init(&app_cfg);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+    
+    appui->PutMsg("Starting..");
+    status = pjsua_app_run(PJ_FALSE);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+on_return:
+    if (status != PJ_SUCCESS)
+	appui->PutMsg("Initialization failed");
+}
+
+void PjsuaDestroyL()
+{
+    if (app_ioqueue) {
+	pj_ioqueue_destroy(app_ioqueue);
+	app_ioqueue = NULL;
+    }
+    pjsua_app_destroy();
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaApplication.cpp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaApplication.cpp
new file mode 100644
index 0000000..9196b9f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaApplication.cpp
@@ -0,0 +1,78 @@
+/*
+========================================================================
+ Name        : pjsuaApplication.cpp
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+// [[[ begin generated region: do not modify [Generated System Includes]
+// ]]] end generated region [Generated System Includes]
+
+// [[[ begin generated region: do not modify [Generated Includes]
+#include "pjsuaApplication.h"
+#include "pjsuaDocument.h"
+#ifdef EKA2
+#include <eikstart.h>
+#endif
+// ]]] end generated region [Generated Includes]
+
+/**
+ * @brief Returns the application's UID (override from CApaApplication::AppDllUid())
+ * @return UID for this application (KUidpjsuaApplication)
+ */
+TUid CpjsuaApplication::AppDllUid() const
+	{
+	return KUidpjsuaApplication;
+	}
+
+/**
+ * @brief Creates the application's document (override from CApaApplication::CreateDocumentL())
+ * @return Pointer to the created document object (CpjsuaDocument)
+ */
+CApaDocument* CpjsuaApplication::CreateDocumentL()
+	{
+	return CpjsuaDocument::NewL( *this );
+	}
+
+#ifdef EKA2
+
+/**
+ *	@brief Called by the application framework to construct the application object
+ *  @return The application (CpjsuaApplication)
+ */	
+LOCAL_C CApaApplication* NewApplication()
+	{
+	return new CpjsuaApplication;
+	}
+
+/**
+* @brief This standard export is the entry point for all Series 60 applications
+* @return error code
+ */	
+GLDEF_C TInt E32Main()
+	{
+	return EikStart::RunApplication( NewApplication );
+	}
+	
+#else 	// Series 60 2.x main DLL program code
+
+/**
+* @brief This standard export constructs the application object.
+* @return The application (CpjsuaApplication)
+*/
+EXPORT_C CApaApplication* NewApplication()
+	{
+	return new CpjsuaApplication;
+	}
+
+/**
+* @brief This standard export is the entry point for all Series 60 applications
+* @return error code
+*/
+GLDEF_C TInt E32Dll(TDllReason /*reason*/)
+	{
+	return KErrNone;
+	}
+
+#endif // EKA2
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaContainer.cpp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaContainer.cpp
new file mode 100644
index 0000000..5dec51f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaContainer.cpp
@@ -0,0 +1,312 @@
+/*
+========================================================================
+ Name        : pjsuaContainer.cpp
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+// [[[ begin generated region: do not modify [Generated System Includes]
+#include <barsread.h>
+#include <eikimage.h>
+#include <eikenv.h>
+#include <stringloader.h>
+#include <eiklabel.h>
+#include <aknviewappui.h>
+#include <eikappui.h>
+#include <akniconutils.h>
+#include <pjsua.mbg>
+#include <pjsua.rsg>
+// ]]] end generated region [Generated System Includes]
+
+// [[[ begin generated region: do not modify [Generated User Includes]
+#include "pjsuaContainer.h"
+#include "pjsuaContainerView.h"
+#include "pjsua.hrh"
+// ]]] end generated region [Generated User Includes]
+
+#include <eikmenub.h>
+
+// [[[ begin generated region: do not modify [Generated Constants]
+_LIT( KpjsuaFile, "\\resource\\apps\\pjsua.mbm" );
+// ]]] end generated region [Generated Constants]
+
+/**
+ * First phase of Symbian two-phase construction. Should not 
+ * contain any code that could leave.
+ */
+CPjsuaContainer::CPjsuaContainer()
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	iImage1 = NULL;
+	iLabel1 = NULL;
+	// ]]] end generated region [Generated Contents]
+	
+	}
+/** 
+ * Destroy child controls.
+ */
+CPjsuaContainer::~CPjsuaContainer()
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	delete iImage1;
+	iImage1 = NULL;
+	delete iLabel1;
+	iLabel1 = NULL;
+	// ]]] end generated region [Generated Contents]
+	
+	}
+				
+/**
+ * Construct the control (first phase).
+ *  Creates an instance and initializes it.
+ *  Instance is not left on cleanup stack.
+ * @param aRect bounding rectangle
+ * @param aParent owning parent, or NULL
+ * @param aCommandObserver command observer
+ * @return initialized instance of CPjsuaContainer
+ */
+CPjsuaContainer* CPjsuaContainer::NewL( 
+		const TRect& aRect, 
+		const CCoeControl* aParent, 
+		MEikCommandObserver* aCommandObserver )
+	{
+	CPjsuaContainer* self = CPjsuaContainer::NewLC( 
+			aRect, 
+			aParent, 
+			aCommandObserver );
+	CleanupStack::Pop( self );
+	return self;
+	}
+
+/**
+ * Construct the control (first phase).
+ *  Creates an instance and initializes it.
+ *  Instance is left on cleanup stack.
+ * @param aRect The rectangle for this window
+ * @param aParent owning parent, or NULL
+ * @param aCommandObserver command observer
+ * @return new instance of CPjsuaContainer
+ */
+CPjsuaContainer* CPjsuaContainer::NewLC( 
+		const TRect& aRect, 
+		const CCoeControl* aParent, 
+		MEikCommandObserver* aCommandObserver )
+	{
+	CPjsuaContainer* self = new ( ELeave ) CPjsuaContainer();
+	CleanupStack::PushL( self );
+	self->ConstructL( aRect, aParent, aCommandObserver );
+	return self;
+	}
+			
+/**
+ * Construct the control (second phase).
+ *  Creates a window to contain the controls and activates it.
+ * @param aRect bounding rectangle
+ * @param aCommandObserver command observer
+ * @param aParent owning parent, or NULL
+ */ 
+void CPjsuaContainer::ConstructL( 
+		const TRect& aRect, 
+		const CCoeControl* aParent, 
+		MEikCommandObserver* aCommandObserver )
+	{
+	if ( aParent == NULL )
+	    {
+		CreateWindowL();
+	    }
+	else
+	    {
+	    SetContainerWindowL( *aParent );
+	    }
+	iFocusControl = NULL;
+	iCommandObserver = aCommandObserver;
+	InitializeControlsL();
+	SetRect( aRect );
+
+	// Full screen
+	SetExtentToWholeScreen();
+	
+	// Set label color
+	//iLabel1->OverrideColorL( EColorLabelText, KRgbWhite );
+	//iLabel1->OverrideColorL(EColorControlBackground, KRgbBlack )
+	iLabel1->SetEmphasis( CEikLabel::EFullEmphasis);
+	iLabel1->OverrideColorL( EColorLabelHighlightFullEmphasis, KRgbBlack );
+	iLabel1->OverrideColorL( EColorLabelTextEmphasis, KRgbWhite );
+
+	// Set label font
+	 CFont* fontUsed;
+	_LIT(f,"Arial");
+	TFontSpec* fontSpec = new TFontSpec(f, 105);
+	TFontStyle* fontStyle = new TFontStyle();
+	fontStyle->SetPosture(EPostureUpright);
+	fontStyle->SetStrokeWeight(EStrokeWeightNormal);
+	fontSpec->iFontStyle = *fontStyle;
+	fontUsed = iCoeEnv->CreateScreenFontL(*fontSpec);
+	iLabel1->SetFont(fontUsed);
+	iLabel1->SetAlignment( EHCenterVCenter );
+	
+	ActivateL();
+	// [[[ begin generated region: do not modify [Post-ActivateL initializations]
+	// ]]] end generated region [Post-ActivateL initializations]
+	
+	}
+			
+/**
+* Return the number of controls in the container (override)
+* @return count
+*/
+TInt CPjsuaContainer::CountComponentControls() const
+	{
+	return ( int ) ELastControl;
+	}
+				
+/**
+* Get the control with the given index (override)
+* @param aIndex Control index [0...n) (limited by #CountComponentControls)
+* @return Pointer to control
+*/
+CCoeControl* CPjsuaContainer::ComponentControl( TInt aIndex ) const
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	switch ( aIndex )
+		{
+		case EImage1:
+			return iImage1;
+		case ELabel1:
+			return iLabel1;
+		}
+	// ]]] end generated region [Generated Contents]
+	
+	// handle any user controls here...
+	
+	return NULL;
+	}
+				
+/**
+ *	Handle resizing of the container. This implementation will lay out
+ *  full-sized controls like list boxes for any screen size, and will layout
+ *  labels, editors, etc. to the size they were given in the UI designer.
+ *  This code will need to be modified to adjust arbitrary controls to
+ *  any screen size.
+ */				
+void CPjsuaContainer::SizeChanged()
+	{
+	CCoeControl::SizeChanged();
+	LayoutControls();
+
+	// Align the image
+	int x = (Size().iWidth - iImage1->Size().iWidth) / 2;
+	int y = (Size().iHeight - iImage1->Size().iHeight) / 2;
+	iImage1->SetPosition(TPoint(x, y));
+	
+	// Align the label
+	iLabel1->SetExtent(TPoint(0, Size().iHeight - iLabel1->Size().iHeight),
+			   TSize(Size().iWidth, iLabel1->Size().iHeight));
+	
+	// [[[ begin generated region: do not modify [Generated Contents]
+			
+	// ]]] end generated region [Generated Contents]
+	
+	}
+				
+// [[[ begin generated function: do not modify
+/**
+ * Layout components as specified in the UI Designer
+ */
+void CPjsuaContainer::LayoutControls()
+	{
+	iImage1->SetExtent( TPoint( 0, 0 ), TSize( 99, 111 ) );
+	iLabel1->SetExtent( TPoint( 0, 196 ), TSize( 241, 27 ) );
+	}
+// ]]] end generated function
+
+/**
+ *	Handle key events.
+ */				
+TKeyResponse CPjsuaContainer::OfferKeyEventL( 
+		const TKeyEvent& aKeyEvent, 
+		TEventCode aType )
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	
+	// ]]] end generated region [Generated Contents]
+	
+	if ( iFocusControl != NULL
+		&& iFocusControl->OfferKeyEventL( aKeyEvent, aType ) == EKeyWasConsumed )
+		{
+		return EKeyWasConsumed;
+		}
+	return CCoeControl::OfferKeyEventL( aKeyEvent, aType );
+	}
+				
+// [[[ begin generated function: do not modify
+/**
+ *	Initialize each control upon creation.
+ */				
+void CPjsuaContainer::InitializeControlsL()
+	{
+	iImage1 = new ( ELeave ) CEikImage;
+		{
+		CFbsBitmap *bitmap, *mask;
+		AknIconUtils::CreateIconL( bitmap, mask,
+				KpjsuaFile, EMbmPjsuaPjsua, -1 );
+		AknIconUtils::SetSize( bitmap, TSize( 99, 111 ), EAspectRatioPreserved );
+		iImage1->SetPicture( bitmap );
+		}
+	iImage1->SetAlignment( EHCenterVTop );
+	iLabel1 = new ( ELeave ) CEikLabel;
+	iLabel1->SetContainerWindowL( *this );
+		{
+		TResourceReader reader;
+		iEikonEnv->CreateResourceReaderLC( reader, R_PJSUA_CONTAINER_LABEL1 );
+		iLabel1->ConstructFromResourceL( reader );
+		CleanupStack::PopAndDestroy(); // reader internal state
+		}
+	
+	}
+// ]]] end generated function
+
+/** 
+ * Handle global resource changes, such as scalable UI or skin events (override)
+ */
+void CPjsuaContainer::HandleResourceChange( TInt aType )
+	{
+	CCoeControl::HandleResourceChange( aType );
+	SetRect( iAvkonViewAppUi->View( TUid::Uid( EPjsuaContainerViewId ) )->ClientRect() );
+	// [[[ begin generated region: do not modify [Generated Contents]
+	// ]]] end generated region [Generated Contents]
+	
+	}
+				
+/**
+ *	Draw container contents.
+ */				
+void CPjsuaContainer::Draw( const TRect& aRect ) const
+	{
+	// [[[ begin generated region: do not modify [Generated Contents]
+	CWindowGc& gc = SystemGc();
+	gc.SetPenStyle( CGraphicsContext::ENullPen );
+	TRgb backColor( 0,0,0 );
+	gc.SetBrushColor( backColor );
+	gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+	gc.DrawRect( aRect );
+	
+	// ]]] end generated region [Generated Contents]
+	
+	}
+
+void CPjsuaContainer::PutMessageL( const char * msg )
+{
+    if (!iLabel1)
+	return;
+    
+    TPtrC8 ptr(reinterpret_cast<const TUint8*>(msg));
+    HBufC* buffer = HBufC::NewLC(ptr.Length());
+    buffer->Des().Copy(ptr);
+
+    iLabel1->SetTextL(*buffer);
+    iLabel1->DrawNow();
+
+    CleanupStack::PopAndDestroy(buffer);
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaDocument.cpp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaDocument.cpp
new file mode 100644
index 0000000..f349c6e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/symbian/src/pjsuaDocument.cpp
@@ -0,0 +1,57 @@
+/*
+========================================================================
+ Name        : pjsuaDocument.cpp
+ Author      : nanang
+ Copyright   : Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ Description : 
+========================================================================
+*/
+// [[[ begin generated region: do not modify [Generated User Includes]
+#include "pjsuaDocument.h"
+#include "pjsuaAppUi.h"
+// ]]] end generated region [Generated User Includes]
+
+/**
+ * @brief Constructs the document class for the application.
+ * @param anApplication the application instance
+ */
+CpjsuaDocument::CpjsuaDocument( CEikApplication& anApplication )
+	: CAknDocument( anApplication )
+	{
+	}
+
+/**
+ * @brief Completes the second phase of Symbian object construction. 
+ * Put initialization code that could leave here.  
+ */ 
+void CpjsuaDocument::ConstructL()
+	{
+	}
+	
+/**
+ * Symbian OS two-phase constructor.
+ *
+ * Creates an instance of CpjsuaDocument, constructs it, and
+ * returns it.
+ *
+ * @param aApp the application instance
+ * @return the new CpjsuaDocument
+ */
+CpjsuaDocument* CpjsuaDocument::NewL( CEikApplication& aApp )
+	{
+	CpjsuaDocument* self = new ( ELeave ) CpjsuaDocument( aApp );
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	CleanupStack::Pop( self );
+	return self;
+	}
+
+/**
+ * @brief Creates the application UI object for this document.
+ * @return the new instance
+ */	
+CEikAppUi* CpjsuaDocument::CreateAppUiL()
+	{
+	return new ( ELeave ) CpjsuaAppUi;
+	}
+				
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/wm/main_wm.c b/jni/libpjsip/sources/pjsip-apps/src/pjsua/wm/main_wm.c
new file mode 100644
index 0000000..d9c2139
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/wm/main_wm.c
@@ -0,0 +1,370 @@
+/* $Id: main_wm.c 4492 2013-04-23 10:59:52Z nanang $ */
+/* 
+ * Copyright (C) 2013 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 <winuserm.h>
+#include <aygshell.h>
+#include "..\pjsua_app.h"
+#include "..\pjsua_app_config.h"
+
+#define MAINWINDOWCLASS TEXT("PjsuaDlg")
+#define MAINWINDOWTITLE TEXT("PJSUA")
+#define LOGO_PATH TEXT("\\Program Files\\pjsua\\pjsua.bmp")
+
+#define WM_APP_INIT	WM_USER + 1
+#define WM_APP_DESTROY	WM_USER + 2
+#define WM_APP_RESTART	WM_USER + 3
+
+static HINSTANCE	 g_hInst;
+static HWND		 g_hWndMenuBar;
+static HWND		 g_hWndMain;
+static HWND		 g_hWndLbl;
+static HWND		 g_hWndImg;
+static HBITMAP		 g_hBmp;
+
+static int		 start_argc;
+static char	       **start_argv;
+
+/* Helper funtions to init/destroy the pjsua */
+static void PjsuaInit();
+static void PjsuaDestroy();
+
+/* pjsua app callbacks */
+static void PjsuaOnStarted(pj_status_t status, const char* title);
+static void PjsuaOnStopped(pj_bool_t restart, int argc, char** argv);
+static void PjsuaOnConfig(pjsua_app_config *cfg);
+
+LRESULT CALLBACK DialogProc(const HWND hWnd,
+			    const UINT Msg, 
+			    const WPARAM wParam,
+			    const LPARAM lParam) 
+{   
+    LRESULT res = 0;
+
+    switch (Msg) {
+    case WM_CREATE:
+	g_hWndMain = hWnd;
+	break;
+
+    case WM_COMMAND: /* Exit menu */
+    case WM_CLOSE:
+	PostQuitMessage(0);
+	break;
+
+    case WM_HOTKEY:
+	/* Exit app when back is pressed. */
+	if (VK_TBACK == HIWORD(lParam) && (0 != (MOD_KEYUP & LOWORD(lParam)))) {
+	    PostQuitMessage(0);
+	} else {
+	    return DefWindowProc(hWnd, Msg, wParam, lParam);
+	}
+	break;
+
+    case WM_CTLCOLORSTATIC:
+	/* Set text and background color for static windows */
+	SetTextColor((HDC)wParam, RGB(255, 255, 255));
+	SetBkColor((HDC)wParam, RGB(0, 0, 0));
+	return (LRESULT)GetStockObject(BLACK_BRUSH);
+
+    case WM_APP_INIT:
+    case WM_APP_RESTART:
+	PjsuaInit();
+	break;
+
+    case WM_APP_DESTROY:
+	PostQuitMessage(0);
+	break;
+
+    default:
+	return DefWindowProc(hWnd, Msg, wParam, lParam);
+    }
+
+    return res;
+}
+
+
+/* === GUI === */
+
+pj_status_t GuiInit()
+{
+    WNDCLASS wc;
+    HWND hWnd = NULL;	
+    RECT r;
+    DWORD dwStyle;
+    enum { LABEL_HEIGHT = 30 };
+    enum { MENU_ID_EXIT = 50000 };
+    BITMAP bmp;
+    HMENU hRootMenu;
+    SHMENUBARINFO mbi;
+
+    pj_status_t status  = PJ_SUCCESS;
+    
+    /* Check if app is running. If it's running then focus on the window */
+    hWnd = FindWindow(MAINWINDOWCLASS, MAINWINDOWTITLE);
+
+    if (NULL != hWnd) {
+	SetForegroundWindow(hWnd);    
+	return status;
+    }
+
+    wc.style = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc = (WNDPROC)DialogProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hInstance = g_hInst;
+    wc.hIcon = 0;
+    wc.hCursor = 0;
+    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+    wc.lpszMenuName	= 0;
+    wc.lpszClassName = MAINWINDOWCLASS;
+    
+    if (!RegisterClass(&wc) != 0) {
+	DWORD err = GetLastError();
+	return PJ_RETURN_OS_ERROR(err);
+    }
+
+    /* Create the app. window */
+    g_hWndMain = CreateWindow(MAINWINDOWCLASS, MAINWINDOWTITLE,
+			      WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 
+			      CW_USEDEFAULT, CW_USEDEFAULT,
+			      (HWND)NULL, NULL, g_hInst, (LPSTR)NULL);
+    if (g_hWndMain == NULL) {
+	DWORD err = GetLastError();
+	return PJ_RETURN_OS_ERROR(err);
+    }
+
+    /* Create exit menu */
+    hRootMenu = CreateMenu();
+    AppendMenu(hRootMenu, MF_STRING, MENU_ID_EXIT, L"Exit");
+
+    /* Initialize menubar */
+    ZeroMemory(&mbi, sizeof(SHMENUBARINFO));
+    mbi.cbSize      = sizeof(SHMENUBARINFO);
+    mbi.hwndParent  = g_hWndMain;
+    mbi.dwFlags	    = SHCMBF_HIDESIPBUTTON|SHCMBF_HMENU;
+    mbi.nToolBarId  = (UINT)hRootMenu;
+    mbi.hInstRes    = g_hInst;
+
+    if (FALSE == SHCreateMenuBar(&mbi)) {
+	DWORD err = GetLastError();
+        return PJ_RETURN_OS_ERROR(err);
+    }
+
+    /* Store menu window handle */
+    g_hWndMenuBar = mbi.hwndMB;
+
+    /* Show the menu */
+    DrawMenuBar(g_hWndMain);
+    ShowWindow(g_hWndMenuBar, SW_SHOW);
+
+    /* Override back button */
+    SendMessage(g_hWndMenuBar, SHCMBM_OVERRIDEKEY, VK_TBACK,
+	    MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY,
+	    SHMBOF_NODEFAULT | SHMBOF_NOTIFY));
+
+    /* Get main window size */
+    GetClientRect(g_hWndMain, &r);
+#if defined(WIN32_PLATFORM_PSPC) && WIN32_PLATFORM_PSPC != 0
+    /* Adjust the height for PocketPC platform */
+    r.bottom -= GetSystemMetrics(SM_CYMENU);
+#endif
+
+    /* Create logo */
+    g_hBmp = SHLoadDIBitmap(LOGO_PATH); /* for jpeg, uses SHLoadImageFile() */
+    if (g_hBmp == NULL) {
+	DWORD err = GetLastError();
+	return PJ_RETURN_OS_ERROR(err);
+    }
+    GetObject(g_hBmp, sizeof(bmp), &bmp);
+
+    dwStyle = SS_CENTERIMAGE | SS_REALSIZEIMAGE | SS_BITMAP |
+	      WS_CHILD | WS_VISIBLE;
+    g_hWndImg = CreateWindow(TEXT("STATIC"), NULL, dwStyle,
+			     (r.right-r.left-bmp.bmWidth)/2,
+			     (r.bottom-r.top-bmp.bmHeight)/2,
+			     bmp.bmWidth, bmp.bmHeight,
+			     g_hWndMain, (HMENU)0, g_hInst, NULL);
+    if (g_hWndImg == NULL) {
+	DWORD err = GetLastError();
+	return PJ_RETURN_OS_ERROR(err);
+    }
+    SendMessage(g_hWndImg, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)g_hBmp);
+
+    /* Create label */
+    dwStyle = WS_CHILD | WS_VISIBLE | ES_CENTER;
+    g_hWndLbl = CreateWindow(TEXT("STATIC"), NULL, dwStyle,
+		0, r.bottom-LABEL_HEIGHT, r.right-r.left, LABEL_HEIGHT,
+                g_hWndMain, (HMENU)0, g_hInst, NULL);
+    if (g_hWndLbl == NULL) {
+	DWORD err = GetLastError();
+	return PJ_RETURN_OS_ERROR(err);
+    }
+    SetWindowText(g_hWndLbl, _T("Please wait.."));
+
+    return status;
+}
+
+
+pj_status_t GuiStart()
+{
+    MSG msg;
+    while (GetMessage(&msg, NULL, 0, 0)) {
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
+    }
+
+    return (msg.wParam);
+}
+
+void GuiDestroy(void)
+{
+    if (g_hWndMain) {
+	DestroyWindow(g_hWndMain);
+	g_hWndMain = NULL;
+    }
+    if (g_hWndMenuBar) {
+	DestroyWindow(g_hWndMenuBar);
+	g_hWndMenuBar = NULL;
+    }
+    if (g_hWndLbl) {
+	DestroyWindow(g_hWndLbl);
+	g_hWndLbl = NULL;
+    }
+    if (g_hWndImg) {
+	DestroyWindow(g_hWndImg);
+	g_hWndImg = NULL;
+    }
+    if (g_hBmp) {
+	DeleteObject(g_hBmp);
+	g_hBmp = NULL;
+    }
+    UnregisterClass(MAINWINDOWCLASS, g_hInst);
+}
+
+/* === ENGINE === */
+
+/* Called when pjsua is started */
+void PjsuaOnStarted(pj_status_t status, const char* title)
+{
+    wchar_t wtitle[128];
+    char err_msg[128];
+
+    if (status != PJ_SUCCESS || title == NULL) {
+	char err_str[PJ_ERR_MSG_SIZE];
+	pj_strerror(status, err_str, sizeof(err_str));
+	pj_ansi_snprintf(err_msg, sizeof(err_msg), "%s: %s",
+			 (title?title:"App start error"), err_str);
+	title = err_msg;
+    }
+
+    pj_ansi_to_unicode(title, strlen(title), wtitle, PJ_ARRAY_SIZE(wtitle));
+    SetWindowText(g_hWndLbl, wtitle);
+}
+
+/* Called when pjsua is stopped */
+void PjsuaOnStopped(pj_bool_t restart, int argc, char** argv)
+{
+    if (restart) {
+	start_argc = argc;
+	start_argv = argv;
+
+	// Schedule Lib Restart
+	PostMessage(g_hWndMain, WM_APP_RESTART, 0, 0);
+    } else {
+	/* Destroy & quit GUI, e.g: clean up window, resources  */
+	PostMessage(g_hWndMain, WM_APP_DESTROY, 0, 0);
+    }
+}
+
+/* Called before pjsua initializing config. */
+void PjsuaOnConfig(pjsua_app_config *cfg)
+{
+    PJ_UNUSED_ARG(cfg);
+}
+
+void PjsuaInit()
+{
+    pjsua_app_cfg_t app_cfg;
+    pj_status_t status;
+
+    /* Destroy pjsua app first */
+    pjsua_app_destroy();
+
+    /* Init pjsua app */
+    pj_bzero(&app_cfg, sizeof(app_cfg));
+    app_cfg.argc = start_argc;
+    app_cfg.argv = start_argv;
+    app_cfg.on_started = &PjsuaOnStarted;
+    app_cfg.on_stopped = &PjsuaOnStopped;
+    app_cfg.on_config_init = &PjsuaOnConfig;
+
+    SetWindowText(g_hWndLbl, _T("Initializing.."));
+    status = pjsua_app_init(&app_cfg);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+    
+    SetWindowText(g_hWndLbl, _T("Starting.."));
+    status = pjsua_app_run(PJ_FALSE);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+on_return:
+    if (status != PJ_SUCCESS)
+	SetWindowText(g_hWndLbl, _T("Initialization failed"));
+}
+
+void PjsuaDestroy()
+{
+    pjsua_app_destroy();
+}
+
+/* === MAIN === */
+
+int WINAPI WinMain(
+    HINSTANCE hInstance,
+    HINSTANCE hPrevInstance,
+    LPWSTR lpCmdLine,
+    int nShowCmd
+)
+{
+    int status;
+
+    PJ_UNUSED_ARG(hPrevInstance);
+    PJ_UNUSED_ARG(lpCmdLine);
+    PJ_UNUSED_ARG(nShowCmd);
+
+    // store the hInstance in global
+    g_hInst = hInstance;
+
+    // Start GUI
+    status = GuiInit();
+    if (status != 0)
+	goto on_return;
+
+    // Setup args and start pjsua
+    start_argc = pjsua_app_def_argc;
+    start_argv = (char**)pjsua_app_def_argv;
+    PostMessage(g_hWndMain, WM_APP_INIT, 0, 0);
+
+    status = GuiStart();
+	
+on_return:
+    PjsuaDestroy();
+    GuiDestroy();
+
+    return status;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsua/wm/pjsua.bmp b/jni/libpjsip/sources/pjsip-apps/src/pjsua/wm/pjsua.bmp
new file mode 100644
index 0000000..6fd0c95
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsua/wm/pjsua.bmp
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsystest/gui.h b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/gui.h
new file mode 100644
index 0000000..ae7d8f4
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/gui.h
@@ -0,0 +1,72 @@
+/* $Id: gui.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 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 __GUI_H__
+#define __GUI_H__
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+typedef char gui_title[32];
+
+typedef void (*gui_menu_handler) (void);
+
+typedef struct gui_menu 
+{
+    gui_title		 title;
+    gui_menu_handler	 handler;
+    unsigned		 submenu_cnt;
+    struct gui_menu	*submenus[16];
+} gui_menu;
+
+enum gui_flag 
+{
+    WITH_OK = 0,
+    WITH_YESNO = 1,
+    WITH_OKCANCEL = 2
+};
+
+enum gui_key
+{
+    KEY_CANCEL = '9',
+    KEY_NO = '0',
+    KEY_YES = '1',
+    KEY_OK = '1',
+};
+
+/* Initialize GUI with the menus and stuff */
+pj_status_t gui_init(gui_menu *menu);
+
+/* Run GUI main loop */
+pj_status_t gui_start(gui_menu *menu);
+
+/* Signal GUI mainloop to stop */
+void gui_destroy(void);
+
+/* AUX: display messagebox */
+enum gui_key gui_msgbox(const char *title, const char *message, enum gui_flag flag);
+
+/* AUX: sleep */
+void gui_sleep(unsigned sec);
+
+
+PJ_END_DECL
+
+
+#endif	/* __GUI_H__ */
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsystest/main_console.c b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/main_console.c
new file mode 100644
index 0000000..02aa3f2
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/main_console.c
@@ -0,0 +1,144 @@
+/* $Id: main_console.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 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 "systest.h"
+#include "gui.h"
+#include <stdio.h>
+#include <pjlib.h>
+
+static pj_bool_t console_quit;
+
+enum gui_key gui_msgbox(const char *title, const char *message, enum gui_flag flag)
+{
+    puts(title);
+    puts(message);
+
+    for (;;) {
+	char input[10], *ret;
+
+	if (flag == WITH_YESNO)
+	    printf("%c:Yes  %c:No  ", KEY_YES, KEY_NO);
+	else if (flag == WITH_OK)
+	    printf("%c:OK  ", KEY_OK);
+	else if (flag == WITH_OKCANCEL)
+	    printf("%c:OK  %c:Cancel  ", KEY_OK, KEY_CANCEL);
+	puts("");
+
+	ret = fgets(input, sizeof(input), stdin);
+	if (!ret)
+	    return KEY_CANCEL;
+
+	if (input[0]==KEY_NO || input[0]==KEY_YES || input[0]==KEY_CANCEL)
+	    return (enum gui_key)input[0];
+    }
+}
+
+pj_status_t gui_init(gui_menu *menu)
+{
+    PJ_UNUSED_ARG(menu);
+    return PJ_SUCCESS;
+}
+
+static void print_menu(const char *indent, char *menu_id, gui_menu *menu)
+{
+    char child_indent[16];
+    unsigned i;
+
+    pj_ansi_snprintf(child_indent, sizeof(child_indent), "%s  ", indent);
+
+    printf("%s%s: %s\n", indent, menu_id, menu->title);
+
+    for (i=0; i<menu->submenu_cnt; ++i) {
+	char child_id[10];
+
+	pj_ansi_sprintf(child_id, "%s%u", menu_id, i);
+
+	if (!menu->submenus[i])
+	    puts("");
+	else
+	    print_menu(child_indent, child_id, menu->submenus[i]);
+    }
+}
+
+pj_status_t gui_start(gui_menu *menu)
+{
+    while (!console_quit) {
+	unsigned i;
+	char input[10], *p;
+	gui_menu *choice;
+
+	puts("M E N U :");
+	puts("---------");
+	for (i=0; i<menu->submenu_cnt; ++i) {
+	    char menu_id[4];
+	    pj_ansi_sprintf(menu_id, "%u", i);
+	    print_menu("", menu_id, menu->submenus[i]);
+	}
+	puts("");
+	printf("Enter the menu number: ");
+
+	if (!fgets(input, sizeof(input), stdin))
+	    break;
+
+	p = input;
+	choice = menu;
+	while (*p && *p!='\r' && *p!='\n') {
+	    unsigned d = (*p - '0');
+	    if (d < 0 || d >= choice->submenu_cnt) {
+		puts("Invalid selection");
+		choice = NULL;
+		break;
+	    }
+
+	    choice = choice->submenus[d];
+	    ++p;
+	}
+
+	if (choice && *p!='\r' && *p!='\n') {
+	    puts("Invalid characters entered");
+	    continue;
+	}
+
+	if (choice && choice->handler)
+	    (*choice->handler)();
+    }
+
+    return PJ_SUCCESS;
+}
+
+void gui_destroy(void)
+{
+    console_quit = PJ_TRUE;
+}
+
+void gui_sleep(unsigned sec)
+{
+    pj_thread_sleep(sec * 1000);
+}
+
+int main()
+{
+    if (systest_init() != PJ_SUCCESS)
+	return 1;
+
+    systest_run();
+    systest_deinit();
+
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsystest/main_wm.c b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/main_wm.c
new file mode 100644
index 0000000..aaaac1e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/main_wm.c
@@ -0,0 +1,444 @@
+/* $Id: main_wm.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 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 "gui.h"
+#include "systest.h"
+#include <windows.h>
+
+
+#include "gui.h"
+#include <pjlib.h>
+#include <windows.h>
+#include <winuserm.h>
+#include <aygshell.h>
+
+#define MAINWINDOWCLASS TEXT("SysTestDlg")
+#define MAINWINDOWTITLE TEXT("PJSYSTEST")
+
+typedef struct menu_handler_t {
+    UINT		 id;
+    gui_menu_handler	 handler;
+} menu_handler_t;
+
+static HINSTANCE	 g_hInst;
+static HWND		 g_hWndMenuBar;
+static HWND		 g_hWndMain;
+static HWND		 g_hWndLog;
+static pj_thread_t	*g_log_thread;
+static gui_menu		*g_menu;
+static unsigned		 g_menu_handler_cnt;
+static menu_handler_t	 g_menu_handlers[64];
+
+static pj_log_func	*g_log_writer_orig;
+
+static pj_status_t gui_update_menu(gui_menu *menu);
+
+static void log_writer(int level, const char *buffer, int len)
+{
+    wchar_t buf[512];
+    int cur_len;
+
+    PJ_UNUSED_ARG(level);
+
+    pj_ansi_to_unicode(buffer, len, buf, 512);
+
+    if (!g_hWndLog)
+	return;
+
+    /* For now, ignore log messages from other thread to avoid deadlock */
+    if (g_log_thread == pj_thread_this()) {
+	cur_len = (int)SendMessage(g_hWndLog, WM_GETTEXTLENGTH, 0, 0);
+	SendMessage(g_hWndLog, EM_SETSEL, (WPARAM)cur_len, (LPARAM)cur_len);
+	SendMessage(g_hWndLog, EM_REPLACESEL, (WPARAM)0, (LPARAM)buf);
+    }
+    
+    //uncomment to forward to the original log writer
+    if (g_log_writer_orig)
+	(*g_log_writer_orig)(level, buffer, len);
+}
+
+/* execute menu handler for id menu specified, return FALSE if menu handler 
+ * is not found.
+ */
+static BOOL handle_menu(UINT id)
+{
+    unsigned i;
+
+    for (i = 0; i < g_menu_handler_cnt; ++i) {
+	if (g_menu_handlers[i].id == id) {
+	    /* menu handler found, execute it */
+	    (*g_menu_handlers[i].handler)();
+	    return TRUE;
+	}
+    }
+
+    return FALSE;
+}
+
+/* generate submenu and register the menu handler, then return next menu id */
+static UINT generate_submenu(HMENU parent, UINT id_start, gui_menu *menu)
+{
+    unsigned i;
+    UINT id = id_start;
+
+    if (!menu)
+	return id;
+
+    /* generate submenu */
+    for (i = 0; i < menu->submenu_cnt; ++i) {
+
+	if (menu->submenus[i] == NULL) {
+
+	    /* add separator */
+	    AppendMenu(parent, MF_SEPARATOR, 0, 0);
+	
+	}  else if (menu->submenus[i]->submenu_cnt != 0) {
+	    
+	    /* this submenu item has children, generate popup menu */
+	    HMENU hMenu;
+	    wchar_t buf[64];
+	    
+	    pj_ansi_to_unicode(menu->submenus[i]->title, 
+			       pj_ansi_strlen(menu->submenus[i]->title),
+			       buf, 64);
+
+	    hMenu = CreatePopupMenu();
+	    AppendMenu(parent, MF_STRING|MF_ENABLED|MF_POPUP, (UINT)hMenu, buf);
+	    id = generate_submenu(hMenu, id, menu->submenus[i]);
+
+	} else {
+
+	    /* this submenu item is leaf, register the handler */
+	    wchar_t buf[64];
+	    
+	    pj_ansi_to_unicode(menu->submenus[i]->title, 
+			       pj_ansi_strlen(menu->submenus[i]->title),
+			       buf, 64);
+
+	    AppendMenu(parent, MF_STRING, id, buf);
+
+	    if (menu->submenus[i]->handler) {
+		g_menu_handlers[g_menu_handler_cnt].id = id;
+		g_menu_handlers[g_menu_handler_cnt].handler = 
+					menu->submenus[i]->handler;
+		++g_menu_handler_cnt;
+	    }
+
+	    ++id;
+	}
+    }
+
+    return id;
+}
+
+BOOL InitDialog()
+{
+    /* update menu */
+    if (gui_update_menu(g_menu) != PJ_SUCCESS)
+	return FALSE;
+
+    return TRUE;
+}
+
+LRESULT CALLBACK DialogProc(const HWND hWnd,
+			    const UINT Msg, 
+			    const WPARAM wParam,
+			    const LPARAM lParam) 
+{   
+    LRESULT res = 0;
+
+    switch (Msg) {
+    case WM_CREATE:
+	g_hWndMain = hWnd;
+	if (FALSE == InitDialog()){
+	    DestroyWindow(g_hWndMain);
+	}
+	break;
+
+    case WM_CLOSE:
+	DestroyWindow(g_hWndMain);
+	break;
+
+    case WM_DESTROY:
+	if (g_hWndMenuBar)
+	    DestroyWindow(g_hWndMenuBar);
+	g_hWndMenuBar = NULL;
+	g_hWndMain = NULL;
+        PostQuitMessage(0);
+        break;
+
+    case WM_HOTKEY:
+	/* Exit app when back is pressed. */
+	if (VK_TBACK == HIWORD(lParam) && (0 != (MOD_KEYUP & LOWORD(lParam)))) {
+	    DestroyWindow(g_hWndMain);
+	} else {
+	    return DefWindowProc(hWnd, Msg, wParam, lParam);
+	}
+	break;
+
+    case WM_COMMAND:
+	res = handle_menu(LOWORD(wParam));
+	break;
+
+    default:
+	return DefWindowProc(hWnd, Msg, wParam, lParam);
+    }
+
+    return res;
+}
+
+
+/* === API === */
+
+pj_status_t gui_init(gui_menu *menu)
+{
+    WNDCLASS wc;
+    HWND hWnd = NULL;	
+    RECT r;
+    DWORD dwStyle;
+
+    pj_status_t status  = PJ_SUCCESS;
+    
+    /* Check if app is running. If it's running then focus on the window */
+    hWnd = FindWindow(MAINWINDOWCLASS, MAINWINDOWTITLE);
+
+    if (NULL != hWnd) {
+	SetForegroundWindow(hWnd);    
+	return status;
+    }
+
+    g_menu = menu;
+
+    wc.style = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc = (WNDPROC)DialogProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hInstance = g_hInst;
+    wc.hIcon = 0;
+    wc.hCursor = 0;
+    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+    wc.lpszMenuName	= 0;
+    wc.lpszClassName = MAINWINDOWCLASS;
+    
+    if (!RegisterClass(&wc) != 0) {
+	DWORD err = GetLastError();
+	return PJ_RETURN_OS_ERROR(err);
+    }
+
+    /* Create the app. window */
+    g_hWndMain = CreateWindow(MAINWINDOWCLASS, MAINWINDOWTITLE,
+			      WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 
+			      CW_USEDEFAULT, CW_USEDEFAULT,
+			      (HWND)NULL, NULL, g_hInst, (LPSTR)NULL);
+
+    /* Create edit control to print log */
+    GetClientRect(g_hWndMain, &r);
+    dwStyle = WS_CHILD | WS_VISIBLE | WS_VSCROLL |
+	      ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL | ES_LEFT;
+    g_hWndLog = CreateWindow(
+                TEXT("EDIT"),   // Class name
+                NULL,           // Window text
+                dwStyle,        // Window style
+                0,		// x-coordinate of the upper-left corner
+                0,              // y-coordinate of the upper-left corner
+		r.right-r.left, // Width of the window for the edit
+                                // control
+		r.bottom-r.top, // Height of the window for the edit
+                                // control
+                g_hWndMain,     // Window handle to the parent window
+                (HMENU) 0,	// Control identifier
+                g_hInst,        // Instance handle
+                NULL);          // Specify NULL for this parameter when 
+                                // you create a control
+
+    /* Resize the log */
+    if (g_hWndMenuBar) {
+	RECT r_menu = {0};
+
+	GetWindowRect(g_hWndLog, &r);
+	GetWindowRect(g_hWndMenuBar, &r_menu);
+	if (r.bottom > r_menu.top) {
+	    MoveWindow(g_hWndLog, 0, 0, r.right-r.left, 
+		       (r.bottom-r.top)-(r_menu.bottom-r_menu.top), TRUE);
+	}
+    }
+
+    /* Focus it, so SP user can scroll the log */
+    SetFocus(g_hWndLog);
+
+    /* Get the log thread */
+    g_log_thread = pj_thread_this();
+
+    /* Redirect log & update log decor setting */
+    /*
+    log_decor = pj_log_get_decor();
+    log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_CR;
+    pj_log_set_decor(log_decor);
+    */
+    g_log_writer_orig = pj_log_get_log_func();
+    pj_log_set_log_func(&log_writer);
+
+    return status;
+}
+
+static pj_status_t gui_update_menu(gui_menu *menu)
+{
+    enum { MENU_ID_START = 50000 };
+    UINT id_start = MENU_ID_START;
+    HMENU hRootMenu;
+    SHMENUBARINFO mbi;
+
+    /* delete existing menu */
+    if (g_hWndMenuBar) {
+	DestroyWindow(g_hWndMenuBar);
+	g_hWndMenuBar = NULL;
+    }
+
+    /* delete menu handler map */
+    g_menu_handler_cnt = 0;
+
+    /* smartphone can only have two root menus */
+    pj_assert(menu->submenu_cnt <= 2);
+
+    /* generate menu tree */
+    hRootMenu = CreateMenu();
+    id_start = generate_submenu(hRootMenu, id_start, menu);
+
+    /* initialize menubar */
+    ZeroMemory(&mbi, sizeof(SHMENUBARINFO));
+    mbi.cbSize      = sizeof(SHMENUBARINFO);
+    mbi.hwndParent  = g_hWndMain;
+    mbi.dwFlags	    = SHCMBF_HIDESIPBUTTON|SHCMBF_HMENU;
+    mbi.nToolBarId  = (UINT)hRootMenu;
+    mbi.hInstRes    = g_hInst;
+
+    if (FALSE == SHCreateMenuBar(&mbi)) {
+	DWORD err = GetLastError();
+        return PJ_RETURN_OS_ERROR(err);
+    }
+
+    /* store menu window handle */
+    g_hWndMenuBar = mbi.hwndMB;
+
+    /* store current menu */
+    g_menu = menu;
+
+    /* show the menu */
+    DrawMenuBar(g_hWndMain);
+    ShowWindow(g_hWndMenuBar, SW_SHOW);
+
+    /* override back button */
+    SendMessage(g_hWndMenuBar, SHCMBM_OVERRIDEKEY, VK_TBACK,
+	    MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY,
+	    SHMBOF_NODEFAULT | SHMBOF_NOTIFY));
+
+
+    return PJ_SUCCESS;
+}
+
+enum gui_key gui_msgbox(const char *title, const char *message, enum gui_flag flag)
+{
+    wchar_t buf_title[64];
+    wchar_t buf_msg[512];
+    UINT wflag = 0;
+    int retcode;
+
+    pj_ansi_to_unicode(title, pj_ansi_strlen(title), buf_title, 64);
+    pj_ansi_to_unicode(message, pj_ansi_strlen(message), buf_msg, 512);
+
+    switch (flag) {
+    case WITH_OK:
+	wflag = MB_OK;
+	break;
+    case WITH_YESNO:
+	wflag = MB_YESNO;
+	break;
+    case WITH_OKCANCEL:
+	wflag = MB_OKCANCEL;
+	break;
+    }
+
+    retcode = MessageBox(g_hWndMain, buf_msg, buf_title, wflag);
+
+    switch (retcode) {
+    case IDOK:
+	return KEY_OK;
+    case IDYES:
+	return KEY_YES;
+    case IDNO:
+	return KEY_NO;
+    default:
+	return KEY_CANCEL;
+    }
+}
+
+void gui_sleep(unsigned sec)
+{
+    pj_thread_sleep(sec * 1000);
+}
+
+pj_status_t gui_start(gui_menu *menu)
+{
+    MSG msg;
+
+    PJ_UNUSED_ARG(menu);
+
+    while (GetMessage(&msg, NULL, 0, 0)) {
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
+    }
+    
+    return (msg.wParam);
+}
+
+void gui_destroy(void)
+{
+    if (g_hWndMain) {
+	DestroyWindow(g_hWndMain);
+	g_hWndMain = NULL;
+    }
+}
+
+
+int WINAPI WinMain(
+    HINSTANCE hInstance,
+    HINSTANCE hPrevInstance,
+    LPWSTR lpCmdLine,
+    int nShowCmd
+)
+{
+    int status;
+
+    PJ_UNUSED_ARG(hPrevInstance);
+    PJ_UNUSED_ARG(lpCmdLine);
+    PJ_UNUSED_ARG(nShowCmd);
+
+    // store the hInstance in global
+    g_hInst = hInstance;
+
+    status = systest_init();
+    if (status != 0)
+	goto on_return;
+
+    status = systest_run();
+	
+on_return:
+    systest_deinit();
+
+    return status;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsystest/pjsystest_wince.rc b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/pjsystest_wince.rc
new file mode 100644
index 0000000..c76ef68
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/pjsystest_wince.rc
@@ -0,0 +1,108 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#include "afxres.h"

+

+/////////////////////////////////////////////////////////////////////////////

+#undef APSTUDIO_READONLY_SYMBOLS

+

+/////////////////////////////////////////////////////////////////////////////

+// English (U.S.) resources

+

+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

+#ifdef _WIN32

+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

+#pragma code_page(1252)

+#endif //_WIN32

+

+#ifdef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// TEXTINCLUDE

+//

+

+1 TEXTINCLUDE 

+BEGIN

+    "resource.h\0"

+END

+

+2 TEXTINCLUDE 

+BEGIN

+    "#include ""afxres.h""\r\n"

+    "\0"

+END

+

+3 TEXTINCLUDE 

+BEGIN

+    "#include ""pjsystest_wince.rc2""\r\n"

+    "\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Dialog

+//

+

+IDD_MAIN_DIALOG DIALOG  0, 0, 82, 73

+STYLE DS_SETFONT | WS_VISIBLE | WS_VSCROLL

+FONT 8, "MS Sans Serif"

+BEGIN

+    EDITTEXT        IDC_EDIT1,7,7,57,59,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// DESIGNINFO

+//

+

+#ifdef APSTUDIO_INVOKED

+GUIDELINES DESIGNINFO 

+BEGIN

+    IDD_MAIN_DIALOG, DIALOG

+    BEGIN

+        LEFTMARGIN, 7

+        RIGHTMARGIN, 64

+        TOPMARGIN, 7

+        BOTTOMMARGIN, 66

+    END

+END

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// String Table

+//

+

+STRINGTABLE 

+BEGIN

+    IDS_MAIN_TITLE          "PJSYSTEST"

+END

+

+#endif    // English (U.S.) resources

+/////////////////////////////////////////////////////////////////////////////

+

+

+

+#ifndef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 3 resource.

+//

+#include "pjsystest_wince.rc2"

+

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

+

diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsystest/pjsystest_wince.rc2 b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/pjsystest_wince.rc2
new file mode 100644
index 0000000..3bee66b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/pjsystest_wince.rc2
@@ -0,0 +1,10 @@
+#ifdef APSTUDIO_INVOKED

+	#error this file is not editable by Microsoft Visual C++

+#endif //APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+// Add manually edited resources here...

+

+

+/////////////////////////////////////////////////////////////////////////////

diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsystest/resource.h b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/resource.h
new file mode 100644
index 0000000..f5208b6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/resource.h
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by pjsystest_wince.rc
+//
+#define IDD_MAIN_DIALOG                 101
+#define IDS_MAIN_TITLE                  102
+#define IDC_EDIT1                       1001
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        103
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1002
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsystest/systest.c b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/systest.c
new file mode 100644
index 0000000..b90ce8f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/systest.c
@@ -0,0 +1,1371 @@
+/* $Id: systest.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 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 "systest.h"
+#include "gui.h"
+
+#define THIS_FILE "systest.c"
+
+unsigned    test_item_count;
+test_item_t test_items[SYSTEST_MAX_TEST];
+char	    doc_path[PATH_LENGTH] = {0};
+char	    res_path[PATH_LENGTH] = {0};
+char	    fpath[PATH_LENGTH];
+
+#define USER_ERROR  "User used said not okay"
+
+static void systest_wizard(void);
+static void systest_list_audio_devs(void);
+static void systest_display_settings(void);
+static void systest_play_tone(void);
+static void systest_play_wav1(void);
+static void systest_play_wav2(void);
+static void systest_rec_audio(void);
+static void systest_audio_test(void);
+static void systest_latency_test(void);
+static void systest_aec_test(void);
+static void exit_app(void);
+
+/* Menus */
+static gui_menu menu_exit = { "Exit", &exit_app };
+
+static gui_menu menu_wizard =  { "Run test wizard", &systest_wizard };
+static gui_menu menu_playtn = { "Play Tone", &systest_play_tone };
+static gui_menu menu_playwv1 = { "Play WAV File1", &systest_play_wav1 };
+static gui_menu menu_playwv2 = { "Play WAV File2", &systest_play_wav2 };
+static gui_menu menu_recaud  = { "Record Audio", &systest_rec_audio };
+static gui_menu menu_audtest = { "Device Test", &systest_audio_test };
+static gui_menu menu_calclat = { "Latency Test", &systest_latency_test };
+static gui_menu menu_sndaec = { "AEC/AES Test", &systest_aec_test };
+
+static gui_menu menu_listdev = { "View Devices", &systest_list_audio_devs };
+static gui_menu menu_getsets = { "View Settings", &systest_display_settings };
+
+static gui_menu menu_tests = { 
+    "Tests", NULL, 
+    10, 
+    {
+	&menu_wizard,
+	&menu_audtest, 
+	&menu_playtn,
+	&menu_playwv1,
+	&menu_playwv2,
+	&menu_recaud,
+	&menu_calclat,
+	&menu_sndaec,
+	NULL, 
+	&menu_exit
+    }
+};
+
+static gui_menu menu_options = { 
+    "Options", NULL, 
+    2, 
+    {
+	&menu_listdev,
+	&menu_getsets,
+    }
+};
+
+static gui_menu root_menu = { 
+    "Root", NULL, 2, {&menu_tests, &menu_options} 
+};
+
+/*****************************************************************/
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+PJ_INLINE(char *) add_path(const char *path, const char *fname)
+{
+    strncpy(fpath, path, PATH_LENGTH);
+    strncat(fpath, fname, PATH_LENGTH);
+    return fpath;
+}
+#else
+#   define add_path(path, fname) fname
+#endif
+
+static void exit_app(void)
+{
+    systest_save_result(add_path(doc_path, RESULT_OUT_PATH));
+    gui_destroy();
+}
+
+
+#include <pjsua-lib/pjsua.h>
+#include <pjmedia_audiodev.h>
+
+typedef struct systest_t
+{
+    pjsua_config	    ua_cfg;
+    pjsua_media_config	    media_cfg;
+    pjmedia_aud_dev_index   rec_id;
+    pjmedia_aud_dev_index   play_id;
+} systest_t;
+
+static systest_t systest;
+static char textbuf[600];
+
+/* Device ID to test */
+int systest_cap_dev_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
+int systest_play_dev_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
+
+static void systest_perror(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    char themsg[PJ_ERR_MSG_SIZE + 100];
+
+    if (status != PJ_SUCCESS)
+	pj_strerror(status, errmsg, sizeof(errmsg));
+    else
+	errmsg[0] = '\0';
+    
+    strcpy(themsg, title);
+    strncat(themsg, errmsg, sizeof(themsg)-1);
+    themsg[sizeof(themsg)-1] = '\0';
+
+    gui_msgbox("Error", themsg, WITH_OK);
+}
+
+test_item_t *systest_alloc_test_item(const char *title)
+{
+    test_item_t *ti;
+
+    if (test_item_count == SYSTEST_MAX_TEST) {
+	gui_msgbox("Error", "You have done too many tests", WITH_OK);
+	return NULL;
+    }
+
+    ti = &test_items[test_item_count++];
+    pj_bzero(ti, sizeof(*ti));
+    pj_ansi_strcpy(ti->title, title);
+
+    return ti;
+}
+
+/*****************************************************************************
+ * test: play simple ringback tone and hear it 
+ */
+static void systest_play_tone(void)
+{
+    /* Ringtones  */
+    #define RINGBACK_FREQ1	    440	    /* 400 */
+    #define RINGBACK_FREQ2	    480	    /* 450 */
+    #define RINGBACK_ON		    3000    /* 400 */
+    #define RINGBACK_OFF	    4000    /* 200 */
+    #define RINGBACK_CNT	    1	    /* 2   */
+    #define RINGBACK_INTERVAL	    4000    /* 2000 */
+
+    unsigned i, samples_per_frame;
+    pjmedia_tone_desc tone[RINGBACK_CNT];
+    pj_pool_t *pool = NULL;
+    pjmedia_port *ringback_port = NULL;
+    enum gui_key key;
+    int ringback_slot = -1;
+    test_item_t *ti;
+    pj_str_t name;
+    const char *title = "Audio Tone Playback Test";
+    pj_status_t status;
+
+    ti = systest_alloc_test_item(title);
+    if (!ti)
+	return;
+
+    key = gui_msgbox(title,
+		     "This test will play simple ringback tone to "
+		     "the speaker. Please listen carefully for audio "
+		     "impairments such as stutter. You may need "
+		     "to let this test running for a while to "
+		     "make sure that everything is okay. Press "
+		     "OK to start, CANCEL to skip",
+		     WITH_OKCANCEL);
+    if (key != KEY_OK) {
+	ti->skipped = PJ_TRUE;
+	return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Running %s", title));
+
+    pool = pjsua_pool_create("ringback", 512, 512);
+    samples_per_frame = systest.media_cfg.audio_frame_ptime * 
+			systest.media_cfg.clock_rate *
+			systest.media_cfg.channel_count / 1000;
+
+    /* Ringback tone (call is ringing) */
+    name = pj_str("ringback");
+    status = pjmedia_tonegen_create2(pool, &name, 
+				     systest.media_cfg.clock_rate,
+				     systest.media_cfg.channel_count, 
+				     samples_per_frame,
+				     16, PJMEDIA_TONEGEN_LOOP, 
+				     &ringback_port);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    pj_bzero(&tone, sizeof(tone));
+    for (i=0; i<RINGBACK_CNT; ++i) {
+	tone[i].freq1 = RINGBACK_FREQ1;
+	tone[i].freq2 = RINGBACK_FREQ2;
+	tone[i].on_msec = RINGBACK_ON;
+	tone[i].off_msec = RINGBACK_OFF;
+    }
+    tone[RINGBACK_CNT-1].off_msec = RINGBACK_INTERVAL;
+
+    status = pjmedia_tonegen_play(ringback_port, RINGBACK_CNT, tone,
+				  PJMEDIA_TONEGEN_LOOP);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    status = pjsua_conf_add_port(pool, ringback_port, &ringback_slot);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    status = pjsua_conf_connect(ringback_slot, 0);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    key = gui_msgbox(title,
+		     "Ringback tone should be playing now in the "
+		     "speaker. Press OK to stop. ", WITH_OK);
+
+    status = PJ_SUCCESS;
+
+on_return:
+    if (ringback_slot != -1)
+	pjsua_conf_remove_port(ringback_slot);
+    if (ringback_port)
+	pjmedia_port_destroy(ringback_port);
+    if (pool)
+	pj_pool_release(pool);
+
+    if (status != PJ_SUCCESS) {
+	systest_perror("Sorry we encounter error when initializing "
+		       "the tone generator: ", status);
+	ti->success = PJ_FALSE;
+	pj_strerror(status, ti->reason, sizeof(ti->reason));
+    } else {
+	key = gui_msgbox(title, "Is the audio okay?", WITH_YESNO);
+	ti->success = (key == KEY_YES);
+	if (!ti->success)
+	    pj_ansi_strcpy(ti->reason, USER_ERROR);
+    }
+    return;
+}
+
+/* Util: create file player, each time trying different paths until we get
+ * the file.
+ */
+static pj_status_t create_player(unsigned path_cnt, const char *paths[], 
+				 pjsua_player_id *p_id)
+{
+    pj_str_t name;
+    pj_status_t status = PJ_ENOTFOUND;
+    unsigned i;
+
+    for (i=0; i<path_cnt; ++i) {
+	status = pjsua_player_create(pj_cstr(&name, paths[i]), 0, p_id);
+	if (status == PJ_SUCCESS)
+	    return PJ_SUCCESS;
+    }
+    return status;
+}
+
+/*****************************************************************************
+ * test: play WAV file
+ */
+static void systest_play_wav(unsigned path_cnt, const char *paths[])
+{
+    pjsua_player_id play_id = PJSUA_INVALID_ID;
+    enum gui_key key;
+    test_item_t *ti;
+    const char *title = "WAV File Playback Test";
+    pj_status_t status;
+
+    ti = systest_alloc_test_item(title);
+    if (!ti)
+	return;
+
+    pj_ansi_snprintf(textbuf, sizeof(textbuf),
+		     "This test will play %s file to "
+		     "the speaker. Please listen carefully for audio "
+		     "impairments such as stutter. Let this test run "
+		     "for a while to make sure that everything is okay."
+		     " Press OK to start, CANCEL to skip",
+		     paths[0]);
+
+    key = gui_msgbox(title, textbuf,
+		     WITH_OKCANCEL);
+    if (key != KEY_OK) {
+	ti->skipped = PJ_TRUE;
+	return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Running %s", title));
+
+    /* WAV port */
+    status = create_player(path_cnt, paths, &play_id);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    status = pjsua_conf_connect(pjsua_player_get_conf_port(play_id), 0);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    key = gui_msgbox(title,
+		     "WAV file should be playing now in the "
+		     "speaker. Press OK to stop. ", WITH_OK);
+
+    status = PJ_SUCCESS;
+
+on_return:
+    if (play_id != -1)
+	pjsua_player_destroy(play_id);
+
+    if (status != PJ_SUCCESS) {
+	systest_perror("Sorry we've encountered error", status);
+	ti->success = PJ_FALSE;
+	pj_strerror(status, ti->reason, sizeof(ti->reason));
+    } else {
+	key = gui_msgbox(title, "Is the audio okay?", WITH_YESNO);
+	ti->success = (key == KEY_YES);
+	if (!ti->success)
+	    pj_ansi_strcpy(ti->reason, USER_ERROR);
+    }
+    return;
+}
+
+static void systest_play_wav1(void)
+{
+    const char *paths[] = { add_path(res_path, WAV_PLAYBACK_PATH),
+			    ALT_PATH1 WAV_PLAYBACK_PATH };
+    systest_play_wav(PJ_ARRAY_SIZE(paths), paths);
+}
+
+static void systest_play_wav2(void)
+{
+    const char *paths[] = { add_path(res_path, WAV_TOCK8_PATH),
+			    ALT_PATH1 WAV_TOCK8_PATH};
+    systest_play_wav(PJ_ARRAY_SIZE(paths), paths);
+}
+
+
+/*****************************************************************************
+ * test: record audio 
+ */
+static void systest_rec_audio(void)
+{
+    const pj_str_t filename = pj_str(add_path(doc_path, WAV_REC_OUT_PATH));
+    pj_pool_t *pool = NULL;
+    enum gui_key key;
+    pjsua_recorder_id rec_id = PJSUA_INVALID_ID;
+    pjsua_player_id play_id = PJSUA_INVALID_ID;
+    pjsua_conf_port_id rec_slot = PJSUA_INVALID_ID;
+    pjsua_conf_port_id play_slot = PJSUA_INVALID_ID;
+    pj_status_t status = PJ_SUCCESS;
+    const char *title = "Audio Recording";
+    test_item_t *ti;
+
+    ti = systest_alloc_test_item(title);
+    if (!ti)
+	return;
+
+    key = gui_msgbox(title,
+		     "This test will allow you to record audio "
+		     "from the microphone, and playback the "
+		     "audio to the speaker. Press OK to start recording, "
+		     "CANCEL to skip.", 
+		     WITH_OKCANCEL);
+    if (key != KEY_OK) {
+	ti->skipped = PJ_TRUE;
+	return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Running %s", title));
+
+    pool = pjsua_pool_create("rectest", 512, 512);
+
+    status = pjsua_recorder_create(&filename, 0, NULL, -1, 0, &rec_id);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    rec_slot = pjsua_recorder_get_conf_port(rec_id);
+
+    status = pjsua_conf_connect(0, rec_slot);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    key = gui_msgbox(title,
+		     "Recording is in progress now, please say "
+		     "something in the microphone. Press OK "
+		     "to stop recording", WITH_OK);
+
+    pjsua_conf_disconnect(0, rec_slot);
+    rec_slot = PJSUA_INVALID_ID;
+    pjsua_recorder_destroy(rec_id);
+    rec_id = PJSUA_INVALID_ID;
+
+    status = pjsua_player_create(&filename, 0, &play_id);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    play_slot = pjsua_player_get_conf_port(play_id);
+
+    status = pjsua_conf_connect(play_slot, 0);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    key = gui_msgbox(title,
+		     "Recording has been stopped. "
+		     "The recorded audio is being played now to "
+		     "the speaker device, in a loop. Listen for "
+		     "any audio impairments. Press OK to stop.", 
+		     WITH_OK);
+
+on_return:
+    if (rec_slot != PJSUA_INVALID_ID)
+	pjsua_conf_disconnect(0, rec_slot);
+    if (rec_id != PJSUA_INVALID_ID)
+	pjsua_recorder_destroy(rec_id);
+    if (play_slot != PJSUA_INVALID_ID)
+	pjsua_conf_disconnect(play_slot, 0);
+    if (play_id != PJSUA_INVALID_ID)
+	pjsua_player_destroy(play_id);
+    if (pool)
+	pj_pool_release(pool);
+
+    if (status != PJ_SUCCESS) {
+	systest_perror("Sorry we encountered an error: ", status);
+	ti->success = PJ_FALSE;
+	pj_strerror(status, ti->reason, sizeof(ti->reason));
+    } else {
+	key = gui_msgbox(title, "Is the audio okay?", WITH_YESNO);
+	ti->success = (key == KEY_YES);
+	if (!ti->success) {
+	    pj_ansi_snprintf(textbuf, sizeof(textbuf),
+			     "You will probably need to copy the recorded "
+			     "WAV file %s to a desktop computer and analyze "
+			     "it, to find out whether it's a recording "
+			     "or playback problem.",
+			     WAV_REC_OUT_PATH);
+	    gui_msgbox(title, textbuf, WITH_OK);
+	    pj_ansi_strcpy(ti->reason, USER_ERROR);
+	}
+    }
+}
+
+
+/****************************************************************************
+ * test: audio system test
+ */
+static void systest_audio_test(void)
+{
+    enum {
+	GOOD_MAX_INTERVAL = 5,
+    };
+    const pjmedia_dir dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
+    pjmedia_aud_param param;
+    pjmedia_aud_test_results result;
+    pj_size_t textbufpos;
+    enum gui_key key;
+    unsigned problem_count = 0;
+    const char *problems[16];
+    char drifttext[120];
+    test_item_t *ti;
+    const char *title = "Audio Device Test";
+    pj_status_t status;
+
+    ti = systest_alloc_test_item(title);
+    if (!ti)
+	return;
+
+    key = gui_msgbox(title,
+		     "This will run an automated test for about "
+		     "ten seconds or so, and display some "
+		     "statistics about your sound device. "
+		     "Please don't do anything until the test completes. "
+		     "Press OK to start, or CANCEL to skip this test.",
+		     WITH_OKCANCEL);
+    if (key != KEY_OK) {
+	ti->skipped = PJ_TRUE;
+	return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Running %s", title));
+
+    /* Disable sound device in pjsua first */
+    pjsua_set_no_snd_dev();
+
+    /* Setup parameters */
+    status = pjmedia_aud_dev_default_param(systest.play_id, &param);
+    if (status != PJ_SUCCESS) {
+	systest_perror("Sorry we had error in pjmedia_aud_dev_default_param()", status);
+	pjsua_set_snd_dev(systest.rec_id, systest.play_id);
+	ti->success = PJ_FALSE;
+	pj_strerror(status, ti->reason, sizeof(ti->reason));
+	ti->reason[sizeof(ti->reason)-1] = '\0';
+	return;
+    }
+
+    param.dir = dir;
+    param.rec_id = systest.rec_id;
+    param.play_id = systest.play_id;
+    param.clock_rate = systest.media_cfg.snd_clock_rate;
+    param.channel_count = systest.media_cfg.channel_count;
+    param.samples_per_frame = param.clock_rate * param.channel_count * 
+			      systest.media_cfg.audio_frame_ptime / 1000;
+
+    /* Latency settings */
+    param.flags |= (PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY | 
+		    PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY);
+    param.input_latency_ms = systest.media_cfg.snd_rec_latency;
+    param.output_latency_ms = systest.media_cfg.snd_play_latency;
+
+    /* Run the test */
+    status = pjmedia_aud_test(&param, &result);
+    if (status != PJ_SUCCESS) {
+	systest_perror("Sorry we encountered error with the test", status);
+	pjsua_set_snd_dev(systest.rec_id, systest.play_id);
+	ti->success = PJ_FALSE;
+	pj_strerror(status, ti->reason, sizeof(ti->reason));
+	ti->reason[sizeof(ti->reason)-1] = '\0';
+	return;
+    }
+
+    /* Restore pjsua sound device */
+    pjsua_set_snd_dev(systest.rec_id, systest.play_id);
+
+    /* Analyze the result! */
+    strcpy(textbuf, "Here are the audio statistics:\r\n");
+    textbufpos = strlen(textbuf);
+
+    if (result.rec.frame_cnt==0) {
+	problems[problem_count++] = 
+	    "No audio frames were captured from the microphone. "
+	    "This means the audio device is not working properly.";
+    } else {
+	pj_ansi_snprintf(textbuf+textbufpos, 
+			 sizeof(textbuf)-textbufpos,
+			 "Rec : interval (min/max/avg/dev)=\r\n"
+			 "         %u/%u/%u/%u (ms)\r\n"
+			 "      max burst=%u\r\n",
+			 result.rec.min_interval,
+			 result.rec.max_interval,
+			 result.rec.avg_interval,
+			 result.rec.dev_interval,
+			 result.rec.max_burst);
+	textbufpos = strlen(textbuf);
+
+	if (result.rec.max_burst > GOOD_MAX_INTERVAL) {
+	    problems[problem_count++] = 
+		"Recording max burst is quite high";
+	}
+    }
+
+    if (result.play.frame_cnt==0) {
+	problems[problem_count++] = 
+	    "No audio frames were played to the speaker. "
+	    "This means the audio device is not working properly.";
+    } else {
+	pj_ansi_snprintf(textbuf+textbufpos, 
+			 sizeof(textbuf)-textbufpos,
+			 "Play: interval (min/max/avg/dev)=\r\n"
+			 "         %u/%u/%u/%u (ms)\r\n"
+			 "      burst=%u\r\n",
+			 result.play.min_interval,
+			 result.play.max_interval,
+			 result.play.avg_interval,
+			 result.play.dev_interval,
+			 result.play.max_burst);
+	textbufpos = strlen(textbuf);
+
+	if (result.play.max_burst > GOOD_MAX_INTERVAL) {
+	    problems[problem_count++] = 
+		"Playback max burst is quite high";
+	}
+    }
+
+    if (result.rec_drift_per_sec) {
+	const char *which = result.rec_drift_per_sec>=0 ? "faster" : "slower";
+	unsigned drift = result.rec_drift_per_sec>=0 ? 
+			    result.rec_drift_per_sec :
+			    -result.rec_drift_per_sec;
+
+	pj_ansi_snprintf(drifttext, sizeof(drifttext),
+			"Clock drifts detected. Capture "
+			"is %d samples/sec %s "
+			"than the playback device",
+			drift, which);
+	problems[problem_count++] = drifttext;
+    }
+
+    if (problem_count == 0) {
+	pj_ansi_snprintf(textbuf+textbufpos, 
+			 sizeof(textbuf)-textbufpos,
+			 "\r\nThe sound device seems to be okay!");
+	textbufpos = strlen(textbuf);
+
+	key = gui_msgbox("Audio Device Test", textbuf, WITH_OK);
+    } else {
+	unsigned i;
+
+	pj_ansi_snprintf(textbuf+textbufpos,
+			 sizeof(textbuf)-textbufpos, 
+			 "There could be %d problem(s) with the "
+			 "sound device:\r\n",
+			 problem_count);
+	textbufpos = strlen(textbuf);
+
+	for (i=0; i<problem_count; ++i) {
+	    pj_ansi_snprintf(textbuf+textbufpos,
+			     sizeof(textbuf)-textbufpos, 
+			     " %d: %s\r\n", i+1, problems[i]);
+	    textbufpos = strlen(textbuf);
+	}
+
+	key = gui_msgbox(title, textbuf, WITH_OK);
+    }
+
+    ti->success = PJ_TRUE;
+    pj_ansi_strncpy(ti->reason, textbuf, sizeof(ti->reason));
+    ti->reason[sizeof(ti->reason)-1] = '\0';
+}
+
+
+/****************************************************************************
+ * sound latency test
+ */
+static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
+			     unsigned *lat_sum, unsigned *lat_cnt, 
+			     unsigned *lat_min, unsigned *lat_max)
+{
+    pjmedia_frame frm;
+    short *buf;
+    unsigned i, clock_rate, samples_per_frame;
+    pj_size_t read, len;
+    unsigned start_pos;
+    pj_bool_t first;
+    pj_status_t status;
+
+    *lat_sum = 0;
+    *lat_cnt = 0;
+    *lat_min = 10000;
+    *lat_max = 0;
+
+    samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
+    clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
+    frm.buf = pj_pool_alloc(pool, samples_per_frame * 2);
+    frm.size = samples_per_frame * 2;
+    len = pjmedia_wav_player_get_len(wav);
+    buf = pj_pool_alloc(pool, len + samples_per_frame);
+
+    /* Read the whole file */
+    read = 0;
+    while (read < len/2) {
+	status = pjmedia_port_get_frame(wav, &frm);
+	if (status != PJ_SUCCESS)
+	    break;
+
+	pjmedia_copy_samples(buf+read, (short*)frm.buf, samples_per_frame);
+	read += samples_per_frame;
+    }
+
+    if (read < 2 * clock_rate) {
+	systest_perror("The WAV file is too short", PJ_SUCCESS);
+	return -1;
+    }
+
+    /* Zero the first 500ms to remove loud click noises 
+     * (keypad press, etc.)
+     */
+    pjmedia_zero_samples(buf, clock_rate / 2);
+
+    /* Loop to calculate latency */
+    start_pos = 0;
+    first = PJ_TRUE;
+    while (start_pos < len/2 - clock_rate) {
+	int max_signal = 0;
+	unsigned max_signal_pos = start_pos;
+	unsigned max_echo_pos = 0;
+	unsigned pos;
+	unsigned lat;
+
+	/* Get the largest signal in the next 0.7s */
+	for (i=start_pos; i<start_pos + clock_rate * 700 / 1000; ++i) {
+	    if (abs(buf[i]) > max_signal) {
+		max_signal = abs(buf[i]);
+		max_signal_pos = i;
+	    }
+	}
+
+	/* Advance 10ms from max_signal_pos */
+	pos = max_signal_pos + 10 * clock_rate / 1000;
+
+	/* Get the largest signal in the next 800ms */
+	max_signal = 0;
+	max_echo_pos = pos;
+	for (i=pos; i<pos+clock_rate * 8 / 10; ++i) {
+	    if (abs(buf[i]) > max_signal) {
+		max_signal = abs(buf[i]);
+		max_echo_pos = i;
+	    }
+	}
+
+	lat = (max_echo_pos - max_signal_pos) * 1000 / clock_rate;
+
+#if 0
+	PJ_LOG(4,(THIS_FILE, "Signal at %dms, echo at %d ms, latency %d ms",
+		  max_signal_pos * 1000 / clock_rate,
+		  max_echo_pos * 1000 / clock_rate,
+		  lat));
+#endif
+
+	*lat_sum += lat;
+	(*lat_cnt)++;
+	if (lat < *lat_min)
+	    *lat_min = lat;
+	if (lat > *lat_max)
+	    *lat_max = lat;
+
+	/* Advance next loop */
+	if (first) {
+	    start_pos = max_signal_pos + clock_rate * 9 / 10;
+	    first = PJ_FALSE;
+	} else {
+	    start_pos += clock_rate;
+	}
+    }
+
+    return 0;
+}
+
+
+static void systest_latency_test(void)
+{
+    const char *ref_wav_paths[] = { add_path(res_path, WAV_TOCK8_PATH), ALT_PATH1 WAV_TOCK8_PATH };
+    pj_str_t rec_wav_file;
+    pjsua_player_id play_id = PJSUA_INVALID_ID;
+    pjsua_conf_port_id play_slot = PJSUA_INVALID_ID;
+    pjsua_recorder_id rec_id = PJSUA_INVALID_ID;
+    pjsua_conf_port_id rec_slot = PJSUA_INVALID_ID;
+    pj_pool_t *pool = NULL;
+    pjmedia_port *wav_port = NULL;
+    unsigned lat_sum=0, lat_cnt=0, lat_min=0, lat_max=0;
+    enum gui_key key;
+    test_item_t *ti;
+    const char *title = "Audio Latency Test";
+    pj_status_t status;
+
+    ti = systest_alloc_test_item(title);
+    if (!ti)
+	return;
+
+    key = gui_msgbox(title,
+		     "This test will try to find the audio device's "
+		     "latency. We will play a special WAV file to the "
+		     "speaker for ten seconds, then at the end "
+		     "calculate the latency. Please don't do anything "
+		     "until the test is done.", WITH_OKCANCEL);
+    if (key != KEY_OK) {
+	ti->skipped = PJ_TRUE;
+	return;
+    }
+    key = gui_msgbox(title, 
+		     "For this test to work, we must be able to capture "
+		     "the audio played in the speaker (the echo), and only"
+		     " that audio (i.e. you must be in relatively quiet "
+		     "place to run this test). "
+		     "Press OK to start, or CANCEL to skip.",
+		     WITH_OKCANCEL);
+    if (key != KEY_OK) {
+	ti->skipped = PJ_TRUE;
+	return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Running %s", title));
+
+    status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths, 
+			   &play_id);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    play_slot = pjsua_player_get_conf_port(play_id);
+
+    rec_wav_file = pj_str(add_path(doc_path, WAV_LATENCY_OUT_PATH));
+    status = pjsua_recorder_create(&rec_wav_file, 0, NULL, -1, 0, &rec_id);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    rec_slot = pjsua_recorder_get_conf_port(rec_id);
+
+    /* Setup the test */
+    //status = pjsua_conf_connect(0, 0);
+    status = pjsua_conf_connect(play_slot, 0);
+    status = pjsua_conf_connect(0, rec_slot);
+    status = pjsua_conf_connect(play_slot, rec_slot);
+    
+
+    /* We're running */
+    PJ_LOG(3,(THIS_FILE, "Please wait while test is running (~10 sec)"));
+    gui_sleep(10);
+
+    /* Done with the test */
+    //status = pjsua_conf_disconnect(0, 0);
+    status = pjsua_conf_disconnect(play_slot, rec_slot);
+    status = pjsua_conf_disconnect(0, rec_slot);
+    status = pjsua_conf_disconnect(play_slot, 0);
+
+    pjsua_recorder_destroy(rec_id);
+    rec_id = PJSUA_INVALID_ID;
+
+    pjsua_player_destroy(play_id);
+    play_id = PJSUA_INVALID_ID;
+
+    /* Confirm that echo is heard */
+    gui_msgbox(title,
+	       "Test is done. Now we need to confirm that we indeed "
+	       "captured the echo. We will play the captured audio "
+	       "and please confirm that you can hear the 'tock' echo.",
+	       WITH_OK);
+
+    status = pjsua_player_create(&rec_wav_file, 0, &play_id);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    play_slot = pjsua_player_get_conf_port(play_id);
+
+    status = pjsua_conf_connect(play_slot, 0);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    key = gui_msgbox(title,
+		     "The captured audio is being played back now. "
+		     "Can you hear the 'tock' echo?",
+		     WITH_YESNO);
+
+    pjsua_player_destroy(play_id);
+    play_id = PJSUA_INVALID_ID;
+
+    if (key != KEY_YES)
+	goto on_return;
+
+    /* Now analyze the latency */
+    pool = pjsua_pool_create("latency", 512, 512);
+
+    status = pjmedia_wav_player_port_create(pool, rec_wav_file.ptr, 0, 0, 0, &wav_port);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    status = calculate_latency(pool, wav_port, &lat_sum, &lat_cnt, 
+			       &lat_min, &lat_max);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+on_return:
+    if (wav_port)
+	pjmedia_port_destroy(wav_port);
+    if (pool)
+	pj_pool_release(pool);
+    if (play_id != PJSUA_INVALID_ID)
+	pjsua_player_destroy(play_id);
+    if (rec_id != PJSUA_INVALID_ID)
+	pjsua_recorder_destroy(rec_id);
+
+    if (status != PJ_SUCCESS) {
+	systest_perror("Sorry we encountered an error: ", status);
+	ti->success = PJ_FALSE;
+	pj_strerror(status, ti->reason, sizeof(ti->reason));
+    } else if (key != KEY_YES) {
+	ti->success = PJ_FALSE;
+	if (!ti->success) {
+	    pj_ansi_strcpy(ti->reason, USER_ERROR);
+	}
+    } else {
+	char msg[200];
+	pj_size_t msglen;
+
+	pj_ansi_snprintf(msg, sizeof(msg),
+			 "The sound device latency:\r\n"
+			 " Min=%u, Max=%u, Avg=%u\r\n",
+			 lat_min, lat_max, lat_sum/lat_cnt);
+	msglen = strlen(msg);
+
+	if (lat_sum/lat_cnt > 500) {
+	    pj_ansi_snprintf(msg+msglen, sizeof(msg)-msglen,
+			     "The latency is huge!\r\n");
+	    msglen = strlen(msg);
+	} else if (lat_sum/lat_cnt > 200) {
+	    pj_ansi_snprintf(msg+msglen, sizeof(msg)-msglen,
+			     "The latency is quite high\r\n");
+	    msglen = strlen(msg);
+	}
+	
+	key = gui_msgbox(title, msg, WITH_OK);
+
+	ti->success = PJ_TRUE;
+	pj_ansi_strncpy(ti->reason, msg, sizeof(ti->reason));
+	ti->reason[sizeof(ti->reason)-1] = '\0';
+    }
+}
+
+
+static void systest_aec_test(void)
+{
+    const char *ref_wav_paths[] = { add_path(res_path, WAV_PLAYBACK_PATH),
+				    ALT_PATH1 WAV_PLAYBACK_PATH };
+    pjsua_player_id player_id = PJSUA_INVALID_ID;
+    pjsua_recorder_id writer_id = PJSUA_INVALID_ID;
+    enum gui_key key;
+    test_item_t *ti;
+    const char *title = "AEC/AES Test";
+    unsigned last_ec_tail = 0;
+    pj_status_t status;
+    pj_str_t tmp;
+
+    ti = systest_alloc_test_item(title);
+    if (!ti)
+	return;
+
+    key = gui_msgbox(title,
+		     "This test will try to find whether the AEC/AES "
+		     "works good on this system. Test will play a file "
+		     "while recording from mic. The recording will be "
+		     "played back later so you can check if echo is there. "
+		     "Press OK to start.",
+		     WITH_OKCANCEL);
+    if (key != KEY_OK) {
+	ti->skipped = PJ_TRUE;
+	return;
+    }
+
+    /* Save current EC tail */
+    status = pjsua_get_ec_tail(&last_ec_tail);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    /* Set EC tail setting to default */
+    status = pjsua_set_ec(PJSUA_DEFAULT_EC_TAIL_LEN, 0);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    /*
+     * Create player and recorder
+     */
+    status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths, 
+			   &player_id);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(1,(THIS_FILE, status, "Error opening WAV file %s",
+		     WAV_PLAYBACK_PATH));
+	goto on_return;
+    }
+
+    status = pjsua_recorder_create(
+                 pj_cstr(&tmp, add_path(doc_path, AEC_REC_PATH)), 0, 0, -1,
+                 0, &writer_id);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(1,(THIS_FILE, status, "Error writing WAV file %s",
+		     AEC_REC_PATH));
+	goto on_return;
+    }
+
+    /*
+     * Start playback and recording.
+     */
+    pjsua_conf_connect(pjsua_player_get_conf_port(player_id), 0);
+    pj_thread_sleep(100);
+    pjsua_conf_connect(0, pjsua_recorder_get_conf_port(writer_id));
+
+    /* Wait user signal */
+    gui_msgbox(title, "AEC/AES test is running. Press OK to stop this test.",
+	       WITH_OK);
+
+    /*
+     * Stop and close playback and recorder
+     */
+    pjsua_conf_disconnect(0, pjsua_recorder_get_conf_port(writer_id));
+    pjsua_conf_disconnect(pjsua_player_get_conf_port(player_id), 0);
+    pjsua_recorder_destroy(writer_id);
+    pjsua_player_destroy(player_id);
+    player_id = PJSUA_INVALID_ID;
+    writer_id = PJSUA_INVALID_ID;
+
+    /*
+     * Play the result.
+     */
+    status = pjsua_player_create(
+                 pj_cstr(&tmp, add_path(doc_path, AEC_REC_PATH)),
+                 0, &player_id);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(1,(THIS_FILE, status, "Error opening WAV file %s", AEC_REC_PATH));
+	goto on_return;
+    }
+    pjsua_conf_connect(pjsua_player_get_conf_port(player_id), 0);
+
+    /* Wait user signal */
+    gui_msgbox(title, "We are now playing the captured audio from the mic. "
+		      "Check if echo (of the audio played back previously) is "
+		      "present in the audio. The recording is stored in " 
+		      AEC_REC_PATH " for offline analysis. "
+		      "Press OK to stop.",
+		      WITH_OK);
+
+    pjsua_conf_disconnect(pjsua_player_get_conf_port(player_id), 0);
+
+    key = gui_msgbox(title,
+		     "Did you notice any echo in the recording?",
+		     WITH_YESNO);
+
+
+on_return:
+    if (player_id != PJSUA_INVALID_ID)
+	pjsua_player_destroy(player_id);
+    if (writer_id != PJSUA_INVALID_ID)
+	pjsua_recorder_destroy(writer_id);
+
+    /* Wait until sound device closed before restoring back EC tail setting */
+    while (pjsua_snd_is_active())
+	pj_thread_sleep(10);
+    pjsua_set_ec(last_ec_tail, 0);
+
+
+    if (status != PJ_SUCCESS) {
+	systest_perror("Sorry we encountered an error: ", status);
+	ti->success = PJ_FALSE;
+	pj_strerror(status, ti->reason, sizeof(ti->reason));
+    } else if (key == KEY_YES) {
+	ti->success = PJ_FALSE;
+	if (!ti->success) {
+	    pj_ansi_strcpy(ti->reason, USER_ERROR);
+	}
+    } else {
+	char msg[200];
+
+	pj_ansi_snprintf(msg, sizeof(msg), "Test succeeded.\r\n");
+
+	ti->success = PJ_TRUE;
+	pj_ansi_strncpy(ti->reason, msg, sizeof(ti->reason));
+	ti->reason[sizeof(ti->reason)-1] = '\0';
+    }
+}
+
+
+/****************************************************************************
+ * configurations
+ */
+static void systest_list_audio_devs()
+{
+    unsigned i, dev_count;
+    pj_size_t len=0;
+    pj_status_t status;
+    test_item_t *ti;
+    enum gui_key key;
+    const char *title = "Audio Device List";
+    
+    ti = systest_alloc_test_item(title);
+    if (!ti)
+	return;
+
+    PJ_LOG(3,(THIS_FILE, "Running %s", title));
+
+    dev_count = pjmedia_aud_dev_count();
+    if (dev_count == 0) {
+	key = gui_msgbox(title, 
+			 "No audio devices are found", WITH_OK);
+	ti->success = PJ_FALSE;
+	pj_ansi_strcpy(ti->reason, "No device found");
+	return;
+    }
+
+    pj_ansi_snprintf(ti->reason+len, sizeof(ti->reason)-len,
+		     "Found %u devices\r\n", dev_count);
+    len = strlen(ti->reason);
+
+    for (i=0; i<dev_count; ++i) {
+	pjmedia_aud_dev_info info;
+
+	status = pjmedia_aud_dev_get_info(i, &info);
+	if (status != PJ_SUCCESS) {
+	    systest_perror("Error retrieving device info: ", status);
+	    ti->success = PJ_FALSE;
+	    pj_strerror(status, ti->reason, sizeof(ti->reason));
+	    return;
+	}
+
+	pj_ansi_snprintf(ti->reason+len, sizeof(ti->reason)-len,
+			 " %2d: %s [%s] (%d/%d)\r\n",
+		          i, info.driver, info.name, 
+			  info.input_count, info.output_count);
+	len = strlen(ti->reason);
+    }
+
+    ti->reason[len] = '\0';
+    key = gui_msgbox(title, ti->reason, WITH_OK);
+
+    ti->success = PJ_TRUE;
+}
+
+static void systest_display_settings(void)
+{
+    pjmedia_aud_dev_info di;
+    pj_size_t len = 0;
+    enum gui_key key;
+    test_item_t *ti;
+    const char *title = "Audio Settings";
+    pj_status_t status;
+
+    ti = systest_alloc_test_item(title);
+    if (!ti)
+	return;
+
+    PJ_LOG(3,(THIS_FILE, "Running %s", title));
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Version: %s\r\n",
+		     pj_get_version());
+    len = strlen(textbuf);
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Test clock rate: %d\r\n",
+		     systest.media_cfg.clock_rate);
+    len = strlen(textbuf);
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Device clock rate: %d\r\n",
+		     systest.media_cfg.snd_clock_rate);
+    len = strlen(textbuf);
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Aud frame ptime: %d\r\n",
+		     systest.media_cfg.audio_frame_ptime);
+    len = strlen(textbuf);
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Channel count: %d\r\n",
+		     systest.media_cfg.channel_count);
+    len = strlen(textbuf);
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Audio switching: %s\r\n",
+	    (PJMEDIA_CONF_USE_SWITCH_BOARD ? "Switchboard" : "Conf bridge"));
+    len = strlen(textbuf);
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len, "Snd buff count: %d\r\n",
+		     PJMEDIA_SOUND_BUFFER_COUNT);
+    len = strlen(textbuf);
+
+    /* Capture device */
+    status = pjmedia_aud_dev_get_info(systest.rec_id, &di);
+    if (status != PJ_SUCCESS) {
+	systest_perror("Error querying device info", status);
+	ti->success = PJ_FALSE;
+	pj_strerror(status, ti->reason, sizeof(ti->reason));
+	return;
+    }
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len,
+		     "Rec dev : %d (%s) [%s]\r\n",
+		     systest.rec_id,
+		     di.name,
+		     di.driver);
+    len = strlen(textbuf);
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len,
+		     "Rec  buf : %d msec\r\n",
+		     systest.media_cfg.snd_rec_latency);
+    len = strlen(textbuf);
+
+    /* Playback device */
+    status = pjmedia_aud_dev_get_info(systest.play_id, &di);
+    if (status != PJ_SUCCESS) {
+	systest_perror("Error querying device info", status);
+	return;
+    }
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len,
+		     "Play dev: %d (%s) [%s]\r\n",
+		     systest.play_id,
+		     di.name,
+		     di.driver);
+    len = strlen(textbuf);
+
+    pj_ansi_snprintf(textbuf+len, sizeof(textbuf)-len,
+		     "Play buf: %d msec\r\n",
+		     systest.media_cfg.snd_play_latency);
+    len = strlen(textbuf);
+
+    ti->success = PJ_TRUE;
+    pj_ansi_strncpy(ti->reason, textbuf, sizeof(ti->reason));
+    ti->reason[sizeof(ti->reason)-1] = '\0';
+    key = gui_msgbox(title, textbuf, WITH_OK);
+
+}
+
+/*****************************************************************/
+
+int systest_init(void)
+{
+    pjsua_logging_config log_cfg;
+    pj_status_t status = PJ_SUCCESS;
+
+    status = pjsua_create();
+    if (status != PJ_SUCCESS) {
+	systest_perror("Sorry we've had error in pjsua_create(): ", status);
+	return status;
+    }
+
+    pjsua_logging_config_default(&log_cfg);
+    log_cfg.log_filename = pj_str(add_path(doc_path, LOG_OUT_PATH));
+
+    pjsua_config_default(&systest.ua_cfg);
+    pjsua_media_config_default(&systest.media_cfg);
+    systest.media_cfg.clock_rate = TEST_CLOCK_RATE;
+    systest.media_cfg.snd_clock_rate = DEV_CLOCK_RATE;
+    if (OVERRIDE_AUD_FRAME_PTIME)
+	systest.media_cfg.audio_frame_ptime = OVERRIDE_AUD_FRAME_PTIME;
+    systest.media_cfg.channel_count = CHANNEL_COUNT;
+    systest.rec_id = REC_DEV_ID;
+    systest.play_id = PLAY_DEV_ID;
+    systest.media_cfg.ec_tail_len = 0;
+    systest.media_cfg.snd_auto_close_time = 0;
+
+#if defined(OVERRIDE_AUDDEV_PLAY_LAT) && OVERRIDE_AUDDEV_PLAY_LAT!=0
+    systest.media_cfg.snd_play_latency = OVERRIDE_AUDDEV_PLAY_LAT;
+#endif
+
+#if defined(OVERRIDE_AUDDEV_REC_LAT) && OVERRIDE_AUDDEV_REC_LAT!=0
+    systest.media_cfg.snd_rec_latency = OVERRIDE_AUDDEV_REC_LAT;
+#endif
+	
+    status = pjsua_init(&systest.ua_cfg, &log_cfg, &systest.media_cfg);
+    if (status != PJ_SUCCESS) {
+	pjsua_destroy();
+	systest_perror("Sorry we've had error in pjsua_init(): ", status);
+	return status;
+    }
+
+    status = pjsua_start();
+    if (status != PJ_SUCCESS) {
+	pjsua_destroy();
+	systest_perror("Sorry we've had error in pjsua_start(): ", status);
+	return status;
+    }
+
+    status = gui_init(&root_menu);
+    if (status != 0)
+	goto on_return;
+
+    return 0;
+
+on_return:
+    gui_destroy();
+    return status;
+}
+
+
+int systest_set_dev(int cap_dev, int play_dev)
+{
+    systest.rec_id = systest_cap_dev_id = cap_dev;
+    systest.play_id = systest_play_dev_id = play_dev;
+    return pjsua_set_snd_dev(cap_dev, play_dev);
+}
+
+static void systest_wizard(void)
+{
+    PJ_LOG(3,(THIS_FILE, "Running test wizard"));
+    systest_list_audio_devs();
+    systest_display_settings();
+    systest_play_tone();
+    systest_play_wav1();
+    systest_rec_audio();
+    systest_audio_test();
+    systest_latency_test();
+    systest_aec_test();
+    gui_msgbox("Test wizard", "Test wizard complete.", WITH_OK);
+}
+
+
+int systest_run(void)
+{
+    gui_start(&root_menu);
+    return 0;
+}
+
+void systest_save_result(const char *filename)
+{
+    unsigned i;
+    pj_oshandle_t fd;
+    pj_time_val tv;
+    pj_parsed_time pt;
+    pj_ssize_t size;
+    const char *text;
+    pj_status_t status;
+
+    status = pj_file_open(NULL, filename, PJ_O_WRONLY | PJ_O_APPEND, &fd);
+    if (status != PJ_SUCCESS) {
+	pj_ansi_snprintf(textbuf, sizeof(textbuf),
+			 "Error opening file %s",
+			 filename);
+	systest_perror(textbuf, status);
+	return;
+    }
+
+    text = "\r\n\r\nPJSYSTEST Report\r\n";
+    size = strlen(text);
+    pj_file_write(fd, text, &size);
+
+    /* Put timestamp */
+    pj_gettimeofday(&tv);
+    if (pj_time_decode(&tv, &pt) == PJ_SUCCESS) {
+	pj_ansi_snprintf(textbuf, sizeof(textbuf),
+			 "Time: %04d/%02d/%02d %02d:%02d:%02d\r\n",
+			 pt.year, pt.mon+1, pt.day,
+			 pt.hour, pt.min, pt.sec);
+	size = strlen(textbuf);
+	pj_file_write(fd, textbuf, &size);
+    }
+
+    pj_ansi_snprintf(textbuf, sizeof(textbuf),
+		     "Tests invoked: %u\r\n"
+		     "-----------------------------------------------\r\n",
+		     test_item_count);
+    size = strlen(textbuf);
+    pj_file_write(fd, textbuf, &size);
+
+    for (i=0; i<test_item_count; ++i) {
+	test_item_t *ti = &test_items[i];
+	pj_ansi_snprintf(textbuf, sizeof(textbuf),
+			 "\r\nTEST %d: %s %s\r\n",
+			 i, ti->title,
+			 (ti->skipped? "Skipped" : (ti->success ? "Success" : "Failed")));
+	size = strlen(textbuf);
+	pj_file_write(fd, textbuf, &size);
+
+	size = strlen(ti->reason);
+	pj_file_write(fd, ti->reason, &size);
+
+	size = 2;
+	pj_file_write(fd, "\r\n", &size);
+    }
+
+
+    pj_file_close(fd);
+
+    pj_ansi_snprintf(textbuf, sizeof(textbuf),
+		     "Test result successfully appended to file %s",
+		     filename);
+    gui_msgbox("Test result saved", textbuf, WITH_OK);
+}
+
+void systest_deinit(void)
+{
+    gui_destroy();
+    pjsua_destroy();
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pjsystest/systest.h b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/systest.h
new file mode 100644
index 0000000..9b5aadb
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pjsystest/systest.h
@@ -0,0 +1,106 @@
+/* $Id: systest.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 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 __SYSTEST_H__
+#define __SYSTEST_H__
+
+#include <pjlib.h>
+
+/*
+ * Overrideable parameters
+ */
+#define REC_DEV_ID			systest_cap_dev_id
+#define PLAY_DEV_ID			systest_play_dev_id
+//#define REC_DEV_ID			5
+//#define PLAY_DEV_ID			5
+#define OVERRIDE_AUDDEV_REC_LAT		0
+#define OVERRIDE_AUDDEV_PLAY_LAT	0
+#define OVERRIDE_AUD_FRAME_PTIME	0
+
+/* Don't change this */
+#define CHANNEL_COUNT			1
+
+/* If you change CLOCK_RATE then the input WAV files need to be
+ * changed, so normally don't need to change this.
+ */
+#define TEST_CLOCK_RATE			8000
+
+/* You may change sound device's clock rate as long as resampling
+ * is enabled.
+ */
+#define DEV_CLOCK_RATE			8000
+
+
+#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE
+    #define LOG_OUT_PATH		"\\PJSYSTEST.TXT"
+    #define RESULT_OUT_PATH		"\\PJSYSTEST_RESULT.TXT"
+    #define WAV_PLAYBACK_PATH		"\\Program Files\\pjsystest\\input.8.wav"
+    #define WAV_REC_OUT_PATH		"\\PJSYSTEST_TESTREC.WAV"
+    #define WAV_TOCK8_PATH		"\\Program Files\\pjsystest\\tock8.WAV"
+    #define WAV_LATENCY_OUT_PATH	"\\PJSYSTEST_LATREC.WAV"
+    #define ALT_PATH1			""
+    #define AEC_REC_PATH		"\\PJSYSTEST_AECREC.WAV"
+#else
+    #define LOG_OUT_PATH		"PJSYSTEST.TXT"
+    #define RESULT_OUT_PATH		"PJSYSTEST_RESULT.TXT"
+    #define WAV_PLAYBACK_PATH		"input.8.wav"
+    #define WAV_REC_OUT_PATH		"PJSYSTEST_TESTREC.WAV"
+    #define WAV_TOCK8_PATH		"tock8.wav"
+    #define WAV_LATENCY_OUT_PATH	"PJSYSTEST_LATREC.WAV"
+    #define ALT_PATH1			"../../tests/pjsua/wavs/"
+    #define AEC_REC_PATH		"PJSYSTEST_AECREC.WAV"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* API, to be called by main() */
+int	    systest_init(void);
+int	    systest_set_dev(int cap_dev, int play_dev);
+int	    systest_run(void);
+void	    systest_save_result(const char *filename);
+void	    systest_deinit(void);
+
+/* Device ID to test */
+extern int systest_cap_dev_id;
+extern int systest_play_dev_id;
+
+/* Test item is used to record the test result */
+typedef struct test_item_t
+{
+    char	title[80];
+    pj_bool_t	skipped;
+    pj_bool_t	success;
+    char	reason[1024];
+} test_item_t;
+
+#define SYSTEST_MAX_TEST    32
+extern unsigned	    test_item_count;
+extern test_item_t  test_items[SYSTEST_MAX_TEST];
+#define PATH_LENGTH	    PJ_MAXPATH
+extern char	    doc_path[PATH_LENGTH];
+extern char	    res_path[PATH_LENGTH];
+
+test_item_t *systest_alloc_test_item(const char *title);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* __SYSTEST_H__ */
diff --git a/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/DEPRECATED.txt b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/DEPRECATED.txt
new file mode 100644
index 0000000..c5e8587
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/DEPRECATED.txt
@@ -0,0 +1,2 @@
+This Python module is now deprecated. Please use the new implementation under
+pjsip-apps/python directory.
diff --git a/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/Makefile b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/Makefile
new file mode 100644
index 0000000..10ed2fb
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/Makefile
@@ -0,0 +1,6 @@
+all:
+	python setup.py install
+
+clean:
+	python setup.py clean
+	rm -rf ./build
diff --git a/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/helper.mak b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/helper.mak
new file mode 100644
index 0000000..b4acce6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/helper.mak
@@ -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
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/pjsua.py b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/pjsua.py
new file mode 100644
index 0000000..f769ba5
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/pjsua.py
@@ -0,0 +1,264 @@
+import py_pjsua
+
+status = py_pjsua.create()
+print "py status " + `status`
+
+
+#
+# Create configuration objects
+#
+ua_cfg = py_pjsua.config_default()
+log_cfg = py_pjsua.logging_config_default()
+media_cfg = py_pjsua.media_config_default()
+
+#
+# Logging callback.
+#
+def logging_cb1(level, str, len):
+    print str,
+
+
+#
+# Configure logging
+#
+log_cfg.cb = logging_cb1
+log_cfg.console_level = 4
+
+#
+# Initialize pjsua!
+#
+status = py_pjsua.init(ua_cfg, log_cfg, media_cfg);
+print "py status after initialization :" + `status`
+
+
+#
+# Start pjsua!
+#
+status = py_pjsua.start()
+if status != 0:
+    exit(1)
+
+
+message = py_pjsua.msg_data_init()
+
+print "identitas object message data :" + `message`
+
+sipaddr = 'sip:167.205.34.99'
+print "checking sip address [%s] : %d" % (sipaddr, py_pjsua.verify_sip_url(sipaddr))
+
+sipaddr = '167.205.34.99'
+print "checking invalid sip address [%s] : %d" % (sipaddr, py_pjsua.verify_sip_url(sipaddr))
+
+object = py_pjsua.get_pjsip_endpt()
+print "identitas Endpoint :" + `object` + ""
+
+mediaend = py_pjsua.get_pjmedia_endpt()
+print "identitas Media Endpoint :" + `mediaend` + ""
+
+pool = py_pjsua.get_pool_factory()
+print "identitas pool factory :" + `pool` + ""
+
+status = py_pjsua.handle_events(3000)
+print "py status after 3 second of blocking wait :" + `status`
+
+
+
+# end of new testrun
+
+#
+
+# lib transport
+stunc = py_pjsua.stun_config_default();
+
+
+tc = py_pjsua.transport_config_default();
+
+
+py_pjsua.normalize_stun_config(stunc);
+
+
+status, id = py_pjsua.transport_create(1, tc);
+print "py transport create status " + `status`
+
+ti = py_pjsua.Transport_Info();
+ti = py_pjsua.transport_get_info(id)
+print "py transport get info status " + `status`
+
+status = py_pjsua.transport_set_enable(id,1)
+print "py transport set enable status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","set enable",status)
+
+
+status = py_pjsua.transport_close(id,1)
+print "py transport close status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","close",status)
+
+# end of lib transport
+
+# lib account 
+
+accfg = py_pjsua.acc_config_default()
+status, accid = py_pjsua.acc_add(accfg, 1)
+print "py acc add status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","add acc",status)
+count = py_pjsua.acc_get_count()
+print "acc count " + `count`
+
+accid = py_pjsua.acc_get_default()
+
+print "acc id default " + `accid`
+
+# end of lib account
+
+#lib buddy
+
+bcfg = py_pjsua.Buddy_Config()
+status, id = py_pjsua.buddy_add(bcfg)
+acc_id = id
+print "py buddy add status " + `status` + " id " + `id`
+bool = py_pjsua.buddy_is_valid(id)
+print "py buddy is valid " + `bool`
+count = py_pjsua.get_buddy_count()
+print "buddy count " + `count`
+binfo = py_pjsua.buddy_get_info(id)
+ids = py_pjsua.enum_buddies()
+status = py_pjsua.buddy_del(id)
+print "py buddy del status " + `status`
+status = py_pjsua.buddy_subscribe_pres(id, 1)
+print "py buddy subscribe pres status " + `status`
+py_pjsua.pres_dump(1)
+status = py_pjsua.im_send(accid, "fahris@divusi.com", "", "hallo", message, 0)
+print "py im send status " + `status`
+status = py_pjsua.im_typing(accid, "fahris@divusi.com", 1, message)
+print "py im typing status " + `status`
+#print "binfo " + `binfo`
+
+#end of lib buddy
+
+#lib media
+count = py_pjsua.conf_get_max_ports()
+print "py media conf get max ports " + `count`
+count = py_pjsua.conf_get_active_ports()
+print "py media conf get active ports " + `count`
+ids = py_pjsua.enum_conf_ports()
+for id in ids:
+	print "py media conf ports " + `id`
+	cp_info = py_pjsua.conf_get_port_info(id)
+	print "port info name " + cp_info.name
+pool = py_pjsua.PJ_Pool()
+port = py_pjsua.PJMedia_Port()
+status, id = py_pjsua.conf_add_port(pool,port)
+print "py media conf add port status " + `status` + " id " + `id`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","add port",status)
+status = py_pjsua.conf_remove_port(id)
+print "py media conf remove port status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","remove port",status)
+status = py_pjsua.conf_connect(id, id)
+print "py media conf connect status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","connect",status)
+status = py_pjsua.conf_disconnect(id, id)
+print "py media conf disconnect status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","disconnect",status)
+status, id = py_pjsua.player_create("test.wav", 0)
+print "py media player create status " + `status` + " id " + `id`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","player create",status)
+c_id = py_pjsua.player_get_conf_port(id)
+print "py media player get conf port id " + `c_id`
+status = py_pjsua.player_set_pos(id, 10)
+if status != 0 :
+	py_pjsua.perror("py_pjsua","player set pos",status)
+status = py_pjsua.player_destroy(id)
+if status != 0 :
+	py_pjsua.perror("py_pjsua","player destroy",status)
+status, id = py_pjsua.recorder_create("rec.wav", 0, "None", 1000, 0)
+print "py media recorder create status " + `status` + " id " + `id`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","recorder create",status)
+status = py_pjsua.recorder_get_conf_port(id)
+print "py media recorder get conf port status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","recorder get conf port",status)
+status = py_pjsua.recorder_destroy(id)
+print "py media recorder destroy status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","recorder destroy",status)
+#cdev, pdev = py_pjsua.get_snd_dev()
+#print "py media get snd dev capture dev " + `cdev` + " playback dev " + `pdev`
+status = py_pjsua.set_snd_dev(0,1)
+print "py media set snd dev status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","set snd dev",status)
+status = py_pjsua.set_null_snd_dev()
+print "py media set null snd dev status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","set null snd dev",status)
+port = py_pjsua.set_no_snd_dev()
+status = py_pjsua.set_ec(0,0)
+print "py media set ec status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","set ec",status)
+tail = py_pjsua.get_ec_tail()
+print "py media get ec tail " + `tail`
+infos = py_pjsua.enum_codecs()
+for info in infos:
+	print "py media enum codecs " + `info`
+status = py_pjsua.codec_set_priority("coba", 0)
+print "py media codec set priority " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","codec set priority",status)
+c_param = py_pjsua.codec_get_param("coba")
+status = py_pjsua.codec_set_param("coba", c_param)
+print "py media codec set param " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","codec set param",status)
+	
+#end of lib media
+
+#lib call
+
+count = py_pjsua.call_get_max_count()
+print "py call get max count " + `count`
+count = py_pjsua.call_get_count()
+print "py call get count " + `count`
+ids = py_pjsua.enum_calls()
+for id in ids:
+	print "py enum calls id " + `id`
+msg_data = py_pjsua.Msg_Data()
+status, id = py_pjsua.call_make_call(-1, "sip:bulukucing1@iptel.org", 0, 0, msg_data)
+print "py call make call " + `status` + " id " + `id`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","call make call",status)
+bool = py_pjsua.call_is_active(id)
+print "py call is active " + `bool`
+bool = py_pjsua.call_has_media(id)
+print "py call has media " + `bool`
+cp_id = py_pjsua.call_get_conf_port(id)
+print "py call get conf port " + `cp_id`
+info = py_pjsua.call_get_info(id)
+if info != None :
+	print "py info id " + `info.id`
+status = py_pjsua.call_set_user_data(id, 0)
+print "py call set user data status " + `status`
+if status != 0 :
+	py_pjsua.perror("py_pjsua","set user data",status)
+user_data = py_pjsua.call_get_user_data(id)
+print "py call get user data " + `user_data`
+
+
+
+#end of lib call
+
+py_pjsua.perror("saya","hallo",70006)
+
+status = py_pjsua.destroy()
+print "py status " + `status`
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/pjsua_app.py b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/pjsua_app.py
new file mode 100644
index 0000000..a0fd56c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/pjsua_app.py
@@ -0,0 +1,780 @@
+# $Id: pjsua_app.py 1438 2007-09-17 15:44:47Z bennylp $
+#
+# Sample and simple Python script to make and receive calls, and do
+# presence and instant messaging/IM using PJSUA-API binding for Python.
+#
+# Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
+#
+import py_pjsua
+import sys
+import thread
+
+#
+# Configurations
+#
+THIS_FILE = "pjsua_app.py"
+C_QUIT = 0
+C_LOG_LEVEL = 4
+
+# STUN config.
+# Set C_STUN_HOST to the address:port of the STUN server to enable STUN
+#
+C_STUN_HOST = ""
+#C_STUN_HOST = "192.168.0.2"
+#C_STUN_HOST = "stun.iptel.org:3478"
+
+# SIP port
+C_SIP_PORT = 5060
+
+
+# Globals
+#
+g_ua_cfg = None
+g_acc_id = py_pjsua.PJSUA_INVALID_ID
+g_current_call = py_pjsua.PJSUA_INVALID_ID
+g_wav_files = []
+g_wav_id = 0
+g_wav_port = 0
+g_rec_file = ""
+g_rec_id = 0
+g_rec_port = 0
+
+# Utility: display PJ error and exit
+#
+def err_exit(title, rc):
+    py_pjsua.perror(THIS_FILE, title, rc)
+    py_pjsua.destroy()
+    exit(1)
+
+
+# Logging function (also callback, called by pjsua-lib)
+#
+def log_cb(level, str, len):
+    if level <= C_LOG_LEVEL:
+        print str,
+
+def write_log(level, str):
+    log_cb(level, str + "\n", 0)
+
+
+# Utility to get call info
+#
+def call_name(call_id):
+	ci = py_pjsua.call_get_info(call_id)
+	return "[Call " + `call_id` + " " + ci.remote_info + "]"
+
+# Callback when call state has changed.
+#
+def on_call_state(call_id, e):	
+	global g_current_call
+	ci = py_pjsua.call_get_info(call_id)
+	write_log(3, call_name(call_id) + " state = " + `ci.state_text`)
+	if ci.state == py_pjsua.PJSIP_INV_STATE_DISCONNECTED:
+		g_current_call = py_pjsua.PJSUA_INVALID_ID
+
+# Callback for incoming call
+#
+def on_incoming_call(acc_id, call_id, rdata):
+	global g_current_call
+	
+	if g_current_call != py_pjsua.PJSUA_INVALID_ID:
+		# There's call in progress - answer Busy
+		py_pjsua.call_answer(call_id, 486, None, None)
+		return
+	
+	g_current_call = call_id
+	ci = py_pjsua.call_get_info(call_id)
+	write_log(3, "*** Incoming call: " + call_name(call_id) + "***")
+	write_log(3, "*** Press a to answer or h to hangup  ***")
+	
+	
+	
+# Callback when media state has changed (e.g. established or terminated)
+#
+def on_call_media_state(call_id):
+	ci = py_pjsua.call_get_info(call_id)
+	if ci.media_status == py_pjsua.PJSUA_CALL_MEDIA_ACTIVE:
+		py_pjsua.conf_connect(ci.conf_slot, 0)
+		py_pjsua.conf_connect(0, ci.conf_slot)
+		write_log(3, call_name(call_id) + ": media is active")
+	else:
+		write_log(3, call_name(call_id) + ": media is inactive")
+
+
+# Callback when account registration state has changed
+#
+def on_reg_state(acc_id):
+	acc_info = py_pjsua.acc_get_info(acc_id)
+	if acc_info.has_registration != 0:
+		cmd = "registration"
+	else:
+		cmd = "unregistration"
+	if acc_info.status != 0 and acc_info.status != 200:
+		write_log(3, "Account " + cmd + " failed: rc=" + `acc_info.status` + " " + acc_info.status_text)
+	else:
+		write_log(3, "Account " + cmd + " success")
+
+
+# Callback when buddy's presence state has changed
+#
+def on_buddy_state(buddy_id):
+	write_log(3, "On Buddy state called")
+	buddy_info = py_pjsua.buddy_get_info(buddy_id)
+	if buddy_info.status != 0 and buddy_info.status != 200:
+		write_log(3, "Status of " + `buddy_info.uri` + " is " + `buddy_info.status_text`)
+	else:
+		write_log(3, "Status : " + `buddy_info.status`)
+
+# Callback on incoming pager (MESSAGE)
+#		
+def on_pager(call_id, strfrom, strto, contact, mime_type, text):
+	write_log(3, "MESSAGE from " + `strfrom` + " : " + `text`)
+
+
+# Callback on the delivery status of outgoing pager (MESSAGE)
+#	
+def on_pager_status(call_id, strto, body, user_data, status, reason):
+	write_log(3, "MESSAGE to " + `strto` + " status " + `status` + " reason " + `reason`)
+
+
+# Received typing indication
+#
+def on_typing(call_id, strfrom, to, contact, is_typing):
+	str_t = ""
+	if is_typing:
+		str_t = "is typing.."
+	else:
+		str_t = "has stopped typing"
+	write_log(3, "IM indication: " + strfrom + " " + str_t)
+
+# Received the status of previous call transfer request
+#
+def on_call_transfer_status(call_id,status_code,status_text,final,p_cont):
+	strfinal = ""
+	if final == 1:
+		strfinal = "[final]"
+	
+	write_log(3, "Call " + `call_id` + ": transfer status= " + `status_code` + " " + status_text+ " " + strfinal)
+	      
+	if status_code/100 == 2:
+		write_log(3, "Call " + `call_id` + " : call transfered successfully, disconnecting call")
+		status = py_pjsua.call_hangup(call_id, 410, None, None)
+		p_cont = 0
+
+# Callback on incoming call transfer request
+#		
+def on_call_transfer_request(call_id, dst, code):
+	write_log(3, "Call transfer request from " + `call_id` + " to " + dst + " with code " + `code`)
+
+#
+# Initialize pjsua.
+#
+def app_init():
+	global g_acc_id, g_ua_cfg
+
+	# Create pjsua before anything else
+	status = py_pjsua.create()
+	if status != 0:
+		err_exit("pjsua create() error", status)
+
+	# Create and initialize logging config
+	log_cfg = py_pjsua.logging_config_default()
+	log_cfg.level = C_LOG_LEVEL
+	log_cfg.cb = log_cb
+
+	# Create and initialize pjsua config
+	# Note: for this Python module, thread_cnt must be 0 since Python
+	#       doesn't like to be called from alien thread (pjsua's thread
+	#       in this case)	    
+	ua_cfg = py_pjsua.config_default()
+	ua_cfg.thread_cnt = 0
+	ua_cfg.user_agent = "PJSUA/Python 0.1"
+	ua_cfg.cb.on_incoming_call = on_incoming_call
+	ua_cfg.cb.on_call_media_state = on_call_media_state
+	ua_cfg.cb.on_reg_state = on_reg_state
+	ua_cfg.cb.on_call_state = on_call_state
+	ua_cfg.cb.on_buddy_state = on_buddy_state
+	ua_cfg.cb.on_pager = on_pager
+	ua_cfg.cb.on_pager_status = on_pager_status
+	ua_cfg.cb.on_typing = on_typing
+	ua_cfg.cb.on_call_transfer_status = on_call_transfer_status
+	ua_cfg.cb.on_call_transfer_request = on_call_transfer_request
+
+	# Configure STUN setting
+	if C_STUN_HOST != "":
+	    ua_cfg.stun_host = C_STUN_HOST;
+
+	# Create and initialize media config
+	med_cfg = py_pjsua.media_config_default()
+	med_cfg.ec_tail_len = 0
+
+	#
+	# Initialize pjsua!!
+	#
+	status = py_pjsua.init(ua_cfg, log_cfg, med_cfg)
+	if status != 0:
+		err_exit("pjsua init() error", status)
+
+	# Configure UDP transport config
+	transport_cfg = py_pjsua.transport_config_default()
+	transport_cfg.port = C_SIP_PORT
+
+	# Create UDP transport
+	status, transport_id = \
+	    py_pjsua.transport_create(py_pjsua.PJSIP_TRANSPORT_UDP, transport_cfg)
+	if status != 0:
+		err_exit("Error creating UDP transport", status)
+		
+
+	# Create initial default account
+	status, acc_id = py_pjsua.acc_add_local(transport_id, 1)
+	if status != 0:
+		err_exit("Error creating account", status)
+
+	g_acc_id = acc_id
+	g_ua_cfg = ua_cfg
+
+# Add SIP account interractively
+#
+def add_account():
+	global g_acc_id
+
+	acc_domain = ""
+	acc_username = ""
+	acc_passwd =""
+	confirm = ""
+	
+	# Input account configs
+	print "Your SIP domain (e.g. myprovider.com): ",
+	acc_domain = sys.stdin.readline()
+	if acc_domain == "\n": 
+		return
+	acc_domain = acc_domain.replace("\n", "")
+
+	print "Your username (e.g. alice): ",
+	acc_username = sys.stdin.readline()
+	if acc_username == "\n":
+		return
+	acc_username = acc_username.replace("\n", "")
+
+	print "Your password (e.g. secret): ",
+	acc_passwd = sys.stdin.readline()
+	if acc_passwd == "\n":
+		return
+	acc_passwd = acc_passwd.replace("\n", "")
+
+	# Configure account configuration
+	acc_cfg = py_pjsua.acc_config_default()
+	acc_cfg.id = "sip:" + acc_username + "@" + acc_domain
+	acc_cfg.reg_uri = "sip:" + acc_domain
+
+	cred_info = py_pjsua.Pjsip_Cred_Info()
+	cred_info.realm = "*"
+	cred_info.scheme = "digest"
+	cred_info.username = acc_username
+	cred_info.data_type = 0
+	cred_info.data = acc_passwd
+
+	acc_cfg.cred_info.append(1)
+	acc_cfg.cred_info[0] = cred_info
+
+	# Add new SIP account
+	status, acc_id = py_pjsua.acc_add(acc_cfg, 1)
+	if status != 0:
+		py_pjsua.perror(THIS_FILE, "Error adding SIP account", status)
+	else:
+		g_acc_id = acc_id
+		write_log(3, "Account " + acc_cfg.id + " added")
+
+def add_player():
+	global g_wav_files
+	global g_wav_id
+	global g_wav_port
+	
+	file_name = ""
+	status = -1
+	wav_id = 0
+	
+	print "Enter the path of the file player(e.g. /tmp/audio.wav): ",
+	file_name = sys.stdin.readline()
+	if file_name == "\n": 
+		return
+	file_name = file_name.replace("\n", "")
+	status, wav_id = py_pjsua.player_create(file_name, 0)
+	if status != 0:
+		py_pjsua.perror(THIS_FILE, "Error adding file player ", status)
+	else:
+		g_wav_files.append(file_name)
+		if g_wav_id == 0:
+			g_wav_id = wav_id
+			g_wav_port = py_pjsua.player_get_conf_port(wav_id)
+		write_log(3, "File player " + file_name + " added")
+		
+def add_recorder():
+	global g_rec_file
+	global g_rec_id
+	global g_rec_port
+	
+	file_name = ""
+	status = -1
+	rec_id = 0
+	
+	print "Enter the path of the file recorder(e.g. /tmp/audio.wav): ",
+	file_name = sys.stdin.readline()
+	if file_name == "\n": 
+		return
+	file_name = file_name.replace("\n", "")
+	status, rec_id = py_pjsua.recorder_create(file_name, 0, None, 0, 0)
+	if status != 0:
+		py_pjsua.perror(THIS_FILE, "Error adding file recorder ", status)
+	else:
+		g_rec_file = file_name
+		g_rec_id = rec_id
+		g_rec_port = py_pjsua.recorder_get_conf_port(rec_id)
+		write_log(3, "File recorder " + file_name + " added")
+
+def conf_list():
+	ports = None
+	print "Conference ports : "
+	ports = py_pjsua.enum_conf_ports()
+
+	for port in ports:
+		info = None
+		info = py_pjsua.conf_get_port_info(port)
+		txlist = ""
+		for listener in info.listeners:
+			txlist = txlist + "#" + `listener` + " "
+		
+		print "Port #" + `info.slot_id` + "[" + `(info.clock_rate/1000)` + "KHz/" + `(info.samples_per_frame * 1000 / info.clock_rate)` + "ms] " + info.name + " transmitting to: " + txlist
+		
+def connect_port():
+	src_port = 0
+	dst_port = 0
+	
+	print "Connect src port # (empty to cancel): "
+	src_port = sys.stdin.readline()
+	if src_port == "\n": 
+		return
+	src_port = src_port.replace("\n", "")
+	src_port = int(src_port)
+	print "To dst port # (empty to cancel): "
+	dst_port = sys.stdin.readline()
+	if dst_port == "\n": 
+		return
+	dst_port = dst_port.replace("\n", "")
+	dst_port = int(dst_port)
+	status = py_pjsua.conf_connect(src_port, dst_port)
+	if status != 0:
+		py_pjsua.perror(THIS_FILE, "Error connecting port ", status)
+	else:		
+		write_log(3, "Port connected from " + `src_port` + " to " + `dst_port`)
+		
+def disconnect_port():
+	src_port = 0
+	dst_port = 0
+	
+	print "Disconnect src port # (empty to cancel): "
+	src_port = sys.stdin.readline()
+	if src_port == "\n": 
+		return
+	src_port = src_port.replace("\n", "")
+	src_port = int(src_port)
+	print "From dst port # (empty to cancel): "
+	dst_port = sys.stdin.readline()
+	if dst_port == "\n": 
+		return
+	dst_port = dst_port.replace("\n", "")
+	dst_port = int(dst_port)
+	status = py_pjsua.conf_disconnect(src_port, dst_port)
+	if status != 0:
+		py_pjsua.perror(THIS_FILE, "Error disconnecting port ", status)
+	else:		
+		write_log(3, "Port disconnected " + `src_port` + " from " + `dst_port`)
+
+def dump_call_quality():
+	global g_current_call
+	
+	buf = ""
+	if g_current_call != -1:
+		buf = py_pjsua.call_dump(g_current_call, 1, 1024, "  ")
+		write_log(3, "\n" + buf)
+	else:
+		write_log(3, "No current call")
+
+def xfer_call():
+	global g_current_call
+	
+	if g_current_call == -1:
+		
+		write_log(3, "No current call")
+
+	else:
+		call = g_current_call		
+		ci = py_pjsua.call_get_info(g_current_call)
+		print "Transfering current call ["+ `g_current_call` + "] " + ci.remote_info
+		print "Enter sip url : "
+		url = sys.stdin.readline()
+		if url == "\n": 
+			return
+		url = url.replace("\n", "")
+		if call != g_current_call:
+			print "Call has been disconnected"
+			return
+		msg_data = py_pjsua.msg_data_init()
+		status = py_pjsua.call_xfer(g_current_call, url, msg_data);
+		if status != 0:
+			py_pjsua.perror(THIS_FILE, "Error transfering call ", status)
+		else:		
+			write_log(3, "Call transfered to " + url)
+		
+def xfer_call_replaces():
+	if g_current_call == -1:
+		write_log(3, "No current call")
+	else:
+		call = g_current_call
+		
+		ids = py_pjsua.enum_calls()
+		if len(ids) <= 1:
+			print "There are no other calls"
+			return		
+
+		ci = py_pjsua.call_get_info(g_current_call)
+		print "Transfer call [" + `g_current_call` + "] " + ci.remote_info + " to one of the following:"
+		for i in range(0, len(ids)):		    
+			if ids[i] == call:
+				continue
+			call_info = py_pjsua.call_get_info(ids[i])
+			print `ids[i]` + "  " +  call_info.remote_info + "  [" + call_info.state_text + "]"		
+
+		print "Enter call number to be replaced : "
+		buf = sys.stdin.readline()
+		buf = buf.replace("\n","")
+		if buf == "":
+			return
+		dst_call = int(buf)
+		
+		if call != g_current_call:
+			print "Call has been disconnected"
+			return		
+		
+		if dst_call == call:
+			print "Destination call number must not be the same as the call being transfered"
+			return
+		
+		if dst_call >= py_pjsua.PJSUA_MAX_CALLS:
+			print "Invalid destination call number"
+			return
+	
+		if py_pjsua.call_is_active(dst_call) == 0:
+			print "Invalid destination call number"
+			return		
+
+		py_pjsua.call_xfer_replaces(call, dst_call, 0, None)
+		
+#
+# Worker thread function.
+# Python doesn't like it when it's called from an alien thread
+# (pjsua's worker thread, in this case), so for Python we must
+# disable worker thread in pjsua and poll pjsua from Python instead.
+#
+def worker_thread_main(arg):
+	global C_QUIT
+	thread_desc = 0;
+	status = py_pjsua.thread_register("python worker", thread_desc)
+	if status != 0:
+		py_pjsua.perror(THIS_FILE, "Error registering thread", status)
+	else:
+		while C_QUIT == 0:
+			py_pjsua.handle_events(50)
+		print "Worker thread quitting.."
+		C_QUIT = 2
+
+
+# Start pjsua
+#
+def app_start():
+	# Done with initialization, start pjsua!!
+	#
+	status = py_pjsua.start()
+	if status != 0:
+		err_exit("Error starting pjsua!", status)
+
+	# Start worker thread
+	thr = thread.start_new(worker_thread_main, (0,))
+    
+	print "PJSUA Started!!"
+
+
+# Print account and buddy list
+def print_acc_buddy_list():
+	global g_acc_id
+	
+	acc_ids = py_pjsua.enum_accs()
+	print "Account list:"
+	for acc_id in acc_ids:
+		acc_info = py_pjsua.acc_get_info(acc_id)
+		if acc_info.has_registration == 0:
+			acc_status = acc_info.status_text
+		else:
+			acc_status = `acc_info.status` + "/" + acc_info.status_text + " (expires=" + `acc_info.expires` + ")"
+
+		if acc_id == g_acc_id:
+			print " *",
+		else:
+			print "  ",
+
+		print "[" + `acc_id` + "] " + acc_info.acc_uri + ": " + acc_status
+		print "       Presence status: ",
+		if acc_info.online_status != 0:
+			print "Online"
+		else:
+			print "Invisible"
+
+	if py_pjsua.get_buddy_count() > 0:
+		print ""
+		print "Buddy list:"
+		buddy_ids = py_pjsua.enum_buddies()
+		for buddy_id in buddy_ids:
+			bi = py_pjsua.buddy_get_info(buddy_id)
+			print "   [" + `buddy_id` + "] " + bi.status_text + " " + bi.uri
+	
+		
+# Print application menu
+#
+def print_menu():
+	print ""
+	print ">>>"
+	print_acc_buddy_list()
+	print """
++============================================================================+
+|         Call Commands :      |  Buddy, IM & Presence:   |    Account:      |
+|                              |                          |                  |
+|  m  Make call                | +b  Add buddy            | +a  Add account  |
+|  a  Answer current call      | -b  Delete buddy         | -a  Delete accnt |
+|  h  Hangup current call      |                          |                  |
+|  H  Hold call                |  i  Send instant message | rr  register     |
+|  v  re-inVite (release Hold) |  s  Subscribe presence   | ru  Unregister   |
+|  #  Send DTMF string         |  u  Unsubscribe presence |                  |
+| dq  Dump curr. call quality  |  t  ToGgle Online status |                  |
+|                              +--------------------------+------------------+
+|  x  Xfer call                |     Media Commands:      |    Status:       |
+|  X  Xfer with Replaces       |                          |                  |
+|                              | cl  List ports           |  d  Dump status  |
+|                              | cc  Connect port         | dd  Dump detail  |
+|                              | cd  Disconnect port      |                  |
+|                              | +p  Add file player      |                  |
+|------------------------------+ +r  Add file recorder    |                  |
+|  q  Quit application         |                          |                  |
++============================================================================+"""
+	print "You have " + `py_pjsua.call_get_count()` + " active call(s)"
+	print ">>>", 
+
+# Menu
+#
+def app_menu():
+	global g_acc_id
+	global g_current_call
+
+	quit = 0
+	while quit == 0:
+		print_menu()
+		choice = sys.stdin.readline()
+
+		if choice[0] == "q":
+			quit = 1
+
+		elif choice[0] == "i":
+			# Sending IM	
+			print "Send IM to SIP URL: ",
+			url = sys.stdin.readline()
+			if url == "\n":
+				continue
+
+			# Send typing indication
+			py_pjsua.im_typing(g_acc_id, url, 1, None) 
+
+			print "The content: ",
+			message = sys.stdin.readline()
+			if message == "\n":
+				py_pjsua.im_typing(g_acc_id, url, 0, None) 		
+				continue
+
+			# Send the IM!
+			py_pjsua.im_send(g_acc_id, url, None, message, None, 0)
+
+		elif choice[0] == "m":
+			# Make call 
+			print "Using account ", g_acc_id
+			print "Make call to SIP URL: ",
+			url = sys.stdin.readline()
+			url = url.replace("\n", "")
+			if url == "":
+				continue
+
+			# Initiate the call!
+			status, call_id = py_pjsua.call_make_call(g_acc_id, url, 0, 0, None)
+            
+			if status != 0:
+				py_pjsua.perror(THIS_FILE, "Error making call", status)
+			else:
+				g_current_call = call_id
+
+		elif choice[0] == "+" and choice[1] == "b":
+			# Add new buddy
+			bc = py_pjsua.Buddy_Config()
+			print "Buddy URL: ",
+			bc.uri = sys.stdin.readline()
+			if bc.uri == "\n":
+				continue
+            
+			bc.uri = bc.uri.replace("\n", "")
+			bc.subscribe = 1
+			status, buddy_id = py_pjsua.buddy_add(bc)
+			if status != 0:
+				py_pjsua.perror(THIS_FILE, "Error adding buddy", status)
+		elif choice[0] == "-" and choice[1] == "b":
+			print "Enter buddy ID to delete : "
+			buf = sys.stdin.readline()
+			buf = buf.replace("\n","")
+			if buf == "":
+				continue
+			i = int(buf)
+			if py_pjsua.buddy_is_valid(i) == 0:
+				print "Invalid buddy id " + `i`
+			else:
+				py_pjsua.buddy_del(i)
+				print "Buddy " + `i` + " deleted"		
+		elif choice[0] == "+" and choice[1] == "a":
+			# Add account
+			add_account()
+		elif choice[0] == "-" and choice[1] == "a":
+			print "Enter account ID to delete : "
+			buf = sys.stdin.readline()
+			buf = buf.replace("\n","")
+			if buf == "":
+				continue
+			i = int(buf)
+
+			if py_pjsua.acc_is_valid(i) == 0:
+				print "Invalid account id " + `i`
+			else:
+				py_pjsua.acc_del(i)
+				print "Account " + `i` + " deleted"
+	    
+		elif choice[0] == "+" and choice[1] == "p":
+			add_player()
+		elif choice[0] == "+" and choice[1] == "r":
+			add_recorder()
+		elif choice[0] == "c" and choice[1] == "l":
+			conf_list()
+		elif choice[0] == "c" and choice[1] == "c":
+			connect_port()
+		elif choice[0] == "c" and choice[1] == "d":
+			disconnect_port()
+		elif choice[0] == "d" and choice[1] == "q":
+			dump_call_quality()
+		elif choice[0] == "x":
+			xfer_call()
+		elif choice[0] == "X":
+			xfer_call_replaces()
+		elif choice[0] == "h":
+			if g_current_call != py_pjsua.PJSUA_INVALID_ID:
+				py_pjsua.call_hangup(g_current_call, 603, None, None)
+			else:
+				print "No current call"
+		elif choice[0] == "H":
+			if g_current_call != py_pjsua.PJSUA_INVALID_ID:
+				py_pjsua.call_set_hold(g_current_call, None)
+		
+			else:
+				print "No current call"
+		elif choice[0] == "v":
+			if g_current_call != py_pjsua.PJSUA_INVALID_ID:
+		
+				py_pjsua.call_reinvite(g_current_call, 1, None);
+
+			else:
+				print "No current call"
+		elif choice[0] == "#":
+			if g_current_call == py_pjsua.PJSUA_INVALID_ID:		
+				print "No current call"
+			elif py_pjsua.call_has_media(g_current_call) == 0:
+				print "Media is not established yet!"
+			else:
+				call = g_current_call
+				print "DTMF strings to send (0-9*#A-B)"
+				buf = sys.stdin.readline()
+				buf = buf.replace("\n", "")
+				if buf == "":
+					continue
+				if call != g_current_call:
+					print "Call has been disconnected"
+					continue
+				status = py_pjsua.call_dial_dtmf(g_current_call, buf)
+				if status != 0:
+					py_pjsua.perror(THIS_FILE, "Unable to send DTMF", status);
+				else:
+					print "DTMF digits enqueued for transmission"
+		elif choice[0] == "s":
+			print "Subscribe presence of (buddy id) : "
+			buf = sys.stdin.readline()
+			buf = buf.replace("\n","")
+			if buf == "":
+				continue
+			i = int(buf)
+			py_pjsua.buddy_subscribe_pres(i, 1)
+		elif choice[0] == "u":
+			print "Unsubscribe presence of (buddy id) : "
+			buf = sys.stdin.readline()
+			buf = buf.replace("\n","")
+			if buf == "":
+				continue
+			i = int(buf)
+			py_pjsua.buddy_subscribe_pres(i, 0)
+		elif choice[0] == "t":
+			acc_info = py_pjsua.acc_get_info(g_acc_id)
+			if acc_info.online_status == 0:
+				acc_info.online_status = 1
+			else:
+				acc_info.online_status = 0
+			py_pjsua.acc_set_online_status(g_acc_id, acc_info.online_status)
+			st = ""
+			if acc_info.online_status == 0:
+				st = "offline"
+			else:
+				st = "online"
+			print "Setting " + acc_info.acc_uri + " online status to " + st
+		elif choice[0] == "r":
+			if choice[1] == "r":	    
+				py_pjsua.acc_set_registration(g_acc_id, 1)
+			elif choice[1] == "u":
+				py_pjsua.acc_set_registration(g_acc_id, 0)
+		elif choice[0] == "d":
+			py_pjsua.dump(choice[1] == "d")
+		elif choice[0] == "a":
+			if g_current_call != py_pjsua.PJSUA_INVALID_ID:				
+				
+				py_pjsua.call_answer(g_current_call, 200, None, None)
+			else:
+				print "No current call"
+
+
+#
+# main
+#
+app_init()
+app_start()
+app_menu()
+
+#
+# Done, quitting..
+#
+print "PJSUA shutting down.."
+C_QUIT = 1
+# Give the worker thread chance to quit itself
+while C_QUIT != 2:
+    py_pjsua.handle_events(50)
+
+print "PJSUA destroying.."
+py_pjsua.destroy()
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/py_pjsua.c b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/py_pjsua.c
new file mode 100644
index 0000000..9d22133
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/py_pjsua.c
@@ -0,0 +1,5872 @@
+/* $Id: py_pjsua.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 "py_pjsua.h"
+
+#define THIS_FILE    "main.c"
+#define POOL_SIZE    4000
+#define SND_DEV_NUM  64
+#define SND_NAME_LEN  64
+
+/* LIB BASE */
+
+static PyObject* obj_log_cb;
+static long thread_id;
+
+#define ENTER_PYTHON()	    PyGILState_STATE state = PyGILState_Ensure()
+#define LEAVE_PYTHON()	    PyGILState_Release(state)
+
+/*
+ * cb_log_cb
+ * declares method for reconfiguring logging process for callback struct
+ */
+static void cb_log_cb(int level, const char *data, int len)
+{
+	
+    /* Ignore if this callback is called from alien thread context,
+     * or otherwise it will crash Python.
+     */
+    if (pj_thread_local_get(thread_id) == 0)
+	return;
+
+    if (PyCallable_Check(obj_log_cb))
+    {
+	ENTER_PYTHON();
+
+        PyObject_CallFunctionObjArgs(
+            obj_log_cb, Py_BuildValue("i",level),
+            PyString_FromString(data), Py_BuildValue("i",len), NULL
+        );
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+
+/*
+ * The global callback object.
+ */
+static PyObj_pjsua_callback * g_obj_callback;
+
+
+/*
+ * cb_on_call_state
+ * declares method on_call_state for callback struct
+ */
+static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_state))
+    {	
+        PyObj_pjsip_event * obj;
+
+	ENTER_PYTHON();
+
+	obj = (PyObj_pjsip_event *)PyType_GenericNew(&PyTyp_pjsip_event,
+						      NULL, NULL);
+		
+	obj->event = e;
+		
+        PyObject_CallFunctionObjArgs(
+            g_obj_callback->on_call_state,
+	    Py_BuildValue("i",call_id),
+	    obj,
+	    NULL
+        );
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_incoming_call
+ * declares method on_incoming_call for callback struct
+ */
+static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
+                                pjsip_rx_data *rdata)
+{
+    if (PyCallable_Check(g_obj_callback->on_incoming_call))
+    {
+	PyObj_pjsip_rx_data * obj;
+
+	ENTER_PYTHON();
+
+	obj = (PyObj_pjsip_rx_data *)PyType_GenericNew(&PyTyp_pjsip_rx_data, 
+							NULL, NULL);
+	obj->rdata = rdata;
+
+        PyObject_CallFunctionObjArgs(
+                g_obj_callback->on_incoming_call,
+		Py_BuildValue("i",acc_id),
+                Py_BuildValue("i",call_id),
+		obj,
+		NULL
+        );
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_call_media_state
+ * declares method on_call_media_state for callback struct
+ */
+static void cb_on_call_media_state(pjsua_call_id call_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_media_state))
+    {
+	ENTER_PYTHON();
+
+        PyObject_CallFunction(
+	    g_obj_callback->on_call_media_state,
+	    "i",
+	    call_id,
+	    NULL
+	);
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_dtmf_digit()
+ * Callback from PJSUA-LIB on receiving DTMF digit
+ */
+static void cb_on_dtmf_digit(pjsua_call_id call_id, int digit)
+{
+    if (PyCallable_Check(g_obj_callback->on_dtmf_digit))
+    {
+	char digit_str[10];
+
+	ENTER_PYTHON();
+
+	pj_ansi_snprintf(digit_str, sizeof(digit_str), "%c", digit);
+
+        PyObject_CallFunctionObjArgs(
+	    g_obj_callback->on_dtmf_digit,
+	    Py_BuildValue("i",call_id),
+	    PyString_FromString(digit_str),
+	    NULL
+	);
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * Notify application on call being transfered.
+ * !modified @061206
+ */
+static void cb_on_call_transfer_request(pjsua_call_id call_id,
+				        const pj_str_t *dst,
+				        pjsip_status_code *code)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_transfer_request))
+    {
+	PyObject * ret;
+	int cd;
+
+	ENTER_PYTHON();
+
+        ret = PyObject_CallFunctionObjArgs(
+            g_obj_callback->on_call_transfer_request,
+	    Py_BuildValue("i",call_id),
+            PyString_FromStringAndSize(dst->ptr, dst->slen),
+            Py_BuildValue("i",*code),
+	    NULL
+        );
+	if (ret != NULL) {
+	    if (ret != Py_None) {
+		if (PyArg_Parse(ret,"i",&cd)) {
+		    *code = cd;
+		}
+	    }
+	}
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * Notify application of the status of previously sent call
+ * transfer request. Application can monitor the status of the
+ * call transfer request, for example to decide whether to 
+ * terminate existing call.
+ * !modified @061206
+ */
+static void cb_on_call_transfer_status( pjsua_call_id call_id,
+					int status_code,
+					const pj_str_t *status_text,
+					pj_bool_t final,
+					pj_bool_t *p_cont)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_transfer_status))
+    {
+	PyObject * ret;
+	int cnt;
+
+	ENTER_PYTHON();
+
+        ret = PyObject_CallFunctionObjArgs(
+            g_obj_callback->on_call_transfer_status,
+	    Py_BuildValue("i",call_id),
+	    Py_BuildValue("i",status_code),
+            PyString_FromStringAndSize(status_text->ptr, status_text->slen),
+	    Py_BuildValue("i",final),
+            Py_BuildValue("i",*p_cont),
+	    NULL
+        );
+	if (ret != NULL) {
+	    if (ret != Py_None) {
+		if (PyArg_Parse(ret,"i",&cnt)) {
+		    *p_cont = cnt;
+		}
+	    }
+	}
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * Notify application about incoming INVITE with Replaces header.
+ * Application may reject the request by setting non-2xx code.
+ * !modified @061206
+ */
+static void cb_on_call_replace_request( pjsua_call_id call_id,
+					pjsip_rx_data *rdata,
+					int *st_code,
+					pj_str_t *st_text)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_replace_request))
+    {
+	PyObject * ret;
+	PyObject * txt;
+	int cd;
+        PyObj_pjsip_rx_data * obj;
+
+	ENTER_PYTHON();
+
+	obj = (PyObj_pjsip_rx_data *)PyType_GenericNew(&PyTyp_pjsip_rx_data,
+							NULL, NULL);
+        obj->rdata = rdata;
+
+        ret = PyObject_CallFunctionObjArgs(
+            g_obj_callback->on_call_replace_request,
+	    Py_BuildValue("i",call_id),
+	    obj,
+	    Py_BuildValue("i",*st_code),
+            PyString_FromStringAndSize(st_text->ptr, st_text->slen),
+	    NULL
+        );
+	if (ret != NULL) {
+	    if (ret != Py_None) {
+		if (PyArg_ParseTuple(ret,"iO",&cd, &txt)) {
+		    *st_code = cd;
+		    st_text->ptr = PyString_AsString(txt);
+		    st_text->slen = strlen(PyString_AsString(txt));
+		}
+	    }
+	}
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * Notify application that an existing call has been replaced with
+ * a new call. This happens when PJSUA-API receives incoming INVITE
+ * request with Replaces header.
+ */
+static void cb_on_call_replaced(pjsua_call_id old_call_id,
+				pjsua_call_id new_call_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_replaced))
+    {
+	ENTER_PYTHON();
+
+        PyObject_CallFunctionObjArgs(
+            g_obj_callback->on_call_replaced,
+	    Py_BuildValue("i",old_call_id),
+	    Py_BuildValue("i",new_call_id),
+	    NULL
+        );
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_reg_state
+ * declares method on_reg_state for callback struct
+ */
+static void cb_on_reg_state(pjsua_acc_id acc_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_reg_state))
+    {
+	ENTER_PYTHON();
+
+        PyObject_CallFunction(
+	    g_obj_callback->on_reg_state,
+	    "i",
+	    acc_id,
+	    NULL
+	);
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_buddy_state
+ * declares method on_buddy state for callback struct
+ */
+static void cb_on_buddy_state(pjsua_buddy_id buddy_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_buddy_state))
+    {
+	ENTER_PYTHON();
+
+        PyObject_CallFunction(
+	    g_obj_callback->on_buddy_state,
+	    "i",
+	    buddy_id,
+	    NULL
+	);
+
+	LEAVE_PYTHON();
+    }
+}
+
+/*
+ * cb_on_pager
+ * declares method on_pager for callback struct
+ */
+static void cb_on_pager(pjsua_call_id call_id, const pj_str_t *from,
+                        const pj_str_t *to, const pj_str_t *contact,
+                        const pj_str_t *mime_type, const pj_str_t *body)
+{
+    if (PyCallable_Check(g_obj_callback->on_pager))
+    {
+	ENTER_PYTHON();
+
+        PyObject_CallFunctionObjArgs(
+            g_obj_callback->on_pager,Py_BuildValue("i",call_id),
+            PyString_FromStringAndSize(from->ptr, from->slen),
+            PyString_FromStringAndSize(to->ptr, to->slen),
+            PyString_FromStringAndSize(contact->ptr, contact->slen),
+            PyString_FromStringAndSize(mime_type->ptr, mime_type->slen),
+            PyString_FromStringAndSize(body->ptr, body->slen), 
+	    NULL
+        );
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_pager_status
+ * declares method on_pager_status for callback struct
+ */
+static void cb_on_pager_status(pjsua_call_id call_id, const pj_str_t *to,
+                                const pj_str_t *body, void *user_data,
+                                pjsip_status_code status,
+                                const pj_str_t *reason)
+{
+    if (PyCallable_Check(g_obj_callback->on_pager))
+    {
+	PyObject * obj_user_data;
+
+	ENTER_PYTHON();
+
+	obj_user_data = Py_BuildValue("i", user_data);
+
+        PyObject_CallFunctionObjArgs(
+            g_obj_callback->on_pager_status,
+	    Py_BuildValue("i",call_id),
+            PyString_FromStringAndSize(to->ptr, to->slen),
+            PyString_FromStringAndSize(body->ptr, body->slen), 
+	    obj_user_data,
+            Py_BuildValue("i",status),
+	    PyString_FromStringAndSize(reason->ptr,reason->slen),
+	    NULL
+        );
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_typing
+ * declares method on_typing for callback struct
+ */
+static void cb_on_typing(pjsua_call_id call_id, const pj_str_t *from,
+                            const pj_str_t *to, const pj_str_t *contact,
+                            pj_bool_t is_typing)
+{
+    if (PyCallable_Check(g_obj_callback->on_typing))
+    {
+	ENTER_PYTHON();
+
+        PyObject_CallFunctionObjArgs(
+            g_obj_callback->on_typing,Py_BuildValue("i",call_id),
+            PyString_FromStringAndSize(from->ptr, from->slen),
+            PyString_FromStringAndSize(to->ptr, to->slen),
+            PyString_FromStringAndSize(contact->ptr, contact->slen),
+            Py_BuildValue("i",is_typing),
+	    NULL
+        );
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+
+/* 
+ * translate_hdr
+ * internal function 
+ * translate from hdr_list to pjsip_generic_string_hdr
+ */
+void translate_hdr(pj_pool_t *pool, pjsip_hdr *hdr, PyObject *py_hdr_list)
+{
+    pj_list_init(hdr);
+
+    if (PyList_Check(py_hdr_list)) {
+	int i;
+
+        for (i = 0; i < PyList_Size(py_hdr_list); i++) 
+	{ 
+            pj_str_t hname, hvalue;
+	    pjsip_generic_string_hdr * new_hdr;
+            PyObject * tuple = PyList_GetItem(py_hdr_list, i);
+
+            if (PyTuple_Check(tuple)) 
+	    {
+                hname.ptr = PyString_AsString(PyTuple_GetItem(tuple,0));
+                hname.slen = strlen(PyString_AsString
+					(PyTuple_GetItem(tuple,0)));
+                hvalue.ptr = PyString_AsString(PyTuple_GetItem(tuple,1));
+                hvalue.slen = strlen(PyString_AsString
+					(PyTuple_GetItem(tuple,1)));
+            } else {
+		hname.ptr = "";
+		hname.slen = 0;
+		hvalue.ptr = "";
+		hvalue.slen = 0;
+            }  
+            new_hdr = pjsip_generic_string_hdr_create(pool, &hname, &hvalue);
+            pj_list_push_back((pj_list_type *)hdr, (pj_list_type *)new_hdr);
+	}     
+    }
+}
+
+/* 
+ * translate_hdr_rev
+ * internal function
+ * translate from pjsip_generic_string_hdr to hdr_list
+ */
+
+void translate_hdr_rev(pjsip_generic_string_hdr *hdr, PyObject *py_hdr_list)
+{
+    int i;
+    int len;
+    pjsip_generic_string_hdr * p_hdr;
+
+    len = pj_list_size(hdr);
+    
+    if (len > 0) 
+    {
+        p_hdr = hdr;
+        Py_XDECREF(py_hdr_list);
+        py_hdr_list = PyList_New(len);
+
+        for (i = 0; i < len && p_hdr != NULL; i++) 
+	{
+            PyObject * tuple;
+            PyObject * str;
+
+            tuple = PyTuple_New(2);
+	    
+            str = PyString_FromStringAndSize(p_hdr->name.ptr, p_hdr->name.slen);
+            PyTuple_SetItem(tuple, 0, str);
+            str = PyString_FromStringAndSize
+		(hdr->hvalue.ptr, p_hdr->hvalue.slen);
+            PyTuple_SetItem(tuple, 1, str);
+            PyList_SetItem(py_hdr_list, i, tuple);
+            p_hdr = p_hdr->next;
+	}
+    }
+    
+    
+}
+
+/*
+ * py_pjsua_thread_register
+ * !added @ 061206
+ */
+static PyObject *py_pjsua_thread_register(PyObject *pSelf, PyObject *pArgs)
+{
+	
+    pj_status_t status;	
+    const char *name;
+    PyObject *py_desc;
+    pj_thread_t *thread;
+    void *thread_desc;
+#if 0
+    int size;
+    int i;
+    int *td;
+#endif
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "sO", &name, &py_desc))
+    {
+         return NULL;
+    }
+#if 0
+    size = PyList_Size(py_desc);
+    td = (int *)malloc(size * sizeof(int));
+    for (i = 0; i < size; i++) 
+    {
+	if (!PyArg_Parse(PyList_GetItem(py_desc,i),"i", td[i])) 
+	{
+	    return NULL;
+	}
+    }
+    thread_desc = td;
+#else
+    thread_desc = malloc(sizeof(pj_thread_desc));
+#endif
+    status = pj_thread_register(name, thread_desc, &thread);
+
+    if (status == PJ_SUCCESS)
+	status = pj_thread_local_set(thread_id, (void*)1);
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_logging_config_default
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_logging_config_default(PyObject *pSelf,
+                                                    PyObject *pArgs)
+{
+    PyObj_pjsua_logging_config *obj;	
+    pjsua_logging_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    
+    pjsua_logging_config_default(&cfg);
+    obj = (PyObj_pjsua_logging_config *) PyObj_pjsua_logging_config_new
+		(&PyTyp_pjsua_logging_config,NULL,NULL);
+    PyObj_pjsua_logging_config_import(obj, &cfg);
+    
+    return (PyObject *)obj;
+}
+
+
+/*
+ * py_pjsua_config_default
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_config_default(PyObject *pSelf, PyObject *pArgs)
+{
+    PyObj_pjsua_config *obj;
+    pjsua_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    pjsua_config_default(&cfg);
+    obj = (PyObj_pjsua_config *) PyObj_pjsua_config_new(&PyTyp_pjsua_config, NULL, NULL);
+    PyObj_pjsua_config_import(obj, &cfg);
+
+    return (PyObject *)obj;
+}
+
+
+/*
+ * py_pjsua_media_config_default
+ * !modified @ 051206
+ */
+static PyObject * py_pjsua_media_config_default(PyObject *pSelf,
+                                                PyObject *pArgs)
+{
+    PyObj_pjsua_media_config *obj;
+    pjsua_media_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    pjsua_media_config_default(&cfg);
+    obj = (PyObj_pjsua_media_config *)
+	  PyType_GenericNew(&PyTyp_pjsua_media_config, NULL, NULL);
+    PyObj_pjsua_media_config_import(obj, &cfg);
+    return (PyObject *)obj;
+}
+
+
+/*
+ * py_pjsua_msg_data_init
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_msg_data_init(PyObject *pSelf, PyObject *pArgs)
+{
+    PyObj_pjsua_msg_data *obj;
+    pjsua_msg_data msg;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    pjsua_msg_data_init(&msg);
+    obj = (PyObj_pjsua_msg_data *)PyObj_pjsua_msg_data_new(&PyTyp_pjsua_msg_data, NULL, NULL);
+    Py_XDECREF(obj->content_type);
+    obj->content_type = PyString_FromStringAndSize(
+        msg.content_type.ptr, msg.content_type.slen
+    );
+    Py_XDECREF(obj->msg_body);
+    obj->msg_body = PyString_FromStringAndSize(
+        msg.msg_body.ptr, msg.msg_body.slen
+    );
+
+    translate_hdr_rev((pjsip_generic_string_hdr *)&msg.hdr_list,obj->hdr_list);
+    
+    return (PyObject *)obj;
+}
+
+
+/*
+ * py_pjsua_reconfigure_logging
+ */
+static PyObject *py_pjsua_reconfigure_logging(PyObject *pSelf, PyObject *pArgs)
+{
+    PyObject * logObj;
+    PyObj_pjsua_logging_config *log;
+    pjsua_logging_config cfg;
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "O", &logObj))
+    {
+        return NULL;
+    }
+    if (logObj != Py_None) 
+    {
+        log = (PyObj_pjsua_logging_config *)logObj;
+        cfg.msg_logging = log->msg_logging;
+        cfg.level = log->level;
+        cfg.console_level = log->console_level;
+        cfg.decor = log->decor;
+        cfg.log_filename.ptr = PyString_AsString(log->log_filename);
+        cfg.log_filename.slen = strlen(cfg.log_filename.ptr);
+        Py_XDECREF(obj_log_cb);
+        obj_log_cb = log->cb;
+        Py_INCREF(obj_log_cb);
+        cfg.cb = &cb_log_cb;
+        status = pjsua_reconfigure_logging(&cfg);
+    } else {
+        status = pjsua_reconfigure_logging(NULL);
+    }
+    return Py_BuildValue("i",status);
+}
+
+
+/*
+ * py_pjsua_pool_create
+ */
+static PyObject *py_pjsua_pool_create(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_size_t init_size;
+    pj_size_t increment;
+    const char * name;
+    pj_pool_t *p;
+    PyObj_pj_pool *pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "sII", &name, &init_size, &increment))
+    {
+        return NULL;
+    }
+    
+    p = pjsua_pool_create(name, init_size, increment);
+    pool = (PyObj_pj_pool *)PyType_GenericNew(&PyTyp_pj_pool_t, NULL, NULL);
+    pool->pool = p;
+    return (PyObject *)pool;
+
+}
+
+
+/*
+ * py_pjsua_get_pjsip_endpt
+ */
+static PyObject *py_pjsua_get_pjsip_endpt(PyObject *pSelf, PyObject *pArgs)
+{
+    PyObj_pjsip_endpoint *endpt;
+    pjsip_endpoint *e;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    e = pjsua_get_pjsip_endpt();
+    endpt = (PyObj_pjsip_endpoint *)PyType_GenericNew(
+        &PyTyp_pjsip_endpoint, NULL, NULL
+    );
+    endpt->endpt = e;
+    return (PyObject *)endpt;
+}
+
+
+/*
+ * py_pjsua_get_pjmedia_endpt
+ */
+static PyObject *py_pjsua_get_pjmedia_endpt(PyObject *pSelf, PyObject *pArgs)
+{
+    PyObj_pjmedia_endpt *endpt;
+    pjmedia_endpt *e;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    e = pjsua_get_pjmedia_endpt();
+    endpt = (PyObj_pjmedia_endpt *)PyType_GenericNew(
+        &PyTyp_pjmedia_endpt, NULL, NULL
+    );
+    endpt->endpt = e;
+    return (PyObject *)endpt;
+}
+
+
+/*
+ * py_pjsua_get_pool_factory
+ */
+static PyObject *py_pjsua_get_pool_factory(PyObject *pSelf, PyObject *pArgs)
+{
+    PyObj_pj_pool_factory *pool;
+    pj_pool_factory *p;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    p = pjsua_get_pool_factory();
+    pool = (PyObj_pj_pool_factory *)PyType_GenericNew(
+        &PyTyp_pj_pool_factory, NULL, NULL
+    );
+    pool->pool_fact = p;
+    return (PyObject *)pool;
+}
+
+
+/*
+ * py_pjsua_perror
+ */
+static PyObject *py_pjsua_perror(PyObject *pSelf, PyObject *pArgs)
+{
+    const char *sender;
+    const char *title;
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ssi", &sender, &title, &status))
+    {
+        return NULL;
+    }
+	
+    pjsua_perror(sender, title, status);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+/*
+ * py_pjsua_create
+ */
+static PyObject *py_pjsua_create(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    status = pjsua_create();
+    
+    if (status == PJ_SUCCESS) 
+    {
+	status = pj_thread_local_alloc(&thread_id);
+	if (status == PJ_SUCCESS)
+	    status = pj_thread_local_set(thread_id, (void*)1);
+    }
+
+    return Py_BuildValue("i",status);
+}
+
+
+/*
+ * py_pjsua_init
+ */
+static PyObject *py_pjsua_init(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *o_ua_cfg, *o_log_cfg, *o_media_cfg;
+    pjsua_config cfg_ua, *p_cfg_ua;
+    pjsua_logging_config cfg_log, *p_cfg_log;
+    pjsua_media_config cfg_media, *p_cfg_media;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OOO", &o_ua_cfg, &o_log_cfg, &o_media_cfg))
+    {
+        return NULL;
+    }
+    
+    pjsua_config_default(&cfg_ua);
+    pjsua_logging_config_default(&cfg_log);
+    pjsua_media_config_default(&cfg_media);
+
+    if (o_ua_cfg != Py_None) 
+    {
+	PyObj_pjsua_config *obj_ua_cfg = (PyObj_pjsua_config*)o_ua_cfg;
+
+	PyObj_pjsua_config_export(&cfg_ua, obj_ua_cfg);
+
+    	g_obj_callback = obj_ua_cfg->cb;
+    	Py_INCREF(g_obj_callback);
+
+    	cfg_ua.cb.on_call_state = &cb_on_call_state;
+    	cfg_ua.cb.on_incoming_call = &cb_on_incoming_call;
+    	cfg_ua.cb.on_call_media_state = &cb_on_call_media_state;
+	cfg_ua.cb.on_dtmf_digit = &cb_on_dtmf_digit;
+    	cfg_ua.cb.on_call_transfer_request = &cb_on_call_transfer_request;
+    	cfg_ua.cb.on_call_transfer_status = &cb_on_call_transfer_status;
+    	cfg_ua.cb.on_call_replace_request = &cb_on_call_replace_request;
+    	cfg_ua.cb.on_call_replaced = &cb_on_call_replaced;
+    	cfg_ua.cb.on_reg_state = &cb_on_reg_state;
+    	cfg_ua.cb.on_buddy_state = &cb_on_buddy_state;
+    	cfg_ua.cb.on_pager = &cb_on_pager;
+    	cfg_ua.cb.on_pager_status = &cb_on_pager_status;
+    	cfg_ua.cb.on_typing = &cb_on_typing;
+
+        p_cfg_ua = &cfg_ua;
+
+    } else {
+        p_cfg_ua = NULL;
+    }
+
+    if (o_log_cfg != Py_None) 
+    {
+	PyObj_pjsua_logging_config * obj_log;
+
+        obj_log = (PyObj_pjsua_logging_config *)o_log_cfg;
+        
+        PyObj_pjsua_logging_config_export(&cfg_log, obj_log);
+
+        Py_XDECREF(obj_log_cb);
+        obj_log_cb = obj_log->cb;
+        Py_INCREF(obj_log_cb);
+
+        cfg_log.cb = &cb_log_cb;
+        p_cfg_log = &cfg_log;
+
+    } else {
+        p_cfg_log = NULL;
+    }
+
+    if (o_media_cfg != Py_None) 
+    {
+	PyObj_pjsua_media_config_export(&cfg_media, 
+				        (PyObj_pjsua_media_config*)o_media_cfg);
+	p_cfg_media = &cfg_media;
+
+    } else {
+        p_cfg_media = NULL;
+    }
+
+    status = pjsua_init(p_cfg_ua, p_cfg_log, p_cfg_media);
+    return Py_BuildValue("i",status);
+}
+
+
+/*
+ * py_pjsua_start
+ */
+static PyObject *py_pjsua_start(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    status = pjsua_start();
+    
+    return Py_BuildValue("i",status);
+}
+
+
+/*
+ * py_pjsua_destroy
+ */
+static PyObject *py_pjsua_destroy(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    status = pjsua_destroy();
+    
+    return Py_BuildValue("i",status);
+}
+
+
+/*
+ * py_pjsua_handle_events
+ */
+static PyObject *py_pjsua_handle_events(PyObject *pSelf, PyObject *pArgs)
+{
+    int ret;
+    unsigned msec;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &msec))
+    {
+        return NULL;
+    }
+
+    /* Since handle_events() will block, we must wrap it with ALLOW_THREADS
+     * construct, or otherwise many Python blocking functions (such as
+     * time.sleep(), readline(), etc.) may hang/block indefinitely.
+     * See http://www.python.org/doc/current/api/threads.html for more info.
+     */
+    Py_BEGIN_ALLOW_THREADS
+    ret = pjsua_handle_events(msec);
+    Py_END_ALLOW_THREADS
+    
+    return Py_BuildValue("i",ret);
+}
+
+
+/*
+ * py_pjsua_verify_sip_url
+ */
+static PyObject *py_pjsua_verify_sip_url(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    const char *url;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "s", &url))
+    {
+        return NULL;
+    }
+    status = pjsua_verify_sip_url(url);
+    
+    return Py_BuildValue("i",status);
+}
+
+
+/*
+ * function doc
+ */
+
+static char pjsua_thread_register_doc[] =
+    "int py_pjsua.thread_register(string name, int[] desc)";
+static char pjsua_perror_doc[] =
+    "void py_pjsua.perror (string sender, string title, int status) "
+    "Display error message for the specified error code. Parameters: "
+    "sender: The log sender field;  "
+    "title: Message title for the error; "
+    "status: Status code.";
+
+static char pjsua_create_doc[] =
+    "int py_pjsua.create (void) "
+    "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 pjsua_destroy() "
+    "before quitting.";
+
+static char pjsua_init_doc[] =
+    "int py_pjsua.init (py_pjsua.Config obj_ua_cfg, "
+        "py_pjsua.Logging_Config log_cfg, py_pjsua.Media_Config media_cfg) "
+    "Initialize pjsua with the specified settings. All the settings are "
+    "optional, and the default values will be used when the config is not "
+    "specified. Parameters: "
+    "obj_ua_cfg : User agent configuration;  "
+    "log_cfg : Optional logging configuration; "
+    "media_cfg : Optional media configuration.";
+
+static char pjsua_start_doc[] =
+    "int py_pjsua.start (void) "
+    "Application is recommended to call this function after all "
+    "initialization is done, so that the library can do additional checking "
+    "set up additional";
+
+static char pjsua_destroy_doc[] =
+    "int py_pjsua.destroy (void) "
+    "Destroy pjsua This function must be called once PJSUA is created. To "
+    "make it easier for application, application may call this function "
+    "several times with no danger.";
+
+static char pjsua_handle_events_doc[] =
+    "int py_pjsua.handle_events (int msec_timeout) "
+    "Poll pjsua for events, and if necessary block the caller thread for the "
+    "specified maximum interval (in miliseconds) Parameters: "
+    "msec_timeout: Maximum time to wait, in miliseconds. "
+    "Returns: The number of events that have been handled during the poll. "
+    "Negative value indicates error, and application can retrieve the error "
+    "as (err = -return_value).";
+
+static char pjsua_verify_sip_url_doc[] =
+    "int py_pjsua.verify_sip_url (string c_url) "
+    "Verify that valid SIP url is given Parameters: "
+    "c_url: The URL, as NULL terminated string.";
+
+static char pjsua_pool_create_doc[] =
+    "py_pjsua.Pj_Pool py_pjsua.pool_create (string name, int init_size, "
+                                            "int increment) "
+    "Create memory pool Parameters: "
+    "name: Optional pool name; "
+    "init_size: Initial size of the pool;  "
+    "increment: Increment size.";
+
+static char pjsua_get_pjsip_endpt_doc[] =
+    "py_pjsua.Pjsip_Endpoint py_pjsua.get_pjsip_endpt (void) "
+    "Internal function to get SIP endpoint instance of pjsua, which is needed "
+    "for example to register module, create transports, etc. Probably is only "
+    "valid after pjsua_init() is called.";
+
+static char pjsua_get_pjmedia_endpt_doc[] =
+    "py_pjsua.Pjmedia_Endpt py_pjsua.get_pjmedia_endpt (void) "
+    "Internal function to get media endpoint instance. Only valid after "
+    "pjsua_init() is called.";
+
+static char pjsua_get_pool_factory_doc[] =
+    "py_pjsua.Pj_Pool_Factory py_pjsua.get_pool_factory (void) "
+    "Internal function to get PJSUA pool factory. Only valid after "
+    "pjsua_init() is called.";
+
+static char pjsua_reconfigure_logging_doc[] =
+    "int py_pjsua.reconfigure_logging (py_pjsua.Logging_Config c) "
+    "Application can call this function at any time (after pjsua_create(), of "
+    "course) to change logging settings. Parameters: "
+    "c: Logging configuration.";
+
+static char pjsua_logging_config_default_doc[] =
+    "py_pjsua.Logging_Config py_pjsua.logging_config_default  ()  "
+    "Use this function to initialize logging config.";
+
+static char pjsua_config_default_doc[] =
+    "py_pjsua.Config py_pjsua.config_default (). Use this function to "
+    "initialize pjsua config. ";
+
+static char pjsua_media_config_default_doc[] =
+    "py_pjsua.Media_Config py_pjsua.media_config_default (). "
+    "Use this function to initialize media config.";
+
+static char pjsua_msg_data_init_doc[] =
+    "py_pjsua.Msg_Data void py_pjsua.msg_data_init () "
+    "Initialize message data ";
+        
+
+/* END OF LIB BASE */
+
+/* LIB TRANSPORT */
+
+/*
+ * py_pjsua_transport_config_default
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_transport_config_default(PyObject *pSelf, 
+						   PyObject *pArgs)
+{
+    PyObj_pjsua_transport_config *obj;
+    pjsua_transport_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }
+
+    pjsua_transport_config_default(&cfg);
+    obj = (PyObj_pjsua_transport_config*)
+	  PyObj_pjsua_transport_config_new(&PyTyp_pjsua_transport_config,
+					   NULL, NULL);
+    PyObj_pjsua_transport_config_import(obj, &cfg);
+
+    return (PyObject *)obj;
+}
+
+/*
+ * py_pjsua_transport_create
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_transport_create(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    int type;
+    PyObject * tmpObj;
+    pjsua_transport_config cfg;
+    pjsua_transport_id id;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &type, &tmpObj)) {
+        return NULL;
+    }
+
+    if (tmpObj != Py_None) {
+	PyObj_pjsua_transport_config *obj;
+        obj = (PyObj_pjsua_transport_config*)tmpObj;
+	PyObj_pjsua_transport_config_export(&cfg, obj);
+        status = pjsua_transport_create(type, &cfg, &id);
+    } else {
+        status = pjsua_transport_create(type, NULL, &id);
+    }
+    
+    
+    return Py_BuildValue("ii", status, id);
+}
+
+/*
+ * py_pjsua_enum_transports
+ * !modified @ 261206
+ */
+static PyObject *py_pjsua_enum_transports(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    
+    pjsua_transport_id id[PJSIP_MAX_TRANSPORTS];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    c = PJ_ARRAY_SIZE(id);
+    status = pjsua_enum_transports(id, &c);
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) 
+    {     
+        int ret = PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
+        if (ret == -1) 
+        {
+            return NULL;
+        }
+    }
+    
+    return Py_BuildValue("O",list);
+}
+
+/*
+ * py_pjsua_transport_get_info
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_transport_get_info(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    int id;
+    pjsua_transport_info info;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }	
+    
+    status = pjsua_transport_get_info(id, &info);	
+    if (status == PJ_SUCCESS) {
+	PyObj_pjsua_transport_info *obj;
+        obj = (PyObj_pjsua_transport_info *) 
+	      PyObj_pjsua_transport_info_new(&PyTyp_pjsua_transport_info, 
+					     NULL, NULL);
+	PyObj_pjsua_transport_info_import(obj, &info);
+        return Py_BuildValue("O", obj);
+    } else {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+}
+
+/*
+ * py_pjsua_transport_set_enable
+ */
+static PyObject *py_pjsua_transport_set_enable
+(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    int id;
+    int enabled;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &id, &enabled))
+    {
+        return NULL;
+    }	
+    status = pjsua_transport_set_enable(id, enabled);	
+    
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_transport_close
+ */
+static PyObject *py_pjsua_transport_close(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    int id;
+    int force;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &id, &force))
+    {
+        return NULL;
+    }	
+    status = pjsua_transport_close(id, force);	
+    
+    return Py_BuildValue("i",status);
+}
+
+static char pjsua_transport_config_default_doc[] =
+    "py_pjsua.Transport_Config py_pjsua.transport_config_default () "
+    "Call this function to initialize UDP config with default values.";
+static char pjsua_transport_create_doc[] =
+    "int, int py_pjsua.transport_create (int type, "
+    "py_pjsua.Transport_Config cfg) "
+    "Create SIP transport.";
+static char pjsua_enum_transports_doc[] =
+    "int[] py_pjsua.enum_transports () "
+    "Enumerate all transports currently created in the system.";
+static char pjsua_transport_get_info_doc[] =
+    "void py_pjsua.transport_get_info "
+    "(py_pjsua.Transport_ID id, py_pjsua.Transport_Info info) "
+    "Get information about transports.";
+static char pjsua_transport_set_enable_doc[] =
+    "void py_pjsua.transport_set_enable "
+    "(py_pjsua.Transport_ID id, int enabled) "
+    "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.";
+static char pjsua_transport_close_doc[] =
+    "void py_pjsua.transport_close (py_pjsua.Transport_ID id, int force) "
+    "Close the transport. If transport is forcefully closed, "
+    "it will be immediately closed, and any pending transactions "
+    "that are using the transport may not terminate properly. "
+    "Otherwise, the system will wait until all transactions are closed "
+    "while preventing new users from using the transport, and will close "
+    "the transport when it is safe to do so.";
+
+/* END OF LIB TRANSPORT */
+
+/* LIB ACCOUNT */
+
+
+/*
+ * py_pjsua_acc_config_default
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_acc_config_default(PyObject *pSelf, PyObject *pArgs)
+{
+    PyObj_pjsua_acc_config *obj;
+    pjsua_acc_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }
+
+    pjsua_acc_config_default(&cfg);
+    obj = (PyObj_pjsua_acc_config *)
+	  PyObj_pjsua_acc_config_new(&PyTyp_pjsua_acc_config, 
+				     NULL, NULL);
+    PyObj_pjsua_acc_config_import(obj, &cfg);
+    return (PyObject *)obj;
+}
+
+/*
+ * py_pjsua_acc_get_count
+ */
+static PyObject *py_pjsua_acc_get_count(PyObject *pSelf, PyObject *pArgs)
+{
+    int count;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }
+
+    count = pjsua_acc_get_count();
+    return Py_BuildValue("i",count);
+}
+
+/*
+ * py_pjsua_acc_is_valid
+ */
+static PyObject *py_pjsua_acc_is_valid(PyObject *pSelf, PyObject *pArgs)
+{    
+    int id;
+    int is_valid;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }
+
+    is_valid = pjsua_acc_is_valid(id);	
+    return Py_BuildValue("i", is_valid);
+}
+
+/*
+ * py_pjsua_acc_set_default
+ */
+static PyObject *py_pjsua_acc_set_default(PyObject *pSelf, PyObject *pArgs)
+{    
+    int id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }
+    status = pjsua_acc_set_default(id);
+	
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_get_default
+ */
+static PyObject *py_pjsua_acc_get_default(PyObject *pSelf, PyObject *pArgs)
+{    
+    int id;
+	
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }
+
+    id = pjsua_acc_get_default();
+	
+    return Py_BuildValue("i", id);
+}
+
+/*
+ * py_pjsua_acc_add
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_acc_add(PyObject *pSelf, PyObject *pArgs)
+{    
+    int is_default;
+    PyObject * acObj;
+    PyObj_pjsua_acc_config * ac;
+    int acc_id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "Oi", &acObj, &is_default)) {
+        return NULL;
+    }
+    
+    if (acObj != Py_None) {
+	pjsua_acc_config cfg;
+
+	pjsua_acc_config_default(&cfg);
+        ac = (PyObj_pjsua_acc_config *)acObj;
+        PyObj_pjsua_acc_config_export(&cfg, ac);
+        status = pjsua_acc_add(&cfg, is_default, &acc_id);
+    } else {
+        status = PJ_EINVAL;
+	acc_id = PJSUA_INVALID_ID;
+    }
+    
+    return Py_BuildValue("ii", status, acc_id);
+}
+
+/*
+ * py_pjsua_acc_add_local
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_acc_add_local(PyObject *pSelf, PyObject *pArgs)
+{    
+    int is_default;
+    int tid;
+    int p_acc_id;
+    int status;
+	
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &tid, &is_default)) {
+        return NULL;
+    }
+	
+    
+    status = pjsua_acc_add_local(tid, is_default, &p_acc_id);
+    
+    return Py_BuildValue("ii", status, p_acc_id);
+}
+
+/*
+ * py_pjsua_acc_del
+ */
+static PyObject *py_pjsua_acc_del(PyObject *pSelf, PyObject *pArgs)
+{    
+    int acc_id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &acc_id))
+    {
+        return NULL;
+    }
+	
+	
+    status = pjsua_acc_del(acc_id);	
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_modify
+ */
+static PyObject *py_pjsua_acc_modify(PyObject *pSelf, PyObject *pArgs)
+{    	
+    PyObject * acObj;
+    PyObj_pjsua_acc_config * ac;
+    int acc_id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &acc_id, &acObj)) {
+        return NULL;
+    }
+
+    if (acObj != Py_None) {
+	pjsua_acc_config cfg;	
+
+	pjsua_acc_config_default(&cfg);
+        ac = (PyObj_pjsua_acc_config *)acObj;
+        PyObj_pjsua_acc_config_export(&cfg, ac);
+
+        status = pjsua_acc_modify(acc_id, &cfg);
+    } else {
+        status = PJ_EINVAL;
+    }
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_set_online_status
+ */
+static PyObject *py_pjsua_acc_set_online_status(PyObject *pSelf, 
+						PyObject *pArgs)
+{    
+    int is_online;	
+    int acc_id;
+    int status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &is_online)) {
+        return NULL;
+    }
+	
+    status = pjsua_acc_set_online_status(acc_id, is_online);
+	
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_set_online_status2
+ */
+static PyObject *py_pjsua_acc_set_online_status2(PyObject *pSelf, 
+						 PyObject *pArgs)
+{    
+    int is_online;	
+    int acc_id;
+    int activity_id;
+    const char *activity_text;
+    pjrpid_element rpid;
+    pj_status_t status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiis", &acc_id, &is_online,
+			  &activity_id, &activity_text)) {
+        return NULL;
+    }
+
+    pj_bzero(&rpid, sizeof(rpid));
+    rpid.activity = activity_id;
+    rpid.note = pj_str((char*)activity_text);
+
+    status = pjsua_acc_set_online_status2(acc_id, is_online, &rpid);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_set_registration
+ */
+static PyObject *py_pjsua_acc_set_registration(PyObject *pSelf, 
+					       PyObject *pArgs)
+{    
+    int renew;	
+    int acc_id;
+    int status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &renew)) {
+        return NULL;
+    }
+	
+    status = pjsua_acc_set_registration(acc_id, renew);
+	
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_get_info
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_acc_get_info(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int acc_id;
+    PyObj_pjsua_acc_info * obj;
+    pjsua_acc_info info;
+    int status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &acc_id)) {
+        return NULL;
+    }
+    
+    status = pjsua_acc_get_info(acc_id, &info);
+    if (status == PJ_SUCCESS) {
+	obj = (PyObj_pjsua_acc_info *)
+	    PyObj_pjsua_acc_info_new(&PyTyp_pjsua_acc_info,NULL, NULL);
+	PyObj_pjsua_acc_info_import(obj, &info);
+        return Py_BuildValue("O", obj);
+    } else {
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+}
+
+/*
+ * py_pjsua_enum_accs
+ * !modified @ 241206
+ */
+static PyObject *py_pjsua_enum_accs(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    
+    pjsua_acc_id id[PJSUA_MAX_ACC];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    c = PJ_ARRAY_SIZE(id);
+    
+    status = pjsua_enum_accs(id, &c);
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) 
+    {
+        int ret = PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
+        if (ret == -1) 
+	{
+            return NULL;
+        }
+    }
+    
+    return Py_BuildValue("O",list);
+}
+
+/*
+ * py_pjsua_acc_enum_info
+ * !modified @ 241206
+ */
+static PyObject *py_pjsua_acc_enum_info(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    pjsua_acc_info info[PJSUA_MAX_ACC];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }	
+    
+    c = PJ_ARRAY_SIZE(info);
+    status = pjsua_acc_enum_info(info, &c);
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) {
+        PyObj_pjsua_acc_info *obj;
+        obj = (PyObj_pjsua_acc_info *)
+	      PyObj_pjsua_acc_info_new(&PyTyp_pjsua_acc_info, NULL, NULL);
+
+	PyObj_pjsua_acc_info_import(obj, &info[i]);
+
+        PyList_SetItem(list, i, (PyObject *)obj);
+    }
+    
+    return Py_BuildValue("O",list);
+}
+
+/*
+ * py_pjsua_acc_find_for_outgoing
+ */
+static PyObject *py_pjsua_acc_find_for_outgoing(PyObject *pSelf, 
+						PyObject *pArgs)
+{    	
+    int acc_id;	
+    PyObject * url;
+    pj_str_t str;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "O", &url))
+    {
+        return NULL;
+    }
+    str.ptr = PyString_AsString(url);
+    str.slen = strlen(PyString_AsString(url));
+	
+    acc_id = pjsua_acc_find_for_outgoing(&str);
+	
+    return Py_BuildValue("i", acc_id);
+}
+
+/*
+ * py_pjsua_acc_find_for_incoming
+ */
+static PyObject *py_pjsua_acc_find_for_incoming(PyObject *pSelf, 
+						PyObject *pArgs)
+{    	
+    int acc_id;	
+    PyObject * tmpObj;
+    PyObj_pjsip_rx_data * obj;
+    pjsip_rx_data * rdata;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "O", &tmpObj))
+    {
+        return NULL;
+    }
+    if (tmpObj != Py_None)
+    {
+        obj = (PyObj_pjsip_rx_data *)tmpObj;
+        rdata = obj->rdata;
+        acc_id = pjsua_acc_find_for_incoming(rdata);
+    } else {
+        acc_id = pjsua_acc_find_for_incoming(NULL);
+    }
+    return Py_BuildValue("i", acc_id);
+}
+
+/*
+ * py_pjsua_acc_create_uac_contact
+ * !modified @ 061206
+ */
+static PyObject *py_pjsua_acc_create_uac_contact(PyObject *pSelf, 
+						 PyObject *pArgs)
+{    	
+    int status;
+    int acc_id;
+    PyObject * pObj;
+    PyObj_pj_pool * p;
+    pj_pool_t * pool;
+    PyObject * strc;
+    pj_str_t contact;
+    PyObject * stru;
+    pj_str_t uri;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OiO", &pObj, &acc_id, &stru))
+    {
+        return NULL;
+    }
+    if (pObj != Py_None)
+    {
+        p = (PyObj_pj_pool *)pObj;
+        pool = p->pool;    
+        uri.ptr = PyString_AsString(stru);
+        uri.slen = strlen(PyString_AsString(stru));
+        status = pjsua_acc_create_uac_contact(pool, &contact, acc_id, &uri);
+    } else {
+        status = pjsua_acc_create_uac_contact(NULL, &contact, acc_id, &uri);
+    }
+    strc = PyString_FromStringAndSize(contact.ptr, contact.slen);
+	
+    return Py_BuildValue("O", strc);
+}
+
+/*
+ * py_pjsua_acc_create_uas_contact
+ * !modified @ 061206
+ */
+static PyObject *py_pjsua_acc_create_uas_contact(PyObject *pSelf, 
+						 PyObject *pArgs)
+{    	
+    int status;
+    int acc_id;	
+    PyObject * pObj;
+    PyObj_pj_pool * p;
+    pj_pool_t * pool;
+    PyObject * strc;
+    pj_str_t contact;
+    PyObject * rObj;
+    PyObj_pjsip_rx_data * objr;
+    pjsip_rx_data * rdata;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OiO", &pObj, &acc_id, &rObj))
+    {
+        return NULL;
+    }
+    if (pObj != Py_None)
+    {
+        p = (PyObj_pj_pool *)pObj;
+        pool = p->pool;
+    } else {
+		pool = NULL;
+    }
+    if (rObj != Py_None)
+    {
+        objr = (PyObj_pjsip_rx_data *)rObj;
+        rdata = objr->rdata;
+    } else {
+        rdata = NULL;
+    }
+    status = pjsua_acc_create_uas_contact(pool, &contact, acc_id, rdata);
+    strc = PyString_FromStringAndSize(contact.ptr, contact.slen);
+	
+    return Py_BuildValue("O", strc);
+}
+
+static char pjsua_acc_config_default_doc[] =
+    "py_pjsua.Acc_Config py_pjsua.acc_config_default () "
+    "Call this function to initialize account config with default values.";
+static char pjsua_acc_get_count_doc[] =
+    "int py_pjsua.acc_get_count () "
+    "Get number of current accounts.";
+static char pjsua_acc_is_valid_doc[] =
+    "int py_pjsua.acc_is_valid (int acc_id)  "
+    "Check if the specified account ID is valid.";
+static char pjsua_acc_set_default_doc[] =
+    "int py_pjsua.acc_set_default (int acc_id) "
+    "Set default account to be used when incoming "
+    "and outgoing requests doesn't match any accounts.";
+static char pjsua_acc_get_default_doc[] =
+    "int py_pjsua.acc_get_default () "
+    "Get default account.";
+static char pjsua_acc_add_doc[] =
+    "int, int py_pjsua.acc_add (py_pjsua.Acc_Config cfg, "
+    "int is_default) "
+    "Add a new account to pjsua. PJSUA must have been initialized "
+    "(with pjsua_init()) before calling this function.";
+static char pjsua_acc_add_local_doc[] =
+    "int,int py_pjsua.acc_add_local (int tid, "
+    "int is_default) "
+    "Add a local account. A local account is used to identify "
+    "local endpoint instead of a specific user, and for this reason, "
+    "a transport ID is needed to obtain the local address information.";
+static char pjsua_acc_del_doc[] =
+    "int py_pjsua.acc_del (int acc_id) "
+    "Delete account.";
+static char pjsua_acc_modify_doc[] =
+    "int py_pjsua.acc_modify (int acc_id, py_pjsua.Acc_Config cfg) "
+    "Modify account information.";
+static char pjsua_acc_set_online_status_doc[] =
+    "int py_pjsua.acc_set_online_status2(int acc_id, int is_online) "
+    "Modify account's presence status to be advertised "
+    "to remote/presence subscribers.";
+static char pjsua_acc_set_online_status2_doc[] =
+    "int py_pjsua.acc_set_online_status (int acc_id, int is_online, "
+                                         "int activity_id, string activity_text) "
+    "Modify account's presence status to be advertised "
+    "to remote/presence subscribers.";
+static char pjsua_acc_set_registration_doc[] =
+    "int py_pjsua.acc_set_registration (int acc_id, int renew) "
+    "Update registration or perform unregistration.";
+static char pjsua_acc_get_info_doc[] =
+    "py_pjsua.Acc_Info py_pjsua.acc_get_info (int acc_id) "
+    "Get account information.";
+static char pjsua_enum_accs_doc[] =
+    "int[] py_pjsua.enum_accs () "
+    "Enum accounts all account ids.";
+static char pjsua_acc_enum_info_doc[] =
+    "py_pjsua.Acc_Info[] py_pjsua.acc_enum_info () "
+    "Enum accounts info.";
+static char pjsua_acc_find_for_outgoing_doc[] =
+    "int py_pjsua.acc_find_for_outgoing (string url) "
+    "This is an internal function to find the most appropriate account "
+    "to used to reach to the specified URL.";
+static char pjsua_acc_find_for_incoming_doc[] =
+    "int py_pjsua.acc_find_for_incoming (PyObj_pjsip_rx_data rdata) "
+    "This is an internal function to find the most appropriate account "
+    "to be used to handle incoming calls.";
+static char pjsua_acc_create_uac_contact_doc[] =
+    "string py_pjsua.acc_create_uac_contact (PyObj_pj_pool pool, "
+    "int acc_id, string uri) "
+    "Create a suitable URI to be put as Contact based on the specified "
+    "target URI for the specified account.";
+static char pjsua_acc_create_uas_contact_doc[] =
+    "string py_pjsua.acc_create_uas_contact (PyObj_pj_pool pool, "
+    "int acc_id, PyObj_pjsip_rx_data rdata) "
+    "Create a suitable URI to be put as Contact based on the information "
+    "in the incoming request.";
+
+/* END OF LIB ACCOUNT */
+
+/* LIB BUDDY */
+
+
+
+/*
+ * py_pjsua_buddy_config_default
+ */
+static PyObject *py_pjsua_buddy_config_default(PyObject *pSelf, 
+					       PyObject *pArgs)
+{    
+    PyObj_pjsua_buddy_config *obj;	
+    pjsua_buddy_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }
+    
+    pjsua_buddy_config_default(&cfg);
+    obj = (PyObj_pjsua_buddy_config *) 
+	  PyObj_pjsua_buddy_config_new(&PyTyp_pjsua_buddy_config, NULL, NULL);
+    PyObj_pjsua_buddy_config_import(obj, &cfg);
+    
+    return (PyObject *)obj;
+}
+
+/*
+ * py_pjsua_get_buddy_count
+ */
+static PyObject *py_pjsua_get_buddy_count(PyObject *pSelf, PyObject *pArgs)
+{    
+    int ret;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }
+    ret = pjsua_get_buddy_count();
+	
+    return Py_BuildValue("i", ret);
+}
+
+/*
+ * py_pjsua_buddy_is_valid
+ */
+static PyObject *py_pjsua_buddy_is_valid(PyObject *pSelf, PyObject *pArgs)
+{    
+    int id;
+    int is_valid;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }
+    is_valid = pjsua_buddy_is_valid(id);
+	
+    return Py_BuildValue("i", is_valid);
+}
+
+/*
+ * py_pjsua_enum_buddies
+ * !modified @ 241206
+ */
+static PyObject *py_pjsua_enum_buddies(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    
+    pjsua_buddy_id id[PJSUA_MAX_BUDDIES];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }	
+    c = PJ_ARRAY_SIZE(id);
+    status = pjsua_enum_buddies(id, &c);
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) {
+        PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
+    }
+    
+    return Py_BuildValue("O",list);
+}
+
+/*
+ * py_pjsua_buddy_get_info
+ * !modified @ 071206
+ */
+static PyObject *py_pjsua_buddy_get_info(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int buddy_id;
+    PyObj_pjsua_buddy_info * obj;
+    pjsua_buddy_info info;
+    int status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
+        return NULL;
+    }
+
+    status = pjsua_buddy_get_info(buddy_id, &info);
+    if (status == PJ_SUCCESS) {
+	obj = (PyObj_pjsua_buddy_info *)
+	      PyObj_pjsua_buddy_config_new(&PyTyp_pjsua_buddy_info,NULL,NULL);
+	PyObj_pjsua_buddy_info_import(obj, &info);	
+        return Py_BuildValue("O", obj);
+    } else {
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+}
+
+/*
+ * py_pjsua_buddy_add
+ * !modified @ 061206
+ */
+static PyObject *py_pjsua_buddy_add(PyObject *pSelf, PyObject *pArgs)
+{   
+    PyObject * bcObj;
+    int buddy_id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "O", &bcObj)) {
+        return NULL;
+    }
+
+    if (bcObj != Py_None) {
+	pjsua_buddy_config cfg;
+	PyObj_pjsua_buddy_config * bc;
+
+        bc = (PyObj_pjsua_buddy_config *)bcObj;
+
+	pjsua_buddy_config_default(&cfg);
+        PyObj_pjsua_buddy_config_export(&cfg, bc);  
+    
+        status = pjsua_buddy_add(&cfg, &buddy_id);
+    } else {
+        status = PJ_EINVAL;
+	buddy_id = PJSUA_INVALID_ID;
+    }
+    return Py_BuildValue("ii", status, buddy_id);
+}
+
+/*
+ * py_pjsua_buddy_del
+ */
+static PyObject *py_pjsua_buddy_del(PyObject *pSelf, PyObject *pArgs)
+{    
+    int buddy_id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
+        return NULL;
+    }
+	
+	
+    status = pjsua_buddy_del(buddy_id);	
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_buddy_subscribe_pres
+ */
+static PyObject *py_pjsua_buddy_subscribe_pres(PyObject *pSelf, PyObject *pArgs)
+{    
+    int buddy_id;
+    int status;
+    int subscribe;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &buddy_id, &subscribe)) {
+        return NULL;
+    }
+	
+	
+    status = pjsua_buddy_subscribe_pres(buddy_id, subscribe);	
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_pres_dump
+ */
+static PyObject *py_pjsua_pres_dump(PyObject *pSelf, PyObject *pArgs)
+{    
+    int verbose;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &verbose)) {
+        return NULL;
+    }
+	
+	
+    pjsua_pres_dump(verbose);	
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/*
+ * py_pjsua_im_send
+ * !modified @ 071206
+ */
+static PyObject *py_pjsua_im_send(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int acc_id;
+    pj_str_t * mime_type, tmp_mime_type;
+    pj_str_t to, content;
+    PyObject * st;
+    PyObject * smt;
+    PyObject * sc;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;
+    
+    int user_data;
+    pj_pool_t *pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iOOOOi", &acc_id, 
+		&st, &smt, &sc, &omdObj, &user_data))
+    {
+        return NULL;
+    }
+    if (smt != Py_None) {
+        mime_type = &tmp_mime_type;
+	tmp_mime_type = PyString_to_pj_str(smt);
+    } else {
+        mime_type = NULL;
+    }
+    to = PyString_to_pj_str(st);
+        content = PyString_to_pj_str(sc);
+
+    if (omdObj != Py_None) {
+		
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+	msg_data.content_type = PyString_to_pj_str(omd->content_type);
+	msg_data.msg_body = PyString_to_pj_str(omd->msg_body);
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_im_send(acc_id, &to, mime_type, 
+			&content, &msg_data, (void *)user_data);	
+        pj_pool_release(pool);
+    } else {
+		
+        status = pjsua_im_send(acc_id, &to, mime_type, 
+			&content, NULL, NULL);	
+    }
+    
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_im_typing
+ */
+static PyObject *py_pjsua_im_typing(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int acc_id;
+    pj_str_t to;
+    PyObject * st;
+    int is_typing;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;
+    pj_pool_t * pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iOiO", &acc_id, &st, &is_typing, &omdObj)) {
+        return NULL;
+    }
+	
+    to = PyString_to_pj_str(st);
+
+    if (omdObj != Py_None) {
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+	msg_data.content_type = PyString_to_pj_str(omd->content_type);
+	msg_data.msg_body = PyString_to_pj_str(omd->msg_body);
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_im_typing(acc_id, &to, is_typing, &msg_data);	
+        pj_pool_release(pool);
+    } else {
+        status = pjsua_im_typing(acc_id, &to, is_typing, NULL);
+    }
+    return Py_BuildValue("i",status);
+}
+
+static char pjsua_buddy_config_default_doc[] =
+    "py_pjsua.Buddy_Config py_pjsua.buddy_config_default () "
+    "Set default values to the buddy config.";
+static char pjsua_get_buddy_count_doc[] =
+    "int py_pjsua.get_buddy_count () "
+    "Get total number of buddies.";
+static char pjsua_buddy_is_valid_doc[] =
+    "int py_pjsua.buddy_is_valid (int buddy_id) "
+    "Check if buddy ID is valid.";
+static char pjsua_enum_buddies_doc[] =
+    "int[] py_pjsua.enum_buddies () "
+    "Enum buddy IDs.";
+static char pjsua_buddy_get_info_doc[] =
+    "py_pjsua.Buddy_Info py_pjsua.buddy_get_info (int buddy_id) "
+    "Get detailed buddy info.";
+static char pjsua_buddy_add_doc[] =
+    "int,int py_pjsua.buddy_add (py_pjsua.Buddy_Config cfg) "
+    "Add new buddy.";
+static char pjsua_buddy_del_doc[] =
+    "int py_pjsua.buddy_del (int buddy_id) "
+    "Delete buddy.";
+static char pjsua_buddy_subscribe_pres_doc[] =
+    "int py_pjsua.buddy_subscribe_pres (int buddy_id, int subscribe) "
+    "Enable/disable buddy's presence monitoring.";
+static char pjsua_pres_dump_doc[] =
+    "void py_pjsua.pres_dump (int verbose) "
+    "Dump presence subscriptions to log file.";
+static char pjsua_im_send_doc[] =
+    "int py_pjsua.im_send (int acc_id, string to, string mime_type, "
+    "string content, py_pjsua.Msg_Data msg_data, int user_data) "
+    "Send instant messaging outside dialog, using the specified account "
+    "for route set and authentication.";
+static char pjsua_im_typing_doc[] =
+    "int py_pjsua.im_typing (int acc_id, string to, int is_typing, "
+    "py_pjsua.Msg_Data msg_data) "
+    "Send typing indication outside dialog.";
+
+/* END OF LIB BUDDY */
+
+/* LIB MEDIA */
+
+
+
+/*
+ * PyObj_pjsua_codec_info
+ * Codec Info
+ * !modified @ 071206
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    PyObject * codec_id;
+    pj_uint8_t priority;    
+    char buf_[32];
+} PyObj_pjsua_codec_info;
+
+
+/*
+ * codec_info_dealloc
+ * deletes a codec_info from memory
+ * !modified @ 071206
+ */
+static void codec_info_dealloc(PyObj_pjsua_codec_info* self)
+{
+    Py_XDECREF(self->codec_id);    
+    
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * codec_info_new
+ * constructor for codec_info object
+ * !modified @ 071206
+ */
+static PyObject * codec_info_new(PyTypeObject *type, PyObject *args,
+                                    PyObject *kwds)
+{
+    PyObj_pjsua_codec_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_codec_info *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->codec_id = PyString_FromString("");
+        if (self->codec_id == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }        
+	
+
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * codec_info_members
+ * !modified @ 071206
+ */
+static PyMemberDef codec_info_members[] =
+{    
+    {
+        "codec_id", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_codec_info, codec_id), 0,
+        "Codec unique identification."        
+    },
+    
+    {
+        "priority", T_INT, 
+        offsetof(PyObj_pjsua_codec_info, priority), 0,
+        "Codec priority (integer 0-255)."
+    },
+    
+    
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_codec_info
+ */
+static PyTypeObject PyTyp_pjsua_codec_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Codec_Info",      /*tp_name*/
+    sizeof(PyObj_pjsua_codec_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)codec_info_dealloc,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Codec Info objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    codec_info_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    codec_info_new,             /* tp_new */
+
+};
+
+/*
+ * PyObj_pjsua_conf_port_info
+ * Conf Port Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    int  slot_id;
+    PyObject *  name;
+    unsigned  clock_rate;
+    unsigned  channel_count;
+    unsigned  samples_per_frame;
+    unsigned  bits_per_sample;
+    PyListObject * listeners;
+
+} PyObj_pjsua_conf_port_info;
+
+
+/*
+ * conf_port_info_dealloc
+ * deletes a conf_port_info from memory
+ */
+static void conf_port_info_dealloc(PyObj_pjsua_conf_port_info* self)
+{
+    Py_XDECREF(self->name);    
+    Py_XDECREF(self->listeners);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * conf_port_info_new
+ * constructor for conf_port_info object
+ */
+static PyObject * conf_port_info_new(PyTypeObject *type, PyObject *args,
+                                    PyObject *kwds)
+{
+    PyObj_pjsua_conf_port_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_conf_port_info *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->name = PyString_FromString("");
+        if (self->name == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }        
+	
+	self->listeners = (PyListObject *)PyList_New(0);
+        if (self->listeners == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * conf_port_info_members
+ */
+static PyMemberDef conf_port_info_members[] =
+{   
+    {
+        "slot_id", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, slot_id), 0,
+        "Conference port number."
+    },
+    {
+        "name", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_conf_port_info, name), 0,
+        "Port name"        
+    },
+    {
+        "clock_rate", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, clock_rate), 0,
+        "Clock rate"
+    },
+    {
+        "channel_count", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, channel_count), 0,
+        "Number of channels."
+    },
+    {
+        "samples_per_frame", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, samples_per_frame), 0,
+        "Samples per frame "
+    },
+    {
+        "bits_per_sample", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, bits_per_sample), 0,
+        "Bits per sample"
+    },
+    {
+        "listeners", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_conf_port_info, listeners), 0,
+        "Array of listeners (in other words, ports where this port "
+	"is transmitting to"
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_conf_port_info
+ */
+static PyTypeObject PyTyp_pjsua_conf_port_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Conf_Port_Info",      /*tp_name*/
+    sizeof(PyObj_pjsua_conf_port_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)conf_port_info_dealloc,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Conf Port Info objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    conf_port_info_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    conf_port_info_new,             /* tp_new */
+
+};
+
+/*
+ * PyObj_pjmedia_port
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    pjmedia_port * port;
+} PyObj_pjmedia_port;
+
+
+/*
+ * PyTyp_pjmedia_port
+ */
+static PyTypeObject PyTyp_pjmedia_port =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "py_pjsua.PJMedia_Port",        /*tp_name*/
+    sizeof(PyObj_pjmedia_port),    /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    0,                         /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "pjmedia_port objects",       /* tp_doc */
+
+};
+
+/*
+ * PyObj_pjmedia_snd_dev_info
+ * PJMedia Snd Dev Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    
+    unsigned  input_count;
+    unsigned  output_count;
+    unsigned  default_samples_per_sec;    
+    PyObject * name;
+
+} PyObj_pjmedia_snd_dev_info;
+
+
+/*
+ * pjmedia_snd_dev_info_dealloc
+ * deletes a pjmedia_snd_dev_info from memory
+ */
+static void pjmedia_snd_dev_info_dealloc(PyObj_pjmedia_snd_dev_info* self)
+{
+    Py_XDECREF(self->name);        
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * pjmedia_snd_dev_info_new
+ * constructor for pjmedia_snd_dev_info object
+ */
+static PyObject * pjmedia_snd_dev_info_new(PyTypeObject *type, PyObject *args,
+                                    PyObject *kwds)
+{
+    PyObj_pjmedia_snd_dev_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjmedia_snd_dev_info *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->name = PyString_FromString("");
+        if (self->name == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }        
+	
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * pjmedia_snd_dev_info_members
+ */
+static PyMemberDef pjmedia_snd_dev_info_members[] =
+{   
+    
+    {
+        "name", T_OBJECT_EX,
+        offsetof(PyObj_pjmedia_snd_dev_info, name), 0,
+        "Device name"        
+    },
+    {
+        "input_count", T_INT, 
+        offsetof(PyObj_pjmedia_snd_dev_info, input_count), 0,
+        "Max number of input channels"
+    },
+    {
+        "output_count", T_INT, 
+        offsetof(PyObj_pjmedia_snd_dev_info, output_count), 0,
+        "Max number of output channels"
+    },
+    {
+        "default_samples_per_sec", T_INT, 
+        offsetof(PyObj_pjmedia_snd_dev_info, default_samples_per_sec), 0,
+        "Default sampling rate."
+    },
+    
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjmedia_snd_dev_info
+ */
+static PyTypeObject PyTyp_pjmedia_snd_dev_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.PJMedia_Snd_Dev_Info",      /*tp_name*/
+    sizeof(PyObj_pjmedia_snd_dev_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)pjmedia_snd_dev_info_dealloc,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJMedia Snd Dev Info objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    pjmedia_snd_dev_info_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    pjmedia_snd_dev_info_new,             /* tp_new */
+
+};
+
+/*
+ * PyObj_pjmedia_codec_param_info
+ * PJMedia Codec Param Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    unsigned  clock_rate;
+    unsigned  channel_cnt;
+    pj_uint32_t avg_bps;
+    pj_uint16_t frm_ptime;
+    pj_uint8_t  pcm_bits_per_sample;
+    pj_uint8_t  pt;	
+
+} PyObj_pjmedia_codec_param_info;
+
+
+
+/*
+ * pjmedia_codec_param_info_members
+ */
+static PyMemberDef pjmedia_codec_param_info_members[] =
+{   
+    
+    {
+        "clock_rate", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, clock_rate), 0,
+        "Sampling rate in Hz"
+    },
+    {
+        "channel_cnt", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, channel_cnt), 0,
+        "Channel count"
+    },
+    {
+        "avg_bps", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, avg_bps), 0,
+        "Average bandwidth in bits/sec"
+    },
+    {
+        "frm_ptime", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, frm_ptime), 0,
+        "Base frame ptime in msec."
+    },
+    {
+        "pcm_bits_per_sample", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, pcm_bits_per_sample), 0,
+        "Bits/sample in the PCM side"
+    },
+    {
+        "pt", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, pt), 0,
+        "Payload type"
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjmedia_codec_param_info
+ */
+static PyTypeObject PyTyp_pjmedia_codec_param_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.PJMedia_Codec_Param_Info",      /*tp_name*/
+    sizeof(PyObj_pjmedia_codec_param_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    0,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJMedia Codec Param Info objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    pjmedia_codec_param_info_members,         /* tp_members */
+    
+
+};
+
+/*
+ * PyObj_pjmedia_codec_param_setting
+ * PJMedia Codec Param Setting
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    pj_uint8_t  frm_per_pkt; 
+    unsigned    vad;
+    unsigned    cng;
+    unsigned    penh;
+    unsigned    plc;
+    unsigned    reserved;
+    pj_uint8_t  enc_fmtp_mode;
+    pj_uint8_t  dec_fmtp_mode; 
+
+} PyObj_pjmedia_codec_param_setting;
+
+
+
+/*
+ * pjmedia_codec_param_setting_members
+ */
+static PyMemberDef pjmedia_codec_param_setting_members[] =
+{   
+    
+    {
+        "frm_per_pkt", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, frm_per_pkt), 0,
+        "Number of frames per packet"
+    },
+    {
+        "vad", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, vad), 0,
+        "Voice Activity Detector"
+    },
+    {
+        "penh", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, penh), 0,
+        "Perceptual Enhancement"
+    },
+    {
+        "plc", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, plc), 0,
+        "Packet loss concealment"
+    },
+    {
+        "reserved", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, reserved), 0,
+        "Reserved, must be zero"
+    },
+    {
+        "cng", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, cng), 0,
+        "Comfort Noise Generator"
+    },
+    {
+        "enc_fmtp_mode", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, enc_fmtp_mode), 0,
+        "Mode param in fmtp (def:0)"
+    },
+    {
+        "dec_fmtp_mode", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, dec_fmtp_mode), 0,
+        "Mode param in fmtp (def:0)"
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjmedia_codec_param_setting
+ */
+static PyTypeObject PyTyp_pjmedia_codec_param_setting =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.PJMedia_Codec_Param_Setting",      /*tp_name*/
+    sizeof(PyObj_pjmedia_codec_param_setting),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    0,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJMedia Codec Param Setting objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    pjmedia_codec_param_setting_members,         /* tp_members */
+    
+
+};
+
+/*
+ * PyObj_pjmedia_codec_param
+ * PJMedia Codec Param
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    PyObj_pjmedia_codec_param_info * info;
+    PyObj_pjmedia_codec_param_setting * setting;
+
+} PyObj_pjmedia_codec_param;
+
+
+/*
+ * pjmedia_codec_param_dealloc
+ * deletes a pjmedia_codec_param from memory
+ */
+static void pjmedia_codec_param_dealloc(PyObj_pjmedia_codec_param* self)
+{
+    Py_XDECREF(self->info);        
+    Py_XDECREF(self->setting);        
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * pjmedia_codec_param_new
+ * constructor for pjmedia_codec_param object
+ */
+static PyObject * pjmedia_codec_param_new(PyTypeObject *type, PyObject *args,
+                                    PyObject *kwds)
+{
+    PyObj_pjmedia_codec_param *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjmedia_codec_param *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->info = (PyObj_pjmedia_codec_param_info *)
+	    PyType_GenericNew(&PyTyp_pjmedia_codec_param_info, NULL, NULL);
+        if (self->info == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }        
+	self->setting = (PyObj_pjmedia_codec_param_setting *)
+	    PyType_GenericNew(&PyTyp_pjmedia_codec_param_setting, NULL, NULL);
+        if (self->setting == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }        
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * pjmedia_codec_param_members
+ */
+static PyMemberDef pjmedia_codec_param_members[] =
+{   
+    
+    {
+        "info", T_OBJECT_EX,
+        offsetof(PyObj_pjmedia_codec_param, info), 0,
+        "The 'info' part of codec param describes the capability of the codec,"
+        " and the value should NOT be changed by application."        
+    },
+    {
+        "setting", T_OBJECT_EX,
+        offsetof(PyObj_pjmedia_codec_param, setting), 0, 
+        "The 'setting' part of codec param describes various settings to be "
+        "applied to the codec. When the codec param is retrieved from the "
+        "codec or codec factory, the values of these will be filled by "
+        "the capability of the codec. Any features that are supported by "
+        "the codec (e.g. vad or plc) will be turned on, so that application "
+        "can query which capabilities are supported by the codec. "
+        "Application may change the settings here before instantiating "
+        "the codec/stream."        
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjmedia_codec_param
+ */
+static PyTypeObject PyTyp_pjmedia_codec_param =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.PJMedia_Codec_Param",      /*tp_name*/
+    sizeof(PyObj_pjmedia_codec_param),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)pjmedia_codec_param_dealloc,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJMedia Codec Param objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    pjmedia_codec_param_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    pjmedia_codec_param_new,             /* tp_new */
+
+};
+
+/*
+ * py_pjsua_conf_get_max_ports
+ */
+static PyObject *py_pjsua_conf_get_max_ports
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int ret;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    ret = pjsua_conf_get_max_ports();
+	
+    return Py_BuildValue("i", ret);
+}
+
+/*
+ * py_pjsua_conf_get_active_ports
+ */
+static PyObject *py_pjsua_conf_get_active_ports
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int ret;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }
+    ret = pjsua_conf_get_active_ports();
+	
+    return Py_BuildValue("i", ret);
+}
+
+/*
+ * py_pjsua_enum_conf_ports
+ * !modified @ 241206
+ */
+static PyObject *py_pjsua_enum_conf_ports(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    
+    pjsua_conf_port_id id[PJSUA_MAX_CONF_PORTS];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    c = PJ_ARRAY_SIZE(id);
+    status = pjsua_enum_conf_ports(id, &c);
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) 
+    {
+        int ret = PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
+        if (ret == -1) 
+	{
+            return NULL;
+	}
+    }
+    
+    return Py_BuildValue("O",list);
+}
+
+/*
+ * py_pjsua_conf_get_port_info
+ */
+static PyObject *py_pjsua_conf_get_port_info
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    PyObj_pjsua_conf_port_info * obj;
+    pjsua_conf_port_info info;
+    int status;	
+    unsigned i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id))
+    {
+        return NULL;
+    }
+	
+    
+    status = pjsua_conf_get_port_info(id, &info);
+    obj = (PyObj_pjsua_conf_port_info *)conf_port_info_new
+	    (&PyTyp_pjsua_conf_port_info,NULL,NULL);
+    obj->bits_per_sample = info.bits_per_sample;
+    obj->channel_count = info.bits_per_sample;
+    obj->clock_rate = info.clock_rate;
+    obj->name = PyString_FromStringAndSize(info.name.ptr, info.name.slen);
+    obj->samples_per_frame = info.samples_per_frame;
+    obj->slot_id = info.slot_id;
+    
+    obj->listeners = (PyListObject *)PyList_New(info.listener_cnt);
+    for (i = 0; i < info.listener_cnt; i++) {
+	PyObject * item = Py_BuildValue("i",info.listeners[i]);
+	PyList_SetItem((PyObject *)obj->listeners, i, item);
+    }
+    return Py_BuildValue("O", obj);
+}
+
+/*
+ * py_pjsua_conf_add_port
+ */
+static PyObject *py_pjsua_conf_add_port
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int p_id;
+    PyObject * oportObj;
+    PyObj_pjmedia_port * oport;
+    pjmedia_port * port;
+    PyObject * opoolObj;
+    PyObj_pj_pool * opool;
+    pj_pool_t * pool;
+    
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OO", &opoolObj, &oportObj))
+    {
+        return NULL;
+    }
+    if (opoolObj != Py_None)
+    {
+        opool = (PyObj_pj_pool *)opoolObj;
+		pool = opool->pool;
+    } else {
+       opool = NULL;
+       pool = NULL;
+    }
+    if (oportObj != Py_None)
+    {
+        oport = (PyObj_pjmedia_port *)oportObj;
+		port = oport->port;
+    } else {
+        oport = NULL;
+        port = NULL;
+    }
+
+    status = pjsua_conf_add_port(pool, port, &p_id);
+    
+    
+    return Py_BuildValue("ii", status, p_id);
+}
+
+/*
+ * py_pjsua_conf_remove_port
+ */
+static PyObject *py_pjsua_conf_remove_port
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_conf_remove_port(id);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_conf_connect
+ */
+static PyObject *py_pjsua_conf_connect
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int source, sink;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &source, &sink))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_conf_connect(source, sink);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_conf_disconnect
+ */
+static PyObject *py_pjsua_conf_disconnect
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int source, sink;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &source, &sink))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_conf_disconnect(source, sink);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_player_create
+ */
+static PyObject *py_pjsua_player_create
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int options;
+    PyObject * filename;
+    pj_str_t str;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "Oi", &filename, &options))
+    {
+        return NULL;
+    }	
+    str.ptr = PyString_AsString(filename);
+    str.slen = strlen(PyString_AsString(filename));
+    status = pjsua_player_create(&str, options, &id);
+    
+    return Py_BuildValue("ii", status, id);
+}
+
+/*
+ * py_pjsua_player_get_conf_port
+ */
+static PyObject *py_pjsua_player_get_conf_port
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    
+    int id, port_id;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id))
+    {
+        return NULL;
+    }	
+    
+    port_id = pjsua_player_get_conf_port(id);
+    
+    
+    return Py_BuildValue("i", port_id);
+}
+
+/*
+ * py_pjsua_player_set_pos
+ */
+static PyObject *py_pjsua_player_set_pos
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    pj_uint32_t samples;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iI", &id, &samples))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_player_set_pos(id, samples);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_player_destroy
+ */
+static PyObject *py_pjsua_player_destroy
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_player_destroy(id);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_recorder_create
+ * !modified @ 261206
+ */
+static PyObject *py_pjsua_recorder_create
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int p_id;
+    int options;
+    int max_size;
+    PyObject * filename;
+    pj_str_t str;
+    PyObject * enc_param;
+    pj_str_t strparam;
+    int enc_type;
+    
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OiOii", &filename, 
+		&enc_type, &enc_param, &max_size, &options))
+    {
+        return NULL;
+    }	
+    str.ptr = PyString_AsString(filename);
+    str.slen = strlen(PyString_AsString(filename));
+    if (enc_param != Py_None)
+    {
+        strparam.ptr = PyString_AsString(enc_param);
+        strparam.slen = strlen(PyString_AsString(enc_param));
+        status = pjsua_recorder_create
+		(&str, enc_type, NULL, max_size, options, &p_id);
+    } else {
+        status = pjsua_recorder_create
+		(&str, enc_type, NULL, max_size, options, &p_id);
+    }
+    return Py_BuildValue("ii", status, p_id);
+}
+
+/*
+ * py_pjsua_recorder_get_conf_port
+ */
+static PyObject *py_pjsua_recorder_get_conf_port
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    
+    int id, port_id;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id))
+    {
+        return NULL;
+    }	
+    
+    port_id = pjsua_recorder_get_conf_port(id);
+    
+    
+    return Py_BuildValue("i", port_id);
+}
+
+/*
+ * py_pjsua_recorder_destroy
+ */
+static PyObject *py_pjsua_recorder_destroy
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_recorder_destroy(id);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_enum_snd_devs
+ */
+static PyObject *py_pjsua_enum_snd_devs(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    
+    pjmedia_snd_dev_info info[SND_DEV_NUM];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    c = PJ_ARRAY_SIZE(info);
+    status = pjsua_enum_snd_devs(info, &c);
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) 
+    {
+        int ret;
+        int j;
+        char * str;
+	
+        PyObj_pjmedia_snd_dev_info * obj;
+        obj = (PyObj_pjmedia_snd_dev_info *)pjmedia_snd_dev_info_new
+	    (&PyTyp_pjmedia_snd_dev_info, NULL, NULL);
+        obj->default_samples_per_sec = info[i].default_samples_per_sec;
+        obj->input_count = info[i].input_count;
+        obj->output_count = info[i].output_count;
+        str = (char *)malloc(SND_NAME_LEN * sizeof(char));
+        memset(str, 0, SND_NAME_LEN);
+        for (j = 0; j < SND_NAME_LEN; j++)
+	{
+            str[j] = info[i].name[j];
+	}
+        obj->name = PyString_FromStringAndSize(str, SND_NAME_LEN);
+        free(str);
+        ret = PyList_SetItem(list, i, (PyObject *)obj);
+        if (ret == -1) 
+	{
+            return NULL;
+	}
+    }
+    
+    return Py_BuildValue("O",list);
+}
+
+/*
+ * py_pjsua_get_snd_dev
+ */
+static PyObject *py_pjsua_get_snd_dev
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int capture_dev, playback_dev;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_get_snd_dev(&capture_dev, &playback_dev);
+    
+    
+    return Py_BuildValue("ii", capture_dev, playback_dev);
+}
+
+/*
+ * py_pjsua_set_snd_dev
+ */
+static PyObject *py_pjsua_set_snd_dev
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int capture_dev, playback_dev;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &capture_dev, &playback_dev))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_set_snd_dev(capture_dev, playback_dev);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_set_null_snd_dev
+ */
+static PyObject *py_pjsua_set_null_snd_dev
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_set_null_snd_dev();
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_set_no_snd_dev
+ */
+static PyObject *py_pjsua_set_no_snd_dev
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    
+    PyObj_pjmedia_port * obj;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+     
+    obj = (PyObj_pjmedia_port *)PyType_GenericNew
+	(&PyTyp_pjmedia_port, NULL, NULL);
+    obj->port = pjsua_set_no_snd_dev();
+    return Py_BuildValue("O", obj);
+}
+
+/*
+ * py_pjsua_set_ec
+ */
+static PyObject *py_pjsua_set_ec
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int options;
+    int tail_ms;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &tail_ms, &options))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_set_ec(tail_ms, options);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_get_ec_tail
+ */
+static PyObject *py_pjsua_get_ec_tail
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    
+    int status;	
+    unsigned p_tail_ms;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_get_ec_tail(&p_tail_ms);
+    
+    
+    return Py_BuildValue("i", p_tail_ms);
+}
+
+/*
+ * py_pjsua_enum_codecs
+ * !modified @ 261206
+ */
+static PyObject *py_pjsua_enum_codecs(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    
+    pjsua_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    c = PJ_ARRAY_SIZE(info);
+    status = pjsua_enum_codecs(info, &c);
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) 
+    {
+        int ret;
+        int j;
+        PyObj_pjsua_codec_info * obj;
+        obj = (PyObj_pjsua_codec_info *)codec_info_new
+	    (&PyTyp_pjsua_codec_info, NULL, NULL);
+        obj->codec_id = PyString_FromStringAndSize
+	    (info[i].codec_id.ptr, info[i].codec_id.slen);
+        obj->priority = info[i].priority;
+        for (j = 0; j < 32; j++)
+        {	    
+             obj->buf_[j] = info[i].buf_[j];
+        }	
+        ret = PyList_SetItem(list, i, (PyObject *)obj);
+        if (ret == -1) {
+            return NULL;
+        }	
+    }
+    
+
+    return Py_BuildValue("O",list);
+}
+
+/*
+ * py_pjsua_codec_set_priority
+ */
+static PyObject *py_pjsua_codec_set_priority
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    
+    int status;	
+    PyObject * id;
+    pj_str_t str;
+    pj_uint8_t priority;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OB", &id, &priority))
+    {
+        return NULL;
+    }	
+    str.ptr = PyString_AsString(id);
+    str.slen = strlen(PyString_AsString(id));
+    status = pjsua_codec_set_priority(&str, priority);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_codec_get_param
+ */
+static PyObject *py_pjsua_codec_get_param
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    
+    int status;	
+    PyObject * id;
+    pj_str_t str;
+    pjmedia_codec_param param;
+    PyObj_pjmedia_codec_param *obj;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "O", &id))
+    {
+        return NULL;
+    }	
+    str.ptr = PyString_AsString(id);
+    str.slen = strlen(PyString_AsString(id));
+    status = pjsua_codec_get_param(&str, &param);
+    obj = (PyObj_pjmedia_codec_param *)pjmedia_codec_param_new
+	(&PyTyp_pjmedia_codec_param, NULL, NULL);
+    obj->info->avg_bps = param.info.avg_bps;
+    obj->info->channel_cnt = param.info.channel_cnt;
+    obj->info->clock_rate = param.info.clock_rate;
+    obj->info->frm_ptime = param.info.frm_ptime;
+    obj->info->pcm_bits_per_sample = param.info.pcm_bits_per_sample;
+    obj->info->pt = param.info.pt;
+    obj->setting->cng = param.setting.cng;
+    //deprecated:
+    //obj->setting->dec_fmtp_mode = param.setting.dec_fmtp_mode;
+    //obj->setting->enc_fmtp_mode = param.setting.enc_fmtp_mode;
+    obj->setting->frm_per_pkt = param.setting.frm_per_pkt;
+    obj->setting->penh = param.setting.penh;
+    obj->setting->plc = param.setting.plc;
+    obj->setting->reserved = param.setting.reserved;
+    obj->setting->vad = param.setting.vad;
+
+    return Py_BuildValue("O", obj);
+}
+/*
+ * py_pjsua_codec_set_param
+ */
+static PyObject *py_pjsua_codec_set_param
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    
+    int status;	
+    PyObject * id;
+    pj_str_t str;
+    pjmedia_codec_param param;
+    PyObject * tmpObj;
+    PyObj_pjmedia_codec_param *obj;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OO", &id, &tmpObj))
+    {
+        return NULL;
+    }	
+
+    str.ptr = PyString_AsString(id);
+    str.slen = strlen(PyString_AsString(id));
+    if (tmpObj != Py_None)
+    {
+        obj = (PyObj_pjmedia_codec_param *)tmpObj;
+        param.info.avg_bps = obj->info->avg_bps;
+        param.info.channel_cnt = obj->info->channel_cnt;
+        param.info.clock_rate = obj->info->clock_rate;
+        param.info.frm_ptime = obj->info->frm_ptime;
+        param.info.pcm_bits_per_sample = obj->info->pcm_bits_per_sample;
+        param.info.pt = obj->info->pt;
+        param.setting.cng = obj->setting->cng;
+	//Deprecated:
+        //param.setting.dec_fmtp_mode = obj->setting->dec_fmtp_mode;
+        //param.setting.enc_fmtp_mode = obj->setting->enc_fmtp_mode;
+        param.setting.frm_per_pkt = obj->setting->frm_per_pkt;
+        param.setting.penh = obj->setting->penh;
+        param.setting.plc = obj->setting->plc;
+        param.setting.reserved = obj->setting->reserved;
+        param.setting.vad = obj->setting->vad;
+        status = pjsua_codec_set_param(&str, &param);
+    } else {
+        status = pjsua_codec_set_param(&str, NULL);
+    }
+    return Py_BuildValue("i", status);
+}
+
+static char pjsua_conf_get_max_ports_doc[] =
+    "int py_pjsua.conf_get_max_ports () "
+    "Get maxinum number of conference ports.";
+static char pjsua_conf_get_active_ports_doc[] =
+    "int py_pjsua.conf_get_active_ports () "
+    "Get current number of active ports in the bridge.";
+static char pjsua_enum_conf_ports_doc[] =
+    "int[] py_pjsua.enum_conf_ports () "
+    "Enumerate all conference ports.";
+static char pjsua_conf_get_port_info_doc[] =
+    "py_pjsua.Conf_Port_Info py_pjsua.conf_get_port_info (int id) "
+    "Get information about the specified conference port";
+static char pjsua_conf_add_port_doc[] =
+    "int, int py_pjsua.conf_add_port "
+    "(py_pjsua.Pj_Pool pool, py_pjsua.PJMedia_Port port) "
+    "Add arbitrary media port to PJSUA's conference bridge. "
+    "Application can use this function to add the media port "
+    "that it creates. For media ports that are created by PJSUA-LIB "
+    "(such as calls, file player, or file recorder), PJSUA-LIB will "
+    "automatically add the port to the bridge.";
+static char pjsua_conf_remove_port_doc[] =
+    "int py_pjsua.conf_remove_port (int id) "
+    "Remove arbitrary slot from the conference bridge. "
+    "Application should only call this function "
+    "if it registered the port manually.";
+static char pjsua_conf_connect_doc[] =
+    "int py_pjsua.conf_connect (int source, int sink) "
+    "Establish unidirectional media flow from souce to sink. "
+    "One source may transmit to multiple destinations/sink. "
+    "And if multiple sources are transmitting to the same sink, "
+    "the media will be mixed together. Source and sink may refer "
+    "to the same ID, effectively looping the media. "
+    "If bidirectional media flow is desired, application "
+    "needs to call this function twice, with the second "
+    "one having the arguments reversed.";
+static char pjsua_conf_disconnect_doc[] =
+    "int py_pjsua.conf_disconnect (int source, int sink) "
+    "Disconnect media flow from the source to destination port.";
+static char pjsua_player_create_doc[] =
+    "int, int py_pjsua.player_create (string filename, int options) "
+    "Create a file player, and automatically connect "
+    "this player to the conference bridge.";
+static char pjsua_player_get_conf_port_doc[] =
+    "int py_pjsua.player_get_conf_port (int) "
+    "Get conference port ID associated with player.";
+static char pjsua_player_set_pos_doc[] =
+    "int py_pjsua.player_set_pos (int id, int samples) "
+    "Set playback position.";
+static char pjsua_player_destroy_doc[] =
+    "int py_pjsua.player_destroy (int id) "
+    "Close the file, remove the player from the bridge, "
+    "and free resources associated with the file player.";
+static char pjsua_recorder_create_doc[] =
+    "int, int py_pjsua.recorder_create (string filename, "
+    "int enc_type, int enc_param, int max_size, int options) "
+    "Create a file recorder, and automatically connect this recorder "
+    "to the conference bridge. The recorder currently supports recording "
+    "WAV file, and on Windows, MP3 file. The type of the recorder to use "
+    "is determined by the extension of the file (e.g. '.wav' or '.mp3').";
+static char pjsua_recorder_get_conf_port_doc[] =
+    "int py_pjsua.recorder_get_conf_port (int id) "
+    "Get conference port associated with recorder.";
+static char pjsua_recorder_destroy_doc[] =
+    "int py_pjsua.recorder_destroy (int id) "
+    "Destroy recorder (this will complete recording).";
+static char pjsua_enum_snd_devs_doc[] =
+    "py_pjsua.PJMedia_Snd_Dev_Info[] py_pjsua.enum_snd_devs (int count) "
+    "Enum sound devices.";
+static char pjsua_get_snd_dev_doc[] =
+    "int, int py_pjsua.get_snd_dev () "
+    "Get currently active sound devices. "
+    "If sound devices has not been created "
+    "(for example when pjsua_start() is not called), "
+    "it is possible that the function returns "
+    "PJ_SUCCESS with -1 as device IDs.";
+static char pjsua_set_snd_dev_doc[] =
+    "int py_pjsua.set_snd_dev (int capture_dev, int playback_dev) "
+    "Select or change sound device. Application may call this function "
+    "at any time to replace current sound device.";
+static char pjsua_set_null_snd_dev_doc[] =
+    "int py_pjsua.set_null_snd_dev () "
+    "Set pjsua to use null sound device. The null sound device only "
+    "provides the timing needed by the conference bridge, and will not "
+    "interract with any hardware.";
+static char pjsua_set_no_snd_dev_doc[] =
+    "py_pjsua.PJMedia_Port py_pjsua.set_no_snd_dev () "
+    "Disconnect the main conference bridge from any sound devices, "
+    "and let application connect the bridge to it's "
+    "own sound device/master port.";
+static char pjsua_set_ec_doc[] =
+    "int py_pjsua.set_ec (int tail_ms, int options) "
+    "Configure the echo canceller tail length of the sound port.";
+static char pjsua_get_ec_tail_doc[] =
+    "int py_pjsua.get_ec_tail () "
+    "Get current echo canceller tail length.";
+static char pjsua_enum_codecs_doc[] =
+    "py_pjsua.Codec_Info[] py_pjsua.enum_codecs () "
+    "Enum all supported codecs in the system.";
+static char pjsua_codec_set_priority_doc[] =
+    "int py_pjsua.codec_set_priority (string id, int priority) "
+    "Change codec priority.";
+static char pjsua_codec_get_param_doc[] =
+    "py_pjsua.PJMedia_Codec_Param py_pjsua.codec_get_param (string id) "
+    "Get codec parameters";
+static char pjsua_codec_set_param_doc[] =
+    "int py_pjsua.codec_set_param (string id, "
+    "py_pjsua.PJMedia_Codec_Param param) "
+    "Set codec parameters.";
+
+/* END OF LIB MEDIA */
+
+/* LIB CALL */
+
+/*
+ * PyObj_pj_time_val
+ * PJ Time Val
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    long sec;
+    long msec;
+
+} PyObj_pj_time_val;
+
+
+
+/*
+ * pj_time_val_members
+ */
+static PyMemberDef pj_time_val_members[] =
+{   
+    
+    {
+        "sec", T_INT, 
+        offsetof(PyObj_pj_time_val, sec), 0,
+        "The seconds part of the time"
+    },
+    {
+        "msec", T_INT, 
+        offsetof(PyObj_pj_time_val, sec), 0,
+        "The milliseconds fraction of the time"
+    },
+    
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pj_time_val
+ */
+static PyTypeObject PyTyp_pj_time_val =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.PJ_Time_Val",      /*tp_name*/
+    sizeof(PyObj_pj_time_val),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    0,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJ Time Val objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    pj_time_val_members,         /* tp_members */
+    
+
+};
+
+/*
+ * PyObj_pjsua_call_info
+ * Call Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    int id;
+    int role;
+    int acc_id;
+    PyObject * local_info;
+    PyObject * local_contact;
+    PyObject * remote_info;
+    PyObject * remote_contact;
+    PyObject * call_id;
+    int state;
+    PyObject * state_text;
+    int last_status;
+    PyObject * last_status_text;
+    int media_status;
+    int media_dir;
+    int conf_slot;
+    PyObj_pj_time_val * connect_duration;
+    PyObj_pj_time_val * total_duration;
+    struct {
+	char local_info[128];
+	char local_contact[128];
+	char remote_info[128];
+	char remote_contact[128];
+	char call_id[128];
+	char last_status_text[128];
+    } buf_;
+
+} PyObj_pjsua_call_info;
+
+
+/*
+ * call_info_dealloc
+ * deletes a call_info from memory
+ */
+static void call_info_dealloc(PyObj_pjsua_call_info* self)
+{
+    Py_XDECREF(self->local_info);
+    Py_XDECREF(self->local_contact);
+    Py_XDECREF(self->remote_info);
+    Py_XDECREF(self->remote_contact);
+    Py_XDECREF(self->call_id);
+    Py_XDECREF(self->state_text);
+    Py_XDECREF(self->last_status_text);
+    Py_XDECREF(self->connect_duration);
+    Py_XDECREF(self->total_duration);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * call_info_new
+ * constructor for call_info object
+ */
+static PyObject * call_info_new(PyTypeObject *type, PyObject *args,
+                                    PyObject *kwds)
+{
+    PyObj_pjsua_call_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_call_info *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->local_info = PyString_FromString("");
+        if (self->local_info == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }       
+	self->local_contact = PyString_FromString("");
+        if (self->local_contact == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->remote_info = PyString_FromString("");
+        if (self->remote_info == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->remote_contact = PyString_FromString("");
+        if (self->remote_contact == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->call_id = PyString_FromString("");
+        if (self->call_id == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->state_text = PyString_FromString("");
+        if (self->state_text == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->last_status_text = PyString_FromString("");
+        if (self->last_status_text == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->connect_duration = (PyObj_pj_time_val *)PyType_GenericNew
+	    (&PyTyp_pj_time_val,NULL,NULL);
+        if (self->connect_duration == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->total_duration = (PyObj_pj_time_val *)PyType_GenericNew
+	    (&PyTyp_pj_time_val,NULL,NULL);
+        if (self->total_duration == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * call_info_members
+ */
+static PyMemberDef call_info_members[] =
+{   
+    {
+        "id", T_INT, 
+        offsetof(PyObj_pjsua_call_info, id), 0,
+        "Call identification"
+    },
+    {
+        "role", T_INT, 
+        offsetof(PyObj_pjsua_call_info, role), 0,
+        "Initial call role (UAC == caller)"
+    },
+    {
+        "acc_id", T_INT, 
+        offsetof(PyObj_pjsua_call_info, acc_id), 0,
+        "The account ID where this call belongs."
+    },
+    {
+        "local_info", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, local_info), 0,
+        "Local URI"        
+    },
+    {
+        "local_contact", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, local_contact), 0,
+        "Local Contact"        
+    },
+    {
+        "remote_info", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, remote_info), 0,
+        "Remote URI"        
+    },
+    {
+        "remote_contact", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, remote_contact), 0,
+        "Remote Contact"        
+    },
+    {
+        "call_id", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, call_id), 0,
+        "Dialog Call-ID string"        
+    },
+    {
+        "state", T_INT, 
+        offsetof(PyObj_pjsua_call_info, state), 0,
+        "Call state"
+    },
+    {
+        "state_text", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, state_text), 0,
+        "Text describing the state "        
+    },
+    {
+        "last_status", T_INT, 
+        offsetof(PyObj_pjsua_call_info, last_status), 0,
+        "Last status code heard, which can be used as cause code"
+    },
+    {
+        "last_status_text", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, last_status_text), 0,
+        "The reason phrase describing the status."        
+    },
+    {
+        "media_status", T_INT, 
+        offsetof(PyObj_pjsua_call_info, media_status), 0,
+        "Call media status."
+    },
+    {
+        "media_dir", T_INT, 
+        offsetof(PyObj_pjsua_call_info, media_dir), 0,
+        "Media direction"
+    },
+    {
+        "conf_slot", T_INT, 
+        offsetof(PyObj_pjsua_call_info, conf_slot), 0,
+        "The conference port number for the call"
+    },
+    {
+        "connect_duration", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, connect_duration), 0,
+        "Up-to-date call connected duration(zero when call is not established)"
+    },
+    {
+        "total_duration", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, total_duration), 0,
+        "Total call duration, including set-up time"        
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_call_info
+ */
+static PyTypeObject PyTyp_pjsua_call_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Call_Info",      /*tp_name*/
+    sizeof(PyObj_pjsua_call_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)call_info_dealloc,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Call Info objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    call_info_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    call_info_new,             /* tp_new */
+
+};
+
+/*
+ * py_pjsua_call_get_max_count
+ */
+static PyObject *py_pjsua_call_get_max_count
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int count;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    count = pjsua_call_get_max_count();
+    
+    
+    return Py_BuildValue("i", count);
+}
+
+/*
+ * py_pjsua_call_get_count
+ */
+static PyObject *py_pjsua_call_get_count
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    
+    int count;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    count = pjsua_call_get_count();
+    
+    
+    return Py_BuildValue("i", count);
+}
+
+/*
+ * py_pjsua_enum_calls
+ */
+static PyObject *py_pjsua_enum_calls(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    
+    pjsua_transport_id id[PJSUA_MAX_CALLS];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    c = PJ_ARRAY_SIZE(id);
+    status = pjsua_enum_calls(id, &c);
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) 
+    {     
+        int ret = PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
+        if (ret == -1) 
+        {
+            return NULL;
+        }
+    }
+    
+    return Py_BuildValue("O",list);
+}
+
+/*
+ * py_pjsua_call_make_call
+ */
+static PyObject *py_pjsua_call_make_call
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int acc_id;
+    pj_str_t dst_uri;
+    PyObject * sd;
+    unsigned options;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;
+    int user_data;
+    int call_id;
+    pj_pool_t * pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple
+		(pArgs, "iOIiO", &acc_id, &sd, &options, &user_data, &omdObj))
+    {
+        return NULL;
+    }
+	
+    dst_uri.ptr = PyString_AsString(sd);
+    dst_uri.slen = strlen(PyString_AsString(sd));
+    if (omdObj != Py_None) 
+    {
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type.ptr = PyString_AsString(omd->content_type);
+        msg_data.content_type.slen = strlen
+			(PyString_AsString(omd->content_type));
+        msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
+        msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_call_make_call(acc_id, &dst_uri, 
+			options, (void*)user_data, &msg_data, &call_id);	
+        pj_pool_release(pool);
+    } else {
+		
+        status = pjsua_call_make_call(acc_id, &dst_uri, 
+			options, (void*)user_data, NULL, &call_id);	
+    }
+	
+    return Py_BuildValue("ii",status, call_id);
+	
+}
+
+/*
+ * py_pjsua_call_is_active
+ */
+static PyObject *py_pjsua_call_is_active
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int isActive;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id))
+    {
+        return NULL;
+    }	
+    
+    isActive = pjsua_call_is_active(call_id);
+    
+    
+    return Py_BuildValue("i", isActive);
+}
+
+/*
+ * py_pjsua_call_has_media
+ */
+static PyObject *py_pjsua_call_has_media
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int hasMedia;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id))
+    {
+        return NULL;
+    }	
+    
+    hasMedia = pjsua_call_has_media(call_id);
+    
+    
+    return Py_BuildValue("i", hasMedia);
+}
+
+/*
+ * py_pjsua_call_get_conf_port
+ */
+static PyObject *py_pjsua_call_get_conf_port
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int port_id;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id))
+    {
+        return NULL;
+    }	
+    
+    port_id = pjsua_call_get_conf_port(call_id);
+    
+    
+    return Py_BuildValue("i", port_id);
+}
+
+/*
+ * py_pjsua_call_get_info
+ */
+static PyObject *py_pjsua_call_get_info
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int status;
+    PyObj_pjsua_call_info * oi;
+    pjsua_call_info info;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id))
+    {
+        return NULL;
+    }	
+    
+    
+    status = pjsua_call_get_info(call_id, &info);
+    if (status == PJ_SUCCESS) 
+    {
+        oi = (PyObj_pjsua_call_info *)call_info_new(&PyTyp_pjsua_call_info, NULL, NULL);
+        oi->acc_id = info.acc_id;
+        pj_ansi_snprintf(oi->buf_.call_id, sizeof(oi->buf_.call_id),
+	    "%.*s", (int)info.call_id.slen, info.call_id.ptr);
+        pj_ansi_snprintf(oi->buf_.last_status_text, 
+	    sizeof(oi->buf_.last_status_text),
+	    "%.*s", (int)info.last_status_text.slen, info.last_status_text.ptr);
+        pj_ansi_snprintf(oi->buf_.local_contact, sizeof(oi->buf_.local_contact),
+	    "%.*s", (int)info.local_contact.slen, info.local_contact.ptr);
+        pj_ansi_snprintf(oi->buf_.local_info, sizeof(oi->buf_.local_info),
+	    "%.*s", (int)info.local_info.slen, info.local_info.ptr);
+        pj_ansi_snprintf(oi->buf_.remote_contact,
+	    sizeof(oi->buf_.remote_contact),
+	    "%.*s", (int)info.remote_contact.slen, info.remote_contact.ptr);
+        pj_ansi_snprintf(oi->buf_.remote_info, sizeof(oi->buf_.remote_info),
+	    "%.*s", (int)info.remote_info.slen, info.remote_info.ptr);
+
+        oi->call_id = PyString_FromStringAndSize(info.call_id.ptr, 
+	    info.call_id.slen);
+        oi->conf_slot = info.conf_slot;
+        oi->connect_duration->sec = info.connect_duration.sec;
+        oi->connect_duration->msec = info.connect_duration.msec;
+        oi->total_duration->sec = info.total_duration.sec;
+        oi->total_duration->msec = info.total_duration.msec;
+        oi->id = info.id;
+        oi->last_status = info.last_status;
+        oi->last_status_text = PyString_FromStringAndSize(
+	    info.last_status_text.ptr, info.last_status_text.slen);
+        oi->local_contact = PyString_FromStringAndSize(
+	    info.local_contact.ptr, info.local_contact.slen);
+        oi->local_info = PyString_FromStringAndSize(
+   	    info.local_info.ptr, info.local_info.slen);
+        oi->remote_contact = PyString_FromStringAndSize(
+	    info.remote_contact.ptr, info.remote_contact.slen);
+        oi->remote_info = PyString_FromStringAndSize(
+	    info.remote_info.ptr, info.remote_info.slen);
+        oi->media_dir = info.media_dir;
+        oi->media_status = info.media_status;
+        oi->role = info.role;
+        oi->state = info.state;
+        oi->state_text = PyString_FromStringAndSize(
+   	    info.state_text.ptr, info.state_text.slen);
+
+	return Py_BuildValue("O", oi);
+    } else {
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+}
+
+/*
+ * py_pjsua_call_set_user_data
+ */
+static PyObject *py_pjsua_call_set_user_data
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int user_data;	
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &call_id, &user_data))
+    {
+        return NULL;
+    }	
+    
+    status = pjsua_call_set_user_data(call_id, (void*)user_data);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_get_user_data
+ */
+static PyObject *py_pjsua_call_get_user_data
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    void * user_data;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id))
+    {
+        return NULL;
+    }	
+    
+    user_data = pjsua_call_get_user_data(call_id);
+    
+    
+    return Py_BuildValue("i", (int)user_data);
+}
+
+/*
+ * py_pjsua_call_answer
+ */
+static PyObject *py_pjsua_call_answer
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    pj_str_t * reason, tmp_reason;
+    PyObject * sr;
+    unsigned code;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;    
+    pj_pool_t * pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &sr, &omdObj))
+    {
+        return NULL;
+    }
+    if (sr == Py_None) 
+    {
+        reason = NULL;
+    } else {
+	reason = &tmp_reason;
+        tmp_reason.ptr = PyString_AsString(sr);
+        tmp_reason.slen = strlen(PyString_AsString(sr));
+    }
+    if (omdObj != Py_None) 
+    {
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type.ptr = PyString_AsString(omd->content_type);
+        msg_data.content_type.slen = strlen
+			(PyString_AsString(omd->content_type));
+        msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
+        msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+	
+        status = pjsua_call_answer(call_id, code, reason, &msg_data);	
+    
+        pj_pool_release(pool);
+    } else {
+	
+        status = pjsua_call_answer(call_id, code, reason, NULL);
+	
+    }
+    
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_call_hangup
+ */
+static PyObject *py_pjsua_call_hangup
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    pj_str_t * reason, tmp_reason;
+    PyObject * sr;
+    unsigned code;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;    
+    pj_pool_t * pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &sr, &omdObj))
+    {
+        return NULL;
+    }
+    if (sr == Py_None)
+    {
+        reason = NULL;
+    } else {
+        reason = &tmp_reason;
+        tmp_reason.ptr = PyString_AsString(sr);
+        tmp_reason.slen = strlen(PyString_AsString(sr));
+    }
+    if (omdObj != Py_None) 
+    {
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type.ptr = PyString_AsString(omd->content_type);
+        msg_data.content_type.slen = strlen
+			(PyString_AsString(omd->content_type));
+        msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
+        msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_call_hangup(call_id, code, reason, &msg_data);	
+        pj_pool_release(pool);
+    } else {
+        status = pjsua_call_hangup(call_id, code, reason, NULL);	
+    }
+    
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_call_set_hold
+ */
+static PyObject *py_pjsua_call_set_hold
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;    
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;    
+    pj_pool_t * pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &omdObj))
+    {
+        return NULL;
+    }
+
+    if (omdObj != Py_None) 
+    {
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type.ptr = PyString_AsString(omd->content_type);
+        msg_data.content_type.slen = strlen
+			(PyString_AsString(omd->content_type));
+        msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
+        msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_call_set_hold(call_id, &msg_data);	
+        pj_pool_release(pool);
+    } else {
+        status = pjsua_call_set_hold(call_id, NULL);	
+    }
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_call_reinvite
+ */
+static PyObject *py_pjsua_call_reinvite
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;    
+    int unhold;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;    
+    pj_pool_t * pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &unhold, &omdObj))
+    {
+        return NULL;
+    }
+
+    if (omdObj != Py_None)
+    {
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type.ptr = PyString_AsString(omd->content_type);
+        msg_data.content_type.slen = strlen
+			(PyString_AsString(omd->content_type));
+        msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
+        msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_call_reinvite(call_id, unhold, &msg_data);	
+        pj_pool_release(pool);
+    } else {
+        status = pjsua_call_reinvite(call_id, unhold, NULL);
+    }
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_call_xfer
+ */
+static PyObject *py_pjsua_call_xfer
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    pj_str_t dest;
+    PyObject * sd;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;    
+    pj_pool_t * pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iOO", &call_id, &sd, &omdObj))
+    {
+        return NULL;
+    }
+	
+    dest.ptr = PyString_AsString(sd);
+    dest.slen = strlen(PyString_AsString(sd));
+    
+    if (omdObj != Py_None)
+    {
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type.ptr = PyString_AsString(omd->content_type);
+        msg_data.content_type.slen = strlen
+			(PyString_AsString(omd->content_type));
+        msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
+        msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_call_xfer(call_id, &dest, &msg_data);	
+        pj_pool_release(pool);
+    } else {
+        status = pjsua_call_xfer(call_id, &dest, NULL);	
+    }
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_call_xfer_replaces
+ */
+static PyObject *py_pjsua_call_xfer_replaces
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    int dest_call_id;
+    unsigned options;    
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;    
+    pj_pool_t * pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple
+		(pArgs, "iiIO", &call_id, &dest_call_id, &options, &omdObj))
+    {
+        return NULL;
+    }
+	
+    if (omdObj != Py_None)
+    {
+        omd = (PyObj_pjsua_msg_data *)omdObj;    
+        msg_data.content_type.ptr = PyString_AsString(omd->content_type);
+        msg_data.content_type.slen = strlen
+			(PyString_AsString(omd->content_type));
+        msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
+        msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_call_xfer_replaces
+			(call_id, dest_call_id, options, &msg_data);	
+        pj_pool_release(pool);
+    } else {
+        status = pjsua_call_xfer_replaces(call_id, dest_call_id,options, NULL);	
+    }
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_call_dial_dtmf
+ */
+static PyObject *py_pjsua_call_dial_dtmf
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    PyObject * sd;
+    pj_str_t digits;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &sd))
+    {
+        return NULL;
+    }	
+    digits.ptr = PyString_AsString(sd);
+    digits.slen = strlen(PyString_AsString(sd));
+    status = pjsua_call_dial_dtmf(call_id, &digits);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_send_im
+ */
+static PyObject *py_pjsua_call_send_im
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    pj_str_t content;
+    pj_str_t * mime_type, tmp_mime_type;
+    PyObject * sm;
+    PyObject * sc;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;    
+    int user_data;
+    pj_pool_t * pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple
+		(pArgs, "iOOOi", &call_id, &sm, &sc, &omdObj, &user_data))
+    {
+        return NULL;
+    }
+    if (sm == Py_None)
+    {
+        mime_type = NULL;
+    } else {
+        mime_type = &tmp_mime_type;
+        tmp_mime_type.ptr = PyString_AsString(sm);
+        tmp_mime_type.slen = strlen(PyString_AsString(sm));
+    }
+    content.ptr = PyString_AsString(sc);
+    content.slen = strlen(PyString_AsString(sc));
+    
+    if (omdObj != Py_None)
+    {
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type.ptr = PyString_AsString(omd->content_type);
+        msg_data.content_type.slen = strlen
+			(PyString_AsString(omd->content_type));
+        msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
+        msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_call_send_im
+		(call_id, mime_type, &content, &msg_data, (void *)user_data);	
+        pj_pool_release(pool);
+    } else {
+        status = pjsua_call_send_im
+			(call_id, mime_type, &content, NULL, (void *)user_data);	
+    }
+    
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_call_send_typing_ind
+ */
+static PyObject *py_pjsua_call_send_typing_ind
+(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;    
+    int is_typing;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    PyObj_pjsua_msg_data * omd;    
+    pj_pool_t * pool;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &is_typing, &omdObj))
+    {
+        return NULL;
+    }
+	
+    if (omdObj != Py_None)
+    {
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type.ptr = PyString_AsString(omd->content_type);
+        msg_data.content_type.slen = strlen
+			(PyString_AsString(omd->content_type));
+        msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
+        msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
+        pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+        status = pjsua_call_send_typing_ind(call_id, is_typing, &msg_data);	
+        pj_pool_release(pool);
+    } else {
+        status = pjsua_call_send_typing_ind(call_id, is_typing, NULL);	
+    }
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_call_hangup_all
+ */
+static PyObject *py_pjsua_call_hangup_all
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, ""))
+    {
+        return NULL;
+    }	
+    
+    pjsua_call_hangup_all();
+    
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/*
+ * py_pjsua_call_dump
+ */
+static PyObject *py_pjsua_call_dump
+(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int with_media;
+    PyObject * sb;
+    PyObject * si;
+    char * buffer;
+    char * indent;
+    unsigned maxlen;    
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiIO", &call_id, &with_media, &maxlen, &si))
+    {
+        return NULL;
+    }	
+    buffer = (char *) malloc (maxlen * sizeof(char));
+    indent = PyString_AsString(si);
+    
+    status = pjsua_call_dump(call_id, with_media, buffer, maxlen, indent);
+    sb = PyString_FromStringAndSize(buffer, maxlen);
+    free(buffer);
+    return Py_BuildValue("O", sb);
+}
+
+
+/*
+ * py_pjsua_dump
+ * Dump application states.
+ */
+static PyObject *py_pjsua_dump(PyObject *pSelf, PyObject *pArgs)
+{
+    unsigned old_decor;
+    char buf[1024];
+    int detail;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &detail))
+    {
+        return NULL;
+    }	
+
+    PJ_LOG(3,(THIS_FILE, "Start dumping application states:"));
+
+    old_decor = pj_log_get_decor();
+    pj_log_set_decor(old_decor & (PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_CR));
+
+    if (detail)
+	pj_dump_config();
+
+    pjsip_endpt_dump(pjsua_get_pjsip_endpt(), detail);
+    pjmedia_endpt_dump(pjsua_get_pjmedia_endpt());
+    pjsip_tsx_layer_dump(detail);
+    pjsip_ua_dump(detail);
+
+
+    /* Dump all invite sessions: */
+    PJ_LOG(3,(THIS_FILE, "Dumping invite sessions:"));
+
+    if (pjsua_call_get_count() == 0) {
+
+	PJ_LOG(3,(THIS_FILE, "  - no sessions -"));
+
+    } else {
+	unsigned i, max;
+
+	max = pjsua_call_get_max_count();
+	for (i=0; i<max; ++i) {
+	    if (pjsua_call_is_active(i)) {
+		pjsua_call_dump(i, detail, buf, sizeof(buf), "  ");
+		PJ_LOG(3,(THIS_FILE, "%s", buf));
+	    }
+	}
+    }
+
+    /* Dump presence status */
+    pjsua_pres_dump(detail);
+
+    pj_log_set_decor(old_decor);
+    PJ_LOG(3,(THIS_FILE, "Dump complete"));
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+static char pjsua_call_get_max_count_doc[] =
+    "int py_pjsua.call_get_max_count () "
+    "Get maximum number of calls configured in pjsua.";
+static char pjsua_call_get_count_doc[] =
+    "int py_pjsua.call_get_count () "
+    "Get number of currently active calls.";
+static char pjsua_enum_calls_doc[] =
+    "int[] py_pjsua.enum_calls () "
+    "Get maximum number of calls configured in pjsua.";
+static char pjsua_call_make_call_doc[] =
+    "int,int py_pjsua.call_make_call (int acc_id, string dst_uri, int options,"
+    "int user_data, py_pjsua.Msg_Data msg_data) "
+    "Make outgoing call to the specified URI using the specified account.";
+static char pjsua_call_is_active_doc[] =
+    "int py_pjsua.call_is_active (int call_id) "
+    "Check if the specified call has active INVITE session and the INVITE "
+    "session has not been disconnected.";
+static char pjsua_call_has_media_doc[] =
+    "int py_pjsua.call_has_media (int call_id) "
+    "Check if call has an active media session.";
+static char pjsua_call_get_conf_port_doc[] =
+    "int py_pjsua.call_get_conf_port (int call_id) "
+    "Get the conference port identification associated with the call.";
+static char pjsua_call_get_info_doc[] =
+    "py_pjsua.Call_Info py_pjsua.call_get_info (int call_id) "
+    "Obtain detail information about the specified call.";
+static char pjsua_call_set_user_data_doc[] =
+    "int py_pjsua.call_set_user_data (int call_id, int user_data) "
+    "Attach application specific data to the call.";
+static char pjsua_call_get_user_data_doc[] =
+    "int py_pjsua.call_get_user_data (int call_id) "
+    "Get user data attached to the call.";
+static char pjsua_call_answer_doc[] =
+    "int py_pjsua.call_answer (int call_id, int code, string reason, "
+    "py_pjsua.Msg_Data msg_data) "
+    "Send response to incoming INVITE request.";
+static char pjsua_call_hangup_doc[] =
+    "int py_pjsua.call_hangup (int call_id, int code, string reason, "
+    "py_pjsua.Msg_Data msg_data) "
+    "Hangup call by using method that is appropriate according "
+    "to the call state.";
+static char pjsua_call_set_hold_doc[] =
+    "int py_pjsua.call_set_hold (int call_id, py_pjsua.Msg_Data msg_data) "
+    "Put the specified call on hold.";
+static char pjsua_call_reinvite_doc[] =
+    "int py_pjsua.call_reinvite (int call_id, int unhold, "
+    "py_pjsua.Msg_Data msg_data) "
+    "Send re-INVITE (to release hold).";
+static char pjsua_call_xfer_doc[] =
+    "int py_pjsua.call_xfer (int call_id, string dest, "
+    "py_pjsua.Msg_Data msg_data) "
+    "Initiate call transfer to the specified address. "
+    "This function will send REFER request to instruct remote call party "
+    "to initiate a new INVITE session to the specified destination/target.";
+static char pjsua_call_xfer_replaces_doc[] =
+    "int py_pjsua.call_xfer_replaces (int call_id, int dest_call_id, "
+    "int options, py_pjsua.Msg_Data msg_data) "
+    "Initiate attended call transfer. This function will send REFER request "
+    "to instruct remote call party to initiate new INVITE session to the URL "
+    "of dest_call_id. The party at dest_call_id then should 'replace' the call"
+    "with us with the new call from the REFER recipient.";
+static char pjsua_call_dial_dtmf_doc[] =
+    "int py_pjsua.call_dial_dtmf (int call_id, string digits) "
+    "Send DTMF digits to remote using RFC 2833 payload formats.";
+static char pjsua_call_send_im_doc[] =
+    "int py_pjsua.call_send_im (int call_id, string mime_type, string content,"
+    "py_pjsua.Msg_Data msg_data, int user_data) "
+    "Send instant messaging inside INVITE session.";
+static char pjsua_call_send_typing_ind_doc[] =
+    "int py_pjsua.call_send_typing_ind (int call_id, int is_typing, "
+    "py_pjsua.Msg_Data msg_data) "
+    "Send IM typing indication inside INVITE session.";
+static char pjsua_call_hangup_all_doc[] =
+    "void py_pjsua.call_hangup_all () "
+    "Terminate all calls.";
+static char pjsua_call_dump_doc[] =
+    "int py_pjsua.call_dump (int call_id, int with_media, int maxlen, "
+    "string indent) "
+    "Dump call and media statistics to string.";
+
+/* END OF LIB CALL */
+
+/*
+ * Map of function names to functions
+ */
+static PyMethodDef py_pjsua_methods[] =
+{
+    {
+        "thread_register", py_pjsua_thread_register, METH_VARARGS, 
+         pjsua_thread_register_doc
+    },
+    {
+    	"perror", py_pjsua_perror, METH_VARARGS, pjsua_perror_doc
+    },
+    {
+    	"create", py_pjsua_create, METH_VARARGS, pjsua_create_doc
+    },
+    {
+    	"init", py_pjsua_init, METH_VARARGS, pjsua_init_doc
+    },
+    {
+    	"start", py_pjsua_start, METH_VARARGS, pjsua_start_doc
+    },
+    {
+    	"destroy", py_pjsua_destroy, METH_VARARGS, pjsua_destroy_doc
+    },
+    {
+    	"handle_events", py_pjsua_handle_events, METH_VARARGS,
+    	pjsua_handle_events_doc
+    },
+    {
+    	"verify_sip_url", py_pjsua_verify_sip_url, METH_VARARGS,
+    	pjsua_verify_sip_url_doc
+    },
+    {
+    	"pool_create", py_pjsua_pool_create, METH_VARARGS,
+    	pjsua_pool_create_doc
+    },
+    {
+    	"get_pjsip_endpt", py_pjsua_get_pjsip_endpt, METH_VARARGS,
+    	pjsua_get_pjsip_endpt_doc
+    },
+    {
+    	"get_pjmedia_endpt", py_pjsua_get_pjmedia_endpt, METH_VARARGS,
+    	pjsua_get_pjmedia_endpt_doc
+    },
+    {
+    	"get_pool_factory", py_pjsua_get_pool_factory, METH_VARARGS,
+    	pjsua_get_pool_factory_doc
+    },
+    {
+    	"reconfigure_logging", py_pjsua_reconfigure_logging, METH_VARARGS,
+    	pjsua_reconfigure_logging_doc
+    },
+    {
+    	"logging_config_default", py_pjsua_logging_config_default,
+    	METH_VARARGS, pjsua_logging_config_default_doc
+    },
+    {
+    	"config_default", py_pjsua_config_default, METH_VARARGS,
+    	pjsua_config_default_doc
+    },
+    {
+    	"media_config_default", py_pjsua_media_config_default, METH_VARARGS,
+    	pjsua_media_config_default_doc
+    },
+    
+    
+    {
+    	"msg_data_init", py_pjsua_msg_data_init, METH_VARARGS,
+    	pjsua_msg_data_init_doc
+    },
+    {
+        "transport_config_default", py_pjsua_transport_config_default, 
+        METH_VARARGS,pjsua_transport_config_default_doc
+    },
+    {
+        "transport_create", py_pjsua_transport_create, METH_VARARGS,
+        pjsua_transport_create_doc
+    },
+    {
+        "transport_enum_transports", py_pjsua_enum_transports, METH_VARARGS,
+        pjsua_enum_transports_doc
+    },
+    {
+        "transport_get_info", py_pjsua_transport_get_info, METH_VARARGS,
+        pjsua_transport_get_info_doc
+    },
+    {
+        "transport_set_enable", py_pjsua_transport_set_enable, METH_VARARGS,
+        pjsua_transport_set_enable_doc
+    },
+    {
+       "transport_close", py_pjsua_transport_close, METH_VARARGS,
+        pjsua_transport_close_doc
+    },
+    {
+        "acc_config_default", py_pjsua_acc_config_default, METH_VARARGS,
+        pjsua_acc_config_default_doc
+    },
+    {
+        "acc_get_count", py_pjsua_acc_get_count, METH_VARARGS,
+        pjsua_acc_get_count_doc
+    },
+    {
+        "acc_is_valid", py_pjsua_acc_is_valid, METH_VARARGS,
+        pjsua_acc_is_valid_doc
+    },
+    {
+        "acc_set_default", py_pjsua_acc_set_default, METH_VARARGS,
+        pjsua_acc_set_default_doc
+    },
+    {
+        "acc_get_default", py_pjsua_acc_get_default, METH_VARARGS,
+        pjsua_acc_get_default_doc
+    },
+    {
+        "acc_add", py_pjsua_acc_add, METH_VARARGS,
+        pjsua_acc_add_doc
+    },
+    {
+        "acc_add_local", py_pjsua_acc_add_local, METH_VARARGS,
+        pjsua_acc_add_local_doc
+    },
+    {
+        "acc_del", py_pjsua_acc_del, METH_VARARGS,
+        pjsua_acc_del_doc
+    },
+    {
+        "acc_modify", py_pjsua_acc_modify, METH_VARARGS,
+        pjsua_acc_modify_doc
+    },
+    {
+        "acc_set_online_status", py_pjsua_acc_set_online_status, METH_VARARGS,
+        pjsua_acc_set_online_status_doc
+    },
+    {
+        "acc_set_online_status2", py_pjsua_acc_set_online_status2, METH_VARARGS,
+        pjsua_acc_set_online_status2_doc
+    },
+    {
+        "acc_set_registration", py_pjsua_acc_set_registration, METH_VARARGS,
+        pjsua_acc_set_registration_doc
+    },
+    {
+        "acc_get_info", py_pjsua_acc_get_info, METH_VARARGS,
+        pjsua_acc_get_info_doc
+    },
+    {
+        "enum_accs", py_pjsua_enum_accs, METH_VARARGS,
+        pjsua_enum_accs_doc
+    },
+    {
+        "acc_enum_info", py_pjsua_acc_enum_info, METH_VARARGS,
+        pjsua_acc_enum_info_doc
+    },
+    {
+        "acc_find_for_outgoing", py_pjsua_acc_find_for_outgoing, METH_VARARGS,
+        pjsua_acc_find_for_outgoing_doc
+    },
+    {
+        "acc_find_for_incoming", py_pjsua_acc_find_for_incoming, METH_VARARGS,
+        pjsua_acc_find_for_incoming_doc
+    },
+    {
+        "acc_create_uac_contact", py_pjsua_acc_create_uac_contact, METH_VARARGS,
+        pjsua_acc_create_uac_contact_doc
+    },
+    {
+        "acc_create_uas_contact", py_pjsua_acc_create_uas_contact, METH_VARARGS,
+        pjsua_acc_create_uas_contact_doc
+    },
+    {
+        "buddy_config_default", py_pjsua_buddy_config_default, METH_VARARGS,
+        pjsua_buddy_config_default_doc
+    },
+    {
+        "get_buddy_count", py_pjsua_get_buddy_count, METH_VARARGS,
+        pjsua_get_buddy_count_doc
+    },
+    {
+        "buddy_is_valid", py_pjsua_buddy_is_valid, METH_VARARGS,
+        pjsua_buddy_is_valid_doc
+    },
+    {
+        "enum_buddies", py_pjsua_enum_buddies, METH_VARARGS,
+        pjsua_enum_buddies_doc
+    },    
+    {
+        "buddy_get_info", py_pjsua_buddy_get_info, METH_VARARGS,
+        pjsua_buddy_get_info_doc
+    },
+    {
+        "buddy_add", py_pjsua_buddy_add, METH_VARARGS,
+        pjsua_buddy_add_doc
+    },
+    {
+        "buddy_del", py_pjsua_buddy_del, METH_VARARGS,
+        pjsua_buddy_del_doc
+    },
+    {
+        "buddy_subscribe_pres", py_pjsua_buddy_subscribe_pres, METH_VARARGS,
+        pjsua_buddy_subscribe_pres_doc
+    },
+    {
+        "pres_dump", py_pjsua_pres_dump, METH_VARARGS,
+        pjsua_pres_dump_doc
+    },
+    {
+        "im_send", py_pjsua_im_send, METH_VARARGS,
+        pjsua_im_send_doc
+    },
+    {
+        "im_typing", py_pjsua_im_typing, METH_VARARGS,
+        pjsua_im_typing_doc
+    },
+        {
+        "conf_get_max_ports", py_pjsua_conf_get_max_ports, METH_VARARGS,
+        pjsua_conf_get_max_ports_doc
+    },
+    {
+        "conf_get_active_ports", py_pjsua_conf_get_active_ports, METH_VARARGS,
+        pjsua_conf_get_active_ports_doc
+    },
+    {
+        "enum_conf_ports", py_pjsua_enum_conf_ports, METH_VARARGS,
+        pjsua_enum_conf_ports_doc
+    },
+    {
+        "conf_get_port_info", py_pjsua_conf_get_port_info, METH_VARARGS,
+        pjsua_conf_get_port_info_doc
+    },
+    {
+        "conf_add_port", py_pjsua_conf_add_port, METH_VARARGS,
+        pjsua_conf_add_port_doc
+    },
+    {
+        "conf_remove_port", py_pjsua_conf_remove_port, METH_VARARGS,
+        pjsua_conf_remove_port_doc
+    },
+    {
+        "conf_connect", py_pjsua_conf_connect, METH_VARARGS,
+        pjsua_conf_connect_doc
+    },
+    {
+        "conf_disconnect", py_pjsua_conf_disconnect, METH_VARARGS,
+        pjsua_conf_disconnect_doc
+    },
+    {
+        "player_create", py_pjsua_player_create, METH_VARARGS,
+        pjsua_player_create_doc
+    },
+    {
+        "player_get_conf_port", py_pjsua_player_get_conf_port, METH_VARARGS,
+        pjsua_player_get_conf_port_doc
+    },
+    {
+        "player_set_pos", py_pjsua_player_set_pos, METH_VARARGS,
+        pjsua_player_set_pos_doc
+    },
+    {
+        "player_destroy", py_pjsua_player_destroy, METH_VARARGS,
+        pjsua_player_destroy_doc
+    },
+    {
+        "recorder_create", py_pjsua_recorder_create, METH_VARARGS,
+        pjsua_recorder_create_doc
+    },
+    {
+        "recorder_get_conf_port", py_pjsua_recorder_get_conf_port, METH_VARARGS,
+        pjsua_recorder_get_conf_port_doc
+    },
+    {
+        "recorder_destroy", py_pjsua_recorder_destroy, METH_VARARGS,
+        pjsua_recorder_destroy_doc
+    },
+    {
+        "enum_snd_devs", py_pjsua_enum_snd_devs, METH_VARARGS,
+        pjsua_enum_snd_devs_doc
+    },
+    {
+        "get_snd_dev", py_pjsua_get_snd_dev, METH_VARARGS,
+        pjsua_get_snd_dev_doc
+    },
+    {
+        "set_snd_dev", py_pjsua_set_snd_dev, METH_VARARGS,
+        pjsua_set_snd_dev_doc
+    },
+    {
+        "set_null_snd_dev", py_pjsua_set_null_snd_dev, METH_VARARGS,
+        pjsua_set_null_snd_dev_doc
+    },
+    {
+        "set_no_snd_dev", py_pjsua_set_no_snd_dev, METH_VARARGS,
+        pjsua_set_no_snd_dev_doc
+    },
+    {
+        "set_ec", py_pjsua_set_ec, METH_VARARGS,
+        pjsua_set_ec_doc
+    },
+    {
+        "get_ec_tail", py_pjsua_get_ec_tail, METH_VARARGS,
+        pjsua_get_ec_tail_doc
+    },
+    {
+        "enum_codecs", py_pjsua_enum_codecs, METH_VARARGS,
+        pjsua_enum_codecs_doc
+    },
+    {
+        "codec_set_priority", py_pjsua_codec_set_priority, METH_VARARGS,
+        pjsua_codec_set_priority_doc
+    },
+    {
+        "codec_get_param", py_pjsua_codec_get_param, METH_VARARGS,
+        pjsua_codec_get_param_doc
+    },
+    {
+        "codec_set_param", py_pjsua_codec_set_param, METH_VARARGS,
+        pjsua_codec_set_param_doc
+    },
+    {
+        "call_get_max_count", py_pjsua_call_get_max_count, METH_VARARGS,
+        pjsua_call_get_max_count_doc
+    },
+    {
+        "call_get_count", py_pjsua_call_get_count, METH_VARARGS,
+        pjsua_call_get_count_doc
+    },
+    {
+        "enum_calls", py_pjsua_enum_calls, METH_VARARGS,
+        pjsua_enum_calls_doc
+    },
+    {
+        "call_make_call", py_pjsua_call_make_call, METH_VARARGS,
+        pjsua_call_make_call_doc
+    },
+    {
+        "call_is_active", py_pjsua_call_is_active, METH_VARARGS,
+        pjsua_call_is_active_doc
+    },
+    {
+        "call_has_media", py_pjsua_call_has_media, METH_VARARGS,
+        pjsua_call_has_media_doc
+    },
+    {
+        "call_get_conf_port", py_pjsua_call_get_conf_port, METH_VARARGS,
+        pjsua_call_get_conf_port_doc
+    },
+    {
+        "call_get_info", py_pjsua_call_get_info, METH_VARARGS,
+        pjsua_call_get_info_doc
+    },
+    {
+        "call_set_user_data", py_pjsua_call_set_user_data, METH_VARARGS,
+        pjsua_call_set_user_data_doc
+    },
+    {
+        "call_get_user_data", py_pjsua_call_get_user_data, METH_VARARGS,
+        pjsua_call_get_user_data_doc
+    },
+    {
+        "call_answer", py_pjsua_call_answer, METH_VARARGS,
+        pjsua_call_answer_doc
+    },
+    {
+        "call_hangup", py_pjsua_call_hangup, METH_VARARGS,
+        pjsua_call_hangup_doc
+    },
+    {
+        "call_set_hold", py_pjsua_call_set_hold, METH_VARARGS,
+        pjsua_call_set_hold_doc
+    },
+    {
+        "call_reinvite", py_pjsua_call_reinvite, METH_VARARGS,
+        pjsua_call_reinvite_doc
+    },
+    {
+        "call_xfer", py_pjsua_call_xfer, METH_VARARGS,
+        pjsua_call_xfer_doc
+    },
+    {
+        "call_xfer_replaces", py_pjsua_call_xfer_replaces, METH_VARARGS,
+        pjsua_call_xfer_replaces_doc
+    },
+    {
+        "call_dial_dtmf", py_pjsua_call_dial_dtmf, METH_VARARGS,
+        pjsua_call_dial_dtmf_doc
+    },
+    {
+        "call_send_im", py_pjsua_call_send_im, METH_VARARGS,
+        pjsua_call_send_im_doc
+    },
+    {
+        "call_send_typing_ind", py_pjsua_call_send_typing_ind, METH_VARARGS,
+        pjsua_call_send_typing_ind_doc
+    },
+    {
+        "call_hangup_all", py_pjsua_call_hangup_all, METH_VARARGS,
+        pjsua_call_hangup_all_doc
+    },
+    {
+        "call_dump", py_pjsua_call_dump, METH_VARARGS,
+        pjsua_call_dump_doc
+    },
+    {
+	"dump", py_pjsua_dump, METH_VARARGS, "Dump application state"
+    },
+
+    
+    {NULL, NULL} /* end of function list */
+};
+
+
+
+/*
+ * Mapping C structs from and to Python objects & initializing object
+ */
+DL_EXPORT(void)
+initpy_pjsua(void)
+{
+    PyObject* m = NULL;
+#define ADD_CONSTANT(mod,name)	PyModule_AddIntConstant(mod,#name,name)
+
+    
+    PyEval_InitThreads();
+
+    if (PyType_Ready(&PyTyp_pjsua_callback) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_config) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_logging_config) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_msg_data) < 0)
+        return;
+    PyTyp_pjsua_media_config.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjsua_media_config) < 0)
+        return;
+    PyTyp_pjsip_event.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjsip_event) < 0)
+        return;
+    PyTyp_pjsip_rx_data.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjsip_rx_data) < 0)
+        return;
+    PyTyp_pj_pool_t.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pj_pool_t) < 0)
+        return;
+    PyTyp_pjsip_endpoint.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjsip_endpoint) < 0)
+        return;
+    PyTyp_pjmedia_endpt.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjmedia_endpt) < 0)
+        return;
+    PyTyp_pj_pool_factory.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pj_pool_factory) < 0)
+        return;
+    PyTyp_pjsip_cred_info.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjsip_cred_info) < 0)
+        return;
+
+    /* LIB TRANSPORT */
+
+    if (PyType_Ready(&PyTyp_pjsua_transport_config) < 0)
+        return;
+    
+    if (PyType_Ready(&PyTyp_pjsua_transport_info) < 0)
+        return;
+    
+    /* END OF LIB TRANSPORT */
+
+    /* LIB ACCOUNT */
+
+    
+    if (PyType_Ready(&PyTyp_pjsua_acc_config) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_acc_info) < 0)
+        return;
+
+    /* END OF LIB ACCOUNT */
+
+    /* LIB BUDDY */
+
+    if (PyType_Ready(&PyTyp_pjsua_buddy_config) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_buddy_info) < 0)
+        return;
+
+    /* END OF LIB BUDDY */
+
+    /* LIB MEDIA */
+  
+    if (PyType_Ready(&PyTyp_pjsua_codec_info) < 0)
+        return;
+
+    if (PyType_Ready(&PyTyp_pjsua_conf_port_info) < 0)
+        return;
+
+    PyTyp_pjmedia_port.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjmedia_port) < 0)
+        return;
+
+    if (PyType_Ready(&PyTyp_pjmedia_snd_dev_info) < 0)
+        return;
+
+    PyTyp_pjmedia_codec_param_info.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjmedia_codec_param_info) < 0)
+        return;
+    PyTyp_pjmedia_codec_param_setting.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjmedia_codec_param_setting) < 0)
+        return;
+
+    if (PyType_Ready(&PyTyp_pjmedia_codec_param) < 0)
+        return;
+
+    /* END OF LIB MEDIA */
+
+    /* LIB CALL */
+
+    PyTyp_pj_time_val.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pj_time_val) < 0)
+        return;
+
+    if (PyType_Ready(&PyTyp_pjsua_call_info) < 0)
+        return;
+
+    /* END OF LIB CALL */
+
+    m = Py_InitModule3(
+        "py_pjsua", py_pjsua_methods,"PJSUA-lib module for python"
+    );
+
+    Py_INCREF(&PyTyp_pjsua_callback);
+    PyModule_AddObject(m, "Callback", (PyObject *)&PyTyp_pjsua_callback);
+
+    Py_INCREF(&PyTyp_pjsua_config);
+    PyModule_AddObject(m, "Config", (PyObject *)&PyTyp_pjsua_config);
+
+    Py_INCREF(&PyTyp_pjsua_media_config);
+    PyModule_AddObject(m, "Media_Config", (PyObject *)&PyTyp_pjsua_media_config);
+
+    Py_INCREF(&PyTyp_pjsua_logging_config);
+    PyModule_AddObject(m, "Logging_Config", (PyObject *)&PyTyp_pjsua_logging_config);
+
+    Py_INCREF(&PyTyp_pjsua_msg_data);
+    PyModule_AddObject(m, "Msg_Data", (PyObject *)&PyTyp_pjsua_msg_data);
+
+    Py_INCREF(&PyTyp_pjsip_event);
+    PyModule_AddObject(m, "Pjsip_Event", (PyObject *)&PyTyp_pjsip_event);
+
+    Py_INCREF(&PyTyp_pjsip_rx_data);
+    PyModule_AddObject(m, "Pjsip_Rx_Data", (PyObject *)&PyTyp_pjsip_rx_data);
+
+    Py_INCREF(&PyTyp_pj_pool_t);
+    PyModule_AddObject(m, "Pj_Pool", (PyObject *)&PyTyp_pj_pool_t);
+
+    Py_INCREF(&PyTyp_pjsip_endpoint);
+    PyModule_AddObject(m, "Pjsip_Endpoint", (PyObject *)&PyTyp_pjsip_endpoint);
+
+    Py_INCREF(&PyTyp_pjmedia_endpt);
+    PyModule_AddObject(m, "Pjmedia_Endpt", (PyObject *)&PyTyp_pjmedia_endpt);
+
+    Py_INCREF(&PyTyp_pj_pool_factory);
+    PyModule_AddObject(
+        m, "Pj_Pool_Factory", (PyObject *)&PyTyp_pj_pool_factory
+    );
+
+    Py_INCREF(&PyTyp_pjsip_cred_info);
+    PyModule_AddObject(m, "Pjsip_Cred_Info",
+        (PyObject *)&PyTyp_pjsip_cred_info
+    );
+
+    /* LIB TRANSPORT */
+
+    Py_INCREF(&PyTyp_pjsua_transport_config);
+    PyModule_AddObject
+        (m, "Transport_Config", (PyObject *)&PyTyp_pjsua_transport_config);
+    
+    Py_INCREF(&PyTyp_pjsua_transport_info);
+    PyModule_AddObject(m, "Transport_Info", (PyObject *)&PyTyp_pjsua_transport_info);
+    
+
+    /* END OF LIB TRANSPORT */
+
+    /* LIB ACCOUNT */
+
+    
+    Py_INCREF(&PyTyp_pjsua_acc_config);
+    PyModule_AddObject(m, "Acc_Config", (PyObject *)&PyTyp_pjsua_acc_config);
+    Py_INCREF(&PyTyp_pjsua_acc_info);
+    PyModule_AddObject(m, "Acc_Info", (PyObject *)&PyTyp_pjsua_acc_info);
+
+    /* END OF LIB ACCOUNT */
+
+    /* LIB BUDDY */
+    
+    Py_INCREF(&PyTyp_pjsua_buddy_config);
+    PyModule_AddObject(m, "Buddy_Config", (PyObject *)&PyTyp_pjsua_buddy_config);
+    Py_INCREF(&PyTyp_pjsua_buddy_info);
+    PyModule_AddObject(m, "Buddy_Info", (PyObject *)&PyTyp_pjsua_buddy_info);
+
+    /* END OF LIB BUDDY */
+
+    /* LIB MEDIA */
+
+    Py_INCREF(&PyTyp_pjsua_codec_info);
+    PyModule_AddObject(m, "Codec_Info", (PyObject *)&PyTyp_pjsua_codec_info);
+    Py_INCREF(&PyTyp_pjsua_conf_port_info);
+    PyModule_AddObject(m, "Conf_Port_Info", (PyObject *)&PyTyp_pjsua_conf_port_info);
+    Py_INCREF(&PyTyp_pjmedia_port);
+    PyModule_AddObject(m, "PJMedia_Port", (PyObject *)&PyTyp_pjmedia_port);
+    Py_INCREF(&PyTyp_pjmedia_snd_dev_info);
+    PyModule_AddObject(m, "PJMedia_Snd_Dev_Info", 
+	(PyObject *)&PyTyp_pjmedia_snd_dev_info);
+    Py_INCREF(&PyTyp_pjmedia_codec_param_info);
+    PyModule_AddObject(m, "PJMedia_Codec_Param_Info", 
+	(PyObject *)&PyTyp_pjmedia_codec_param_info);
+    Py_INCREF(&PyTyp_pjmedia_codec_param_setting);
+    PyModule_AddObject(m, "PJMedia_Codec_Param_Setting", 
+	(PyObject *)&PyTyp_pjmedia_codec_param_setting);
+    Py_INCREF(&PyTyp_pjmedia_codec_param);
+    PyModule_AddObject(m, "PJMedia_Codec_Param", 
+	(PyObject *)&PyTyp_pjmedia_codec_param);
+
+    /* END OF LIB MEDIA */
+
+    /* LIB CALL */
+
+    Py_INCREF(&PyTyp_pj_time_val);
+    PyModule_AddObject(m, "PJ_Time_Val", (PyObject *)&PyTyp_pj_time_val);
+
+    Py_INCREF(&PyTyp_pjsua_call_info);
+    PyModule_AddObject(m, "Call_Info", (PyObject *)&PyTyp_pjsua_call_info);
+
+    /* END OF LIB CALL */
+
+
+    /*
+     * Add various constants.
+     */
+
+    /* Call states */
+    ADD_CONSTANT(m, PJSIP_INV_STATE_NULL);
+    ADD_CONSTANT(m, PJSIP_INV_STATE_CALLING);
+    ADD_CONSTANT(m, PJSIP_INV_STATE_INCOMING);
+    ADD_CONSTANT(m, PJSIP_INV_STATE_EARLY);
+    ADD_CONSTANT(m, PJSIP_INV_STATE_CONNECTING);
+    ADD_CONSTANT(m, PJSIP_INV_STATE_CONFIRMED);
+    ADD_CONSTANT(m, PJSIP_INV_STATE_DISCONNECTED);
+
+    /* Call media status (enum pjsua_call_media_status) */
+    ADD_CONSTANT(m, PJSUA_CALL_MEDIA_NONE);
+    ADD_CONSTANT(m, PJSUA_CALL_MEDIA_ACTIVE);
+    ADD_CONSTANT(m, PJSUA_CALL_MEDIA_LOCAL_HOLD);
+    ADD_CONSTANT(m, PJSUA_CALL_MEDIA_REMOTE_HOLD);
+
+    /* Buddy status */
+    ADD_CONSTANT(m, PJSUA_BUDDY_STATUS_UNKNOWN);
+    ADD_CONSTANT(m, PJSUA_BUDDY_STATUS_ONLINE);
+    ADD_CONSTANT(m, PJSUA_BUDDY_STATUS_OFFLINE);
+
+    /* PJSIP transport types (enum pjsip_transport_type_e) */
+    ADD_CONSTANT(m, PJSIP_TRANSPORT_UNSPECIFIED);
+    ADD_CONSTANT(m, PJSIP_TRANSPORT_UDP);
+    ADD_CONSTANT(m, PJSIP_TRANSPORT_TCP);
+    ADD_CONSTANT(m, PJSIP_TRANSPORT_TLS);
+    ADD_CONSTANT(m, PJSIP_TRANSPORT_SCTP);
+    ADD_CONSTANT(m, PJSIP_TRANSPORT_LOOP);
+    ADD_CONSTANT(m, PJSIP_TRANSPORT_LOOP_DGRAM);
+
+
+    /* Invalid IDs */
+    ADD_CONSTANT(m, PJSUA_INVALID_ID);
+
+
+    /* Various compile time constants */
+    ADD_CONSTANT(m, PJSUA_ACC_MAX_PROXIES);
+    ADD_CONSTANT(m, PJSUA_MAX_ACC);
+    ADD_CONSTANT(m, PJSUA_REG_INTERVAL);
+    ADD_CONSTANT(m, PJSUA_PUBLISH_EXPIRATION);
+    ADD_CONSTANT(m, PJSUA_DEFAULT_ACC_PRIORITY);
+    ADD_CONSTANT(m, PJSUA_MAX_BUDDIES);
+    ADD_CONSTANT(m, PJSUA_MAX_CONF_PORTS);
+    ADD_CONSTANT(m, PJSUA_DEFAULT_CLOCK_RATE);
+    ADD_CONSTANT(m, PJSUA_DEFAULT_CODEC_QUALITY);
+    ADD_CONSTANT(m, PJSUA_DEFAULT_ILBC_MODE);
+    ADD_CONSTANT(m, PJSUA_DEFAULT_EC_TAIL_LEN);
+    ADD_CONSTANT(m, PJSUA_MAX_CALLS);
+    ADD_CONSTANT(m, PJSUA_XFER_NO_REQUIRE_REPLACES);
+
+
+#undef ADD_CONSTANT
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/py_pjsua.def b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/py_pjsua.def
new file mode 100644
index 0000000..a8dd2f3
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/py_pjsua.def
@@ -0,0 +1,2 @@
+EXPORTS
+	initpy_pjsua
diff --git a/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/py_pjsua.h b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/py_pjsua.h
new file mode 100644
index 0000000..4068635
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/py_pjsua.h
@@ -0,0 +1,2662 @@
+/* $Id: py_pjsua.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 __PY_PJSUA_H__
+#define __PY_PJSUA_H__
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include <Python.h>
+#include <structmember.h>
+#include <pjsua-lib/pjsua.h>
+
+
+PJ_INLINE(pj_str_t) PyString_to_pj_str(const PyObject *obj)
+{
+    pj_str_t str;
+
+    if (obj) {
+	str.ptr = PyString_AS_STRING(obj);
+	str.slen = PyString_GET_SIZE(obj);
+    } else {
+	str.ptr = NULL;
+	str.slen = 0;
+    }
+
+    return str;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pj_pool
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    pj_pool_t * pool;
+} PyObj_pj_pool;
+
+
+/*
+ * PyTyp_pj_pool_t
+ */
+static PyTypeObject PyTyp_pj_pool_t =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "py_pjsua.Pj_Pool",        /*tp_name*/
+    sizeof(PyObj_pj_pool),    /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    0,                         /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "pj_pool_t objects",       /* tp_doc */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsip_endpoint
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    pjsip_endpoint * endpt;
+} PyObj_pjsip_endpoint;
+
+
+/*
+ * PyTyp_pjsip_endpoint
+ */
+static PyTypeObject PyTyp_pjsip_endpoint =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "py_pjsua.Pjsip_Endpoint", /*tp_name*/
+    sizeof(PyObj_pjsip_endpoint),/*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    0,                         /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "pjsip_endpoint objects",  /* tp_doc */
+};
+
+
+/*
+ * PyObj_pjmedia_endpt
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    pjmedia_endpt * endpt;
+} PyObj_pjmedia_endpt;
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyTyp_pjmedia_endpt
+ */
+static PyTypeObject PyTyp_pjmedia_endpt =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "py_pjsua.Pjmedia_Endpt",  /*tp_name*/
+    sizeof(PyObj_pjmedia_endpt), /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    0,                         /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "pjmedia_endpt objects",   /* tp_doc */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pj_pool_factory
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    pj_pool_factory * pool_fact;
+} PyObj_pj_pool_factory;
+
+
+
+/*
+ * PyTyp_pj_pool_factory
+ */
+static PyTypeObject PyTyp_pj_pool_factory =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "py_pjsua.Pj_Pool_Factory",/*tp_name*/
+    sizeof(PyObj_pj_pool_factory), /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    0,                         /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "pj_pool_factory objects", /* tp_doc */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsip_cred_info
+ */
+typedef struct
+{
+    PyObject_HEAD
+
+    /* Type-specific fields go here. */
+    PyObject *realm;
+    PyObject *scheme;
+    PyObject *username;
+    int	      data_type;
+    PyObject *data;
+    
+} PyObj_pjsip_cred_info;
+
+/*
+ * cred_info_dealloc
+ * deletes a cred info from memory
+ */
+static void PyObj_pjsip_cred_info_delete(PyObj_pjsip_cred_info* self)
+{
+    Py_XDECREF(self->realm);
+    Py_XDECREF(self->scheme);
+    Py_XDECREF(self->username);
+    Py_XDECREF(self->data);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsip_cred_info_import(PyObj_pjsip_cred_info *obj,
+					 const pjsip_cred_info *cfg)
+{
+    Py_XDECREF(obj->realm);
+    obj->realm = PyString_FromStringAndSize(cfg->realm.ptr, cfg->realm.slen);
+    Py_XDECREF(obj->scheme);
+    obj->scheme = PyString_FromStringAndSize(cfg->scheme.ptr, cfg->scheme.slen);
+    Py_XDECREF(obj->username);
+    obj->username = PyString_FromStringAndSize(cfg->username.ptr, cfg->username.slen);
+    obj->data_type = cfg->data_type;
+    Py_XDECREF(obj->data);
+    obj->data = PyString_FromStringAndSize(cfg->data.ptr, cfg->data.slen);
+}
+
+static void PyObj_pjsip_cred_info_export(pjsip_cred_info *cfg,
+					 PyObj_pjsip_cred_info *obj)
+{
+    cfg->realm	= PyString_to_pj_str(obj->realm);
+    cfg->scheme	= PyString_to_pj_str(obj->scheme);
+    cfg->username = PyString_to_pj_str(obj->username);
+    cfg->data_type = obj->data_type;
+    cfg->data	= PyString_to_pj_str(obj->data);
+}
+
+
+/*
+ * cred_info_new
+ * constructor for cred_info object
+ */
+static PyObject * PyObj_pjsip_cred_info_new(PyTypeObject *type, 
+					    PyObject *args,
+					    PyObject *kwds)
+{
+    PyObj_pjsip_cred_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsip_cred_info *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->realm = PyString_FromString("");
+        if (self->realm == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->scheme = PyString_FromString("");
+        if (self->scheme == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->username = PyString_FromString("");
+        if (self->username == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
+        self->data = PyString_FromString("");
+        if (self->data == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsip_cred_info_members
+ */
+static PyMemberDef PyObj_pjsip_cred_info_members[] =
+{
+    {
+        "realm", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_cred_info, realm), 0,
+        "Realm"
+    },
+    {
+        "scheme", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_cred_info, scheme), 0,
+        "Scheme"
+    },
+    {
+        "username", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_cred_info, username), 0,
+        "User name"
+    },
+    {
+        "data", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_cred_info, data), 0,
+        "The data, which can be a plaintext password or a hashed digest, "
+	"depending on the value of data_type"
+    },
+    {
+        "data_type", T_INT, 
+	offsetof(PyObj_pjsip_cred_info, data_type), 0,
+        "Type of data"
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+/*
+ * PyTyp_pjsip_cred_info
+ */
+static PyTypeObject PyTyp_pjsip_cred_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Pjsip_Cred_Info",      /*tp_name*/
+    sizeof(PyObj_pjsip_cred_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsip_cred_info_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJSIP credential information", /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsip_cred_info_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsip_cred_info_new,             /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsip_event
+ * C/python typewrapper for event struct
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    pjsip_event * event;
+} PyObj_pjsip_event;
+
+
+
+/*
+ * PyTyp_pjsip_event
+ * event struct signatures
+ */
+static PyTypeObject PyTyp_pjsip_event =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                          /*ob_size*/
+    "py_pjsua.Pjsip_Event",     /*tp_name*/
+    sizeof(PyObj_pjsip_event),  /*tp_basicsize*/
+    0,                          /*tp_itemsize*/
+    0,                          /*tp_dealloc*/
+    0,                          /*tp_print*/
+    0,                          /*tp_getattr*/
+    0,                          /*tp_setattr*/
+    0,                          /*tp_compare*/
+    0,                          /*tp_repr*/
+    0,                          /*tp_as_number*/
+    0,                          /*tp_as_sequence*/
+    0,                          /*tp_as_mapping*/
+    0,                          /*tp_hash */
+    0,                          /*tp_call*/
+    0,                          /*tp_str*/
+    0,                          /*tp_getattro*/
+    0,                          /*tp_setattro*/
+    0,                          /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,         /*tp_flags*/
+    "pjsip_event object",       /*tp_doc */
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsip_rx_data
+ * C/python typewrapper for pjsip_rx_data struct
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    pjsip_rx_data * rdata;
+} PyObj_pjsip_rx_data;
+
+
+/*
+ * PyTyp_pjsip_rx_data
+ */
+static PyTypeObject PyTyp_pjsip_rx_data =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Pjsip_Rx_Data",       /*tp_name*/
+    sizeof(PyObj_pjsip_rx_data),    /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    0,                              /*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "pjsip_rx_data object",         /*tp_doc*/
+};
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_callback
+ * C/python typewrapper for callback struct
+ */
+typedef struct PyObj_pjsua_callback
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    PyObject * on_call_state;
+    PyObject * on_incoming_call;
+    PyObject * on_call_media_state;
+    PyObject * on_dtmf_digit;
+    PyObject * on_call_transfer_request;
+    PyObject * on_call_transfer_status;
+    PyObject * on_call_replace_request;
+    PyObject * on_call_replaced;
+    PyObject * on_reg_state;
+    PyObject * on_buddy_state;
+    PyObject * on_pager;
+    PyObject * on_pager_status;
+    PyObject * on_typing;
+} PyObj_pjsua_callback;
+
+
+/*
+ * PyObj_pjsua_callback_delete
+ * destructor function for callback struct
+ */
+static void PyObj_pjsua_callback_delete(PyObj_pjsua_callback* self)
+{
+    Py_XDECREF(self->on_call_state);
+    Py_XDECREF(self->on_incoming_call);
+    Py_XDECREF(self->on_call_media_state);
+    Py_XDECREF(self->on_dtmf_digit);
+    Py_XDECREF(self->on_call_transfer_request);
+    Py_XDECREF(self->on_call_transfer_status);
+    Py_XDECREF(self->on_call_replace_request);
+    Py_XDECREF(self->on_call_replaced);
+    Py_XDECREF(self->on_reg_state);
+    Py_XDECREF(self->on_buddy_state);
+    Py_XDECREF(self->on_pager);
+    Py_XDECREF(self->on_pager_status);
+    Py_XDECREF(self->on_typing);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * PyObj_pjsua_callback_new
+ * * declares constructor for callback struct
+ */
+static PyObject * PyObj_pjsua_callback_new(PyTypeObject *type, 
+					   PyObject *args,
+					   PyObject *kwds)
+{
+    PyObj_pjsua_callback *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_callback *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        Py_INCREF(Py_None);
+        self->on_call_state = Py_None;
+        if (self->on_call_state == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_incoming_call = Py_None;
+        if (self->on_incoming_call == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_call_media_state = Py_None;
+        if (self->on_call_media_state == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_dtmf_digit = Py_None;
+        if (self->on_dtmf_digit == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_call_transfer_request = Py_None;
+        if (self->on_call_transfer_request == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_call_transfer_status = Py_None;
+        if (self->on_call_transfer_status == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_call_replace_request = Py_None;
+        if (self->on_call_replace_request == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_call_replaced = Py_None;
+        if (self->on_call_replaced == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_reg_state = Py_None;
+        if (self->on_reg_state == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_buddy_state = Py_None;
+        if (self->on_buddy_state == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_pager = Py_None;
+        if (self->on_pager == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_pager_status = Py_None;
+        if (self->on_pager_status == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->on_typing = Py_None;
+        if (self->on_typing == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_callback_members
+ * declares available functions for callback object
+ */
+static PyMemberDef PyObj_pjsua_callback_members[] =
+{
+    {
+        "on_call_state", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_callback, on_call_state), 0, 
+	"Notify application when invite state has changed. Application may "
+        "then query the call info to get the detail call states."
+    },
+    {
+        "on_incoming_call", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_incoming_call), 0,
+        "Notify application on incoming call."
+    },
+    {
+        "on_call_media_state", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_media_state), 0,
+        "Notify application when media state in the call has changed. Normal "
+        "application would need to implement this callback, e.g. to connect "
+        "the call's media to sound device."
+    },
+    {
+	"on_dtmf_digit", T_OBJECT_EX,
+	offsetof(PyObj_pjsua_callback, on_dtmf_digit), 0,
+	"Notify application upon receiving incoming DTMF digit."
+    },
+    {
+        "on_call_transfer_request", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_transfer_request), 0,
+        "Notify application on call being transfered. "
+	"Application can decide to accept/reject transfer request "
+	"by setting the code (default is 200). When this callback "
+	"is not defined, the default behavior is to accept the "
+	"transfer."
+    },
+    {
+        "on_call_transfer_status", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_transfer_status), 0,
+        "Notify application of the status of previously sent call "
+        "transfer request. Application can monitor the status of the "
+        "call transfer request, for example to decide whether to "
+        "terminate existing call."
+    },
+    {
+        "on_call_replace_request", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_replace_request), 0,
+        "Notify application about incoming INVITE with Replaces header. "
+        "Application may reject the request by setting non-2xx code."
+    },
+    {
+        "on_call_replaced", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_replaced), 0,
+	"Notify application that an existing call has been replaced with "
+	"a new call. This happens when PJSUA-API receives incoming INVITE "
+	"request with Replaces header."
+	" "
+	"After this callback is called, normally PJSUA-API will disconnect "
+	"old_call_id and establish new_call_id."
+    },
+    {
+        "on_reg_state", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_reg_state), 0,
+        "Notify application when registration status has changed. Application "
+        "may then query the account info to get the registration details."
+    },
+    {
+        "on_buddy_state", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_buddy_state), 0,
+        "Notify application when the buddy state has changed. Application may "
+        "then query the buddy into to get the details."
+    },
+    {
+        "on_pager", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_callback, on_pager), 0,
+        "Notify application on incoming pager (i.e. MESSAGE request). "
+        "Argument call_id will be -1 if MESSAGE request is not related to an "
+        "existing call."
+    },
+    {
+        "on_pager_status", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_pager_status), 0,
+        "Notify application about the delivery status of outgoing pager "
+        "request."
+    },
+    {
+        "on_typing", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_callback, on_typing), 0,
+        "Notify application about typing indication."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjsua_callback
+ * callback class definition
+ */
+static PyTypeObject PyTyp_pjsua_callback =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,					/*ob_size*/
+    "py_pjsua.Callback",		/*tp_name*/
+    sizeof(PyObj_pjsua_callback),	/*tp_basicsize*/
+    0,					/*tp_itemsize*/
+    (destructor)PyObj_pjsua_callback_delete,   /*tp_dealloc*/
+    0,                             	/*tp_print*/
+    0,                             	/*tp_getattr*/
+    0,                             	/*tp_setattr*/
+    0,                             	/*tp_compare*/
+    0,                             	/*tp_repr*/
+    0,                             	/*tp_as_number*/
+    0,                             	/*tp_as_sequence*/
+    0,                             	/*tp_as_mapping*/
+    0,                             	/*tp_hash */
+    0,                             	/*tp_call*/
+    0,                             	/*tp_str*/
+    0,                             	/*tp_getattro*/
+    0,                             	/*tp_setattro*/
+    0,                             	/*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,            	/*tp_flags*/
+    "This structure describes application callback "
+    "to receive various event notifications from "
+    "PJSUA-API",			/* tp_doc */
+    0,                           	/* tp_traverse */
+    0,                           	/* tp_clear */
+    0,                           	/* tp_richcompare */
+    0,                           	/* tp_weaklistoffset */
+    0,                           	/* tp_iter */
+    0,                           	/* tp_iternext */
+    0,                 			/* tp_methods */
+    PyObj_pjsua_callback_members,       /* tp_members */
+    0,                             	/* tp_getset */
+    0,                             	/* tp_base */
+    0,                             	/* tp_dict */
+    0,                             	/* tp_descr_get */
+    0,                             	/* tp_descr_set */
+    0,                             	/* tp_dictoffset */
+    0,          			/* tp_init */
+    0,                             	/* tp_alloc */
+    PyObj_pjsua_callback_new,           /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_media_config
+ * C/Python wrapper for pjsua_media_config object
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    unsigned clock_rate;
+    unsigned max_media_ports;
+    int	     has_ioqueue;
+    unsigned thread_cnt;
+    unsigned quality;
+    unsigned ptime;
+    int	     no_vad;
+    unsigned ilbc_mode;
+    unsigned tx_drop_pct;
+    unsigned rx_drop_pct;
+    unsigned ec_options;
+    unsigned ec_tail_len;
+} PyObj_pjsua_media_config;
+
+
+/*
+ * PyObj_pjsua_media_config_members
+ * declares attributes accessible from both C and Python for media_config file
+ */
+static PyMemberDef PyObj_pjsua_media_config_members[] =
+{
+    {
+        "clock_rate", T_INT, 
+	offsetof(PyObj_pjsua_media_config, clock_rate), 0,
+        "Clock rate to be applied to the conference bridge. If value is zero, "
+        "default clock rate will be used (16KHz)."
+    },
+    {
+        "max_media_ports", T_INT,
+        offsetof(PyObj_pjsua_media_config, max_media_ports), 0,
+        "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."
+    },
+    {
+        "has_ioqueue", T_INT, 
+	offsetof(PyObj_pjsua_media_config, has_ioqueue), 0,
+        "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."
+    },
+    {
+        "thread_cnt", T_INT, 
+	offsetof(PyObj_pjsua_media_config, thread_cnt), 0,
+        "Specify the number of worker threads to handle incoming RTP packets. "
+        "A value of one is recommended for most applications."
+    },
+    {
+        "quality", T_INT, 
+	offsetof(PyObj_pjsua_media_config, quality), 0,
+        "The media quality also sets speex codec quality/complexity to the "
+        "number."
+    },
+    {
+        "ptime", T_INT, 
+	offsetof(PyObj_pjsua_media_config, ptime), 0,
+        "Specify default ptime."
+    },
+    {
+        "no_vad", T_INT, 
+	offsetof(PyObj_pjsua_media_config, no_vad), 0,
+        "Disable VAD?"
+    },
+    {
+        "ilbc_mode", T_INT, 
+	offsetof(PyObj_pjsua_media_config, ilbc_mode), 0,
+        "iLBC mode (20 or 30)."
+    },
+    {
+        "tx_drop_pct", T_INT, 
+	offsetof(PyObj_pjsua_media_config, tx_drop_pct), 0,
+        "Percentage of RTP packet to drop in TX direction (to simulate packet "
+        "lost)."
+    },
+    {
+        "rx_drop_pct", T_INT, 
+	offsetof(PyObj_pjsua_media_config, rx_drop_pct), 0,
+        "Percentage of RTP packet to drop in RX direction (to simulate packet "
+        "lost)."},
+    {
+        "ec_options", T_INT, 
+	offsetof(PyObj_pjsua_media_config, ec_options), 0,
+        "Echo canceller options (see pjmedia_echo_create())"
+    },
+    {
+        "ec_tail_len", T_INT, 
+	offsetof(PyObj_pjsua_media_config, ec_tail_len), 0,
+        "Echo canceller tail length, in miliseconds."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjsua_media_config
+ */
+static PyTypeObject PyTyp_pjsua_media_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Media_Config",        /*tp_name*/
+    sizeof(PyObj_pjsua_media_config),/*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    0,                              /*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Media Config objects",         /*tp_doc*/
+    0,                              /*tp_traverse*/
+    0,                              /*tp_clear*/
+    0,                              /*tp_richcompare*/
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_media_config_members, /* tp_members */
+
+};
+
+
+static void PyObj_pjsua_media_config_import(PyObj_pjsua_media_config *obj,
+					    const pjsua_media_config *cfg)
+{
+    obj->clock_rate	    = cfg->clock_rate;
+    obj->max_media_ports    = cfg->max_media_ports;
+    obj->has_ioqueue	    = cfg->has_ioqueue;
+    obj->thread_cnt	    = cfg->thread_cnt;
+    obj->quality	    = cfg->quality;
+    obj->ptime		    = cfg->ptime;
+    obj->no_vad		    = cfg->no_vad;
+    obj->ilbc_mode	    = cfg->ilbc_mode;
+    obj->tx_drop_pct	    = cfg->tx_drop_pct;
+    obj->rx_drop_pct	    = cfg->rx_drop_pct;
+    obj->ec_options	    = cfg->ec_options;
+    obj->ec_tail_len	    = cfg->ec_tail_len;
+}
+
+static void PyObj_pjsua_media_config_export(pjsua_media_config *cfg,
+					    const PyObj_pjsua_media_config *obj)
+{
+    cfg->clock_rate	    = obj->clock_rate;
+    cfg->max_media_ports    = obj->max_media_ports;
+    cfg->has_ioqueue	    = obj->has_ioqueue;
+    cfg->thread_cnt	    = obj->thread_cnt;
+    cfg->quality	    = obj->quality;
+    cfg->ptime		    = obj->ptime;
+    cfg->no_vad		    = obj->no_vad;
+    cfg->ilbc_mode	    = obj->ilbc_mode;
+    cfg->tx_drop_pct	    = obj->tx_drop_pct;
+    cfg->rx_drop_pct	    = obj->rx_drop_pct;
+    cfg->ec_options	    = obj->ec_options;
+    cfg->ec_tail_len	    = obj->ec_tail_len;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_config
+ * attribute list for config object
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    unsigned		  max_calls;
+    unsigned		  thread_cnt;
+    PyObject		 *outbound_proxy;
+    PyObject	         *stun_domain;
+    PyObject		 *stun_host;
+    PyObject		 *stun_relay_host;
+    PyObj_pjsua_callback *cb;
+    PyObject		 *user_agent;
+} PyObj_pjsua_config;
+
+
+static void PyObj_pjsua_config_delete(PyObj_pjsua_config* self)
+{
+    Py_XDECREF(self->outbound_proxy);
+    Py_XDECREF(self->stun_domain);
+    Py_XDECREF(self->stun_host);
+    Py_XDECREF(self->stun_relay_host);
+    Py_XDECREF(self->cb);
+    Py_XDECREF(self->user_agent);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_config_import(PyObj_pjsua_config *obj,
+				      const pjsua_config *cfg)
+{
+    obj->max_calls	= cfg->max_calls;
+    obj->thread_cnt	= cfg->thread_cnt;
+    Py_XDECREF(obj->outbound_proxy);
+    obj->outbound_proxy = PyString_FromStringAndSize(cfg->outbound_proxy[0].ptr,
+						     cfg->outbound_proxy[0].slen);
+    Py_XDECREF(obj->stun_domain);
+    obj->stun_domain	= PyString_FromStringAndSize(cfg->stun_domain.ptr,
+						     cfg->stun_domain.slen);
+    Py_XDECREF(obj->stun_host);
+    obj->stun_host	= PyString_FromStringAndSize(cfg->stun_host.ptr,
+						     cfg->stun_host.slen);
+    Py_XDECREF(obj->stun_relay_host);
+    obj->stun_relay_host= PyString_FromStringAndSize(cfg->stun_host.ptr,
+						     cfg->stun_host.slen);
+    Py_XDECREF(obj->user_agent);
+    obj->user_agent	= PyString_FromStringAndSize(cfg->user_agent.ptr,
+						     cfg->user_agent.slen);
+}
+
+
+static void PyObj_pjsua_config_export(pjsua_config *cfg,
+				      PyObj_pjsua_config *obj)
+{
+    cfg->max_calls	= obj->max_calls;
+    cfg->thread_cnt	= obj->thread_cnt;
+    if (PyString_Size(obj->outbound_proxy) > 0) {
+	cfg->outbound_proxy_cnt = 1;
+	cfg->outbound_proxy[0] = PyString_to_pj_str(obj->outbound_proxy);
+    } else {
+	cfg->outbound_proxy_cnt = 0;
+    }
+    cfg->stun_domain	= PyString_to_pj_str(obj->stun_domain);
+    cfg->stun_host	= PyString_to_pj_str(obj->stun_host);
+    //cfg->stun_relay_host= PyString_to_pj_str(obj->stun_host);
+    cfg->user_agent	= PyString_to_pj_str(obj->user_agent);
+
+}
+
+
+static PyObject *PyObj_pjsua_config_new(PyTypeObject *type, 
+					PyObject *args, 
+					PyObject *kwds)
+{
+    PyObj_pjsua_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_config *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->user_agent = PyString_FromString("");
+        if (self->user_agent == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->outbound_proxy = PyString_FromString("");
+        if (self->outbound_proxy == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->cb = (PyObj_pjsua_callback *)
+		   PyType_GenericNew(&PyTyp_pjsua_callback, NULL, NULL);
+        if (self->cb == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+    }
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_config_members
+ * attribute list accessible from Python/C
+ */
+static PyMemberDef PyObj_pjsua_config_members[] =
+{
+    {
+    	"max_calls", T_INT, 
+	offsetof(PyObj_pjsua_config, max_calls), 0,
+    	"Maximum calls to support (default: 4) "
+    },
+    {
+    	"thread_cnt", T_INT, 
+	offsetof(PyObj_pjsua_config, thread_cnt), 0,
+    	"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."
+    },
+    {
+    	"outbound_proxy", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_config, outbound_proxy), 0,
+    	"SIP URL of the outbound proxy (optional)"
+    },
+    {
+    	"stun_domain", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_config, stun_domain), 0,
+    	"Domain of the STUN server (optional). STUN server will be resolved "
+	"using DNS SRV resolution only when nameserver is configured. "
+	"Alternatively, if DNS SRV resolution for STUN is not desired, "
+	"application can specify the STUN server hostname or IP address "
+	"in stun_host attribute."
+    },
+    {
+    	"stun_host", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_config, stun_host), 0,
+    	"Hostname or IP address of the STUN server (optional)."
+    },
+    {
+    	"stun_relay_host", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_config, stun_relay_host), 0,
+    	"Hostname or IP address of the TURN server (optional)."
+    },
+    {
+    	"cb", T_OBJECT_EX, offsetof(PyObj_pjsua_config, cb), 0,
+    	"Application callback."
+    },
+    {
+    	"user_agent", T_OBJECT_EX, offsetof(PyObj_pjsua_config, user_agent), 0,
+    	"User agent string (default empty)"
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjsua_config
+ * type wrapper for config class
+ */
+static PyTypeObject PyTyp_pjsua_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "py_pjsua.Config",         /*tp_name*/
+    sizeof(PyObj_pjsua_config),/*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)PyObj_pjsua_config_delete,/*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "Config object",           /* tp_doc */
+    0,                         /* tp_traverse */
+    0,                         /* tp_clear */
+    0,                         /* tp_richcompare */
+    0,                         /* tp_weaklistoffset */
+    0,                         /* tp_iter */
+    0,                         /* tp_iternext */
+    0,                         /* tp_methods */
+    PyObj_pjsua_config_members,/* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    0,                         /* tp_init */
+    0,                         /* tp_alloc */
+    PyObj_pjsua_config_new,    /* tp_new */
+
+};
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_logging_config
+ * configuration class for logging_config object
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    int		 msg_logging;
+    unsigned	 level;
+    unsigned	 console_level;
+    unsigned	 decor;
+    PyObject	*log_filename;
+    PyObject	*cb;
+} PyObj_pjsua_logging_config;
+
+
+/*
+ * PyObj_pjsua_logging_config_delete
+ * deletes a logging config from memory
+ */
+static void PyObj_pjsua_logging_config_delete(PyObj_pjsua_logging_config* self)
+{
+    Py_XDECREF(self->log_filename);
+    Py_XDECREF(self->cb);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_logging_config_import(PyObj_pjsua_logging_config *obj,
+					      const pjsua_logging_config *cfg)
+{
+    obj->msg_logging	= cfg->msg_logging;
+    obj->level		= cfg->level;
+    obj->console_level	= cfg->console_level;
+    obj->decor		= cfg->decor;
+}
+
+static void PyObj_pjsua_logging_config_export(pjsua_logging_config *cfg,
+					      PyObj_pjsua_logging_config *obj)
+{
+    cfg->msg_logging	= obj->msg_logging;
+    cfg->level		= obj->level;
+    cfg->console_level	= obj->console_level;
+    cfg->decor		= obj->decor;
+    cfg->log_filename	= PyString_to_pj_str(obj->log_filename);
+}
+
+
+/*
+ * PyObj_pjsua_logging_config_new
+ * constructor for logging_config object
+ */
+static PyObject * PyObj_pjsua_logging_config_new(PyTypeObject *type, 
+						 PyObject *args,
+					         PyObject *kwds)
+{
+    PyObj_pjsua_logging_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_logging_config *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->log_filename = PyString_FromString("");
+        if (self->log_filename == NULL)
+    	{
+            Py_DECREF(self);
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        self->cb = Py_None;
+        if (self->cb == NULL)
+    	{
+            Py_DECREF(Py_None);
+            return NULL;
+        }
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_logging_config_members
+ */
+static PyMemberDef PyObj_pjsua_logging_config_members[] =
+{
+    {
+    	"msg_logging", T_INT, 
+	offsetof(PyObj_pjsua_logging_config, msg_logging), 0,
+    	"Log incoming and outgoing SIP message? Yes!"
+    },
+    {
+    	"level", T_INT, 
+	offsetof(PyObj_pjsua_logging_config, level), 0,
+    	"Input verbosity level. Value 5 is reasonable."
+    },
+    {
+    	"console_level", T_INT, 
+	offsetof(PyObj_pjsua_logging_config, console_level),
+    	0, "Verbosity level for console. Value 4 is reasonable."
+    },
+    {
+    	"decor", T_INT, 
+	 offsetof(PyObj_pjsua_logging_config, decor), 0,
+    	"Log decoration"
+    },
+    {
+    	"log_filename", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_logging_config, log_filename), 0,
+    	"Optional log filename"
+    },
+    {
+    	"cb", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_logging_config, cb), 0,
+    	"Optional callback function to be called to write log to application "
+    	"specific device. This function will be called forlog messages on "
+    	"input verbosity level."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_logging_config
+ */
+static PyTypeObject PyTyp_pjsua_logging_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Logging_Config",      /*tp_name*/
+    sizeof(PyObj_pjsua_logging_config),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_logging_config_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Logging Config objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_logging_config_members,/* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_logging_config_new, /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_msg_data
+ * typewrapper for MessageData class
+ * !modified @ 061206
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    PyObject * hdr_list;
+    PyObject * content_type;
+    PyObject * msg_body;
+} PyObj_pjsua_msg_data;
+
+
+/*
+ * PyObj_pjsua_msg_data_delete
+ * deletes a msg_data
+ * !modified @ 061206
+ */
+static void PyObj_pjsua_msg_data_delete(PyObj_pjsua_msg_data* self)
+{
+    Py_XDECREF(self->hdr_list);
+    Py_XDECREF(self->content_type);
+    Py_XDECREF(self->msg_body);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * PyObj_pjsua_msg_data_new
+ * constructor for msg_data object
+ * !modified @ 061206
+ */
+static PyObject * PyObj_pjsua_msg_data_new(PyTypeObject *type, 
+					   PyObject *args,
+					   PyObject *kwds)
+{
+    PyObj_pjsua_msg_data *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_msg_data *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        Py_INCREF(Py_None);
+        self->hdr_list = Py_None;
+        if (self->hdr_list == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->content_type = PyString_FromString("");
+        if (self->content_type == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->msg_body = PyString_FromString("");
+        if (self->msg_body == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_msg_data_members
+ * !modified @ 061206
+ */
+static PyMemberDef PyObj_pjsua_msg_data_members[] =
+{
+    {
+        "hdr_list", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_msg_data, hdr_list), 0, 
+	"Additional message headers as linked list of strings."
+    }, 
+    {
+	"content_type", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_msg_data, content_type), 0, 
+	"MIME type of optional message body."
+    },
+    {
+    	"msg_body", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_msg_data, msg_body), 0,
+    	"Optional message body."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjsua_msg_data
+ */
+static PyTypeObject PyTyp_pjsua_msg_data =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "py_pjsua.Msg_Data",       /*tp_name*/
+    sizeof(PyObj_pjsua_msg_data),   /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)PyObj_pjsua_msg_data_delete,/*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "msg_data objects",        /* tp_doc */
+    0,                         /* tp_traverse */
+    0,                         /* tp_clear */
+    0,                         /* tp_richcompare */
+    0,                         /* tp_weaklistoffset */
+    0,                         /* tp_iter */
+    0,                         /* tp_iternext */
+    0,                         /* tp_methods */
+    PyObj_pjsua_msg_data_members,          /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    0,                         /* tp_init */
+    0,                         /* tp_alloc */
+    PyObj_pjsua_msg_data_new,                 /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_transport_config
+ * Transport configuration for creating UDP transports for both SIP
+ * and media.
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    unsigned	port;
+    PyObject   *public_addr;
+    PyObject   *bound_addr;
+} PyObj_pjsua_transport_config;
+
+
+/*
+ * PyObj_pjsua_transport_config_delete
+ * deletes a transport config from memory
+ */
+static void PyObj_pjsua_transport_config_delete(PyObj_pjsua_transport_config* self)
+{
+    Py_XDECREF(self->public_addr);    
+    Py_XDECREF(self->bound_addr);    
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_transport_config_export(pjsua_transport_config *cfg,
+						PyObj_pjsua_transport_config *obj)
+{
+    cfg->public_addr	= PyString_to_pj_str(obj->public_addr);
+    cfg->bound_addr	= PyString_to_pj_str(obj->bound_addr);
+    cfg->port		= obj->port;
+
+}
+
+static void PyObj_pjsua_transport_config_import(PyObj_pjsua_transport_config *obj,
+						const pjsua_transport_config *cfg)
+{
+    Py_XDECREF(obj->public_addr);    
+    obj->public_addr = PyString_FromStringAndSize(cfg->public_addr.ptr, 
+						  cfg->public_addr.slen);
+
+    Py_XDECREF(obj->bound_addr);    
+    obj->bound_addr = PyString_FromStringAndSize(cfg->bound_addr.ptr, 
+					         cfg->bound_addr.slen);
+
+    obj->port = cfg->port;
+}
+
+
+/*
+ * PyObj_pjsua_transport_config_new
+ * constructor for transport_config object
+ */
+static PyObject * PyObj_pjsua_transport_config_new(PyTypeObject *type, 
+						   PyObject *args,
+						   PyObject *kwds)
+{
+    PyObj_pjsua_transport_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_transport_config *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->public_addr = PyString_FromString("");
+        if (self->public_addr == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->bound_addr = PyString_FromString("");
+        if (self->bound_addr == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_transport_config_members
+ */
+static PyMemberDef PyObj_pjsua_transport_config_members[] =
+{
+    {
+        "port", T_INT, 
+	offsetof(PyObj_pjsua_transport_config, port), 0,
+        "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."
+    },
+    {
+        "public_addr", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_transport_config, public_addr), 0,
+        "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."		
+    },    
+    {
+        "bound_addr", T_OBJECT_EX, 
+        offsetof(PyObj_pjsua_transport_config, bound_addr), 0,
+        "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)."		
+    },    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_transport_config
+ */
+static PyTypeObject PyTyp_pjsua_transport_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Transport_Config",    /*tp_name*/
+    sizeof(PyObj_pjsua_transport_config),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_transport_config_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Transport setting",	    /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_transport_config_members,/* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_transport_config_new,/* tp_new */
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_transport_info
+ * Transport info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    int		 id;
+    int		 type;
+    PyObject	*type_name;
+    PyObject	*info;
+    unsigned	 flag;
+    PyObject	*addr;
+    unsigned	 port;
+    unsigned	 usage_count;
+} PyObj_pjsua_transport_info;
+
+
+/*
+ * PyObj_pjsua_transport_info_delete
+ * deletes a transport info from memory
+ */
+static void PyObj_pjsua_transport_info_delete(PyObj_pjsua_transport_info* self)
+{
+    Py_XDECREF(self->type_name); 
+    Py_XDECREF(self->info);
+    Py_XDECREF(self->addr);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_transport_info_import(PyObj_pjsua_transport_info *obj,
+					      const pjsua_transport_info *info)
+{
+    obj->id	    = info->id;
+    obj->type	    = info->type;
+    obj->type_name  = PyString_FromStringAndSize(info->type_name.ptr,
+						 info->type_name.slen);
+    obj->info	    = PyString_FromStringAndSize(info->info.ptr,
+						 info->info.slen);
+    obj->flag	    = info->flag;
+    obj->addr	    = PyString_FromStringAndSize(info->local_name.host.ptr,
+						 info->local_name.host.slen);
+    obj->port	    = info->local_name.port;
+    obj->usage_count= info->usage_count;
+}
+
+/*
+ * PyObj_pjsua_transport_info_new
+ * constructor for transport_info object
+ */
+static PyObject * PyObj_pjsua_transport_info_new(PyTypeObject *type, 
+						 PyObject *args,
+						 PyObject *kwds)
+{
+    PyObj_pjsua_transport_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_transport_info *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->type_name = PyString_FromString("");
+        if (self->type_name == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->info = PyString_FromString(""); 
+        if (self->info == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->addr = PyString_FromString("");
+        if (self->addr == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_transport_info_members
+ */
+static PyMemberDef PyObj_pjsua_transport_info_members[] =
+{
+    {
+        "id", T_INT, 
+	offsetof(PyObj_pjsua_transport_info, id), 0,
+        "PJSUA transport identification."
+    },
+    {
+        "type", T_INT, 
+	offsetof(PyObj_pjsua_transport_info, id), 0,
+        "Transport type."
+    },
+    {
+        "type_name", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_transport_info, type_name), 0,
+        "Transport type name."
+    },
+    {
+        "info", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_transport_info, info), 0,
+        "Transport string info/description."
+    },
+    {
+        "flag", T_INT, 
+	offsetof(PyObj_pjsua_transport_info, flag), 0,
+        "Transport flag (see ##pjsip_transport_flags_e)."
+    },
+    {
+        "addr", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_transport_info, addr), 0,
+        "Published address (or transport address name)."
+    },
+    {
+        "port", T_INT,
+        offsetof(PyObj_pjsua_transport_info, port), 0,
+        "Published port number."
+    },
+    {
+        "usage_count", T_INT, 
+	offsetof(PyObj_pjsua_transport_info, usage_count), 0,
+        "Current number of objects currently referencing this transport."
+    },    
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjsua_transport_info
+ */
+static PyTypeObject PyTyp_pjsua_transport_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Transport_Info",      /*tp_name*/
+    sizeof(PyObj_pjsua_transport_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_transport_info_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Transport Info objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_transport_info_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_transport_info_new, /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjsua_acc_config
+ * Acc Config
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    int		     priority;	
+    PyObject	    *id;
+    PyObject	    *reg_uri;
+    int		     publish_enabled;
+    PyObject	    *force_contact;
+    /*pj_str_t proxy[8];*/
+    PyListObject    *proxy;
+    unsigned	     reg_timeout;
+    /*pjsip_cred_info cred_info[8];*/
+    PyListObject    *cred_info;
+    int		     transport_id;
+} PyObj_pjsua_acc_config;
+
+
+/*
+ * PyObj_pjsua_acc_config_delete
+ * deletes a acc_config from memory
+ */
+static void PyObj_pjsua_acc_config_delete(PyObj_pjsua_acc_config* self)
+{
+    Py_XDECREF(self->id); 
+    Py_XDECREF(self->reg_uri);
+    Py_XDECREF(self->force_contact);	
+    Py_XDECREF(self->proxy);
+    Py_XDECREF(self->cred_info);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_acc_config_import(PyObj_pjsua_acc_config *obj,
+					  const pjsua_acc_config *cfg)
+{
+    unsigned i;
+
+    obj->priority   = cfg->priority;
+    Py_XDECREF(obj->id);
+    obj->id	    = PyString_FromStringAndSize(cfg->id.ptr, cfg->id.slen);
+    Py_XDECREF(obj->reg_uri);
+    obj->reg_uri    = PyString_FromStringAndSize(cfg->reg_uri.ptr, 
+						 cfg->reg_uri.slen);
+    obj->publish_enabled = cfg->publish_enabled;
+    Py_XDECREF(obj->force_contact);
+    obj->force_contact = PyString_FromStringAndSize(cfg->force_contact.ptr,
+						    cfg->force_contact.slen);
+    Py_XDECREF(obj->proxy);
+    obj->proxy = (PyListObject *)PyList_New(0);
+    for (i=0; i<cfg->proxy_cnt; ++i) {
+	PyObject * str;
+	str = PyString_FromStringAndSize(cfg->proxy[i].ptr, 
+					 cfg->proxy[i].slen);
+	PyList_Append((PyObject *)obj->proxy, str);
+    }
+
+    obj->reg_timeout = cfg->reg_timeout;
+
+    Py_XDECREF(obj->cred_info);
+    obj->cred_info = (PyListObject *)PyList_New(0);
+    for (i=0; i<cfg->cred_count; ++i) {
+	PyObj_pjsip_cred_info * ci;
+	
+	ci = (PyObj_pjsip_cred_info *)
+	     PyObj_pjsip_cred_info_new(&PyTyp_pjsip_cred_info,NULL,NULL);
+	PyObj_pjsip_cred_info_import(ci, &cfg->cred_info[i]);
+	PyList_Append((PyObject *)obj->cred_info, (PyObject *)ci);
+    }
+
+    obj->transport_id = cfg->transport_id;
+}
+
+static void PyObj_pjsua_acc_config_export(pjsua_acc_config *cfg,
+					  PyObj_pjsua_acc_config *obj)
+{
+    unsigned i;
+
+    cfg->priority   = obj->priority;
+    cfg->id	    = PyString_to_pj_str(obj->id);
+    cfg->reg_uri    = PyString_to_pj_str(obj->reg_uri);
+    cfg->publish_enabled = obj->publish_enabled;
+    cfg->force_contact = PyString_to_pj_str(obj->force_contact);
+
+    cfg->proxy_cnt = PyList_Size((PyObject*)obj->proxy);
+    for (i = 0; i < cfg->proxy_cnt; i++) {
+        /*cfg.proxy[i] = ac->proxy[i];*/
+        cfg->proxy[i] = PyString_to_pj_str(PyList_GetItem((PyObject *)obj->proxy,i));
+    }
+
+    cfg->reg_timeout = obj->reg_timeout;
+
+    cfg->cred_count = PyList_Size((PyObject*)obj->cred_info);
+    for (i = 0; i < cfg->cred_count; i++) {
+        /*cfg.cred_info[i] = ac->cred_info[i];*/
+        PyObj_pjsip_cred_info *ci;
+	ci = (PyObj_pjsip_cred_info*) 
+	     PyList_GetItem((PyObject *)obj->cred_info,i);
+	PyObj_pjsip_cred_info_export(&cfg->cred_info[i], ci);
+    }
+
+    cfg->transport_id = obj->transport_id;
+}
+
+
+/*
+ * PyObj_pjsua_acc_config_new
+ * constructor for acc_config object
+ */
+static PyObject * PyObj_pjsua_acc_config_new(PyTypeObject *type, 
+					     PyObject *args,
+					     PyObject *kwds)
+{
+    PyObj_pjsua_acc_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_acc_config *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->id = PyString_FromString("");
+        if (self->id == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->reg_uri = PyString_FromString("");
+        if (self->reg_uri == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+        self->force_contact = PyString_FromString("");
+        if (self->force_contact == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->proxy = (PyListObject *)PyList_New(0);
+	if (self->proxy == NULL) {
+	    Py_DECREF(self);
+	    return NULL;
+	}
+	self->cred_info = (PyListObject *)PyList_New(0);
+	if (self->cred_info == NULL) {
+	    Py_DECREF(self);
+	    return NULL;
+	}
+    }
+
+    return (PyObject *)self;
+}
+
+
+
+/*
+ * PyObj_pjsua_acc_config_members
+ */
+static PyMemberDef PyObj_pjsua_acc_config_members[] =
+{
+    {
+        "priority", T_INT, offsetof(PyObj_pjsua_acc_config, priority), 0,
+        "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. "
+    },
+    {
+        "id", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, id), 0,
+        "The full SIP URL for the account. "
+        "The value can take name address or URL format, "
+        "and will look something like 'sip:account@serviceprovider'. "
+        "This field is mandatory."
+    },
+    {
+        "reg_uri", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, reg_uri), 0,
+        "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. "
+    },
+    {
+        "publish_enabled", T_INT, 
+        offsetof(PyObj_pjsua_acc_config, publish_enabled), 0,
+        "Publish presence? "
+    },
+    {
+        "force_contact", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, force_contact), 0,
+        "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. "
+    },
+    {
+        "proxy", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, proxy), 0,
+        "Optional URI of the proxies to be visited for all outgoing requests "
+	"that are using this account (REGISTER, INVITE, etc). Application need "
+	"to specify these proxies if the service provider requires "
+	"that requests destined towards its network should go through certain "
+	"proxies first (for example, border controllers)."
+    },
+    {
+        "reg_timeout", T_INT, offsetof(PyObj_pjsua_acc_config, reg_timeout), 0,
+        "Optional interval for registration, in seconds. "
+        "If the value is zero, default interval will be used "
+        "(PJSUA_REG_INTERVAL, 55 seconds). "
+    },
+    {
+        "cred_info", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, cred_info), 0,
+        "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."
+    },
+    {
+	"transport_id", T_INT,
+	offsetof(PyObj_pjsua_acc_config, transport_id), 0,
+	"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."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_acc_config
+ */
+static PyTypeObject PyTyp_pjsua_acc_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Acc_Config",      /*tp_name*/
+    sizeof(PyObj_pjsua_acc_config),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_acc_config_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Acc Config objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0/*acc_config_methods*/,                              /* tp_methods */
+    PyObj_pjsua_acc_config_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_acc_config_new,             /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_acc_info
+ * Acc Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    int		 id;	
+    int		 is_default;
+    PyObject	*acc_uri;
+    int		 has_registration;
+    int		 expires;
+    int		 status;
+    PyObject	*status_text;
+    int		 online_status;	
+    PyObject	*online_status_text;
+} PyObj_pjsua_acc_info;
+
+
+/*
+ * PyObj_pjsua_acc_info_delete
+ * deletes a acc_info from memory
+ */
+static void PyObj_pjsua_acc_info_delete(PyObj_pjsua_acc_info* self)
+{
+    Py_XDECREF(self->acc_uri);
+    Py_XDECREF(self->status_text);
+    Py_XDECREF(self->online_status_text);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_acc_info_import(PyObj_pjsua_acc_info *obj,
+					const pjsua_acc_info *info)
+{
+    obj->id	    = info->id;
+    obj->is_default = info->is_default;
+    obj->acc_uri    = PyString_FromStringAndSize(info->acc_uri.ptr, 
+						 info->acc_uri.slen);
+    obj->has_registration = info->has_registration;
+    obj->expires    = info->expires;
+    obj->status	    = info->status;
+    obj->status_text= PyString_FromStringAndSize(info->status_text.ptr,
+						 info->status_text.slen);
+    obj->online_status = info->online_status;
+    obj->online_status_text = PyString_FromStringAndSize(info->online_status_text.ptr,
+							 info->online_status_text.slen);
+}
+
+
+/*
+ * PyObj_pjsua_acc_info_new
+ * constructor for acc_info object
+ */
+static PyObject * PyObj_pjsua_acc_info_new(PyTypeObject *type, 
+					   PyObject *args,
+					   PyObject *kwds)
+{
+    PyObj_pjsua_acc_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_acc_info *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->acc_uri = PyString_FromString("");
+        if (self->acc_uri == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->status_text = PyString_FromString("");
+        if (self->status_text == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->online_status_text = PyString_FromString("");
+        if (self->online_status_text == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }        
+    }
+
+    return (PyObject *)self;
+}
+
+/*
+ * acc_info_members
+ */
+static PyMemberDef acc_info_members[] =
+{
+    {
+        "id", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, id), 0,
+        "The account ID."
+    },
+    {
+        "is_default", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, is_default), 0,
+        "Flag to indicate whether this is the default account. "
+    },
+    {
+        "acc_uri", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_info, acc_uri), 0,
+        "Account URI"
+    },
+    {
+        "has_registration", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, has_registration), 0,
+        "Flag to tell whether this account has registration setting "
+        "(reg_uri is not empty)."
+    },
+    {
+        "expires", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, expires), 0,
+        "An up to date expiration interval for account registration session."
+    },
+    {
+        "status", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, status), 0,
+        "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. "
+    },
+    {
+        "status_text", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_info, status_text), 0,
+        "String describing the registration status."
+    },
+    {
+        "online_status", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, online_status), 0,
+        "Presence online status for this account. "
+    },
+    {
+        "online_status_text", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_acc_info, online_status_text), 0,
+        "Presence online status text."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_acc_info
+ */
+static PyTypeObject PyTyp_pjsua_acc_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Acc_Info",      /*tp_name*/
+    sizeof(PyObj_pjsua_acc_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_acc_info_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Acc Info objects",             /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    NULL,                           /* tp_methods */
+    acc_info_members,		    /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_acc_info_new,       /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjsua_buddy_config
+ * Buddy Config
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    PyObject	*uri;
+    int		 subscribe;
+} PyObj_pjsua_buddy_config;
+
+
+/*
+ * PyObj_pjsua_buddy_config_delete
+ * deletes a buddy_config from memory
+ */
+static void PyObj_pjsua_buddy_config_delete(PyObj_pjsua_buddy_config* self)
+{
+    Py_XDECREF(self->uri);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_buddy_config_import(PyObj_pjsua_buddy_config *obj,
+					    const pjsua_buddy_config *cfg)
+{
+    Py_XDECREF(obj->uri);
+    obj->uri = PyString_FromStringAndSize(cfg->uri.ptr, cfg->uri.slen);
+    obj->subscribe = cfg->subscribe;
+}
+
+
+static void PyObj_pjsua_buddy_config_export(pjsua_buddy_config *cfg,
+					    PyObj_pjsua_buddy_config *obj)
+{
+    cfg->uri = PyString_to_pj_str(obj->uri);
+    cfg->subscribe = obj->subscribe;
+}
+
+
+
+/*
+ * PyObj_pjsua_buddy_config_new
+ * constructor for buddy_config object
+ */
+static PyObject *PyObj_pjsua_buddy_config_new(PyTypeObject *type, 
+					      PyObject *args,
+					      PyObject *kwds)
+{
+    PyObj_pjsua_buddy_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_buddy_config *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->uri = PyString_FromString("");
+        if (self->uri == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }        
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * PyObj_pjsua_buddy_config_members
+ */
+static PyMemberDef PyObj_pjsua_buddy_config_members[] =
+{
+    
+    {
+        "uri", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_buddy_config, uri), 0,
+        "TBuddy URL or name address."        
+    },
+    
+    {
+        "subscribe", T_INT, 
+        offsetof(PyObj_pjsua_buddy_config, subscribe), 0,
+        "Specify whether presence subscription should start immediately. "
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_buddy_config
+ */
+static PyTypeObject PyTyp_pjsua_buddy_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Buddy_Config",        /*tp_name*/
+    sizeof(PyObj_pjsua_buddy_config),/*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_buddy_config_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Buddy Config objects",         /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_buddy_config_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_buddy_config_new,   /* tp_new */
+
+};
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_buddy_info
+ * Buddy Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    int		 id;
+    PyObject	*uri;
+    PyObject	*contact;
+    int		 status;
+    PyObject	*status_text;
+    int		 monitor_pres;
+} PyObj_pjsua_buddy_info;
+
+
+/*
+ * PyObj_pjsua_buddy_info_delete
+ * deletes a buddy_info from memory
+ * !modified @ 071206
+ */
+static void PyObj_pjsua_buddy_info_delete(PyObj_pjsua_buddy_info* self)
+{
+    Py_XDECREF(self->uri);
+    Py_XDECREF(self->contact);
+    Py_XDECREF(self->status_text);
+    
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_buddy_info_import(PyObj_pjsua_buddy_info *obj,
+					  const pjsua_buddy_info *info)
+{
+    obj->id = info->id;
+    Py_XDECREF(obj->uri);
+    obj->uri = PyString_FromStringAndSize(info->uri.ptr, info->uri.slen);
+    Py_XDECREF(obj->contact);
+    obj->contact = PyString_FromStringAndSize(info->contact.ptr, info->contact.slen);
+    obj->status = info->status;
+    Py_XDECREF(obj->status_text);
+    obj->status_text = PyString_FromStringAndSize(info->status_text.ptr, 
+						  info->status_text.slen);
+    obj->monitor_pres = info->monitor_pres;
+}
+
+
+/*
+ * PyObj_pjsua_buddy_info_new
+ * constructor for buddy_info object
+ * !modified @ 071206
+ */
+static PyObject * PyObj_pjsua_buddy_info_new(PyTypeObject *type, 
+					     PyObject *args,
+					     PyObject *kwds)
+{
+    PyObj_pjsua_buddy_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_buddy_info *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->uri = PyString_FromString("");
+        if (self->uri == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }        
+	self->contact = PyString_FromString("");
+        if (self->contact == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+	self->status_text = PyString_FromString("");
+        if (self->status_text == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+	
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * PyObj_pjsua_buddy_info_members
+ * !modified @ 071206
+ */
+static PyMemberDef PyObj_pjsua_buddy_info_members[] =
+{
+    {
+        "id", T_INT, 
+        offsetof(PyObj_pjsua_buddy_info, id), 0,
+        "The buddy ID."
+    },
+    {
+        "uri", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_buddy_info, uri), 0,
+        "The full URI of the buddy, as specified in the configuration. "        
+    },
+    {
+        "contact", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_buddy_info, contact), 0,
+        "Buddy's Contact, only available when presence subscription "
+        "has been established to the buddy."        
+    },
+    {
+        "status", T_INT, 
+        offsetof(PyObj_pjsua_buddy_info, status), 0,
+        "Buddy's online status. "
+    },
+    {
+        "status_text", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_buddy_info, status_text), 0,
+        "Text to describe buddy's online status."        
+    },
+    {
+        "monitor_pres", T_INT, 
+        offsetof(PyObj_pjsua_buddy_info, monitor_pres), 0,
+        "Flag to indicate that we should monitor the presence information "
+        "for this buddy (normally yes, unless explicitly disabled). "
+    },
+    
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_buddy_info
+ */
+static PyTypeObject PyTyp_pjsua_buddy_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "py_pjsua.Buddy_Info",      /*tp_name*/
+    sizeof(PyObj_pjsua_buddy_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_buddy_info_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Buddy Info objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_buddy_info_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_buddy_info_new,             /* tp_new */
+
+};
+
+
+
+
+
+#endif	/* __PY_PJSUA_H__ */
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/setup.py b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/setup.py
new file mode 100644
index 0000000..2db59c2
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/py_pjsua/setup.py
@@ -0,0 +1,44 @@
+from distutils.core import setup, Extension
+import os
+import sys
+
+# Fill in pj_inc_dirs
+pj_inc_dirs = []
+f = os.popen("make -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 -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 = []
+f = os.popen("make -f helper.mak libs")
+for line in f:
+	pj_libs.append(line.rstrip("\r\n"))
+f.close()
+
+# Mac OS X depedencies
+if sys.platform == 'darwin':
+	extra_link_args = ["-framework", "CoreFoundation", 
+			   "-framework", "AudioToolbox"]
+else:
+	extra_link_args = []
+
+
+setup(name="py_pjsua", version="0.8",
+	ext_modules = [
+		Extension("py_pjsua", 
+			  ["py_pjsua.c"], 
+			  define_macros=[('PJ_AUTOCONF', '1'),],
+			  include_dirs=pj_inc_dirs, 
+			  library_dirs=pj_lib_dirs, 
+			  libraries=pj_libs,
+			  extra_link_args=extra_link_args),
+	])
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/account.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/account.py
new file mode 100644
index 0000000..1bc91b4
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/account.py
@@ -0,0 +1,239 @@
+# $Id: account.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+	from tkinter import messagebox as msgbox
+else:
+	import Tkinter as tk
+	import tkMessageBox as msgbox
+	import ttk
+
+import random
+import pjsua2 as pj
+import _pjsua2
+import accountsetting
+import application
+import call
+import chat as ch
+
+# Account class
+class Account(pj.Account):
+	"""
+	High level Python Account object, derived from pjsua2's Account object.
+	"""
+	def __init__(self, app):
+		pj.Account.__init__(self)
+		self.app = app
+		self.randId = random.randint(1, 9999)
+		self.cfg =  pj.AccountConfig()
+		self.cfgChanged = False
+		self.buddyList = []
+		self.chatList = []
+		self.deleting = False
+
+	def findChat(self, uri_str):
+		uri = ch.ParseSipUri(uri_str)
+		if not uri: return None
+			
+		for chat in self.chatList:
+			if chat.isUriParticipant(uri) and chat.isPrivate():
+				return chat
+		return None
+	
+	def newChat(self, uri_str):
+		uri = ch.ParseSipUri(uri_str)
+		if not uri: return None
+			
+		chat = ch.Chat(self.app, self, uri)
+		self.chatList.append(chat)
+		self.app.updateWindowMenu()
+		return chat
+	
+	def statusText(self):
+		status = '?'
+		if self.isValid():
+			ai = self.getInfo()
+			if ai.regLastErr:
+				status = self.app.ep.utilStrError(ai.regLastErr)
+			elif ai.regIsActive:
+				if ai.onlineStatus:
+					if len(ai.onlineStatusText):
+						status = ai.onlineStatusText
+					else:
+						status = "Online"
+				else:
+					status = "Registered"
+			else:
+				if ai.regIsConfigured:
+					if ai.regStatus/100 == 2:
+						status = "Unregistered"
+					else:
+						status = ai.regStatusText
+				else:
+					status = "Doesn't register"
+		else:
+			status = '- not created -'
+		return status
+        	
+	def onRegState(self, prm):
+		self.app.updateAccount(self)
+
+        def onIncomingCall(self, prm):
+		c = call.Call(self, call_id=prm.callId)
+                call_prm = pj.CallOpParam()
+		call_prm.statusCode = 180
+		c.answer(call_prm)
+		ci = c.getInfo()
+		msg = "Incoming call for account '%s'" % self.cfg.idUri
+		if msgbox.askquestion(msg, "Accept call from '%s'?" % (ci.remoteUri), default=msgbox.YES) == u'yes':
+			call_prm.statusCode = 200
+			c.answer(call_prm)
+			
+			# find/create chat instance
+			chat = self.findChat(ci.remoteUri)
+			if not chat: chat = self.newChat(ci.remoteUri)
+			
+			chat.showWindow()
+			chat.registerCall(ci.remoteUri, c)
+			chat.updateCallState(c, ci)
+		else:
+			c.hangup(call_prm)
+			
+	def onInstantMessage(self, prm):
+		chat = self.findChat(prm.fromUri)
+		if not chat: chat = self.newChat(prm.fromUri)
+		
+		chat.showWindow()
+		chat.addMessage(prm.fromUri, prm.msgBody)
+		
+	def onInstantMessageStatus(self, prm):
+		if prm.code/100 == 2: return
+		
+		chat = self.findChat(prm.toUri)
+		if not chat:
+			print "=== IM status to '%s' cannot find chat" % prm.toUri
+			return
+		
+		chat.addMessage(None, "Failed sending message to '%s': %s" % (prm.toUri, prm.reason))
+		
+	def onTypingIndication(self, prm):
+		chat = self.findChat(prm.fromUri)
+		if not chat:
+			print "=== Incoming typing indication from '%s' cannot find chat" % prm.fromUri
+			return
+		
+		chat.setTypingIndication(prm.fromUri, prm.isTyping)
+
+		
+# Account frame, to list accounts
+class AccountListFrame(ttk.Frame):
+	"""
+	This implements a Frame which contains account list and buttons to operate
+	on them (Add, Modify, Delete, etc.). 
+	"""
+	def __init__(self, parent, app, acc_list = []):
+		ttk.Frame.__init__(self, parent, name='acclist')
+		self.app = app
+		self.accList = acc_list
+		self.accDeletedList = []
+		self.pack(expand='yes', fill='both')
+		self._createWidgets()
+		for acc in self.accList:
+			self._showAcc(acc)
+		
+	def _createWidgets(self):
+		self.tv = ttk.Treeview(self, columns=('ID', 'Registrar', 'Default'), selectmode='browse')
+		self.tv.heading('#0', text='Priority')
+		self.tv.heading(0, text='ID')
+		self.tv.heading(1, text='Registrar')
+		self.tv.heading(2, text='Default?')
+		self.tv.column('#0', width=60)
+		self.tv.column(0, width=300)
+		self.tv.column(1, width=200)
+		self.tv.column(2, width=60)
+		self.tv.grid(column=0, row=0, rowspan=4, padx=5, pady=5)
+		
+		ttk.Button(self, text='Add..', command=self._onBtnAdd).grid(column=1, row=0, padx=5)
+		ttk.Button(self, text='Settings..', command=self._onBtnSettings).grid(column=1, row=1)
+		ttk.Button(self, text='Set Default', command=self._onBtnSetDefault).grid(column=1, row=2)
+		ttk.Button(self, text='Delete..', command=self._onBtnDelete).grid(column=1, row=3)
+
+	def _showAcc(self, acc):
+		is_default = 'Yes' if acc.isValid() and acc.isDefault() else ''
+		values = (acc.cfg.idUri, acc.cfg.regConfig.registrarUri, is_default)
+		self.tv.insert('', 0, str(acc.randId), open=True, text=str(acc.cfg.priority), values=values)
+	
+	def updateAccount(self, acc):
+		is_default = 'Yes' if acc.isValid() and acc.isDefault() else ''
+		values = (acc.cfg.idUri, acc.cfg.regConfig.registrarUri, is_default)
+		self.tv.item(str(acc.randId), text=str(acc.cfg.priority), values=values)
+	
+	def _getSelectedAcc(self):
+		items = self.tv.selection()
+		if not items:
+			return None
+		iid = int(items[0])
+		return [acc for acc in self.accList if acc.randId==iid][0]
+	
+	def _onBtnAdd(self):
+		cfg = pj.AccountConfig()
+		dlg = accountsetting.Dialog(self.master, cfg)
+		if dlg.doModal():
+			acc = Account(self.app)
+			acc.cfg = cfg
+			self._showAcc(acc)
+			self.accList.append(acc)
+			self.cfgChanged = True
+	
+	def _onBtnSettings(self):
+		acc = self._getSelectedAcc()
+		if not acc:
+			return
+		dlg = accountsetting.Dialog(self.master, acc.cfg)
+		if dlg.doModal():
+			self.updateAccount(acc)
+			self.cfgChanged = True
+
+	def _onBtnDelete(self):
+		acc = self._getSelectedAcc()
+		if not acc:
+			return
+		msg = "Do you really want to delete account '%s'" % acc.cfg.idUri
+		if msgbox.askquestion('Delete account?', msg, default=msgbox.NO) != u'yes':
+			return
+		self.accList.remove(acc)
+		self.accDeletedList.append(acc)
+		self.tv.delete( (str(acc.randId),) )
+
+	def _onBtnSetDefault(self):
+		acc = self._getSelectedAcc()
+		if not acc:
+			return
+		if acc.isValid():
+			acc.setDefault()
+		for acc in self.accList:
+			self.updateAccount(acc)
+		
+		
+if __name__ == '__main__':
+	application.main()
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/accountsetting.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/accountsetting.py
new file mode 100644
index 0000000..92cf2c4
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/accountsetting.py
@@ -0,0 +1,369 @@
+# $Id: accountsetting.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+	from tkinter import messagebox as msgbox
+else:
+	import Tkinter as tk
+	import tkMessageBox as msgbox
+	import ttk
+
+import pjsua2 as pj
+import endpoint
+import application
+
+class Dialog(tk.Toplevel):
+	"""
+	This implements account settings dialog to manipulate account settings.
+	"""
+	def __init__(self, parent, cfg):
+		tk.Toplevel.__init__(self, parent)
+		self.transient(parent)
+		self.parent = parent
+		self.geometry("+100+100")
+		self.title('Account settings')
+		
+		self.frm = ttk.Frame(self)
+		self.frm.pack(expand='yes', fill='both')
+		
+		self.isOk = False
+		self.cfg = cfg
+		
+		self.createWidgets()
+	
+	def doModal(self):
+		if self.parent:
+			self.parent.wait_window(self)
+		else:
+			self.wait_window(self)
+		return self.isOk
+		
+	def createWidgets(self):
+		# The notebook
+		self.frm.rowconfigure(0, weight=1)
+		self.frm.rowconfigure(1, weight=0)
+		self.frm.columnconfigure(0, weight=1)
+		self.frm.columnconfigure(1, weight=1)
+		self.wTab = ttk.Notebook(self.frm)
+		self.wTab.grid(column=0, row=0, columnspan=2, padx=10, pady=10, ipadx=20, ipady=20, sticky=tk.N+tk.S+tk.W+tk.E)
+		
+		# Main buttons
+		btnOk = ttk.Button(self.frm, text='Ok', command=self.onOk)
+		btnOk.grid(column=0, row=1, sticky=tk.E, padx=20, pady=10)
+		btnCancel = ttk.Button(self.frm, text='Cancel', command=self.onCancel)
+		btnCancel.grid(column=1, row=1, sticky=tk.W, padx=20, pady=10)
+		
+		# Tabs
+		self.createBasicTab()
+		self.createSipTab()
+		self.createMediaTab()
+		self.createMediaNatTab()
+		
+	def createBasicTab(self):
+		# Prepare the variables to set/receive values from GUI
+		self.cfgPriority = tk.IntVar(value=self.cfg.priority)
+		self.cfgAccId = tk.StringVar(value=self.cfg.idUri)
+		self.cfgRegistrar = tk.StringVar(value=self.cfg.regConfig.registrarUri)
+		self.cfgRegisterOnAdd = tk.IntVar(value=self.cfg.regConfig.registerOnAdd)
+		self.cfgUsername = tk.StringVar()
+		self.cfgPassword = tk.StringVar()
+		if len(self.cfg.sipConfig.authCreds):
+			self.cfgUsername.set( self.cfg.sipConfig.authCreds[0].username )
+			self.cfgPassword.set( self.cfg.sipConfig.authCreds[0].data )
+		self.cfgProxy = tk.StringVar()
+		if len(self.cfg.sipConfig.proxies):
+			self.cfgProxy.set( self.cfg.sipConfig.proxies[0] )
+		
+		# Build the tab page
+		frm = ttk.Frame(self.frm)
+		frm.columnconfigure(0, weight=1)
+		frm.columnconfigure(1, weight=2)
+		row = 0
+		ttk.Label(frm, text='Priority:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		tk.Spinbox(frm, from_=0, to=9, textvariable=self.cfgPriority, width=2).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='ID (URI):').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Entry(frm, textvariable=self.cfgAccId, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='Registrar URI:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Entry(frm, textvariable=self.cfgRegistrar, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Checkbutton(frm, text='Register on add', variable=self.cfgRegisterOnAdd).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='Optional proxy URI:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Entry(frm, textvariable=self.cfgProxy, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='Auth username:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Entry(frm, textvariable=self.cfgUsername, width=16).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='Password:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Entry(frm, textvariable=self.cfgPassword, show='*', width=16).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+
+		self.wTab.add(frm, text='Basic Settings')
+		
+
+	def createSipTab(self):
+		# Prepare the variables to set/receive values from GUI
+		self.cfgPrackUse 	= tk.IntVar(value=self.cfg.callConfig.prackUse)
+		self.cfgTimerUse 	= tk.IntVar(value=self.cfg.callConfig.timerUse)
+		self.cfgTimerExpires 	= tk.IntVar(value=self.cfg.callConfig.timerSessExpiresSec)
+		self.cfgPublish 	= tk.BooleanVar(value=self.cfg.presConfig.publishEnabled)
+		self.cfgMwiEnabled 	= tk.BooleanVar(value=self.cfg.mwiConfig.enabled)
+		self.cfgEnableContactRewrite = tk.BooleanVar(value=self.cfg.natConfig.contactRewriteUse != 0) 
+		self.cfgEnableViaRewrite = tk.BooleanVar(value=self.cfg.natConfig.viaRewriteUse != 0) 
+		self.cfgEnableSdpRewrite = tk.BooleanVar(value=self.cfg.natConfig.sdpNatRewriteUse != 0)
+		self.cfgEnableSipOutbound = tk.BooleanVar(value=self.cfg.natConfig.sipOutboundUse != 0)
+		self.cfgKaInterval 	= tk.IntVar(value=self.cfg.natConfig.udpKaIntervalSec)
+		
+		# Build the tab page
+		frm = ttk.Frame(self.frm)
+		frm.columnconfigure(0, weight=1)
+		frm.columnconfigure(1, weight=2)
+		row = 0
+		ttk.Label(frm, text='100rel/PRACK:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Radiobutton(frm, text='Only offer PRACK', value=pj.PJSUA_100REL_NOT_USED, variable=self.cfgPrackUse).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Offer and use if remote supports', value=pj.PJSUA_100REL_OPTIONAL, variable=self.cfgPrackUse).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Required', value=pj.PJSUA_100REL_MANDATORY, variable=self.cfgPrackUse).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='Session Timer:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Radiobutton(frm, text='Not offered', value=pj.PJSUA_SIP_TIMER_INACTIVE, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Optional', value=pj.PJSUA_SIP_TIMER_OPTIONAL, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Required', value=pj.PJSUA_SIP_TIMER_REQUIRED, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text="Always use", value=pj.PJSUA_SIP_TIMER_ALWAYS, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='Session Timer Expiration:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		tk.Spinbox(frm, from_=90, to=7200, textvariable=self.cfgTimerExpires, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='(seconds)').grid(row=row, column=1, sticky=tk.E)
+		row += 1
+		ttk.Label(frm, text='Presence:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Checkbutton(frm, text='Enable PUBLISH', variable=self.cfgPublish).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='Message Waiting Indication:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Checkbutton(frm, text='Enable MWI', variable=self.cfgMwiEnabled).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='NAT Traversal:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Checkbutton(frm, text='Enable Contact Rewrite', variable=self.cfgEnableContactRewrite).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Checkbutton(frm, text='Enable Via Rewrite', variable=self.cfgEnableViaRewrite).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Checkbutton(frm, text='Enable SDP IP Address Rewrite', variable=self.cfgEnableSdpRewrite).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Checkbutton(frm, text='Enable SIP Outbound Extension', variable=self.cfgEnableSipOutbound).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='UDP Keep-Alive Interval:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		tk.Spinbox(frm, from_=0, to=3600, textvariable=self.cfgKaInterval, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='(seconds) Zero to disable.').grid(row=row, column=1, sticky=tk.E)
+
+
+		self.wTab.add(frm, text='SIP Features')
+
+	def createMediaTab(self):
+		# Prepare the variables to set/receive values from GUI
+		self.cfgMedPort = tk.IntVar(value=self.cfg.mediaConfig.transportConfig.port)
+		self.cfgMedPortRange = tk.IntVar(value=self.cfg.mediaConfig.transportConfig.portRange)
+		self.cfgMedLockCodec = tk.BooleanVar(value=self.cfg.mediaConfig.lockCodecEnabled)
+		self.cfgMedSrtp = tk.IntVar(value=self.cfg.mediaConfig.srtpUse)
+		self.cfgMedSrtpSecure = tk.IntVar(value=self.cfg.mediaConfig.srtpSecureSignaling)
+		self.cfgMedIpv6 = tk.BooleanVar(value=self.cfg.mediaConfig.ipv6Use==pj.PJSUA_IPV6_ENABLED)
+		
+		# Build the tab page
+		frm = ttk.Frame(self.frm)
+		frm.columnconfigure(0, weight=1)
+		frm.columnconfigure(1, weight=21)
+		row = 0
+		ttk.Label(frm, text='Secure RTP (SRTP):').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Radiobutton(frm, text='Disable', value=pj.PJMEDIA_SRTP_DISABLED, variable=self.cfgMedSrtp).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Mandatory', value=pj.PJMEDIA_SRTP_MANDATORY, variable=self.cfgMedSrtp).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Optional (non-standard)', value=pj.PJMEDIA_SRTP_OPTIONAL, variable=self.cfgMedSrtp).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='SRTP signaling:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Radiobutton(frm, text='Does not require secure signaling', value=0, variable=self.cfgMedSrtpSecure).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Require secure next hop (TLS)', value=1, variable=self.cfgMedSrtpSecure).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Require secure end-to-end (SIPS)', value=2, variable=self.cfgMedSrtpSecure).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='RTP transport start port:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgMedPort, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='(0: any)').grid(row=row, column=1, sticky=tk.E, pady=2)
+		row += 1
+		ttk.Label(frm, text='Port range:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgMedPortRange, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='(0: not limited)').grid(row=row, column=1, sticky=tk.E, pady=2)
+		row += 1
+		ttk.Label(frm, text='Lock codec:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Checkbutton(frm, text='Enable', variable=self.cfgMedLockCodec).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='Use IPv6:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Checkbutton(frm, text='Yes', variable=self.cfgMedIpv6).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+
+		self.wTab.add(frm, text='Media settings')
+
+	def createMediaNatTab(self):
+		# Prepare the variables to set/receive values from GUI
+		self.cfgSipUseStun = tk.IntVar(value = self.cfg.natConfig.sipStunUse)
+		self.cfgMediaUseStun = tk.IntVar(value = self.cfg.natConfig.mediaStunUse)
+		self.cfgIceEnabled = tk.BooleanVar(value = self.cfg.natConfig.iceEnabled)
+		self.cfgIceAggressive = tk.BooleanVar(value = self.cfg.natConfig.iceAggressiveNomination)
+		self.cfgAlwaysUpdate = tk.BooleanVar(value = True if self.cfg.natConfig.iceAlwaysUpdate else False)
+		self.cfgIceNoHostCands = tk.BooleanVar(value = True if self.cfg.natConfig.iceMaxHostCands == 0 else False)
+		self.cfgTurnEnabled = tk.BooleanVar(value = self.cfg.natConfig.turnEnabled)
+		self.cfgTurnServer = tk.StringVar(value = self.cfg.natConfig.turnServer)
+		self.cfgTurnConnType = tk.IntVar(value = self.cfg.natConfig.turnConnType)
+		self.cfgTurnUser = tk.StringVar(value = self.cfg.natConfig.turnUserName)
+		self.cfgTurnPasswd = tk.StringVar(value = self.cfg.natConfig.turnPassword)
+		
+		# Build the tab page
+		frm = ttk.Frame(self.frm)
+		frm.columnconfigure(0, weight=1)
+		frm.columnconfigure(1, weight=2)
+		row = 0
+		ttk.Label(frm, text='SIP STUN Usage:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Radiobutton(frm, text='Default', value=pj.PJSUA_STUN_USE_DEFAULT, variable=self.cfgSipUseStun).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Disable', value=pj.PJSUA_STUN_USE_DISABLED, variable=self.cfgSipUseStun).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='Media STUN Usage:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Radiobutton(frm, text='Default', value=pj.PJSUA_STUN_USE_DEFAULT, variable=self.cfgMediaUseStun).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='Disable', value=pj.PJSUA_STUN_USE_DISABLED, variable=self.cfgMediaUseStun).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='ICE:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Checkbutton(frm, text='Enable', variable=self.cfgIceEnabled).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Checkbutton(frm, text='Use aggresive nomination', variable=self.cfgIceAggressive).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Checkbutton(frm, text='Always re-INVITE after negotiation', variable=self.cfgAlwaysUpdate).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Checkbutton(frm, text='Disable host candidates', variable=self.cfgIceNoHostCands).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='TURN:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Checkbutton(frm, text='Enable', variable=self.cfgTurnEnabled).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='TURN server:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Entry(frm, textvariable=self.cfgTurnServer, width=20).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='host[:port]').grid(row=row, column=1, sticky=tk.E, pady=6)
+		row += 1
+		ttk.Label(frm, text='TURN connection:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Radiobutton(frm, text='UDP', value=pj.PJ_TURN_TP_UDP, variable=self.cfgTurnConnType).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Radiobutton(frm, text='TCP', value=pj.PJ_TURN_TP_TCP, variable=self.cfgTurnConnType).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='TURN username:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Entry(frm, textvariable=self.cfgTurnUser, width=16).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='TURN password:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Entry(frm, textvariable=self.cfgTurnPasswd, show='*', width=16).grid(row=row, column=1, sticky=tk.W, padx=6)
+
+		self.wTab.add(frm, text='NAT settings')
+		
+	def onOk(self):
+		# Check basic settings
+		errors = "";
+		if not self.cfgAccId.get():
+			errors += "Account ID is required\n"
+		if self.cfgAccId.get():
+			if not endpoint.validateSipUri(self.cfgAccId.get()):
+				errors += "Invalid SIP ID URI: '%s'\n" % (self.cfgAccId.get())
+		if self.cfgRegistrar.get():
+			if not endpoint.validateSipUri(self.cfgRegistrar.get()):
+				errors += "Invalid SIP registrar URI: '%s'\n" % (self.cfgRegistrar.get())
+		if self.cfgProxy.get():
+			if not endpoint.validateSipUri(self.cfgProxy.get()):
+				errors += "Invalid SIP proxy URI: '%s'\n" % (self.cfgProxy.get())
+		if self.cfgTurnEnabled.get():
+			if not self.cfgTurnServer.get():
+				errors += "TURN server is required\n"
+		if errors:
+			msgbox.showerror("Error detected:", errors)
+			return
+		
+		# Basic settings
+		self.cfg.priority = self.cfgPriority.get()
+		self.cfg.idUri = self.cfgAccId.get()
+		self.cfg.regConfig.registrarUri = self.cfgRegistrar.get()
+		self.cfg.regConfig.registerOnAdd = self.cfgRegisterOnAdd.get()
+		while len(self.cfg.sipConfig.authCreds):
+			self.cfg.sipConfig.authCreds.pop()
+		if self.cfgUsername.get():
+			cred = pj.AuthCredInfo()
+			cred.scheme = "digest"
+			cred.realm = "*"
+			cred.username = self.cfgUsername.get()
+			cred.data = self.cfgPassword.get()
+			self.cfg.sipConfig.authCreds.append(cred)
+		while len(self.cfg.sipConfig.proxies):
+			self.cfg.sipConfig.proxies.pop()
+		if self.cfgProxy.get():
+			self.cfg.sipConfig.proxies.append(self.cfgProxy.get())
+
+		# SIP features
+		self.cfg.callConfig.prackUse		= self.cfgPrackUse.get() 
+		self.cfg.callConfig.timerUse		= self.cfgTimerUse.get()
+		self.cfg.callConfig.timerSessExpiresSec	= self.cfgTimerExpires.get() 
+		self.cfg.presConfig.publishEnabled	= self.cfgPublish.get() 
+		self.cfg.mwiConfig.enabled		= self.cfgMwiEnabled.get() 
+		self.cfg.natConfig.contactRewriteUse	= 1 if self.cfgEnableContactRewrite.get() else 0
+		self.cfg.natConfig.viaRewriteUse 	= 1 if self.cfgEnableViaRewrite.get() else 0
+		self.cfg.natConfig.sdpNatRewriteUse	= 1 if self.cfgEnableSdpRewrite.get() else 0
+		self.cfg.natConfig.sipOutboundUse	= 1 if self.cfgEnableSipOutbound.get() else 0
+		self.cfg.natConfig.udpKaIntervalSec	= self.cfgKaInterval.get()
+
+		# Media
+		self.cfg.mediaConfig.transportConfig.port	= self.cfgMedPort.get()
+		self.cfg.mediaConfig.transportConfig.portRange	= self.cfgMedPortRange.get()
+		self.cfg.mediaConfig.lockCodecEnabled		= self.cfgMedLockCodec.get()
+		self.cfg.mediaConfig.srtpUse			= self.cfgMedSrtp.get()
+		self.cfg.mediaConfig.srtpSecureSignaling	= self.cfgMedSrtpSecure.get()
+		self.cfg.mediaConfig.ipv6Use			= pj.PJSUA_IPV6_ENABLED if self.cfgMedIpv6.get() else pj.PJSUA_IPV6_DISABLED
+		
+		# NAT
+		self.cfg.natConfig.sipStunUse		= self.cfgSipUseStun.get()
+		self.cfg.natConfig.mediaStunUse		= self.cfgMediaUseStun.get()
+		self.cfg.natConfig.iceEnabled		= self.cfgIceEnabled.get()
+		self.cfg.natConfig.iceAggressiveNomination = self.cfgIceAggressive .get()
+		self.cfg.natConfig.iceAlwaysUpdate	= self.cfgAlwaysUpdate.get()
+		self.cfg.natConfig.iceMaxHostCands	= 0 if self.cfgIceNoHostCands.get() else -1 
+		self.cfg.natConfig.turnEnabled		= self.cfgTurnEnabled.get()
+		self.cfg.natConfig.turnServer		= self.cfgTurnServer.get()
+		self.cfg.natConfig.turnConnType		= self.cfgTurnConnType.get()
+		self.cfg.natConfig.turnUserName		= self.cfgTurnUser.get()
+		self.cfg.natConfig.turnPasswordType	= 0
+		self.cfg.natConfig.turnPassword		= self.cfgTurnPasswd.get()
+		
+		self.isOk = True
+		self.destroy()
+		
+	def onCancel(self):
+		self.destroy()
+
+
+if __name__ == '__main__':
+	application.main()
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/application.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/application.py
new file mode 100644
index 0000000..8be50ed
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/application.py
@@ -0,0 +1,510 @@
+# $Id: application.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+	from tkinter import messagebox as msgbox
+else:
+	import Tkinter as tk
+	import tkMessageBox as msgbox
+	import ttk
+
+import pjsua2 as pj
+import log
+import accountsetting
+import account
+import buddy
+import endpoint
+import settings
+
+import os
+import traceback
+
+	
+class Application(ttk.Frame):
+	"""
+	The Application main frame.
+	"""
+	def __init__(self):
+		ttk.Frame.__init__(self, name='application', width=300, height=500)
+		self.pack(expand='yes', fill='both')
+		self.master.title('pjsua2 Demo')
+		self.master.geometry('500x500+100+100')
+		
+		# Logger
+		self.logger = log.Logger()
+		
+		# Accounts
+		self.accList = []
+		
+		# GUI variables
+		self.showLogWindow = tk.IntVar(value=0)
+		self.quitting = False 
+		
+		# Construct GUI
+		self._createWidgets()
+		
+		# Log window
+		self.logWindow = log.LogWindow(self)
+		self._onMenuShowHideLogWindow()
+		
+		# Instantiate endpoint
+		self.ep = endpoint.Endpoint()
+		self.ep.libCreate()
+		
+		# Default config
+		self.appConfig = settings.AppConfig()
+		self.appConfig.epConfig.uaConfig.threadCnt = 0;
+		self.appConfig.epConfig.uaConfig.mainThreadOnly = True
+		self.appConfig.epConfig.logConfig.writer = self.logger
+		self.appConfig.epConfig.logConfig.filename = "pygui.log"
+		self.appConfig.epConfig.logConfig.fileFlags = pj.PJ_O_APPEND
+		self.appConfig.epConfig.logConfig.level = 5
+		self.appConfig.epConfig.logConfig.consoleLevel = 5
+		
+	def saveConfig(self, filename='pygui.js'):
+		# Save disabled accounts since they are not listed in self.accList
+		disabled_accs = [ac for ac in self.appConfig.accounts if not ac.enabled]
+		self.appConfig.accounts = []
+		
+		# Get account configs from active accounts
+		for acc in self.accList:
+			acfg = settings.AccConfig()
+			acfg.enabled = True
+			acfg.config = acc.cfg
+			for bud in acc.buddyList:
+				acfg.buddyConfigs.append(bud.cfg)
+			self.appConfig.accounts.append(acfg)
+		
+		# Put back disabled accounts
+		self.appConfig.accounts.extend(disabled_accs)
+		# Save
+		self.appConfig.saveFile(filename)
+	
+	def start(self, cfg_file='pygui.js'):
+		# Load config
+		if cfg_file and os.path.exists(cfg_file):
+			self.appConfig.loadFile(cfg_file)
+
+		self.appConfig.epConfig.uaConfig.threadCnt = 0;
+		self.appConfig.epConfig.uaConfig.mainThreadOnly = True
+		self.appConfig.epConfig.logConfig.writer = self.logger
+		self.appConfig.epConfig.logConfig.level = 5
+		self.appConfig.epConfig.logConfig.consoleLevel = 5
+				
+		# Initialize library
+		self.appConfig.epConfig.uaConfig.userAgent = "pygui-" + self.ep.libVersion().full;
+		self.ep.libInit(self.appConfig.epConfig)
+		self.master.title('pjsua2 Demo version ' + self.ep.libVersion().full)
+		
+		# Create transports
+		if self.appConfig.udp.enabled:
+			self.ep.transportCreate(self.appConfig.udp.type, self.appConfig.udp.config)
+		if self.appConfig.tcp.enabled:
+			self.ep.transportCreate(self.appConfig.tcp.type, self.appConfig.tcp.config)
+		if self.appConfig.tls.enabled:
+			self.ep.transportCreate(self.appConfig.tls.type, self.appConfig.tls.config)
+			
+		# Add accounts
+		for cfg in self.appConfig.accounts:
+			if cfg.enabled:
+				self._createAcc(cfg.config)
+				acc = self.accList[-1]
+				for buddy_cfg in cfg.buddyConfigs:
+					self._createBuddy(acc, buddy_cfg)
+				
+		# Start library
+		self.ep.libStart()
+		
+		# Start polling
+		self._onTimer()
+
+	def updateAccount(self, acc):
+		if acc.deleting:
+			return	# ignore
+		iid = str(acc.randId)
+		text = acc.cfg.idUri
+		status = acc.statusText()
+		
+		values = (status,)
+		if self.tv.exists(iid):
+			self.tv.item(iid, text=text, values=values)
+		else:
+			self.tv.insert('', 'end',  iid, open=True, text=text, values=values)
+		
+	def updateBuddy(self, bud):
+		iid = 'buddy' + str(bud.randId)
+		text = bud.cfg.uri
+		status = bud.statusText()
+		
+		values = (status,)
+		if self.tv.exists(iid):
+			self.tv.item(iid, text=text, values=values)
+		else:
+			self.tv.insert(str(bud.account.randId), 'end',  iid, open=True, text=text, values=values)
+		
+	def _createAcc(self, acc_cfg):
+		acc = account.Account(self)
+		acc.cfg = acc_cfg
+		self.accList.append(acc)
+		self.updateAccount(acc)
+		acc.create(acc.cfg)
+		acc.cfgChanged = False
+		self.updateAccount(acc)
+				
+	def _createBuddy(self, acc, buddy_cfg):
+		bud = buddy.Buddy(self)
+		bud.cfg = buddy_cfg
+		bud.account = acc
+		bud.create(acc, bud.cfg)
+		self.updateBuddy(bud)
+		acc.buddyList.append(bud)
+
+	def _createWidgets(self):
+		self._createAppMenu()
+		
+		# Main pane, a Treeview
+		self.tv = ttk.Treeview(self, columns=('Status'), show='tree')
+		self.tv.pack(side='top', fill='both', expand='yes', padx=5, pady=5)
+
+		self._createContextMenu()
+		
+		# Handle close event
+		self.master.protocol("WM_DELETE_WINDOW", self._onClose)
+	
+	def _createAppMenu(self):
+		# Main menu bar
+		top = self.winfo_toplevel()
+		self.menubar = tk.Menu()
+		top.configure(menu=self.menubar)
+		
+		# File menu
+		file_menu = tk.Menu(self.menubar, tearoff=False)
+		self.menubar.add_cascade(label="File", menu=file_menu)
+		file_menu.add_command(label="Add account..", command=self._onMenuAddAccount)
+		file_menu.add_checkbutton(label="Show/hide log window", command=self._onMenuShowHideLogWindow, variable=self.showLogWindow)
+		file_menu.add_separator()
+		file_menu.add_command(label="Settings...", command=self._onMenuSettings)
+		file_menu.add_command(label="Save Settings", command=self._onMenuSaveSettings)
+		file_menu.add_separator()
+		file_menu.add_command(label="Quit", command=self._onMenuQuit)
+
+		# Window menu
+		self.window_menu = tk.Menu(self.menubar, tearoff=False)
+		self.menubar.add_cascade(label="Window", menu=self.window_menu)
+		
+		# Help menu
+		help_menu = tk.Menu(self.menubar, tearoff=False)
+		self.menubar.add_cascade(label="Help", menu=help_menu)
+		help_menu.add_command(label="About", underline=2, command=self._onMenuAbout)
+	
+	def _showChatWindow(self, chat_inst):
+		chat_inst.showWindow()
+		
+	def updateWindowMenu(self):
+		# Chat windows
+		self.window_menu.delete(0, tk.END)
+		for acc in self.accList:
+			for c in acc.chatList:
+				cmd = lambda arg=c: self._showChatWindow(arg)
+				self.window_menu.add_command(label=c.title, command=cmd)
+		
+	def _createContextMenu(self):
+		top = self.winfo_toplevel()
+
+		# Create Account context menu
+		self.accMenu = tk.Menu(top, tearoff=False)
+		# Labels, must match with _onAccContextMenu()
+		labels = ['Unregister', 'Reregister', 'Add buddy...', '-',
+			  'Online', 'Invisible', 'Away', 'Busy', '-',
+			  'Settings...', '-',
+			  'Delete...']
+		for label in labels:
+			if label=='-':
+				self.accMenu.add_separator()
+			else:
+				cmd = lambda arg=label: self._onAccContextMenu(arg)
+				self.accMenu.add_command(label=label, command=cmd)
+		
+		# Create Buddy context menu
+		# Labels, must match with _onBuddyContextMenu()
+		self.buddyMenu = tk.Menu(top, tearoff=False)
+		labels = ['Audio call', 'Send instant message', '-',
+			  'Subscribe', 'Unsubscribe', '-',
+			  'Settings...', '-',
+			  'Delete...']
+		
+		for label in labels:
+			if label=='-':
+				self.buddyMenu.add_separator()
+			else:
+				cmd = lambda arg=label: self._onBuddyContextMenu(arg)
+				self.buddyMenu.add_command(label=label, command=cmd)
+		
+		if (top.tk.call('tk', 'windowingsystem')=='aqua'):
+			self.tv.bind('<2>', self._onTvRightClick)
+			self.tv.bind('<Control-1>', self._onTvRightClick)
+		else:
+			self.tv.bind('<3>', self._onTvRightClick)
+		self.tv.bind('<Double-Button-1>', self._onTvDoubleClick)
+
+	def _getSelectedAccount(self):
+		items = self.tv.selection()
+		if not items:
+			return None
+		try:
+			iid = int(items[0])
+		except:
+			return None
+		accs = [acc for acc in self.accList if acc.randId==iid]
+		if not accs:
+			return None
+		return accs[0]
+	
+	def _getSelectedBuddy(self):
+		items = self.tv.selection()
+		if not items:
+			return None
+		try:
+			iid = int(items[0][5:])
+			iid_parent = int(self.tv.parent(items[0]))
+		except:
+			return None
+			
+		accs = [acc for acc in self.accList if acc.randId==iid_parent]
+		if not accs:
+			return None
+			
+		buds = [b for b in accs[0].buddyList if b.randId==iid]
+		if not buds:
+			return None
+			
+		return buds[0]
+	
+	def _onTvRightClick(self, event):
+		iid = self.tv.identify_row(event.y)
+		#iid = self.tv.identify('item', event.x, event.y)
+		if iid:
+			self.tv.selection_set( (iid,) )
+			acc = self._getSelectedAccount()
+			if acc:
+				self.accMenu.post(event.x_root, event.y_root)
+			else:
+				# A buddy is selected
+				self.buddyMenu.post(event.x_root, event.y_root)
+	
+	def _onTvDoubleClick(self, event):
+		iid = self.tv.identify_row(event.y)
+		if iid:
+			self.tv.selection_set( (iid,) )
+			acc = self._getSelectedAccount()
+			if acc:
+				self.cfgChanged = False
+				dlg = accountsetting.Dialog(self.master, acc.cfg)
+				if dlg.doModal():
+					self.updateAccount(acc)
+					acc.modify(acc.cfg)
+			else:
+				bud = self._getSelectedBuddy()
+				acc = bud.account
+				chat = acc.findChat(bud.cfg.uri)
+				if not chat:
+					chat = acc.newChat(bud.cfg.uri)
+				chat.showWindow()
+	
+	def _onAccContextMenu(self, label):
+		acc = self._getSelectedAccount()
+		if not acc:
+			return
+		
+		if label=='Unregister':
+			acc.setRegistration(False)
+		elif label=='Reregister':
+			acc.setRegistration(True)
+		elif label=='Online':
+			ps = pj.PresenceStatus()
+			ps.status = pj.PJSUA_BUDDY_STATUS_ONLINE
+			acc.setOnlineStatus(ps)
+		elif label=='Invisible':
+			ps = pj.PresenceStatus()
+			ps.status = pj.PJSUA_BUDDY_STATUS_OFFLINE
+			acc.setOnlineStatus(ps)
+		elif label=='Away':
+			ps = pj.PresenceStatus()
+			ps.status = pj.PJSUA_BUDDY_STATUS_ONLINE
+			ps.activity = pj.PJRPID_ACTIVITY_AWAY
+			ps.note = "Away"
+			acc.setOnlineStatus(ps)
+		elif label=='Busy':
+			ps = pj.PresenceStatus()
+			ps.status = pj.PJSUA_BUDDY_STATUS_ONLINE
+			ps.activity = pj.PJRPID_ACTIVITY_BUSY
+			ps.note = "Busy"
+			acc.setOnlineStatus(ps)
+		elif label=='Settings...':
+			self.cfgChanged = False
+			dlg = accountsetting.Dialog(self.master, acc.cfg)
+			if dlg.doModal():
+				self.updateAccount(acc)
+				acc.modify(acc.cfg)
+		elif label=='Delete...':
+			msg = "Do you really want to delete account '%s'?" % acc.cfg.idUri
+			if msgbox.askquestion('Delete account?', msg, default=msgbox.NO) != u'yes':
+				return
+			iid = str(acc.randId)
+			self.accList.remove(acc)
+			acc.setRegistration(False)
+			acc.deleting = True
+			del acc
+			self.tv.delete( (iid,) )
+		elif label=='Add buddy...':
+			cfg = pj.BuddyConfig()
+			dlg = buddy.SettingDialog(self.master, cfg)
+			if dlg.doModal():
+				self._createBuddy(acc, cfg)
+		else:
+			assert not ("Unknown menu " + label)
+	
+	def _onBuddyContextMenu(self, label):
+		bud = self._getSelectedBuddy()
+		if not bud:
+			return
+		acc = bud.account
+			
+		if label=='Audio call':
+			chat = acc.findChat(bud.cfg.uri)
+			if not chat: chat = acc.newChat(bud.cfg.uri)
+			chat.showWindow()
+			chat.startCall()
+		elif label=='Send instant message':
+			chat = acc.findChat(bud.cfg.uri)
+			if not chat: chat = acc.newChat(bud.cfg.uri)
+			chat.showWindow(True)
+		elif label=='Subscribe':
+			bud.subscribePresence(True)
+		elif label=='Unsubscribe':
+			bud.subscribePresence(False)
+		elif label=='Settings...':
+			subs = bud.cfg.subscribe
+			uri  = bud.cfg.uri
+			dlg = buddy.SettingDialog(self.master, bud.cfg)
+			if dlg.doModal():
+				self.updateBuddy(bud)
+				# URI updated?
+				if uri != bud.cfg.uri:
+					cfg = bud.cfg
+					# del old
+					iid = 'buddy' + str(bud.randId)
+					acc.buddyList.remove(bud)
+					del bud
+					self.tv.delete( (iid,) )
+					# add new
+					self._createBuddy(acc, cfg)
+				# presence subscribe setting updated
+				elif subs != bud.cfg.subscribe:
+					bud.subscribePresence(bud.cfg.subscribe)
+		elif label=='Delete...':
+			msg = "Do you really want to delete buddy '%s'?" % bud.cfg.uri
+			if msgbox.askquestion('Delete buddy?', msg, default=msgbox.NO) != u'yes':
+				return
+			iid = 'buddy' + str(bud.randId)
+			acc.buddyList.remove(bud)
+			del bud
+			self.tv.delete( (iid,) )
+		else:
+			assert not ("Unknown menu " + label)
+			
+	def _onTimer(self):
+		if not self.quitting:
+			self.ep.libHandleEvents(10)
+			if not self.quitting:
+				self.master.after(50, self._onTimer)
+			
+	def _onClose(self):
+		self.saveConfig()
+		self.quitting = True
+		self.ep.libDestroy()
+		self.ep = None
+		self.update()
+		self.quit()
+		
+	def _onMenuAddAccount(self):
+		cfg = pj.AccountConfig()
+		dlg = accountsetting.Dialog(self.master, cfg)
+		if dlg.doModal():
+			self._createAcc(cfg)
+			
+	def _onMenuShowHideLogWindow(self):
+		if self.showLogWindow.get():
+			self.logWindow.deiconify()
+		else:
+			self.logWindow.withdraw()
+	
+	def _onMenuSettings(self):
+		dlg = settings.Dialog(self, self.appConfig)
+		if dlg.doModal():
+			msgbox.showinfo(self.master.title(), 'You need to restart for new settings to take effect')
+	
+	def _onMenuSaveSettings(self):
+		self.saveConfig()
+		
+	def _onMenuQuit(self):
+		self._onClose()
+
+	def _onMenuAbout(self):
+		msgbox.showinfo(self.master.title(), 'About')
+		
+
+class ExceptionCatcher:
+	"""Custom Tk exception catcher, mainly to display more information 
+	   from pj.Error exception
+	""" 
+	def __init__(self, func, subst, widget):
+		self.func = func 
+		self.subst = subst
+		self.widget = widget
+	def __call__(self, *args):
+		try:
+			if self.subst:
+				args = apply(self.subst, args)
+			return apply(self.func, args)
+		except pj.Error, error:
+			print 'Exception:'
+			print '  ', error.info()
+			print 'Traceback:'
+			print traceback.print_stack()
+			log.writeLog2(1, 'Exception: ' + error.info() + '\n')
+		except Exception, error:
+			print 'Exception:'
+			print '  ', str(error)
+			print 'Traceback:'
+			print traceback.print_stack()
+			log.writeLog2(1, 'Exception: ' + str(error) + '\n')
+
+def main():
+	#tk.CallWrapper = ExceptionCatcher
+	app = Application()
+	app.start()
+	app.mainloop()
+		
+if __name__ == '__main__':
+	main()
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/buddy.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/buddy.py
new file mode 100644
index 0000000..6cf7477
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/buddy.py
@@ -0,0 +1,152 @@
+# $Id: buddy.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+	from tkinter import messagebox as msgbox
+else:
+	import Tkinter as tk
+	import tkMessageBox as msgbox
+	import ttk
+
+import random
+import pjsua2 as pj
+import endpoint
+import application
+
+# Buddy class
+class Buddy(pj.Buddy):
+	"""
+	High level Python Buddy object, derived from pjsua2's Buddy object.
+	"""
+	def __init__(self, app):
+		pj.Buddy.__init__(self)
+		self.app = app
+		self.randId = random.randint(1, 9999)
+		self.cfg = None
+		self.account = None
+
+	def statusText(self):
+		bi = self.getInfo()
+		status = ''
+		if bi.subState == pj.PJSIP_EVSUB_STATE_ACTIVE:
+			if bi.presStatus.status == pj.PJSUA_BUDDY_STATUS_ONLINE:
+				status = bi.presStatus.statusText
+				if not status:
+					status = 'Online'
+			elif bi.presStatus.status == pj.PJSUA_BUDDY_STATUS_OFFLINE:
+				status = 'Offline'
+			else:
+				status = 'Unknown'
+		return status
+	
+	def onBuddyState(self):
+		self.app.updateBuddy(self)
+
+class SettingDialog(tk.Toplevel):
+	"""
+	This implements buddy settings dialog to manipulate buddy settings.
+	"""
+	def __init__(self, parent, cfg):
+		tk.Toplevel.__init__(self, parent)
+		self.transient(parent)
+		self.parent = parent
+		self.geometry("+100+100")
+		self.title('Buddy settings')
+		
+		self.frm = ttk.Frame(self)
+		self.frm.pack(expand='yes', fill='both')
+		
+		self.isOk = False
+		self.cfg = cfg
+		
+		self.createWidgets()
+	
+	def doModal(self):
+		if self.parent:
+			self.parent.wait_window(self)
+		else:
+			self.wait_window(self)
+		return self.isOk
+		
+	def createWidgets(self):
+		# The notebook
+		self.frm.rowconfigure(0, weight=1)
+		self.frm.rowconfigure(1, weight=0)
+		self.frm.columnconfigure(0, weight=1)
+		self.frm.columnconfigure(1, weight=1)
+		self.wTab = ttk.Notebook(self.frm)
+		self.wTab.grid(column=0, row=0, columnspan=2, padx=5, pady=5, sticky=tk.N+tk.S+tk.W+tk.E)
+		
+		# Main buttons
+		btnOk = ttk.Button(self.frm, text='Ok', command=self.onOk)
+		btnOk.grid(column=0, row=1, sticky=tk.E, padx=20, pady=10)
+		btnCancel = ttk.Button(self.frm, text='Cancel', command=self.onCancel)
+		btnCancel.grid(column=1, row=1, sticky=tk.W, padx=20, pady=10)
+		
+		# Tabs
+		self.createBasicTab()
+		
+	def createBasicTab(self):
+		# Prepare the variables to set/receive values from GUI
+		self.cfgUri = tk.StringVar()
+		self.cfgUri.set( self.cfg.uri )
+		self.cfgSubscribe = tk.IntVar()
+		self.cfgSubscribe.set(self.cfg.subscribe)
+		
+		# Build the tab page
+		frm = ttk.Frame(self.frm)
+		frm.columnconfigure(0, weight=1)
+		frm.columnconfigure(1, weight=2)
+		row = 0
+		ttk.Label(frm, text='URI:').grid(row=row, column=0, sticky=tk.E, pady=2)
+		ttk.Entry(frm, textvariable=self.cfgUri, width=40).grid(row=row, column=1, sticky=tk.W+tk.E, padx=6)
+		row += 1
+		ttk.Checkbutton(frm, text='Subscribe presence', variable=self.cfgSubscribe).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+
+		self.wTab.add(frm, text='Basic Settings')
+		
+	
+	def onOk(self):
+		# Check basic settings
+		errors = "";
+		if self.cfgUri.get():
+			if not endpoint.validateSipUri(self.cfgUri.get()):
+				errors += "Invalid Buddy URI: '%s'\n" % (self.cfgUri.get())
+				
+		if errors:
+			msgbox.showerror("Error detected:", errors)
+			return
+		
+		# Basic settings
+		self.cfg.uri = self.cfgUri.get()
+		self.cfg.subscribe = self.cfgSubscribe.get()
+		
+		self.isOk = True
+		self.destroy()
+		
+	def onCancel(self):
+		self.destroy()
+
+
+if __name__ == '__main__':
+	application.main()
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/call.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/call.py
new file mode 100644
index 0000000..b467fed
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/call.py
@@ -0,0 +1,104 @@
+# $Id: call.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+	from tkinter import messagebox as msgbox
+else:
+	import Tkinter as tk
+	import tkMessageBox as msgbox
+	import ttk
+
+import random
+import pjsua2 as pj
+import application
+import endpoint as ep
+
+# Call class
+class Call(pj.Call):
+	"""
+	High level Python Call object, derived from pjsua2's Call object.
+	"""
+	def __init__(self, acc, peer_uri='', chat=None, call_id = pj.PJSUA_INVALID_ID):
+		pj.Call.__init__(self, acc, call_id)
+                self.acc = acc
+		self.peerUri = peer_uri
+		self.chat = chat
+		self.connected = False
+		self.onhold = False
+
+	def onCallState(self, prm):
+		ci = self.getInfo()
+		self.connected = ci.state == pj.PJSIP_INV_STATE_CONFIRMED			
+		if self.chat:
+			self.chat.updateCallState(self, ci)
+			
+	def onCallMediaState(self, prm):
+		ci = self.getInfo()
+		for mi in ci.media:
+			if mi.type == pj.PJMEDIA_TYPE_AUDIO and \
+			  (mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE or \
+			   mi.status == pj.PJSUA_CALL_MEDIA_REMOTE_HOLD):
+				m = self.getMedia(mi.index)
+				am = pj.AudioMedia.typecastFromMedia(m)
+				# connect ports
+				ep.Endpoint.instance.audDevManager().getCaptureDevMedia().startTransmit(am)
+				am.startTransmit(ep.Endpoint.instance.audDevManager().getPlaybackDevMedia())
+
+				if mi.status == pj.PJSUA_CALL_MEDIA_REMOTE_HOLD and not self.onhold:
+					self.chat.addMessage(None, "'%s' sets call onhold" % (self.peerUri))
+					self.onhold = True
+				elif mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE and self.onhold:
+					self.chat.addMessage(None, "'%s' sets call active" % (self.peerUri))
+					self.onhold = False
+			
+	def onInstantMessage(self, prm):
+		# chat instance should have been initalized
+		if not self.chat: return
+			
+		self.chat.addMessage(self.peerUri, prm.msgBody)
+		self.chat.showWindow()
+			
+	def onInstantMessageStatus(self, prm):
+		if prm.code/100 == 2: return
+		# chat instance should have been initalized
+		if not self.chat: return
+		
+		self.chat.addMessage(None, "Failed sending message to '%s' (%d): %s" % (self.peerUri, prm.code, prm.reason))
+		
+	def onTypingIndication(self, prm):
+		# chat instance should have been initalized
+		if not self.chat: return
+		
+		self.chat.setTypingIndication(self.peerUri, prm.isTyping)
+	
+	def onDtmfDigit(self, prm):
+		#msgbox.showinfo("pygui", 'Got DTMF:' + prm.digit)
+		pass
+		
+	def onCallMediaTransportState(self, prm):
+		#msgbox.showinfo("pygui", "Media transport state")
+		pass
+		
+		
+if __name__ == '__main__':
+	application.main()
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/chat.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/chat.py
new file mode 100644
index 0000000..9d2d2e2
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/chat.py
@@ -0,0 +1,489 @@
+# $Id: chat.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+else:
+	import Tkinter as tk
+	import ttk
+
+import buddy
+import call
+import chatgui as gui
+import endpoint as ep
+import pjsua2 as pj
+import re
+
+SipUriRegex = re.compile('(sip|sips):([^:;>\@]*)@?([^:;>]*):?([^:;>]*)')
+ConfIdx = 1
+
+# Simple SIP uri parser, input URI must have been validated
+def ParseSipUri(sip_uri_str):
+	m = SipUriRegex.search(sip_uri_str)
+	if not m:
+		assert(0)
+		return None
+	
+	scheme = m.group(1)
+	user = m.group(2)
+	host = m.group(3)
+	port = m.group(4)
+	if host == '':
+		host = user
+		user = ''
+		
+	return SipUri(scheme.lower(), user, host.lower(), port)
+	
+class SipUri:
+	def __init__(self, scheme, user, host, port):
+		self.scheme = scheme
+		self.user = user
+		self.host = host
+		self.port = port
+		
+	def __cmp__(self, sip_uri):
+		if self.scheme == sip_uri.scheme and self.user == sip_uri.user and self.host == sip_uri.host:
+			# don't check port, at least for now
+			return 0
+		return -1
+	
+	def __str__(self):
+		s = self.scheme + ':'
+		if self.user: s += self.user + '@'
+		s += self.host
+		if self.port: s+= ':' + self.port
+		return s
+	
+class Chat(gui.ChatObserver):
+	def __init__(self, app, acc, uri, call_inst=None):
+		self._app = app
+		self._acc = acc
+		self.title = ''
+		
+		global ConfIdx
+		self.confIdx = ConfIdx
+		ConfIdx += 1
+		
+		# each participant call/buddy instances are stored in call list
+		# and buddy list with same index as in particpant list
+		self._participantList = []	# list of SipUri
+		self._callList = []		# list of Call
+		self._buddyList = []		# list of Buddy
+		
+		self._gui = gui.ChatFrame(self)
+		self.addParticipant(uri, call_inst)
+	
+	def _updateGui(self):
+		if self.isPrivate():
+			self.title = str(self._participantList[0])
+		else:
+			self.title = 'Conference #%d (%d participants)' % (self.confIdx, len(self._participantList))
+		self._gui.title(self.title)
+		self._app.updateWindowMenu()
+		
+	def _getCallFromUriStr(self, uri_str, op = ''):
+		uri = ParseSipUri(uri_str)
+		if uri not in self._participantList:
+			print "=== %s cannot find participant with URI '%s'" % (op, uri_str)
+			return None
+		idx = self._participantList.index(uri)
+		if idx < len(self._callList):
+			return self._callList[idx]
+		return None
+	
+	def _getActiveMediaIdx(self, thecall):
+		ci = thecall.getInfo()
+		for mi in ci.media:
+			if mi.type == pj.PJMEDIA_TYPE_AUDIO and \
+			  (mi.status != pj.PJSUA_CALL_MEDIA_NONE and \
+			   mi.status != pj.PJSUA_CALL_MEDIA_ERROR):
+				return mi.index
+		return -1
+		
+	def _getAudioMediaFromUriStr(self, uri_str):
+		c = self._getCallFromUriStr(uri_str)
+		if not c: return None
+
+		idx = self._getActiveMediaIdx(c)
+		if idx < 0: return None
+
+		m = c.getMedia(idx)
+		am = pj.AudioMedia.typecastFromMedia(m)
+		return am
+		
+	def _sendTypingIndication(self, is_typing, sender_uri_str=''):
+		sender_uri = ParseSipUri(sender_uri_str) if sender_uri_str else None
+		type_ind_param = pj.SendTypingIndicationParam()
+		type_ind_param.isTyping = is_typing
+		for idx, p in enumerate(self._participantList):
+			# don't echo back to the original sender
+			if sender_uri and p == sender_uri:
+				continue
+				
+			# send via call, if any, or buddy
+			sender = None
+			if self._callList[idx] and self._callList[idx].connected:
+				sender = self._callList[idx]
+			else:
+				sender = self._buddyList[idx]
+			assert(sender)
+				
+			try:
+				sender.sendTypingIndication(type_ind_param)
+			except:
+				pass
+
+	def _sendInstantMessage(self, msg, sender_uri_str=''):
+		sender_uri = ParseSipUri(sender_uri_str) if sender_uri_str else None
+		send_im_param = pj.SendInstantMessageParam()
+		send_im_param.content = str(msg)
+		for idx, p in enumerate(self._participantList):
+			# don't echo back to the original sender
+			if sender_uri and p == sender_uri:
+				continue
+				
+			# send via call, if any, or buddy
+			sender = None
+			if self._callList[idx] and self._callList[idx].connected:
+				sender = self._callList[idx]
+			else:
+				sender = self._buddyList[idx]
+			assert(sender)
+			
+			try:
+				sender.sendInstantMessage(send_im_param)
+			except:
+				# error will be handled via Account::onInstantMessageStatus()
+				pass
+
+	def isPrivate(self):
+		return len(self._participantList) <= 1
+		
+	def isUriParticipant(self, uri):
+		return uri in self._participantList
+		
+	def registerCall(self, uri_str, call_inst):
+		uri = ParseSipUri(uri_str)
+		try:
+			idx = self._participantList.index(uri)
+			bud = self._buddyList[idx]
+			self._callList[idx] = call_inst
+			call_inst.chat = self
+			call_inst.peerUri = bud.cfg.uri
+		except:
+			assert(0) # idx must be found!
+		
+	def showWindow(self, show_text_chat = False):
+		self._gui.bringToFront()
+		if show_text_chat:
+			self._gui.textShowHide(True)
+		
+	def addParticipant(self, uri, call_inst=None):
+		# avoid duplication
+		if self.isUriParticipant(uri): return
+		
+		uri_str = str(uri)
+		
+		# find buddy, create one if not found (e.g: for IM/typing ind),
+		# it is a temporary one and not really registered to acc
+		bud = None
+		try:
+			bud = self._acc.findBuddy(uri_str)
+		except:
+			bud = buddy.Buddy(None)
+			bud_cfg = pj.BuddyConfig()
+			bud_cfg.uri = uri_str
+			bud_cfg.subscribe = False
+			bud.create(self._acc, bud_cfg)
+			bud.cfg = bud_cfg
+			bud.account = self._acc
+			
+		# update URI from buddy URI
+		uri = ParseSipUri(bud.cfg.uri)
+		
+		# add it
+		self._participantList.append(uri)
+		self._callList.append(call_inst)
+		self._buddyList.append(bud)
+		self._gui.addParticipant(str(uri))
+		self._updateGui()
+	
+	def kickParticipant(self, uri):
+		if (not uri) or (uri not in self._participantList):
+			assert(0)
+			return
+		
+		idx = self._participantList.index(uri)
+		del self._participantList[idx]
+		del self._callList[idx]
+		del self._buddyList[idx]
+		self._gui.delParticipant(str(uri))
+		
+		if self._participantList:
+			self._updateGui()
+		else:
+			self.onCloseWindow()
+			
+	def addMessage(self, from_uri_str, msg):
+		if from_uri_str:
+			# print message on GUI
+			msg = from_uri_str + ': ' + msg
+			self._gui.textAddMessage(msg)
+			# now relay to all participants
+			self._sendInstantMessage(msg, from_uri_str)
+		else:
+			self._gui.textAddMessage(msg, False)
+			
+	def setTypingIndication(self, from_uri_str, is_typing):
+		# notify GUI
+		self._gui.textSetTypingIndication(from_uri_str, is_typing)
+		# now relay to all participants
+		self._sendTypingIndication(is_typing, from_uri_str)
+		
+	def startCall(self):
+		self._gui.enableAudio()
+		call_param = pj.CallOpParam()
+		call_param.opt.audioCount = 1
+		call_param.opt.videoCount = 0
+		fails = []
+		for idx, p in enumerate(self._participantList):
+			# just skip if call is instantiated
+			if self._callList[idx]:
+				continue
+			
+			uri_str = str(p)
+			c = call.Call(self._acc, uri_str, self)
+			self._callList[idx] = c
+			self._gui.audioUpdateState(uri_str, gui.AudioState.INITIALIZING)
+			
+			try:
+				c.makeCall(uri_str, call_param)
+			except:
+				self._callList[idx] = None
+				self._gui.audioUpdateState(uri_str, gui.AudioState.FAILED)
+				fails.append(p)
+				
+		for p in fails:
+			# kick participants with call failure, but spare the last (avoid zombie chat)
+			if not self.isPrivate():
+				self.kickParticipant(p)
+			
+	def stopCall(self):
+		for idx, p in enumerate(self._participantList):
+			self._gui.audioUpdateState(str(p), gui.AudioState.DISCONNECTED)
+			c = self._callList[idx]
+			if c:
+				c.hangup(pj.CallOpParam())
+
+	def updateCallState(self, thecall, info = None):
+		# info is optional here, just to avoid calling getInfo() twice (in the caller and here)
+		if not info: info = thecall.getInfo()
+		
+		if info.state < pj.PJSIP_INV_STATE_CONFIRMED:
+			self._gui.audioUpdateState(thecall.peerUri, gui.AudioState.INITIALIZING)
+		elif info.state == pj.PJSIP_INV_STATE_CONFIRMED:
+			self._gui.audioUpdateState(thecall.peerUri, gui.AudioState.CONNECTED)
+			med_idx = self._getActiveMediaIdx(thecall)
+			si = thecall.getStreamInfo(med_idx)
+			stats_str = "Audio codec: %s/%s\n..." % (si.codecName, si.codecClockRate)
+			self._gui.audioSetStatsText(thecall.peerUri, stats_str)
+		elif info.state == pj.PJSIP_INV_STATE_DISCONNECTED:
+			if info.lastStatusCode/100 != 2:
+				self._gui.audioUpdateState(thecall.peerUri, gui.AudioState.FAILED)
+			else:
+				self._gui.audioUpdateState(thecall.peerUri, gui.AudioState.DISCONNECTED)
+			
+			# reset entry in the callList
+			try:
+				idx = self._callList.index(thecall)
+				if idx >= 0: self._callList[idx] = None
+			except:
+				pass
+			
+			self.addMessage(None, "Call to '%s' disconnected: %s" % (thecall.peerUri, info.lastReason))
+			
+			# kick the disconnected participant, but the last (avoid zombie chat)
+			if not self.isPrivate():
+				self.kickParticipant(ParseSipUri(thecall.peerUri))
+
+			
+	# ** callbacks from GUI (ChatObserver implementation) **
+	
+	# Text
+	def onSendMessage(self, msg):
+		self._sendInstantMessage(msg)
+
+	def onStartTyping(self):
+		self._sendTypingIndication(True)
+		
+	def onStopTyping(self):
+		self._sendTypingIndication(False)
+		
+	# Audio
+	def onHangup(self, peer_uri_str):
+		c = self._getCallFromUriStr(peer_uri_str, "onHangup()")
+		if not c: return
+		call_param = pj.CallOpParam()
+		c.hangup(call_param)
+
+	def onHold(self, peer_uri_str):
+		c = self._getCallFromUriStr(peer_uri_str, "onHold()")
+		if not c: return
+		call_param = pj.CallOpParam()
+		c.setHold(call_param)
+
+	def onUnhold(self, peer_uri_str):
+		c = self._getCallFromUriStr(peer_uri_str, "onUnhold()")
+		if not c: return
+		
+		call_param = pj.CallOpParam()
+		call_param.opt.audioCount = 1
+		call_param.opt.videoCount = 0
+		call_param.opt.flag |= pj.PJSUA_CALL_UNHOLD
+		c.reinvite(call_param)
+		
+	def onRxMute(self, peer_uri_str, mute):
+		am = self._getAudioMediaFromUriStr(peer_uri_str)
+		if not am: return
+		if mute:
+			am.stopTransmit(ep.Endpoint.instance.audDevManager().getPlaybackDevMedia())
+			self.addMessage(None, "Muted audio from '%s'" % (peer_uri_str))
+		else:
+			am.startTransmit(ep.Endpoint.instance.audDevManager().getPlaybackDevMedia())
+			self.addMessage(None, "Unmuted audio from '%s'" % (peer_uri_str))
+		
+	def onRxVol(self, peer_uri_str, vol_pct):
+		am = self._getAudioMediaFromUriStr(peer_uri_str)
+		if not am: return
+		# pjsua volume range = 0:mute, 1:no adjustment, 2:100% louder
+		am.adjustRxLevel(vol_pct/50.0)
+		self.addMessage(None, "Adjusted volume level audio from '%s'" % (peer_uri_str))
+			
+	def onTxMute(self, peer_uri_str, mute):
+		am = self._getAudioMediaFromUriStr(peer_uri_str)
+		if not am: return
+		if mute:
+			ep.Endpoint.instance.audDevManager().getCaptureDevMedia().stopTransmit(am)
+			self.addMessage(None, "Muted audio to '%s'" % (peer_uri_str))
+		else:
+			ep.Endpoint.instance.audDevManager().getCaptureDevMedia().startTransmit(am)
+			self.addMessage(None, "Unmuted audio to '%s'" % (peer_uri_str))
+
+	# Chat room
+	def onAddParticipant(self):
+		buds = []
+		dlg = AddParticipantDlg(None, self._app, buds)
+		if dlg.doModal():
+			for bud in buds:
+				uri = ParseSipUri(bud.cfg.uri)
+				self.addParticipant(uri)
+			if not self.isPrivate():
+				self.startCall()
+				
+	def onStartAudio(self):
+		self.startCall()
+
+	def onStopAudio(self):
+		self.stopCall()
+		
+	def onCloseWindow(self):
+		self.stopCall()
+		# will remove entry from list eventually destroy this chat?
+		if self in self._acc.chatList: self._acc.chatList.remove(self)
+		self._app.updateWindowMenu()
+		# destroy GUI
+		self._gui.destroy()
+
+
+class AddParticipantDlg(tk.Toplevel):
+	"""
+	List of buddies
+	"""
+	def __init__(self, parent, app, bud_list):
+		tk.Toplevel.__init__(self, parent)
+		self.title('Add participants..')
+		self.transient(parent)
+		self.parent = parent
+		self._app = app
+		self.buddyList = bud_list
+		
+		self.isOk = False
+		
+		self.createWidgets()
+	
+	def doModal(self):
+		if self.parent:
+			self.parent.wait_window(self)
+		else:
+			self.wait_window(self)
+		return self.isOk
+		
+	def createWidgets(self):
+		# buddy list
+		list_frame = ttk.Frame(self)
+		list_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=1, padx=20, pady=20)
+		#scrl = ttk.Scrollbar(self, orient=tk.VERTICAL, command=list_frame.yview)
+		#list_frame.config(yscrollcommand=scrl.set)
+		#scrl.pack(side=tk.RIGHT, fill=tk.Y)
+		
+		# draw buddy list
+		self.buddies = []
+		for acc in self._app.accList:
+			self.buddies.append((0, acc.cfg.idUri))
+			for bud in acc.buddyList:
+				self.buddies.append((1, bud))
+		
+		self.bud_var = []
+		for idx,(flag,bud) in enumerate(self.buddies):
+			self.bud_var.append(tk.IntVar())
+			if flag==0:
+				s = ttk.Separator(list_frame, orient=tk.HORIZONTAL)
+				s.pack(fill=tk.X)
+				l = tk.Label(list_frame, anchor=tk.W, text="Account '%s':" % (bud))
+				l.pack(fill=tk.X)
+			else:
+				c = tk.Checkbutton(list_frame, anchor=tk.W, text=bud.cfg.uri, variable=self.bud_var[idx])
+				c.pack(fill=tk.X)
+		s = ttk.Separator(list_frame, orient=tk.HORIZONTAL)
+		s.pack(fill=tk.X)
+
+		# Ok/cancel buttons
+		tail_frame = ttk.Frame(self)
+		tail_frame.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=1)
+		
+		btnOk = ttk.Button(tail_frame, text='Ok', default=tk.ACTIVE, command=self.onOk)
+		btnOk.pack(side=tk.LEFT, padx=20, pady=10)
+		btnCancel = ttk.Button(tail_frame, text='Cancel', command=self.onCancel)
+		btnCancel.pack(side=tk.RIGHT, padx=20, pady=10)
+		
+	def onOk(self):
+		self.buddyList[:] = []
+		for idx,(flag,bud) in enumerate(self.buddies):
+			if not flag: continue
+			if self.bud_var[idx].get() and not (bud in self.buddyList):
+				self.buddyList.append(bud)
+			
+		self.isOk = True
+		self.destroy()
+		
+	def onCancel(self):
+		self.destroy()
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/chatgui.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/chatgui.py
new file mode 100644
index 0000000..c39e682
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/chatgui.py
@@ -0,0 +1,420 @@
+# $Id: chatgui.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+	from tkinter import messagebox as msgbox
+else:
+	import Tkinter as tk
+	import ttk
+	import tkMessageBox as msgbox
+
+
+class TextObserver:
+	def onSendMessage(self, msg):
+		pass
+	def onStartTyping(self):
+		pass
+	def onStopTyping(self):
+		pass
+		
+class TextFrame(ttk.Frame):
+	def __init__(self, master, observer):
+		ttk.Frame.__init__(self, master)
+		self._observer = observer
+		self._isTyping = False
+		self._createWidgets()
+
+	def _onSendMessage(self, event):
+		send_text = self._typingBox.get("1.0", tk.END).strip()
+		if send_text == '':
+			return
+		
+		self.addMessage('me: ' + send_text)
+		self._typingBox.delete("0.0", tk.END)
+		self._onTyping(None)
+		
+		# notify app for sending message
+		self._observer.onSendMessage(send_text)
+		
+	def _onTyping(self, event):
+		# notify app for typing indication
+		is_typing = self._typingBox.get("1.0", tk.END).strip() != ''
+		if is_typing != self._isTyping:
+			self._isTyping = is_typing
+			if is_typing:
+				self._observer.onStartTyping()
+			else:
+				self._observer.onStopTyping()
+		
+	def _createWidgets(self):
+		self.rowconfigure(0, weight=1)
+		self.rowconfigure(1, weight=0)
+		self.rowconfigure(2, weight=0)
+		self.columnconfigure(0, weight=1)
+		self.columnconfigure(1, weight=0)
+		
+		self._text = tk.Text(self, width=50, height=30, font=("Arial", "10"))
+		self._text.grid(row=0, column=0, sticky='nswe')
+		self._text.config(state=tk.DISABLED)
+		self._text.tag_config("info", foreground="darkgray", font=("Arial", "9", "italic"))
+		
+		scrl = ttk.Scrollbar(self, orient=tk.VERTICAL, command=self._text.yview)
+		self._text.config(yscrollcommand=scrl.set)
+		scrl.grid(row=0, column=1, sticky='nsw')
+		
+		self._typingBox = tk.Text(self, width=50, height=1, font=("Arial", "10"))
+		self._typingBox.grid(row=1, columnspan=2, sticky='we', pady=0)
+		
+		self._statusBar = tk.Label(self, anchor='w', font=("Arial", "8", "italic"))
+		self._statusBar.grid(row=2, columnspan=2, sticky='we')
+		
+		self._typingBox.bind('<Return>', self._onSendMessage)
+		self._typingBox.bind("<Key>", self._onTyping)
+		self._typingBox.focus_set()
+		
+	def addMessage(self, msg, is_chat = True):
+		self._text.config(state=tk.NORMAL)
+		if is_chat:
+			self._text.insert(tk.END, msg+'\r\n')
+		else:
+			self._text.insert(tk.END, msg+'\r\n', 'info')
+		self._text.config(state=tk.DISABLED)
+		self._text.yview(tk.END)
+
+	def setTypingIndication(self, who, is_typing):
+		if is_typing:
+			self._statusBar['text'] = "'%s' is typing.." % (who)
+		else:
+			self._statusBar['text'] = ''
+
+class AudioState:
+	NULL, INITIALIZING, CONNECTED, DISCONNECTED, FAILED = range(5)
+			
+class AudioObserver:
+	def onHangup(self, peer_uri):
+		pass
+	def onHold(self, peer_uri):
+		pass
+	def onUnhold(self, peer_uri):
+		pass
+	def onRxMute(self, peer_uri, is_muted):
+		pass
+	def onRxVol(self, peer_uri, vol_pct):
+		pass
+	def onTxMute(self, peer_uri, is_muted):
+		pass
+			
+
+class AudioFrame(ttk.Labelframe):
+	def __init__(self, master, peer_uri, observer):
+		ttk.Labelframe.__init__(self, master, text=peer_uri)
+		self.peerUri = peer_uri
+		self._observer = observer
+		self._initFrame = None
+		self._callFrame = None
+		self._rxMute = False
+		self._txMute = False
+		self._state = AudioState.NULL
+		
+		self._createInitWidgets()
+		self._createWidgets()
+		
+	def updateState(self, state):
+		if self._state == state:
+			return
+
+		if state == AudioState.INITIALIZING:
+			self._callFrame.pack_forget()
+			self._initFrame.pack(fill=tk.BOTH)
+			self._btnCancel.pack(side=tk.TOP)
+			self._lblInitState['text'] = 'Intializing..'
+
+		elif state == AudioState.CONNECTED:
+			self._initFrame.pack_forget()
+			self._callFrame.pack(fill=tk.BOTH)			
+		else:
+			self._callFrame.pack_forget()
+			self._initFrame.pack(fill=tk.BOTH)
+			if state == AudioState.FAILED:
+				self._lblInitState['text'] = 'Failed'
+			else:
+				self._lblInitState['text'] = 'Normal cleared'
+				self._btnCancel.pack_forget()
+			
+			self._btnHold['text'] = 'Hold'
+			self._btnHold.config(state=tk.NORMAL)
+			self._rxMute = False
+			self._txMute = False
+			self.btnRxMute['text'] = 'Mute'
+			self.btnTxMute['text'] = 'Mute'
+			self.rxVol.set(5.0)
+		
+		# save last state
+		self._state = state
+		
+	def setStatsText(self, stats_str):
+		self.stat.config(state=tk.NORMAL)
+		self.stat.delete("0.0", tk.END)
+		self.stat.insert(tk.END, stats_str)
+		self.stat.config(state=tk.DISABLED)
+		
+	def _onHold(self):
+		self._btnHold.config(state=tk.DISABLED)
+		# notify app
+		if self._btnHold['text'] == 'Hold':
+			self._observer.onHold(self.peerUri)
+			self._btnHold['text'] = 'Unhold'
+		else:
+			self._observer.onUnhold(self.peerUri)
+			self._btnHold['text'] = 'Hold'
+		self._btnHold.config(state=tk.NORMAL)
+
+	def _onHangup(self):
+		# notify app
+		self._observer.onHangup(self.peerUri)
+
+	def _onRxMute(self):
+		# notify app
+		self._rxMute = not self._rxMute
+		self._observer.onRxMute(self.peerUri, self._rxMute)
+		self.btnRxMute['text'] = 'Unmute' if self._rxMute else 'Mute'
+		
+	def _onRxVol(self, event):
+		# notify app
+		vol = self.rxVol.get()
+		self._observer.onRxVol(self.peerUri, vol*10.0)
+
+	def _onTxMute(self):
+		# notify app
+		self._txMute = not self._txMute
+		self._observer.onTxMute(self.peerUri, self._txMute)
+		self.btnTxMute['text'] = 'Unmute' if self._txMute else 'Mute'
+
+	def _createInitWidgets(self):
+		self._initFrame = ttk.Frame(self)
+		#self._initFrame.pack(fill=tk.BOTH)
+
+	
+		self._lblInitState = tk.Label(self._initFrame, font=("Arial", "12"), text='')
+		self._lblInitState.pack(side=tk.TOP, fill=tk.X, expand=1)
+		
+		# Operation: cancel/kick
+		self._btnCancel = ttk.Button(self._initFrame, text = 'Cancel', command=self._onHangup)
+		self._btnCancel.pack(side=tk.TOP)
+				
+	def _createWidgets(self):
+		self._callFrame = ttk.Frame(self)
+		#self._callFrame.pack(fill=tk.BOTH)
+		
+		# toolbar
+		toolbar = ttk.Frame(self._callFrame)
+		toolbar.pack(side=tk.TOP, fill=tk.X)
+		self._btnHold = ttk.Button(toolbar, text='Hold', command=self._onHold)
+		self._btnHold.pack(side=tk.LEFT, fill=tk.Y)
+		#self._btnXfer = ttk.Button(toolbar, text='Transfer..')
+		#self._btnXfer.pack(side=tk.LEFT, fill=tk.Y)
+		self._btnHangUp = ttk.Button(toolbar, text='Hangup', command=self._onHangup)
+		self._btnHangUp.pack(side=tk.LEFT, fill=tk.Y)
+
+		# volume tool
+		vol_frm = ttk.Frame(self._callFrame)
+		vol_frm.pack(side=tk.TOP, fill=tk.X)
+		
+		self.rxVolFrm = ttk.Labelframe(vol_frm, text='RX volume')
+		self.rxVolFrm.pack(side=tk.LEFT, fill=tk.Y)
+		
+		self.btnRxMute = ttk.Button(self.rxVolFrm, width=8, text='Mute', command=self._onRxMute)
+		self.btnRxMute.pack(side=tk.LEFT)
+		self.rxVol = tk.Scale(self.rxVolFrm, orient=tk.HORIZONTAL, from_=0.0, to=10.0, showvalue=1) #, tickinterval=10.0, showvalue=1)
+		self.rxVol.set(5.0)
+		self.rxVol.bind("<ButtonRelease-1>", self._onRxVol)
+		self.rxVol.pack(side=tk.LEFT)
+		
+		self.txVolFrm = ttk.Labelframe(vol_frm, text='TX volume')
+		self.txVolFrm.pack(side=tk.RIGHT, fill=tk.Y)
+		
+		self.btnTxMute = ttk.Button(self.txVolFrm, width=8, text='Mute', command=self._onTxMute)
+		self.btnTxMute.pack(side=tk.LEFT)
+		
+		# stat
+		self.stat = tk.Text(self._callFrame, width=10, height=2, bg='lightgray', relief=tk.FLAT, font=("Arial", "9"))
+		self.stat.insert(tk.END, 'stat here')
+		self.stat.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=1)
+
+
+class ChatObserver(TextObserver, AudioObserver):
+	def onAddParticipant(self):
+		pass
+	def onStartAudio(self):
+		pass
+	def onStopAudio(self):
+		pass
+	def onCloseWindow(self):
+		pass
+		
+class ChatFrame(tk.Toplevel):
+	"""
+	Room
+	"""
+	def __init__(self, observer):
+		tk.Toplevel.__init__(self)
+		self.protocol("WM_DELETE_WINDOW", self._onClose)
+		self._observer = observer
+
+		self._text = None
+		self._text_shown = True
+		
+		self._audioEnabled = False
+		self._audioFrames = []
+		self._createWidgets()
+	
+	def _createWidgets(self):
+		# toolbar
+		self.toolbar = ttk.Frame(self)
+		self.toolbar.pack(side=tk.TOP, fill=tk.BOTH)
+		
+		btnText = ttk.Button(self.toolbar, text='Show/hide text', command=self._onShowHideText)
+		btnText.pack(side=tk.LEFT, fill=tk.Y)
+		btnAudio = ttk.Button(self.toolbar, text='Start/stop audio', command=self._onStartStopAudio)
+		btnAudio.pack(side=tk.LEFT, fill=tk.Y)
+		
+		ttk.Separator(self.toolbar, orient=tk.VERTICAL).pack(side=tk.LEFT, fill=tk.Y, padx = 4)
+
+		btnAdd = ttk.Button(self.toolbar, text='Add participant..', command=self._onAddParticipant)
+		btnAdd.pack(side=tk.LEFT, fill=tk.Y)
+
+		# media frame
+		self.media = ttk.Frame(self)
+		self.media.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=1)
+		
+		# create Text Chat frame
+		self.media_left = ttk.Frame(self.media)
+		self._text = TextFrame(self.media_left, self._observer)
+		self._text.pack(fill=tk.BOTH, expand=1)
+		self.media_left.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
+		
+		# create other media frame
+		self.media_right = ttk.Frame(self.media)
+		
+	def _arrangeMediaFrames(self):
+		if len(self._audioFrames) == 0:
+			self.media_right.pack_forget()
+			return
+		
+		self.media_right.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
+		MAX_ROWS = 3
+		row_num = 0
+		col_num = 1
+		for frm in self._audioFrames:
+			frm.grid(row=row_num, column=col_num, sticky='nsew', padx=5, pady=5)
+			row_num += 1
+			if row_num >= MAX_ROWS:
+				row_num  = 0
+				col_num += 1
+	
+	def _onShowHideText(self):
+		self.textShowHide(not self._text_shown)
+		
+	def _onAddParticipant(self):
+		self._observer.onAddParticipant()
+	
+	def _onStartStopAudio(self):
+		self._audioEnabled = not self._audioEnabled
+		if self._audioEnabled:
+			self._observer.onStartAudio()
+		else:
+			self._observer.onStopAudio()
+		self.enableAudio(self._audioEnabled)
+		
+	def _onClose(self):
+		self._observer.onCloseWindow()
+			
+	# APIs
+	
+	def bringToFront(self):
+		self.deiconify()
+		self.lift()
+		self._text._typingBox.focus_set()
+		
+	def textAddMessage(self, msg, is_chat = True):
+		self._text.addMessage(msg, is_chat)
+		
+	def textSetTypingIndication(self, who, is_typing = True):
+		self._text.setTypingIndication(who, is_typing)
+		
+	def addParticipant(self, participant_uri):
+		aud_frm = AudioFrame(self.media_right, participant_uri, self._observer)
+		self._audioFrames.append(aud_frm)
+	
+	def delParticipant(self, participant_uri):
+		for aud_frm in self._audioFrames:
+			if participant_uri == aud_frm.peerUri:
+				self._audioFrames.remove(aud_frm)
+				# need to delete aud_frm manually?
+				aud_frm.destroy()
+				return
+
+	def textShowHide(self, show = True):
+		if show:
+			self.media_left.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
+			self._text._typingBox.focus_set()
+		else:
+			self.media_left.pack_forget()
+		self._text_shown = show
+	
+	def enableAudio(self, is_enabled = True):
+		if is_enabled:
+			self._arrangeMediaFrames()
+		else:
+			self.media_right.pack_forget()
+		self._audioEnabled = is_enabled
+			
+	def audioUpdateState(self, participant_uri, state):
+		for aud_frm in self._audioFrames:
+			if participant_uri == aud_frm.peerUri:
+				aud_frm.updateState(state)
+				break
+		if state >= AudioState.DISCONNECTED and len(self._audioFrames) == 1:
+			self.enableAudio(False)
+		else:
+			self.enableAudio(True)
+			
+	def audioSetStatsText(self, participant_uri, stats_str):
+		for aud_frm in self._audioFrames:
+			if participant_uri == aud_frm.peerUri:
+				aud_frm.setStatsText(stats_str)
+				break
+				
+if __name__ == '__main__':
+	root = tk.Tk()
+	root.title("Chat")
+	root.columnconfigure(0, weight=1)
+	root.rowconfigure(0, weight=1)
+	
+	obs = ChatObserver()
+	dlg = ChatFrame(obs)
+	#dlg = TextFrame(root)
+	#dlg = AudioFrame(root)
+
+	#dlg.pack(fill=tk.BOTH, expand=1)
+	root.mainloop()
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/endpoint.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/endpoint.py
new file mode 100644
index 0000000..25367f2
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/endpoint.py
@@ -0,0 +1,53 @@
+# $Id: endpoint.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+	from tkinter import messagebox as msgbox
+else:
+	import Tkinter as tk
+	import tkMessageBox as msgbox
+	import ttk
+
+import pjsua2 as pj
+import application
+
+
+class Endpoint(pj.Endpoint):
+	"""
+	This is high level Python object inherited from pj.Endpoint
+	"""
+	instance = None
+	def __init__(self):
+		pj.Endpoint.__init__(self)
+		Endpoint.instance = self
+	
+	
+def validateUri(uri):
+	return Endpoint.instance.utilVerifyUri(uri) == pj.PJ_SUCCESS
+
+def validateSipUri(uri):
+	return Endpoint.instance.utilVerifySipUri(uri) == pj.PJ_SUCCESS
+
+
+if __name__ == '__main__':
+	application.main()
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/log.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/log.py
new file mode 100644
index 0000000..0011a3e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/log.py
@@ -0,0 +1,127 @@
+# $Id: log.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+	from tkinter import messagebox as msgbox
+else:
+	import Tkinter as tk
+	import tkMessageBox as msgbox
+	import ttk
+
+import pjsua2 as pj
+import application
+
+
+class LogWindow(tk.Toplevel):
+	"""
+	Log window
+	"""
+	instance = None
+	def __init__(self, app):
+		tk.Toplevel.__init__(self, name='logwnd', width=640, height=480)
+		LogWindow.instance = self
+		self.app = app
+		self.state('withdrawn')
+		self.title('Log')
+		self._createWidgets()
+		self.protocol("WM_DELETE_WINDOW", self._onHide)
+
+	def addLog(self, entry):
+		"""entry fields:
+		    int		level;
+		    string	msg;
+		    long	threadId;
+		    string	threadName;
+		"""
+		self.addLog2(entry.level, entry.msg)
+		
+	def addLog2(self, level, msg):
+		if level==5:
+			tags = ('trace',)
+		elif level==3:
+			tags = ('info',)
+		elif level==2:
+			tags = ('warning',)
+		elif level<=1:
+			tags = ('error',)
+		else:
+			tags = None
+		self.text.insert(tk.END, msg, tags)
+		self.text.see(tk.END)
+		
+	def _createWidgets(self):
+		self.rowconfigure(0, weight=1)
+		self.rowconfigure(1, weight=0)
+		self.columnconfigure(0, weight=1)
+		self.columnconfigure(1, weight=0)
+		
+		self.text = tk.Text(self, font=('Courier New', '8'), wrap=tk.NONE, undo=False, padx=4, pady=5)
+		self.text.grid(row=0, column=0, sticky='nswe', padx=5, pady=5)
+		
+		scrl = ttk.Scrollbar(self, orient=tk.VERTICAL, command=self.text.yview)
+		self.text.config(yscrollcommand=scrl.set)
+		scrl.grid(row=0, column=1, sticky='nsw', padx=5, pady=5)
+
+		scrl = ttk.Scrollbar(self, orient=tk.HORIZONTAL, command=self.text.xview)
+		self.text.config(xscrollcommand=scrl.set)
+		scrl.grid(row=1, column=0, sticky='we', padx=5, pady=5)
+		
+		self.text.bind("<Key>", self._onKey)
+		
+		self.text.tag_configure('normal', font=('Courier New', '8'), foreground='black')
+		self.text.tag_configure('trace', font=('Courier New', '8'), foreground='#777777')
+		self.text.tag_configure('info', font=('Courier New', '8', 'bold'), foreground='black')
+		self.text.tag_configure('warning', font=('Courier New', '8', 'bold'), foreground='cyan')
+		self.text.tag_configure('error', font=('Courier New', '8', 'bold'), foreground='red')
+	
+	def _onKey(self, event):
+		# Ignore key event to make text widget read-only
+		return "break"
+	
+	def _onHide(self):
+		# Hide when close ('x') button is clicked
+		self.withdraw()
+		self.app.showLogWindow.set(0)
+		
+	
+def writeLog2(level, msg):
+	if LogWindow.instance:
+		LogWindow.instance.addLog2(level, msg)	
+
+def writeLog(entry):
+	if LogWindow.instance:
+		LogWindow.instance.addLog(entry)
+
+class Logger(pj.LogWriter):
+	"""
+	Logger to receive log messages from pjsua2
+	"""
+	def __init__(self):
+		pj.LogWriter.__init__(self)
+		
+	def write(self, entry):
+		print entry.msg,
+		writeLog(entry)
+
+if __name__ == '__main__':
+	application.main()
diff --git a/jni/libpjsip/sources/pjsip-apps/src/pygui/settings.py b/jni/libpjsip/sources/pjsip-apps/src/pygui/settings.py
new file mode 100644
index 0000000..595bc12
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/pygui/settings.py
@@ -0,0 +1,362 @@
+# $Id: settings.py 4704 2014-01-16 05:30:46Z ming $
+#
+# pjsua Python GUI Demo
+#
+# Copyright (C)2013 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 
+#
+import sys
+if sys.version_info[0] >= 3: # Python 3
+	import tkinter as tk
+	from tkinter import ttk
+	from tkinter import messagebox as msgbox
+else:
+	import Tkinter as tk
+	import tkMessageBox as msgbox
+	import ttk
+
+import pjsua2 as pj
+#import application
+
+# Transport setting
+class SipTransportConfig:
+	def __init__(self, type, enabled):
+		#pj.PersistentObject.__init__(self)
+		self.type = type
+		self.enabled = enabled
+		self.config = pj.TransportConfig()
+	def readObject(self, node):
+		child_node = node.readContainer("SipTransport")
+		self.type = child_node.readInt("type")
+		self.enabled = child_node.readBool("enabled")
+		self.config.readObject(child_node)
+	def writeObject(self, node):
+		child_node = node.writeNewContainer("SipTransport")
+		child_node.writeInt("type", self.type)
+		child_node.writeBool("enabled", self.enabled)
+		self.config.writeObject(child_node)
+
+# Account setting with buddy list
+class AccConfig:
+	def __init__(self):
+		self.enabled = True
+		self.config = pj.AccountConfig()
+		self.buddyConfigs = []
+	def readObject(self, node):
+		acc_node = node.readContainer("Account")
+		self.enabled = acc_node.readBool("enabled")
+		self.config.readObject(acc_node)
+		buddy_node = acc_node.readArray("buddies")
+		while buddy_node.hasUnread():
+			buddy_cfg = pj.BuddyConfig()
+			buddy_cfg.readObject(buddy_node)
+			self.buddyConfigs.append(buddy_cfg)
+	def writeObject(self, node):
+		acc_node = node.writeNewContainer("Account")
+		acc_node.writeBool("enabled", self.enabled)
+		self.config.writeObject(acc_node)
+		buddy_node = acc_node.writeNewArray("buddies")
+		for buddy in self.buddyConfigs:
+			buddy_node.writeObject(buddy)
+
+	
+# Master settings
+class AppConfig:
+	def __init__(self):
+		self.epConfig = pj.EpConfig()	# pj.EpConfig()
+		self.udp = SipTransportConfig(pj.PJSIP_TRANSPORT_UDP, True)
+		self.tcp = SipTransportConfig(pj.PJSIP_TRANSPORT_TCP, True)
+		self.tls = SipTransportConfig(pj.PJSIP_TRANSPORT_TLS, False)
+		self.accounts = []		# Array of AccConfig
+		
+	def loadFile(self, file):
+		json = pj.JsonDocument()
+		json.loadFile(file)
+		root = json.getRootContainer()
+		self.epConfig = pj.EpConfig()
+		self.epConfig.readObject(root)
+		
+		tp_node = root.readArray("transports")
+		self.udp.readObject(tp_node)
+		self.tcp.readObject(tp_node)
+		if tp_node.hasUnread():
+			self.tls.readObject(tp_node)
+			
+		acc_node = root.readArray("accounts")
+		while acc_node.hasUnread():
+			acfg = AccConfig()
+			acfg.readObject(acc_node)
+			self.accounts.append(acfg)
+			
+	def saveFile(self,file):
+		json = pj.JsonDocument()
+		
+		# Write endpoint config
+		json.writeObject(self.epConfig)
+		
+		# Write transport config
+		tp_node = json.writeNewArray("transports")
+		self.udp.writeObject(tp_node)
+		self.tcp.writeObject(tp_node)
+		self.tls.writeObject(tp_node)
+		
+		# Write account configs
+		node = json.writeNewArray("accounts")
+		for acc in self.accounts:
+			acc.writeObject(node)
+				
+		json.saveFile(file)
+		
+
+# Settings dialog
+class Dialog(tk.Toplevel):
+	"""
+	This implements account settings dialog to manipulate account settings.
+	"""
+	def __init__(self, parent, cfg):
+		tk.Toplevel.__init__(self, parent)
+		self.transient(parent)
+		self.parent = parent
+		self.title('Settings')
+		
+		self.frm = ttk.Frame(self)
+		self.frm.pack(expand='yes', fill='both')
+		
+		self.isOk = False
+		self.cfg = cfg
+		
+		self.createWidgets()
+	
+	def doModal(self):
+		if self.parent:
+			self.parent.wait_window(self)
+		else:
+			self.wait_window(self)
+		return self.isOk
+		
+	def createWidgets(self):
+		# The notebook
+		self.frm.rowconfigure(0, weight=1)
+		self.frm.rowconfigure(1, weight=0)
+		self.frm.columnconfigure(0, weight=1)
+		self.frm.columnconfigure(1, weight=1)
+		self.wTab = ttk.Notebook(self.frm)
+		self.wTab.grid(column=0, row=0, columnspan=2, padx=10, pady=10, ipadx=20, ipady=20, sticky=tk.N+tk.S+tk.W+tk.E)
+		
+		# Main buttons
+		btnOk = ttk.Button(self.frm, text='Ok', command=self.onOk)
+		btnOk.grid(column=0, row=1, sticky=tk.E, padx=20, pady=10)
+		btnCancel = ttk.Button(self.frm, text='Cancel', command=self.onCancel)
+		btnCancel.grid(column=1, row=1, sticky=tk.W, padx=20, pady=10)
+		
+		# Tabs
+		self.createBasicTab()
+		self.createNetworkTab()
+		self.createMediaTab()
+
+	def createBasicTab(self):
+		# Prepare the variables to set/receive values from GUI
+		self.cfgLogFile = tk.StringVar(value=self.cfg.epConfig.logConfig.filename)
+		self.cfgLogAppend = tk.BooleanVar(value=True if (self.cfg.epConfig.logConfig.fileFlags & pj.PJ_O_APPEND) else False)
+		
+		# Build the tab page
+		frm = ttk.Frame(self.frm)
+		frm.columnconfigure(0, weight=1)
+		frm.columnconfigure(1, weight=2)
+		row = 0
+		ttk.Label(frm, text='User Agent:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Label(frm, text=self.cfg.epConfig.uaConfig.userAgent).grid(row=row, column=1, sticky=tk.W, pady=2, padx=6)
+		row += 1
+		ttk.Label(frm, text='Max calls:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Label(frm, text=str(self.cfg.epConfig.uaConfig.maxCalls)).grid(row=row, column=1, sticky=tk.W, pady=2, padx=6)
+		row += 1
+		ttk.Label(frm, text='Log file:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Entry(frm, textvariable=self.cfgLogFile, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Checkbutton(frm, text='Append log file', variable=self.cfgLogAppend).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+
+		self.wTab.add(frm, text='Basic')
+		
+	def createNetworkTab(self):
+		self.cfgNameserver = tk.StringVar()
+		if len(self.cfg.epConfig.uaConfig.nameserver):
+			self.cfgNameserver.set(self.cfg.epConfig.uaConfig.nameserver[0])
+		self.cfgStunServer = tk.StringVar()
+		if len(self.cfg.epConfig.uaConfig.stunServer):
+			self.cfgStunServer.set(self.cfg.epConfig.uaConfig.stunServer[0])
+		self.cfgStunIgnoreError = tk.BooleanVar(value=self.cfg.epConfig.uaConfig.stunIgnoreFailure)
+		
+		self.cfgUdpEnabled = tk.BooleanVar(value=self.cfg.udp.enabled)
+		self.cfgUdpPort = tk.IntVar(value=self.cfg.udp.config.port)
+		self.cfgTcpEnabled = tk.BooleanVar(value=self.cfg.tcp.enabled)
+		self.cfgTcpPort = tk.IntVar(value=self.cfg.tcp.config.port)
+		self.cfgTlsEnabled = tk.BooleanVar(value=self.cfg.tls.enabled)
+		self.cfgTlsPort = tk.IntVar(value=self.cfg.tls.config.port)
+		
+		self.cfgTlsCaFile = tk.StringVar(value=self.cfg.tls.config.tlsConfig.CaListFile)
+		self.cfgTlsCertFile = tk.StringVar(value=self.cfg.tls.config.tlsConfig.certFile)
+		self.cfgTlsVerifyClient = tk.BooleanVar(value=self.cfg.tls.config.tlsConfig.verifyClient)
+		self.cfgTlsVerifyServer = tk.BooleanVar(value=self.cfg.tls.config.tlsConfig.verifyServer)
+		
+		# Build the tab page
+		frm = ttk.Frame(self.frm)
+		frm.columnconfigure(0, weight=1)
+		frm.columnconfigure(1, weight=2)
+		row = 0
+		#ttk.Label(frm, text='UDP transport:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Checkbutton(frm, text='Enable UDP transport', variable=self.cfgUdpEnabled).grid(row=row, column=0, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='UDP port:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgUdpPort, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='(0 for any)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
+		row += 1
+		#ttk.Label(frm, text='TCP transport:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Checkbutton(frm, text='Enable TCP transport', variable=self.cfgTcpEnabled).grid(row=row, column=0, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='TCP port:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgTcpPort, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='(0 for any)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
+		row += 1
+		#ttk.Label(frm, text='TLS transport:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Checkbutton(frm, text='Enable TLS transport', variable=self.cfgTlsEnabled).grid(row=row, column=0, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='TLS port:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgTlsPort, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='(0 for any)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
+		row += 1
+		ttk.Label(frm, text='TLS CA file:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Entry(frm, textvariable=self.cfgTlsCaFile, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='TLS cert file:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Entry(frm, textvariable=self.cfgTlsCertFile, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Checkbutton(frm, text='TLS verify server', variable=self.cfgTlsVerifyServer).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Checkbutton(frm, text='TLS verify client', variable=self.cfgTlsVerifyClient).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='DNS and STUN:').grid(row=row, column=0, sticky=tk.W, pady=2, padx=8)
+		row += 1
+		ttk.Label(frm, text='Nameserver:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Entry(frm, textvariable=self.cfgNameserver, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='STUN Server:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Entry(frm, textvariable=self.cfgStunServer, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Checkbutton(frm, text='Ignore STUN failure at startup', variable=self.cfgStunIgnoreError).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		
+		self.wTab.add(frm, text='Network')
+
+	def createMediaTab(self):
+		self.cfgClockrate = tk.IntVar(value=self.cfg.epConfig.medConfig.clockRate)
+		self.cfgSndClockrate = tk.IntVar(value=self.cfg.epConfig.medConfig.sndClockRate)
+		self.cfgAudioPtime = tk.IntVar(value=self.cfg.epConfig.medConfig.audioFramePtime)
+		self.cfgMediaQuality = tk.IntVar(value=self.cfg.epConfig.medConfig.quality)
+		self.cfgCodecPtime = tk.IntVar(value=self.cfg.epConfig.medConfig.ptime)
+		self.cfgVad = tk.BooleanVar(value=not self.cfg.epConfig.medConfig.noVad)
+		self.cfgEcTailLen = tk.IntVar(value=self.cfg.epConfig.medConfig.ecTailLen)
+		
+		# Build the tab page
+		frm = ttk.Frame(self.frm)
+		frm.columnconfigure(0, weight=1)
+		frm.columnconfigure(1, weight=2)
+		row = 0
+		ttk.Label(frm, text='Max media ports:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Label(frm, text=str(self.cfg.epConfig.medConfig.maxMediaPorts)).grid(row=row, column=1, sticky=tk.W, pady=2, padx=6)
+		row += 1
+		ttk.Label(frm, text='Core clock rate:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		tk.Spinbox(frm, from_=8000, to=48000, increment=8000, textvariable=self.cfgClockrate, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='Snd device clock rate:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		tk.Spinbox(frm, from_=0, to=48000, increment=8000, textvariable=self.cfgSndClockrate, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='(0: follow core)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
+		row += 1
+		ttk.Label(frm, text='Core ptime:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		tk.Spinbox(frm, from_=10, to=400, increment=10, textvariable=self.cfgAudioPtime, width=3).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='RTP ptime:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		tk.Spinbox(frm, from_=20, to=400, increment=10, textvariable=self.cfgCodecPtime, width=3).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='Media quality (1-10):').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		tk.Spinbox(frm, from_=1, to=10, textvariable=self.cfgMediaQuality, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
+		row += 1
+		ttk.Label(frm, text='VAD:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		ttk.Checkbutton(frm, text='Enable', variable=self.cfgVad).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
+		row += 1
+		ttk.Label(frm, text='Echo canceller tail length:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
+		tk.Spinbox(frm, from_=0, to=400, increment=10, textvariable=self.cfgEcTailLen, width=3).grid(row=row, column=1, sticky=tk.W, padx=6)
+		ttk.Label(frm, text='(ms, 0 to disable)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
+		
+		self.wTab.add(frm, text='Media')
+
+	def onOk(self):
+		# Check basic settings
+		errors = "";
+		if errors:
+			msgbox.showerror("Error detected:", errors)
+			return
+		
+		# Basic settings
+		self.cfg.epConfig.logConfig.filename = self.cfgLogFile.get()
+		flags = pj.PJ_O_APPEND if self.cfgLogAppend.get() else 0
+		self.cfg.epConfig.logConfig.fileFlags = self.cfg.epConfig.logConfig.fileFlags | flags 
+		
+		# Network settings
+		self.cfg.epConfig.uaConfig.nameserver.clear()
+		if len(self.cfgNameserver.get()): 
+			self.cfg.epConfig.uaConfig.nameserver.append(self.cfgNameserver.get())
+		self.cfg.epConfig.uaConfig.stunServer.clear()
+		if len(self.cfgStunServer.get()):
+			self.cfg.epConfig.uaConfig.stunServer.append(self.cfgStunServer.get())
+			
+		self.cfg.epConfig.uaConfig.stunIgnoreFailure = self.cfgStunIgnoreError.get()
+		
+		self.cfg.udp.enabled 	= self.cfgUdpEnabled.get()
+		self.cfg.udp.config.port = self.cfgUdpPort.get()
+		self.cfg.tcp.enabled 	= self.cfgTcpEnabled.get()
+		self.cfg.tcp.config.port = self.cfgTcpPort.get()
+		self.cfg.tls.enabled 	= self.cfgTlsEnabled.get()
+		self.cfg.tls.config.port = self.cfgTlsPort.get()
+		
+		self.cfg.tls.config.tlsConfig.CaListFile = self.cfgTlsCaFile.get()
+		self.cfg.tls.config.tlsConfig.certFile   = self.cfgTlsCertFile.get()
+		self.cfg.tls.config.tlsConfig.verifyClient = self.cfgTlsVerifyClient.get()
+		self.cfg.tls.config.tlsConfig.verifyServer = self.cfgTlsVerifyServer.get()
+
+		# Media
+		self.cfg.epConfig.medConfig.clockRate	= self.cfgClockrate.get()
+		self.cfg.epConfig.medConfig.sndClockRate = self.cfgSndClockrate.get()
+		self.cfg.epConfig.medConfig.audioFramePtime = self.cfgAudioPtime.get()
+		self.cfg.epConfig.medConfig.quality	= self.cfgMediaQuality.get()
+		self.cfg.epConfig.medConfig.ptime	= self.cfgCodecPtime.get()
+		self.cfg.epConfig.medConfig.noVad	= not self.cfgVad.get()
+		self.cfg.epConfig.medConfig.ecTailLen	= self.cfgEcTailLen.get()
+		
+		self.isOk = True
+		self.destroy()
+		
+	def onCancel(self):
+		self.destroy()
+
+
+if __name__ == '__main__':
+	#application.main()
+	acfg = AppConfig()
+	acfg.loadFile('pygui.js')
+
+	dlg = Dialog(None, acfg)
+	if dlg.doModal():
+		acfg.saveFile('pygui.js')
+		
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/Makefile b/jni/libpjsip/sources/pjsip-apps/src/python/Makefile
new file mode 100644
index 0000000..19a7e81
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/Makefile
@@ -0,0 +1,12 @@
+all:
+	python setup.py build
+
+clean distclean realclean:
+	python setup.py clean
+	rm -rf ./build
+
+install:
+	python setup.py $@
+
+dep doc:
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/_pjsua.c b/jni/libpjsip/sources/pjsip-apps/src/python/_pjsua.c
new file mode 100644
index 0000000..93b70c9
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/_pjsua.c
@@ -0,0 +1,4615 @@
+/* $Id: _pjsua.c 4609 2013-10-02 03:19:54Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 "_pjsua.h"
+
+#define THIS_FILE    "main.c"
+#define POOL_SIZE    512
+#define SND_DEV_NUM  64
+#define SND_NAME_LEN  64
+
+/* LIB BASE */
+
+static PyObject* g_obj_log_cb;
+static long g_thread_id;
+static struct py_thread_desc
+{
+    struct py_thread_desc *next;
+    pj_thread_desc	   desc;
+} *py_thread_desc;
+
+/*
+ * The global callback object.
+ */
+static PyObj_pjsua_callback * g_obj_callback;
+
+/* Set this to 1 if all threads are created by Python */
+#define NO_PJSIP_THREAD 1
+
+#if NO_PJSIP_THREAD
+#   define ENTER_PYTHON()
+#   define LEAVE_PYTHON()
+#else
+#   define ENTER_PYTHON()   PyGILState_STATE state = PyGILState_Ensure()
+#   define LEAVE_PYTHON()   PyGILState_Release(state)
+#endif
+
+
+static void clear_py_thread_desc(void)
+{
+    while (py_thread_desc) {
+	struct py_thread_desc *next = py_thread_desc->next;
+	free(py_thread_desc);
+	py_thread_desc = next;
+    }
+}
+
+
+/*
+ * cb_log_cb
+ * declares method for reconfiguring logging process for callback struct
+ */
+static void cb_log_cb(int level, const char *data, int len)
+{
+	
+    /* Ignore if this callback is called from alien thread context,
+     * or otherwise it will crash Python.
+     */
+    if (pj_thread_local_get(g_thread_id) == 0)
+	return;
+
+    if (PyCallable_Check(g_obj_log_cb)) {
+	PyObject *param_data;
+
+	ENTER_PYTHON();
+
+	param_data = PyString_FromStringAndSize(data, len);
+
+        PyObject_CallFunction(
+            g_obj_log_cb, 
+	    "iOi",
+	    level,
+            param_data, 
+	    len, 
+	    NULL
+        );
+
+	Py_DECREF(param_data);
+
+	LEAVE_PYTHON();
+    }
+}
+
+/*
+ * cb_on_call_state
+ * declares method on_call_state for callback struct
+ */
+static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
+{
+    PJ_UNUSED_ARG(e);
+
+    if (PyCallable_Check(g_obj_callback->on_call_state)) {	
+        PyObject * obj;
+
+	ENTER_PYTHON();
+
+	obj = Py_BuildValue("");
+		
+        PyObject_CallFunction(
+            g_obj_callback->on_call_state,
+	    "iO",
+	    call_id,
+	    obj,
+	    NULL
+        );
+
+	Py_DECREF(obj);
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_incoming_call
+ * declares method on_incoming_call for callback struct
+ */
+static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
+				pjsip_rx_data *rdata)
+{
+    if (PyCallable_Check(g_obj_callback->on_incoming_call)) {
+	PyObj_pjsip_rx_data *obj;
+	
+	ENTER_PYTHON();
+	
+	obj = (PyObj_pjsip_rx_data*)
+	      PyObj_pjsip_rx_data_new(&PyTyp_pjsip_rx_data,
+				      NULL, NULL);
+	PyObj_pjsip_rx_data_import(obj, rdata);
+
+	PyObject_CallFunction(
+	    g_obj_callback->on_incoming_call,
+	    "iiO",
+	    acc_id,
+	    call_id,
+	    obj,
+	    NULL
+	);
+
+	Py_DECREF(obj);
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_call_media_state
+ * declares method on_call_media_state for callback struct
+ */
+static void cb_on_call_media_state(pjsua_call_id call_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_media_state)) {
+
+	ENTER_PYTHON();
+
+        PyObject_CallFunction(
+	    g_obj_callback->on_call_media_state,
+	    "i",
+	    call_id,
+	    NULL
+	);
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_dtmf_digit()
+ * Callback from PJSUA-LIB on receiving DTMF digit
+ */
+static void cb_on_dtmf_digit(pjsua_call_id call_id, int digit)
+{
+    if (PyCallable_Check(g_obj_callback->on_dtmf_digit)) {
+	char digit_str[10];
+
+	PyGILState_STATE state = PyGILState_Ensure();
+
+	pj_ansi_snprintf(digit_str, sizeof(digit_str), "%c", digit);
+
+        PyObject_CallFunction(
+	    g_obj_callback->on_dtmf_digit,
+	    "is",
+	    call_id,
+	    digit_str,
+	    NULL
+	);
+
+	PyGILState_Release(state);
+    }
+}
+
+
+/*
+ * Notify application on call being transfered.
+ * !modified @061206
+ */
+static void cb_on_call_transfer_request(pjsua_call_id call_id,
+				        const pj_str_t *dst,
+				        pjsip_status_code *code)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_transfer_request)) {
+	PyObject *ret, *param_dst;
+	int cd;
+
+	ENTER_PYTHON();
+
+	param_dst = PyString_FromPJ(dst);
+
+        ret = PyObject_CallFunction(
+		    g_obj_callback->on_call_transfer_request,
+		    "iOi",
+		    call_id,
+		    param_dst,
+		    *code,
+		    NULL
+		);
+
+	Py_DECREF(param_dst);
+
+	if (ret != NULL) {
+	    if (ret != Py_None) {
+		if (PyArg_Parse(ret,"i",&cd)) {
+		    *code = cd;
+		}
+	    }
+	    Py_DECREF(ret);
+	}
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * Notify application of the status of previously sent call
+ * transfer request. Application can monitor the status of the
+ * call transfer request, for example to decide whether to 
+ * terminate existing call.
+ * !modified @061206
+ */
+static void cb_on_call_transfer_status( pjsua_call_id call_id,
+					int status_code,
+					const pj_str_t *status_text,
+					pj_bool_t final,
+					pj_bool_t *p_cont)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_transfer_status)) {
+	PyObject *ret, *param_reason;
+
+	ENTER_PYTHON();
+
+	param_reason = PyString_FromPJ(status_text);
+
+        ret = PyObject_CallFunction(
+		    g_obj_callback->on_call_transfer_status,
+		    "iiOii",
+		    call_id,
+		    status_code,
+		    param_reason,
+		    final,
+		    *p_cont,
+		    NULL
+		);
+
+	Py_DECREF(param_reason);
+
+	if (ret != NULL) {
+	    if (ret != Py_None) {
+		int cnt;
+		if (PyArg_Parse(ret,"i",&cnt)) {
+		    *p_cont = cnt;
+		}
+	    }
+	    Py_DECREF(ret);
+	}
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * Notify application about incoming INVITE with Replaces header.
+ * Application may reject the request by setting non-2xx code.
+ * !modified @061206
+ */
+static void cb_on_call_replace_request( pjsua_call_id call_id,
+					pjsip_rx_data *rdata,
+					int *st_code,
+					pj_str_t *st_text)
+{
+    PJ_UNUSED_ARG(rdata);
+
+    if (PyCallable_Check(g_obj_callback->on_call_replace_request)) {
+	PyObject *ret, *param_reason, *param_rdata;
+	int cd;
+
+	ENTER_PYTHON();
+
+	param_reason = PyString_FromPJ(st_text);
+	param_rdata = Py_BuildValue("");
+
+        ret = PyObject_CallFunction(
+		    g_obj_callback->on_call_replace_request,
+		    "iOiO",
+		    call_id,
+		    param_rdata,
+		    *st_code,
+		    param_reason,
+		    NULL
+		);
+
+	Py_DECREF(param_rdata);
+	Py_DECREF(param_reason);
+
+	if (ret != NULL) {
+	    if (ret != Py_None) {
+		PyObject * txt;
+		if (PyArg_ParseTuple(ret,"iO",&cd, &txt)) {
+		    *st_code = cd;
+		    *st_text = PyString_ToPJ(txt);
+		}
+	    }
+	    Py_DECREF(ret);
+	}
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * Notify application that an existing call has been replaced with
+ * a new call. This happens when PJSUA-API receives incoming INVITE
+ * request with Replaces header.
+ */
+static void cb_on_call_replaced(pjsua_call_id old_call_id,
+				pjsua_call_id new_call_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_call_replaced)) {
+	ENTER_PYTHON();
+
+        PyObject_CallFunction(
+            g_obj_callback->on_call_replaced,
+	    "ii",
+	    old_call_id,
+	    new_call_id,
+	    NULL
+        );
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_reg_state
+ * declares method on_reg_state for callback struct
+ */
+static void cb_on_reg_state(pjsua_acc_id acc_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_reg_state)) {
+	ENTER_PYTHON();
+
+        PyObject_CallFunction(
+	    g_obj_callback->on_reg_state,
+	    "i",
+	    acc_id,
+	    NULL
+	);
+
+	LEAVE_PYTHON();
+    }
+}
+
+/* 
+ * cb_on_incoming_subscribe
+ */
+static void cb_on_incoming_subscribe( pjsua_acc_id acc_id,
+				      pjsua_srv_pres *srv_pres,
+				      pjsua_buddy_id buddy_id,
+				      const pj_str_t *from,
+				      pjsip_rx_data *rdata,
+				      pjsip_status_code *code,
+				      pj_str_t *reason,
+				      pjsua_msg_data *msg_data)
+{
+    static char reason_buf[64];
+
+    PJ_UNUSED_ARG(rdata);
+    PJ_UNUSED_ARG(msg_data);
+
+    if (PyCallable_Check(g_obj_callback->on_incoming_subscribe)) {
+	PyObject *ret, *param_from, *param_contact, *param_srv_pres;
+	pjsip_contact_hdr *contact_hdr;
+	pj_pool_t *pool = NULL;
+
+	ENTER_PYTHON();
+
+	param_from = PyString_FromPJ(from);
+	param_srv_pres = PyLong_FromLong((long)srv_pres);
+
+	contact_hdr = (pjsip_contact_hdr*)
+		      pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
+					 NULL);
+	if (contact_hdr) {
+	    char *contact;
+	    int len;
+
+	    pool = pjsua_pool_create("pytmp", 512, 512);
+	    contact = (char*) pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE+1);
+	    len = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contact_hdr->uri, 
+				  contact, PJSIP_MAX_URL_SIZE);
+	    if (len < 1)
+		len = 0;
+	    contact[len] = '\0';
+
+	    param_contact = PyString_FromStringAndSize(contact, len);
+	} else {
+	    param_contact = Py_BuildValue("");
+	}
+
+        ret = PyObject_CallFunction(
+		    g_obj_callback->on_incoming_subscribe,
+		    "iiOOO",
+		    acc_id,
+		    buddy_id,
+		    param_from,
+		    param_contact,
+		    param_srv_pres,
+		    NULL
+		);
+
+	if (pool)
+	    pj_pool_release(pool);
+
+	Py_DECREF(param_from);
+	Py_DECREF(param_contact);
+	Py_DECREF(param_srv_pres);
+
+	if (ret && PyTuple_Check(ret)) {
+	    if (PyTuple_Size(ret) >= 1)
+		*code = (int)PyInt_AsLong(PyTuple_GetItem(ret, 0));
+	    if (PyTuple_Size(ret) >= 2) {
+		if (PyTuple_GetItem(ret, 1) != Py_None) {
+		    pj_str_t tmp;
+		    tmp = PyString_ToPJ(PyTuple_GetItem(ret, 1));
+		    reason->ptr = reason_buf;
+		    pj_strncpy(reason, &tmp, sizeof(reason_buf));
+		} else {
+		    reason->slen = 0;
+		}
+	    }
+	    Py_XDECREF(ret);
+	} else if (ret) {
+	    Py_XDECREF(ret);
+	}
+
+	LEAVE_PYTHON();
+    }
+}
+
+/*
+ * cb_on_buddy_state
+ * declares method on_buddy state for callback struct
+ */
+static void cb_on_buddy_state(pjsua_buddy_id buddy_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_buddy_state)) {
+	ENTER_PYTHON();
+
+        PyObject_CallFunction(
+	    g_obj_callback->on_buddy_state,
+	    "i",
+	    buddy_id,
+	    NULL
+	);
+
+	LEAVE_PYTHON();
+    }
+}
+
+/*
+ * cb_on_pager
+ * declares method on_pager for callback struct
+ */
+static void cb_on_pager(pjsua_call_id call_id, const pj_str_t *from,
+                        const pj_str_t *to, const pj_str_t *contact,
+                        const pj_str_t *mime_type, const pj_str_t *body,
+			pjsip_rx_data *rdata, pjsua_acc_id acc_id)
+{
+    PJ_UNUSED_ARG(rdata);
+
+    if (PyCallable_Check(g_obj_callback->on_pager)) {
+	PyObject *param_from, *param_to, *param_contact, *param_mime_type,
+		 *param_body;
+
+	ENTER_PYTHON();
+
+	param_from = PyString_FromPJ(from);
+	param_to = PyString_FromPJ(to);
+	param_contact = PyString_FromPJ(contact);
+	param_mime_type = PyString_FromPJ(mime_type);
+	param_body = PyString_FromPJ(body);
+
+        PyObject_CallFunction(
+		g_obj_callback->on_pager,
+		"iOOOOOi",
+		call_id,
+		param_from,
+		param_to,
+		param_contact,
+		param_mime_type,
+		param_body, 
+		acc_id,
+		NULL
+	    );
+
+	Py_DECREF(param_body);
+	Py_DECREF(param_mime_type);
+	Py_DECREF(param_contact);
+	Py_DECREF(param_to);
+	Py_DECREF(param_from);
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_pager_status
+ * declares method on_pager_status for callback struct
+ */
+static void cb_on_pager_status(pjsua_call_id call_id, const pj_str_t *to,
+                                const pj_str_t *body, void *user_data,
+                                pjsip_status_code status,
+                                const pj_str_t *reason,
+				pjsip_tx_data *tdata,
+				pjsip_rx_data *rdata,
+				pjsua_acc_id acc_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_pager)) {
+	PyObject *param_call_id, *param_to, *param_body,
+		 *param_user_data, *param_status, *param_reason,
+		 *param_acc_id;
+
+	ENTER_PYTHON();
+
+	PJ_UNUSED_ARG(tdata);
+	PJ_UNUSED_ARG(rdata);
+
+        PyObject_CallFunctionObjArgs(
+		g_obj_callback->on_pager_status,
+		param_call_id	= Py_BuildValue("i",call_id),
+		param_to	= PyString_FromPJ(to),
+		param_body	= PyString_FromPJ(body), 
+		param_user_data = Py_BuildValue("i", user_data),
+		param_status	= Py_BuildValue("i",status),
+		param_reason	= PyString_FromPJ(reason),
+		param_acc_id	= Py_BuildValue("i",acc_id),
+		NULL
+	    );
+
+	Py_DECREF(param_call_id);
+	Py_DECREF(param_to);
+	Py_DECREF(param_body);
+	Py_DECREF(param_user_data);
+	Py_DECREF(param_status);
+	Py_DECREF(param_reason);
+	Py_DECREF(param_acc_id);
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * cb_on_typing
+ * declares method on_typing for callback struct
+ */
+static void cb_on_typing(pjsua_call_id call_id, const pj_str_t *from,
+                            const pj_str_t *to, const pj_str_t *contact,
+                            pj_bool_t is_typing, pjsip_rx_data *rdata,
+			    pjsua_acc_id acc_id)
+{
+    if (PyCallable_Check(g_obj_callback->on_typing)) {
+	PyObject *param_call_id, *param_from, *param_to, *param_contact,
+		 *param_is_typing, *param_acc_id;
+
+	ENTER_PYTHON();
+
+	PJ_UNUSED_ARG(rdata);
+
+        PyObject_CallFunctionObjArgs(
+		g_obj_callback->on_typing,
+		param_call_id	= Py_BuildValue("i",call_id),
+		param_from	= PyString_FromPJ(from),
+		param_to	= PyString_FromPJ(to),
+		param_contact	= PyString_FromPJ(contact),
+		param_is_typing = Py_BuildValue("i",is_typing),
+		param_acc_id	= Py_BuildValue("i",acc_id),
+		NULL
+	    );
+
+	Py_DECREF(param_call_id);
+	Py_DECREF(param_from);
+	Py_DECREF(param_to);
+	Py_DECREF(param_contact);
+	Py_DECREF(param_is_typing); 
+	Py_DECREF(param_acc_id);
+
+	LEAVE_PYTHON();
+    }
+}
+
+
+/*
+ * on_mwi_info
+ */
+static void cb_on_mwi_info(pjsua_acc_id acc_id, pjsua_mwi_info *mwi_info)
+{
+    if (PyCallable_Check(g_obj_callback->on_mwi_info)) {
+	PyObject *param_acc_id, *param_body;
+	pj_str_t body;
+
+	ENTER_PYTHON();
+
+	body.ptr = mwi_info->rdata->msg_info.msg->body->data;
+	body.slen = mwi_info->rdata->msg_info.msg->body->len;
+
+        PyObject_CallFunctionObjArgs(
+		g_obj_callback->on_mwi_info,
+		param_acc_id	= Py_BuildValue("i",acc_id),
+		param_body	= PyString_FromPJ(&body),
+		NULL
+	    );
+
+	Py_DECREF(param_acc_id);
+	Py_DECREF(param_body);
+
+	LEAVE_PYTHON();
+    }
+}
+
+/* 
+ * translate_hdr
+ * internal function 
+ * translate from hdr_list to pjsip_generic_string_hdr
+ */
+void translate_hdr(pj_pool_t *pool, pjsip_hdr *hdr, PyObject *py_hdr_list)
+{
+    pj_list_init(hdr);
+
+    if (PyList_Check(py_hdr_list)) {
+	int i;
+
+        for (i=0; i<PyList_Size(py_hdr_list); ++i)  { 
+            pj_str_t hname, hvalue;
+	    pjsip_generic_string_hdr * new_hdr;
+            PyObject * tuple = PyList_GetItem(py_hdr_list, i);
+
+            if (PyTuple_Check(tuple)) {
+		if (PyTuple_Size(tuple) >= 1)
+		    hname = PyString_ToPJ(PyTuple_GetItem(tuple,0));
+		else
+		    hname.slen = 0;
+		if (PyTuple_Size(tuple) >= 2)
+		    hvalue = PyString_ToPJ(PyTuple_GetItem(tuple,1));
+		else
+		    hvalue.slen = 0;
+            } else {
+		hname.ptr = "";
+		hname.slen = 0;
+		hvalue.ptr = "";
+		hvalue.slen = 0;
+            }  
+            new_hdr = pjsip_generic_string_hdr_create(pool, &hname, &hvalue);
+            pj_list_push_back((pj_list_type *)hdr, (pj_list_type *)new_hdr);
+	}     
+    }
+}
+
+/*
+ * py_pjsua_thread_register
+ */
+static PyObject *py_pjsua_thread_register(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;	
+    const char *name;
+    PyObject *py_desc;
+    pj_thread_t *thread;
+    struct py_thread_desc *thread_desc;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "sO", &name, &py_desc)) {
+         return NULL;
+    }
+    thread_desc = (struct py_thread_desc*)
+		  malloc(sizeof(struct py_thread_desc));
+    thread_desc->next = py_thread_desc;
+    py_thread_desc = thread_desc;
+
+    status = pj_thread_register(name, thread_desc->desc, &thread);
+
+    if (status == PJ_SUCCESS)
+	status = pj_thread_local_set(g_thread_id, (void*)1);
+
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_logging_config_default
+ */
+static PyObject *py_pjsua_logging_config_default(PyObject *pSelf,
+                                                 PyObject *pArgs)
+{
+    PyObj_pjsua_logging_config *obj;	
+    pjsua_logging_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    pjsua_logging_config_default(&cfg);
+    obj = (PyObj_pjsua_logging_config*) 
+	  PyObj_pjsua_logging_config_new(&PyTyp_pjsua_logging_config, 
+					 NULL, NULL);
+    PyObj_pjsua_logging_config_import(obj, &cfg);
+    
+    return (PyObject*)obj;
+}
+
+
+/*
+ * py_pjsua_config_default
+ */
+static PyObject *py_pjsua_config_default(PyObject *pSelf, PyObject *pArgs)
+{
+    PyObj_pjsua_config *obj;
+    pjsua_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    pjsua_config_default(&cfg);
+    obj = (PyObj_pjsua_config *) PyObj_pjsua_config_new(&PyTyp_pjsua_config, 
+							NULL, NULL);
+    PyObj_pjsua_config_import(obj, &cfg);
+
+    return (PyObject*)obj;
+}
+
+
+/*
+ * py_pjsua_media_config_default
+ */
+static PyObject * py_pjsua_media_config_default(PyObject *pSelf,
+                                                PyObject *pArgs)
+{
+    PyObj_pjsua_media_config *obj;
+    pjsua_media_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    pjsua_media_config_default(&cfg);
+    obj = (PyObj_pjsua_media_config *)
+	  PyType_GenericNew(&PyTyp_pjsua_media_config, NULL, NULL);
+    PyObj_pjsua_media_config_import(obj, &cfg);
+
+    return (PyObject *)obj;
+}
+
+
+/*
+ * py_pjsua_msg_data_init
+ */
+static PyObject *py_pjsua_msg_data_init(PyObject *pSelf, PyObject *pArgs)
+{
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    return (PyObject *)PyObj_pjsua_msg_data_new(&PyTyp_pjsua_msg_data, 
+						NULL, NULL);
+}
+
+
+/*
+ * py_pjsua_reconfigure_logging
+ */
+static PyObject *py_pjsua_reconfigure_logging(PyObject *pSelf, 
+					      PyObject *pArgs)
+{
+    PyObject *logObj;
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "O", &logObj)) {
+        return NULL;
+    }
+
+    if (logObj != Py_None) {
+	PyObj_pjsua_logging_config *log;
+	pjsua_logging_config cfg;
+
+        log = (PyObj_pjsua_logging_config*)logObj;
+        cfg.msg_logging = log->msg_logging;
+        cfg.level = log->level;
+        cfg.console_level = log->console_level;
+        cfg.decor = log->decor;
+        cfg.log_filename = PyString_ToPJ(log->log_filename);
+        Py_XDECREF(g_obj_log_cb);
+        g_obj_log_cb = log->cb;
+        Py_INCREF(g_obj_log_cb);
+        cfg.cb = &cb_log_cb;
+        status = pjsua_reconfigure_logging(&cfg);
+    } else {
+        status = pjsua_reconfigure_logging(NULL);
+    }
+
+    return Py_BuildValue("i",status);
+}
+
+
+/*
+ * py_pjsua_perror
+ */
+static PyObject *py_pjsua_perror(PyObject *pSelf, PyObject *pArgs)
+{
+    const char *sender;
+    const char *title;
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ssi", &sender, &title, &status)) {
+        return NULL;
+    }
+	
+    pjsua_perror(sender, title, status);
+
+    return Py_BuildValue("");
+}
+
+
+/*
+ * py_pjsua_create
+ */
+static PyObject *py_pjsua_create(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    status = pjsua_create();
+    
+    if (status == PJ_SUCCESS)  {
+	status = pj_thread_local_alloc(&g_thread_id);
+	if (status == PJ_SUCCESS)
+	    status = pj_thread_local_set(g_thread_id, (void*)1);
+
+	pj_atexit(&clear_py_thread_desc);
+    }
+
+    return Py_BuildValue("i",status);
+}
+
+
+/*
+ * py_pjsua_init
+ */
+static PyObject *py_pjsua_init(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *o_ua_cfg, *o_log_cfg, *o_media_cfg;
+    pjsua_config cfg_ua, *p_cfg_ua;
+    pjsua_logging_config cfg_log, *p_cfg_log;
+    pjsua_media_config cfg_media, *p_cfg_media;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OOO", &o_ua_cfg, &o_log_cfg, &o_media_cfg)) {
+        return NULL;
+    }
+    
+    pjsua_config_default(&cfg_ua);
+    pjsua_logging_config_default(&cfg_log);
+    pjsua_media_config_default(&cfg_media);
+
+    if (o_ua_cfg != Py_None) {
+	PyObj_pjsua_config *obj_ua_cfg = (PyObj_pjsua_config*)o_ua_cfg;
+
+	PyObj_pjsua_config_export(&cfg_ua, obj_ua_cfg);
+
+	Py_XDECREF(g_obj_callback);
+    	g_obj_callback = obj_ua_cfg->cb;
+    	Py_INCREF(g_obj_callback);
+
+    	cfg_ua.cb.on_call_state = &cb_on_call_state;
+    	cfg_ua.cb.on_incoming_call = &cb_on_incoming_call;
+    	cfg_ua.cb.on_call_media_state = &cb_on_call_media_state;
+	cfg_ua.cb.on_dtmf_digit = &cb_on_dtmf_digit;
+    	cfg_ua.cb.on_call_transfer_request = &cb_on_call_transfer_request;
+    	cfg_ua.cb.on_call_transfer_status = &cb_on_call_transfer_status;
+    	cfg_ua.cb.on_call_replace_request = &cb_on_call_replace_request;
+    	cfg_ua.cb.on_call_replaced = &cb_on_call_replaced;
+    	cfg_ua.cb.on_reg_state = &cb_on_reg_state;
+	cfg_ua.cb.on_incoming_subscribe = &cb_on_incoming_subscribe;
+    	cfg_ua.cb.on_buddy_state = &cb_on_buddy_state;
+    	cfg_ua.cb.on_pager2 = &cb_on_pager;
+    	cfg_ua.cb.on_pager_status2 = &cb_on_pager_status;
+    	cfg_ua.cb.on_typing2 = &cb_on_typing;
+	cfg_ua.cb.on_mwi_info = &cb_on_mwi_info;
+
+        p_cfg_ua = &cfg_ua;
+
+    } else {
+        p_cfg_ua = NULL;
+    }
+
+    if (o_log_cfg != Py_None)  {
+	PyObj_pjsua_logging_config * obj_log;
+
+        obj_log = (PyObj_pjsua_logging_config *)o_log_cfg;
+        
+        PyObj_pjsua_logging_config_export(&cfg_log, obj_log);
+
+        Py_XDECREF(g_obj_log_cb);
+        g_obj_log_cb = obj_log->cb;
+        Py_INCREF(g_obj_log_cb);
+
+        cfg_log.cb = &cb_log_cb;
+        p_cfg_log = &cfg_log;
+
+    } else {
+        p_cfg_log = NULL;
+    }
+
+    if (o_media_cfg != Py_None) {
+	PyObj_pjsua_media_config_export(&cfg_media, 
+				        (PyObj_pjsua_media_config*)o_media_cfg);
+	p_cfg_media = &cfg_media;
+
+    } else {
+        p_cfg_media = NULL;
+    }
+
+    status = pjsua_init(p_cfg_ua, p_cfg_log, p_cfg_media);
+
+    return Py_BuildValue("i", status);
+}
+
+
+/*
+ * py_pjsua_start
+ */
+static PyObject *py_pjsua_start(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    status = pjsua_start();
+    
+    return Py_BuildValue("i", status);
+}
+
+
+/*
+ * py_pjsua_destroy
+ */
+static PyObject *py_pjsua_destroy(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    status = pjsua_destroy();
+    
+    return Py_BuildValue("i", status);
+}
+
+
+/*
+ * py_pjsua_handle_events
+ */
+static PyObject *py_pjsua_handle_events(PyObject *pSelf, PyObject *pArgs)
+{
+    int ret;
+    int msec;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &msec)) {
+        return NULL;
+    }
+
+    if (msec < 0)
+	msec = 0;
+
+#if !NO_PJSIP_THREAD
+    /* Since handle_events() will block, we must wrap it with ALLOW_THREADS
+     * construct, or otherwise many Python blocking functions (such as
+     * time.sleep(), readline(), etc.) may hang/block indefinitely.
+     * See http://www.python.org/doc/current/api/threads.html for more info.
+     */
+    Py_BEGIN_ALLOW_THREADS
+#endif
+
+    ret = pjsua_handle_events(msec);
+
+#if !NO_PJSIP_THREAD
+    Py_END_ALLOW_THREADS
+#endif
+    
+    return Py_BuildValue("i", ret);
+}
+
+
+/*
+ * py_pjsua_verify_sip_url
+ */
+static PyObject *py_pjsua_verify_sip_url(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    const char *url;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "s", &url)) {
+        return NULL;
+    }
+
+    status = pjsua_verify_sip_url(url);
+    
+    return Py_BuildValue("i", status);
+}
+
+
+/*
+ * function doc
+ */
+
+static char pjsua_thread_register_doc[] =
+    "int _pjsua.thread_register(string name, int[] desc)";
+static char pjsua_perror_doc[] =
+    "void _pjsua.perror (string sender, string title, int status) "
+    "Display error message for the specified error code. Parameters: "
+    "sender: The log sender field;  "
+    "title: Message title for the error; "
+    "status: Status code.";
+
+static char pjsua_create_doc[] =
+    "int _pjsua.create (void) "
+    "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 pjsua_destroy() "
+    "before quitting.";
+
+static char pjsua_init_doc[] =
+    "int _pjsua.init (_pjsua.Config obj_ua_cfg, "
+        "_pjsua.Logging_Config log_cfg, _pjsua.Media_Config media_cfg) "
+    "Initialize pjsua with the specified settings. All the settings are "
+    "optional, and the default values will be used when the config is not "
+    "specified. Parameters: "
+    "obj_ua_cfg : User agent configuration;  "
+    "log_cfg : Optional logging configuration; "
+    "media_cfg : Optional media configuration.";
+
+static char pjsua_start_doc[] =
+    "int _pjsua.start (void) "
+    "Application is recommended to call this function after all "
+    "initialization is done, so that the library can do additional checking "
+    "set up additional";
+
+static char pjsua_destroy_doc[] =
+    "int _pjsua.destroy (void) "
+    "Destroy pjsua This function must be called once PJSUA is created. To "
+    "make it easier for application, application may call this function "
+    "several times with no danger.";
+
+static char pjsua_handle_events_doc[] =
+    "int _pjsua.handle_events (int msec_timeout) "
+    "Poll pjsua for events, and if necessary block the caller thread for the "
+    "specified maximum interval (in miliseconds) Parameters: "
+    "msec_timeout: Maximum time to wait, in miliseconds. "
+    "Returns: The number of events that have been handled during the poll. "
+    "Negative value indicates error, and application can retrieve the error "
+    "as (err = -return_value).";
+
+static char pjsua_verify_sip_url_doc[] =
+    "int _pjsua.verify_sip_url (string c_url) "
+    "Verify that valid SIP url is given Parameters: "
+    "c_url: The URL, as NULL terminated string.";
+
+static char pjsua_reconfigure_logging_doc[] =
+    "int _pjsua.reconfigure_logging (_pjsua.Logging_Config c) "
+    "Application can call this function at any time (after pjsua_create(), of "
+    "course) to change logging settings. Parameters: "
+    "c: Logging configuration.";
+
+static char pjsua_logging_config_default_doc[] =
+    "_pjsua.Logging_Config _pjsua.logging_config_default  ()  "
+    "Use this function to initialize logging config.";
+
+static char pjsua_config_default_doc[] =
+    "_pjsua.Config _pjsua.config_default (). Use this function to "
+    "initialize pjsua config. ";
+
+static char pjsua_media_config_default_doc[] =
+    "_pjsua.Media_Config _pjsua.media_config_default (). "
+    "Use this function to initialize media config.";
+
+static char pjsua_msg_data_init_doc[] =
+    "_pjsua.Msg_Data void _pjsua.msg_data_init () "
+    "Initialize message data ";
+        
+
+/* END OF LIB BASE */
+
+/* LIB TRANSPORT */
+
+/*
+ * py_pjsua_transport_config_default
+ */
+static PyObject *py_pjsua_transport_config_default(PyObject *pSelf, 
+						   PyObject *pArgs)
+{
+    PyObj_pjsua_transport_config *obj;
+    pjsua_transport_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    pjsua_transport_config_default(&cfg);
+    obj = (PyObj_pjsua_transport_config*)
+	  PyObj_pjsua_transport_config_new(&PyTyp_pjsua_transport_config,
+					   NULL, NULL);
+    PyObj_pjsua_transport_config_import(obj, &cfg);
+
+    return (PyObject *)obj;
+}
+
+/*
+ * py_pjsua_transport_create
+ */
+static PyObject *py_pjsua_transport_create(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    int type;
+    PyObject *pCfg;
+    pjsua_transport_config cfg;
+    pjsua_transport_id id;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &type, &pCfg)) {
+        return NULL;
+    }
+
+    if (pCfg != Py_None) {
+	PyObj_pjsua_transport_config *obj;
+
+        obj = (PyObj_pjsua_transport_config*)pCfg;
+	PyObj_pjsua_transport_config_export(&cfg, obj);
+        status = pjsua_transport_create(type, &cfg, &id);
+    } else {
+        status = pjsua_transport_create(type, NULL, &id);
+    }
+    
+    
+    return Py_BuildValue("ii", status, id);
+}
+
+/*
+ * py_pjsua_enum_transports
+ */
+static PyObject *py_pjsua_enum_transports(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    pjsua_transport_id id[PJSIP_MAX_TRANSPORTS];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    c = PJ_ARRAY_SIZE(id);
+    status = pjsua_enum_transports(id, &c);
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) {     
+        PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
+    }
+    
+    return (PyObject*)list;
+}
+
+/*
+ * py_pjsua_transport_get_info
+ * !modified @ 051206
+ */
+static PyObject *py_pjsua_transport_get_info(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    int id;
+    pjsua_transport_info info;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }	
+    
+    status = pjsua_transport_get_info(id, &info);	
+    if (status == PJ_SUCCESS) {
+	PyObj_pjsua_transport_info *obj;
+        obj = (PyObj_pjsua_transport_info *) 
+	      PyObj_pjsua_transport_info_new(&PyTyp_pjsua_transport_info, 
+					     NULL, NULL);
+	PyObj_pjsua_transport_info_import(obj, &info);
+        return (PyObject*)obj;
+    } else {
+        return Py_BuildValue("");
+    }
+}
+
+/*
+ * py_pjsua_transport_set_enable
+ */
+static PyObject *py_pjsua_transport_set_enable(PyObject *pSelf, 
+					       PyObject *pArgs)
+{
+    pj_status_t status;
+    int id;
+    int enabled;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &id, &enabled)) {
+        return NULL;
+    }
+    status = pjsua_transport_set_enable(id, enabled);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_transport_close
+ */
+static PyObject *py_pjsua_transport_close(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    int id;
+    int force;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &id, &force)) {
+        return NULL;
+    }	
+    status = pjsua_transport_close(id, force);	
+    
+    return Py_BuildValue("i", status);
+}
+
+static char pjsua_transport_config_default_doc[] =
+    "_pjsua.Transport_Config _pjsua.transport_config_default () "
+    "Call this function to initialize UDP config with default values.";
+static char pjsua_transport_create_doc[] =
+    "int, int _pjsua.transport_create (int type, "
+    "_pjsua.Transport_Config cfg) "
+    "Create SIP transport.";
+static char pjsua_enum_transports_doc[] =
+    "int[] _pjsua.enum_transports () "
+    "Enumerate all transports currently created in the system.";
+static char pjsua_transport_get_info_doc[] =
+    "void _pjsua.transport_get_info "
+    "(_pjsua.Transport_ID id, _pjsua.Transport_Info info) "
+    "Get information about transports.";
+static char pjsua_transport_set_enable_doc[] =
+    "void _pjsua.transport_set_enable "
+    "(_pjsua.Transport_ID id, int enabled) "
+    "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.";
+static char pjsua_transport_close_doc[] =
+    "void _pjsua.transport_close (_pjsua.Transport_ID id, int force) "
+    "Close the transport. If transport is forcefully closed, "
+    "it will be immediately closed, and any pending transactions "
+    "that are using the transport may not terminate properly. "
+    "Otherwise, the system will wait until all transactions are closed "
+    "while preventing new users from using the transport, and will close "
+    "the transport when it is safe to do so.";
+
+/* END OF LIB TRANSPORT */
+
+/* LIB ACCOUNT */
+
+
+/*
+ * py_pjsua_acc_config_default
+ */
+static PyObject *py_pjsua_acc_config_default(PyObject *pSelf, PyObject *pArgs)
+{
+    PyObj_pjsua_acc_config *obj;
+    pjsua_acc_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }
+
+    pjsua_acc_config_default(&cfg);
+    obj = (PyObj_pjsua_acc_config *)
+	  PyObj_pjsua_acc_config_new(&PyTyp_pjsua_acc_config, 
+				     NULL, NULL);
+    PyObj_pjsua_acc_config_import(obj, &cfg);
+    return (PyObject *)obj;
+}
+
+/*
+ * py_pjsua_acc_get_count
+ */
+static PyObject *py_pjsua_acc_get_count(PyObject *pSelf, PyObject *pArgs)
+{
+    int count;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    count = pjsua_acc_get_count();
+    return Py_BuildValue("i", count);
+}
+
+/*
+ * py_pjsua_acc_is_valid
+ */
+static PyObject *py_pjsua_acc_is_valid(PyObject *pSelf, PyObject *pArgs)
+{    
+    int id;
+    int is_valid;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }
+
+    is_valid = pjsua_acc_is_valid(id);	
+    return Py_BuildValue("i", is_valid);
+}
+
+/*
+ * py_pjsua_acc_set_default
+ */
+static PyObject *py_pjsua_acc_set_default(PyObject *pSelf, PyObject *pArgs)
+{    
+    int id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }
+    status = pjsua_acc_set_default(id);
+	
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_get_default
+ */
+static PyObject *py_pjsua_acc_get_default(PyObject *pSelf, PyObject *pArgs)
+{    
+    int id;
+	
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    id = pjsua_acc_get_default();
+	
+    return Py_BuildValue("i", id);
+}
+
+/*
+ * py_pjsua_acc_add
+ */
+static PyObject *py_pjsua_acc_add(PyObject *pSelf, PyObject *pArgs)
+{    
+    int is_default;
+    PyObject *pCfg;
+    int acc_id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "Oi", &pCfg, &is_default)) {
+        return NULL;
+    }
+    
+    if (pCfg != Py_None) {
+	pjsua_acc_config cfg;
+	PyObj_pjsua_acc_config *ac;
+
+	pjsua_acc_config_default(&cfg);
+        ac = (PyObj_pjsua_acc_config *)pCfg;
+        PyObj_pjsua_acc_config_export(&cfg, ac);
+        status = pjsua_acc_add(&cfg, is_default, &acc_id);
+    } else {
+        status = PJ_EINVAL;
+	acc_id = PJSUA_INVALID_ID;
+    }
+    
+    return Py_BuildValue("ii", status, acc_id);
+}
+
+/*
+ * py_pjsua_acc_add_local
+ */
+static PyObject *py_pjsua_acc_add_local(PyObject *pSelf, PyObject *pArgs)
+{    
+    int is_default;
+    int tid;
+    int acc_id;
+    int status;
+	
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &tid, &is_default)) {
+        return NULL;
+    }
+	
+    status = pjsua_acc_add_local(tid, is_default, &acc_id);
+    
+    return Py_BuildValue("ii", status, acc_id);
+}
+
+/*
+ * py_pjsua_acc_set_user_data
+ */
+static PyObject *py_pjsua_acc_set_user_data(PyObject *pSelf, PyObject *pArgs)
+{    
+    int acc_id;
+    PyObject *pUserData, *old_user_data;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &acc_id, &pUserData)) {
+        return NULL;
+    }
+
+    old_user_data = (PyObject*) pjsua_acc_get_user_data(acc_id);
+
+    status = pjsua_acc_set_user_data(acc_id, (void*)pUserData);
+
+    if (status == PJ_SUCCESS) {
+	Py_XINCREF(pUserData);
+	Py_XDECREF(old_user_data);
+    }
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_get_user_data
+ */
+static PyObject *py_pjsua_acc_get_user_data(PyObject *pSelf, PyObject *pArgs)
+{    
+    int acc_id;
+    PyObject *user_data;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &acc_id)) {
+        return NULL;
+    }
+
+    user_data = (PyObject*) pjsua_acc_get_user_data(acc_id);
+
+    return user_data ? Py_BuildValue("O", user_data) : Py_BuildValue("");
+}
+
+/*
+ * py_pjsua_acc_del
+ */
+static PyObject *py_pjsua_acc_del(PyObject *pSelf, PyObject *pArgs)
+{    
+    int acc_id;
+    PyObject *user_data;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &acc_id)) {
+        return NULL;
+    }
+
+    user_data = (PyObject*) pjsua_acc_get_user_data(acc_id);
+    Py_XDECREF(user_data);
+
+    status = pjsua_acc_del(acc_id);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_modify
+ */
+static PyObject *py_pjsua_acc_modify(PyObject *pSelf, PyObject *pArgs)
+{    	
+    PyObject *pCfg;
+    PyObj_pjsua_acc_config * ac;
+    int acc_id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &acc_id, &pCfg)) {
+        return NULL;
+    }
+
+    if (pCfg != Py_None) {
+	pjsua_acc_config cfg;	
+
+	pjsua_acc_config_default(&cfg);
+        ac = (PyObj_pjsua_acc_config*)pCfg;
+        PyObj_pjsua_acc_config_export(&cfg, ac);
+
+        status = pjsua_acc_modify(acc_id, &cfg);
+    } else {
+        status = PJ_EINVAL;
+    }
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_set_online_status
+ */
+static PyObject *py_pjsua_acc_set_online_status(PyObject *pSelf, 
+						PyObject *pArgs)
+{    
+    int is_online;	
+    int acc_id;
+    int status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &is_online)) {
+        return NULL;
+    }
+	
+    status = pjsua_acc_set_online_status(acc_id, is_online);
+	
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_set_online_status2
+ */
+static PyObject *py_pjsua_acc_set_online_status2(PyObject *pSelf, 
+						 PyObject *pArgs)
+{    
+    int is_online;	
+    int acc_id;
+    int activity_id;
+    const char *activity_text = NULL;
+    const char *rpid_id = NULL;
+    pjrpid_element rpid;
+    pj_status_t status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiiss", &acc_id, &is_online,
+			  &activity_id, &activity_text, &rpid_id)) 
+    {
+        return NULL;
+    }
+
+    pj_bzero(&rpid, sizeof(rpid));
+    rpid.type = PJRPID_ELEMENT_TYPE_PERSON;
+    rpid.activity = activity_id;
+    if (activity_text)
+	rpid.note = pj_str((char*)activity_text);
+
+    if (rpid_id)
+	rpid.id = pj_str((char*)rpid_id);
+
+    status = pjsua_acc_set_online_status2(acc_id, is_online, &rpid);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_set_registration
+ */
+static PyObject *py_pjsua_acc_set_registration(PyObject *pSelf, 
+					       PyObject *pArgs)
+{    
+    int renew;	
+    int acc_id;
+    int status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &renew)) {
+        return NULL;
+    }
+	
+    status = pjsua_acc_set_registration(acc_id, renew);
+	
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_acc_get_info
+ */
+static PyObject *py_pjsua_acc_get_info(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int acc_id;
+    PyObj_pjsua_acc_info * obj;
+    pjsua_acc_info info;
+    int status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &acc_id)) {
+        return NULL;
+    }
+    
+    status = pjsua_acc_get_info(acc_id, &info);
+    if (status == PJ_SUCCESS) {
+	obj = (PyObj_pjsua_acc_info*)
+	      PyObj_pjsua_acc_info_new(&PyTyp_pjsua_acc_info, NULL, NULL);
+	PyObj_pjsua_acc_info_import(obj, &info);
+        return (PyObject*)obj;
+    } else {
+	return Py_BuildValue("");
+    }
+}
+
+/*
+ * py_pjsua_enum_accs
+ */
+static PyObject *py_pjsua_enum_accs(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    pjsua_acc_id id[PJSUA_MAX_ACC];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    c = PJ_ARRAY_SIZE(id);
+    status = pjsua_enum_accs(id, &c);
+    if (status != PJ_SUCCESS)
+	c = 0;
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) {
+        PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
+    }
+    
+    return (PyObject*)list;
+}
+
+/*
+ * py_pjsua_acc_enum_info
+ */
+static PyObject *py_pjsua_acc_enum_info(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    pjsua_acc_info info[PJSUA_MAX_ACC];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    if (!PyArg_ParseTuple(pArgs, "")) {
+        return NULL;
+    }	
+    
+    c = PJ_ARRAY_SIZE(info);
+    status = pjsua_acc_enum_info(info, &c);
+    if (status != PJ_SUCCESS)
+	c = 0;
+
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) {
+        PyObj_pjsua_acc_info *obj;
+        obj = (PyObj_pjsua_acc_info *)
+	      PyObj_pjsua_acc_info_new(&PyTyp_pjsua_acc_info, NULL, NULL);
+
+	PyObj_pjsua_acc_info_import(obj, &info[i]);
+
+        PyList_SetItem(list, i, (PyObject*)obj);
+    }
+    
+    return (PyObject*)list;
+}
+
+/*
+ * py_pjsua_acc_set_transport
+ */
+static PyObject *py_pjsua_acc_set_transport(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int acc_id, transport_id;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &transport_id)) {
+        return NULL;
+    }	
+    
+    status = pjsua_acc_set_transport(acc_id, transport_id);
+    
+    
+    return Py_BuildValue("i", status);
+}
+
+
+/*
+ * py_pjsua_acc_pres_notify
+ */
+static PyObject *py_pjsua_acc_pres_notify(PyObject *pSelf, 
+					  PyObject *pArgs)
+{
+    int acc_id, state;
+    PyObject *arg_pres, *arg_msg_data, *arg_reason;
+    void *srv_pres;
+    pjsua_msg_data msg_data;
+    pj_str_t reason;
+    pj_bool_t with_body;
+    pj_pool_t *pool = NULL;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iOiOO", &acc_id, &arg_pres, 
+			  &state, &arg_reason, &arg_msg_data))
+    {
+        return NULL;
+    }	
+    
+    srv_pres = (void*) PyLong_AsLong(arg_pres);
+    with_body = (state != PJSIP_EVSUB_STATE_TERMINATED);
+
+    if (arg_reason && PyString_Check(arg_reason)) {
+	reason = PyString_ToPJ(arg_reason);
+    } else {
+	reason = pj_str("");
+    }
+
+    pjsua_msg_data_init(&msg_data);
+    if (arg_msg_data && arg_msg_data != Py_None) {
+        PyObj_pjsua_msg_data *omd = (PyObj_pjsua_msg_data *)arg_msg_data;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_pres_notify(acc_id, (pjsua_srv_pres*)srv_pres,
+			       (pjsip_evsub_state)state, NULL,
+			       &reason, with_body, &msg_data);
+    
+    if (pool) {
+	pj_pool_release(pool);
+    }
+
+    return Py_BuildValue("i", status);
+}
+
+static char pjsua_acc_config_default_doc[] =
+    "_pjsua.Acc_Config _pjsua.acc_config_default () "
+    "Call this function to initialize account config with default values.";
+static char pjsua_acc_get_count_doc[] =
+    "int _pjsua.acc_get_count () "
+    "Get number of current accounts.";
+static char pjsua_acc_is_valid_doc[] =
+    "int _pjsua.acc_is_valid (int acc_id)  "
+    "Check if the specified account ID is valid.";
+static char pjsua_acc_set_default_doc[] =
+    "int _pjsua.acc_set_default (int acc_id) "
+    "Set default account to be used when incoming "
+    "and outgoing requests doesn't match any accounts.";
+static char pjsua_acc_get_default_doc[] =
+    "int _pjsua.acc_get_default () "
+    "Get default account.";
+static char pjsua_acc_add_doc[] =
+    "int, int _pjsua.acc_add (_pjsua.Acc_Config cfg, "
+    "int is_default) "
+    "Add a new account to pjsua. PJSUA must have been initialized "
+    "(with pjsua_init()) before calling this function.";
+static char pjsua_acc_add_local_doc[] =
+    "int,int _pjsua.acc_add_local (int tid, "
+    "int is_default) "
+    "Add a local account. A local account is used to identify "
+    "local endpoint instead of a specific user, and for this reason, "
+    "a transport ID is needed to obtain the local address information.";
+static char pjsua_acc_del_doc[] =
+    "int _pjsua.acc_del (int acc_id) "
+    "Delete account.";
+static char pjsua_acc_modify_doc[] =
+    "int _pjsua.acc_modify (int acc_id, _pjsua.Acc_Config cfg) "
+    "Modify account information.";
+static char pjsua_acc_set_online_status_doc[] =
+    "int _pjsua.acc_set_online_status2(int acc_id, int is_online) "
+    "Modify account's presence status to be advertised "
+    "to remote/presence subscribers.";
+static char pjsua_acc_set_online_status2_doc[] =
+    "int _pjsua.acc_set_online_status (int acc_id, int is_online, "
+                                         "int activity_id, string activity_text) "
+    "Modify account's presence status to be advertised "
+    "to remote/presence subscribers.";
+static char pjsua_acc_set_registration_doc[] =
+    "int _pjsua.acc_set_registration (int acc_id, int renew) "
+    "Update registration or perform unregistration.";
+static char pjsua_acc_get_info_doc[] =
+    "_pjsua.Acc_Info _pjsua.acc_get_info (int acc_id) "
+    "Get account information.";
+static char pjsua_enum_accs_doc[] =
+    "int[] _pjsua.enum_accs () "
+    "Enum accounts all account ids.";
+static char pjsua_acc_enum_info_doc[] =
+    "_pjsua.Acc_Info[] _pjsua.acc_enum_info () "
+    "Enum accounts info.";
+
+/* END OF LIB ACCOUNT */
+
+/* LIB BUDDY */
+
+
+
+/*
+ * py_pjsua_buddy_config_default
+ */
+static PyObject *py_pjsua_buddy_config_default(PyObject *pSelf, 
+					       PyObject *pArgs)
+{    
+    PyObj_pjsua_buddy_config *obj;	
+    pjsua_buddy_config cfg;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    pjsua_buddy_config_default(&cfg);
+    obj = (PyObj_pjsua_buddy_config *) 
+	  PyObj_pjsua_buddy_config_new(&PyTyp_pjsua_buddy_config, NULL, NULL);
+    PyObj_pjsua_buddy_config_import(obj, &cfg);
+    
+    return (PyObject *)obj;
+}
+
+/*
+ * py_pjsua_get_buddy_count
+ */
+static PyObject *py_pjsua_get_buddy_count(PyObject *pSelf, PyObject *pArgs)
+{    
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    return Py_BuildValue("i", pjsua_get_buddy_count());
+}
+
+/*
+ * py_pjsua_buddy_is_valid
+ */
+static PyObject *py_pjsua_buddy_is_valid(PyObject *pSelf, PyObject *pArgs)
+{    
+    int id;
+    int is_valid;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }
+    is_valid = pjsua_buddy_is_valid(id);
+	
+    return Py_BuildValue("i", is_valid);
+}
+
+/*
+ * py_pjsua_enum_buddies
+ */
+static PyObject *py_pjsua_enum_buddies(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    pjsua_buddy_id id[PJSUA_MAX_BUDDIES];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    c = PJ_ARRAY_SIZE(id);
+    status = pjsua_enum_buddies(id, &c);
+    if (status != PJ_SUCCESS)
+	c = 0;
+
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) {
+        PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
+    }
+    
+    return (PyObject*)list;
+}
+
+/*
+ * py_pjsua_buddy_find
+ */
+static PyObject *py_pjsua_buddy_find(PyObject *pSelf, PyObject *pArgs)
+{    
+    PyObject *pURI;
+    pj_str_t uri;
+    pjsua_buddy_id buddy_id;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "O", &pURI)) {
+        return NULL;
+    }
+
+    if (!PyString_Check(pURI))
+	return Py_BuildValue("i", PJSUA_INVALID_ID);
+
+    uri = PyString_ToPJ(pURI);
+    buddy_id = pjsua_buddy_find(&uri);
+
+    return Py_BuildValue("i", buddy_id);
+}
+
+/*
+ * py_pjsua_buddy_get_info
+ */
+static PyObject *py_pjsua_buddy_get_info(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int buddy_id;
+    pjsua_buddy_info info;
+    int status;	
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
+        return NULL;
+    }
+
+    status = pjsua_buddy_get_info(buddy_id, &info);
+    if (status == PJ_SUCCESS) {
+	PyObj_pjsua_buddy_info *obj;
+
+	obj = (PyObj_pjsua_buddy_info *)
+	      PyObj_pjsua_buddy_config_new(&PyTyp_pjsua_buddy_info, 
+					   NULL, NULL);
+	PyObj_pjsua_buddy_info_import(obj, &info);	
+        return (PyObject*)obj;
+    } else {
+	return Py_BuildValue("");
+    }
+}
+
+/*
+ * py_pjsua_buddy_add
+ */
+static PyObject *py_pjsua_buddy_add(PyObject *pSelf, PyObject *pArgs)
+{   
+    PyObject *pCfg;
+    int buddy_id;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "O", &pCfg)) {
+        return NULL;
+    }
+
+    if (pCfg != Py_None) {
+	pjsua_buddy_config cfg;
+	PyObj_pjsua_buddy_config *bc;
+
+        bc = (PyObj_pjsua_buddy_config *)pCfg;
+
+	pjsua_buddy_config_default(&cfg);
+        PyObj_pjsua_buddy_config_export(&cfg, bc);  
+    
+        status = pjsua_buddy_add(&cfg, &buddy_id);
+
+    } else {
+        status = PJ_EINVAL;
+	buddy_id = PJSUA_INVALID_ID;
+    }
+    return Py_BuildValue("ii", status, buddy_id);
+}
+
+/*
+ * py_pjsua_buddy_del
+ */
+static PyObject *py_pjsua_buddy_del(PyObject *pSelf, PyObject *pArgs)
+{    
+    int buddy_id;
+    int status;
+    PyObject *user_data;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
+        return NULL;
+    }
+
+    user_data = (PyObject*) pjsua_buddy_get_user_data(buddy_id);
+    Py_XDECREF(user_data);
+
+    status = pjsua_buddy_del(buddy_id);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_buddy_set_user_data
+ */
+static PyObject *py_pjsua_buddy_set_user_data(PyObject *pSelf, PyObject *pArgs)
+{    
+    int buddy_id;
+    int status;
+    PyObject *user_data, *old_user_data;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &buddy_id, &user_data)) {
+        return NULL;
+    }
+
+    if (!pjsua_buddy_is_valid(buddy_id)) {
+	return Py_BuildValue("i", 0);
+    }
+
+    old_user_data = (PyObject*) pjsua_buddy_get_user_data(buddy_id);
+
+    status = pjsua_buddy_set_user_data(buddy_id, (void*)user_data);
+
+    if (status == PJ_SUCCESS) {
+	Py_XINCREF(user_data);
+	Py_XDECREF(old_user_data);
+    }
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_buddy_get_user_data
+ */
+static PyObject *py_pjsua_buddy_get_user_data(PyObject *pSelf, PyObject *pArgs)
+{    
+    int buddy_id;
+    PyObject *user_data;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
+        return NULL;
+    }
+
+    user_data = (PyObject*) pjsua_buddy_get_user_data(buddy_id);
+
+    return user_data? Py_BuildValue("O", user_data) : Py_BuildValue("");
+}
+
+/*
+ * py_pjsua_buddy_subscribe_pres
+ */
+static PyObject *py_pjsua_buddy_subscribe_pres(PyObject *pSelf, 
+					       PyObject *pArgs)
+{
+    int buddy_id;
+    int status;
+    int subscribe;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &buddy_id, &subscribe)) {
+        return NULL;
+    }
+
+    status = pjsua_buddy_subscribe_pres(buddy_id, subscribe);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_pres_dump
+ */
+static PyObject *py_pjsua_pres_dump(PyObject *pSelf, PyObject *pArgs)
+{    
+    int verbose;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &verbose)) {
+        return NULL;
+    }
+
+    pjsua_pres_dump(verbose);	
+
+    return Py_BuildValue("");
+}
+
+/*
+ * py_pjsua_im_send
+ */
+static PyObject *py_pjsua_im_send(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int acc_id;
+    pj_str_t *mime_type, tmp_mime_type;
+    pj_str_t to, content;
+    PyObject *pTo;
+    PyObject *pMimeType;
+    PyObject *pContent;
+    pjsua_msg_data msg_data;
+    PyObject *pMsgData;
+    int user_data;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iOOOOi", &acc_id, 
+		&pTo, &pMimeType, &pContent, &pMsgData, &user_data))
+    {
+        return NULL;
+    }
+
+    if (pMimeType != Py_None) {
+        mime_type = &tmp_mime_type;
+	tmp_mime_type = PyString_ToPJ(pMimeType);
+    } else {
+        mime_type = NULL;
+    }
+
+    to = PyString_ToPJ(pTo);
+    content = PyString_ToPJ(pContent);
+
+    pjsua_msg_data_init(&msg_data);
+
+    if (pMsgData != Py_None) {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)pMsgData;
+	msg_data.content_type = PyString_ToPJ(omd->content_type);
+	msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_im_send(acc_id, &to, mime_type, &content, 
+			   &msg_data, (void*)(long)user_data);
+    if (pool)
+	pj_pool_release(pool);
+    
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_im_typing
+ */
+static PyObject *py_pjsua_im_typing(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int acc_id;
+    pj_str_t to;
+    PyObject *pTo;
+    int is_typing;
+    pjsua_msg_data msg_data;
+    PyObject *pMsgData;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iOiO", &acc_id, &pTo, &is_typing, 
+			  &pMsgData)) 
+    {
+        return NULL;
+    }
+	
+    to = PyString_ToPJ(pTo);
+
+    pjsua_msg_data_init(&msg_data);
+
+    if (pMsgData != Py_None) {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)pMsgData;
+	msg_data.content_type = PyString_ToPJ(omd->content_type);
+	msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_im_typing(acc_id, &to, is_typing, &msg_data);
+
+    if (pool)
+	pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+static char pjsua_buddy_config_default_doc[] =
+    "_pjsua.Buddy_Config _pjsua.buddy_config_default () "
+    "Set default values to the buddy config.";
+static char pjsua_get_buddy_count_doc[] =
+    "int _pjsua.get_buddy_count () "
+    "Get total number of buddies.";
+static char pjsua_buddy_is_valid_doc[] =
+    "int _pjsua.buddy_is_valid (int buddy_id) "
+    "Check if buddy ID is valid.";
+static char pjsua_enum_buddies_doc[] =
+    "int[] _pjsua.enum_buddies () "
+    "Enum buddy IDs.";
+static char pjsua_buddy_get_info_doc[] =
+    "_pjsua.Buddy_Info _pjsua.buddy_get_info (int buddy_id) "
+    "Get detailed buddy info.";
+static char pjsua_buddy_add_doc[] =
+    "int,int _pjsua.buddy_add (_pjsua.Buddy_Config cfg) "
+    "Add new buddy.";
+static char pjsua_buddy_del_doc[] =
+    "int _pjsua.buddy_del (int buddy_id) "
+    "Delete buddy.";
+static char pjsua_buddy_subscribe_pres_doc[] =
+    "int _pjsua.buddy_subscribe_pres (int buddy_id, int subscribe) "
+    "Enable/disable buddy's presence monitoring.";
+static char pjsua_pres_dump_doc[] =
+    "void _pjsua.pres_dump (int verbose) "
+    "Dump presence subscriptions to log file.";
+static char pjsua_im_send_doc[] =
+    "int _pjsua.im_send (int acc_id, string to, string mime_type, "
+    "string content, _pjsua.Msg_Data msg_data, int user_data) "
+    "Send instant messaging outside dialog, using the specified account "
+    "for route set and authentication.";
+static char pjsua_im_typing_doc[] =
+    "int _pjsua.im_typing (int acc_id, string to, int is_typing, "
+    "_pjsua.Msg_Data msg_data) "
+    "Send typing indication outside dialog.";
+
+/* END OF LIB BUDDY */
+
+/* LIB MEDIA */
+
+
+/*
+ * py_pjsua_conf_get_max_ports
+ */
+static PyObject *py_pjsua_conf_get_max_ports(PyObject *pSelf, PyObject *pArgs)
+{    
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    return Py_BuildValue("i", pjsua_conf_get_max_ports());
+}
+
+/*
+ * py_pjsua_conf_get_active_ports
+ */
+static PyObject *py_pjsua_conf_get_active_ports(PyObject *pSelf, 
+						PyObject *pArgs)
+{    
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    return Py_BuildValue("i", pjsua_conf_get_active_ports());
+}
+
+/*
+ * py_pjsua_enum_conf_ports
+ */
+static PyObject *py_pjsua_enum_conf_ports(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *list;
+    pjsua_conf_port_id id[PJSUA_MAX_CONF_PORTS];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    c = PJ_ARRAY_SIZE(id);
+    status = pjsua_enum_conf_ports(id, &c);
+    if (status != PJ_SUCCESS)
+	c = 0;
+    
+    list = PyList_New(c);
+    for (i = 0; i < c; i++) {
+        PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
+    }
+    
+    return (PyObject*)list;
+}
+
+/*
+ * py_pjsua_conf_get_port_info
+ */
+static PyObject *py_pjsua_conf_get_port_info(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    PyObj_pjsua_conf_port_info *ret;
+    pjsua_conf_port_info info;
+    int status;	
+    unsigned i;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }
+    
+    status = pjsua_conf_get_port_info(id, &info);
+    ret = (PyObj_pjsua_conf_port_info *)
+	  conf_port_info_new(&PyTyp_pjsua_conf_port_info, NULL, NULL);
+    ret->bits_per_sample = info.bits_per_sample;
+    ret->channel_count = info.channel_count;
+    ret->clock_rate = info.clock_rate;
+    ret->name = PyString_FromPJ(&info.name);
+    ret->samples_per_frame = info.samples_per_frame;
+    ret->slot_id = info.slot_id;
+    Py_XDECREF(ret->listeners);
+    ret->listeners = PyList_New(info.listener_cnt);
+    for (i = 0; i < info.listener_cnt; i++) {
+	PyObject *item = Py_BuildValue("i",info.listeners[i]);
+	PyList_SetItem(ret->listeners, i, item);
+    }
+    return (PyObject*)ret;
+}
+
+/*
+ * py_pjsua_conf_remove_port
+ */
+static PyObject *py_pjsua_conf_remove_port(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }	
+    
+    status = pjsua_conf_remove_port(id);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_conf_connect
+ */
+static PyObject *py_pjsua_conf_connect(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int source, sink;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &source, &sink)) {
+        return NULL;
+    }	
+    
+    status = pjsua_conf_connect(source, sink);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_conf_disconnect
+ */
+static PyObject *py_pjsua_conf_disconnect(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int source, sink;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &source, &sink)) {
+        return NULL;
+    }	
+    
+    status = pjsua_conf_disconnect(source, sink);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_conf_set_tx_level
+ */
+static PyObject *py_pjsua_conf_set_tx_level(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int slot;
+    float level;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "if", &slot, &level)) {
+        return NULL;
+    }	
+    
+    status = pjsua_conf_adjust_tx_level(slot, level);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_conf_set_rx_level
+ */
+static PyObject *py_pjsua_conf_set_rx_level(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int slot;
+    float level;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "if", &slot, &level)) {
+        return NULL;
+    }	
+    
+    status = pjsua_conf_adjust_rx_level(slot, level);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_conf_get_signal_level
+ */
+static PyObject *py_pjsua_conf_get_signal_level(PyObject *pSelf, 
+						PyObject *pArgs)
+{    	
+    int slot;
+    unsigned tx_level, rx_level;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &slot)) {
+        return NULL;
+    }	
+    
+    status = pjsua_conf_get_signal_level(slot, &tx_level, &rx_level);
+    
+    return Py_BuildValue("iff", status, (float)(tx_level/255.0), 
+			 (float)(rx_level/255.0));
+}
+
+/*
+ * py_pjsua_player_create
+ */
+static PyObject *py_pjsua_player_create(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int options;
+    PyObject *pFilename;
+    pj_str_t filename;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "Oi", &pFilename, &options)) {
+        return NULL;
+    }
+
+    filename = PyString_ToPJ(pFilename);
+    status = pjsua_player_create(&filename, options, &id);
+    
+    return Py_BuildValue("ii", status, id);
+}
+
+/*
+ * py_pjsua_playlist_create
+ */
+static PyObject *py_pjsua_playlist_create(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int options;
+    PyObject *pLabel, *pFileList;
+    pj_str_t label;
+    int count;
+    pj_str_t files[64];
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OOi", &pLabel, &pFileList, &options)) {
+        return NULL;
+    }
+
+    label = PyString_ToPJ(pLabel);
+    if (!PyList_Check(pFileList))
+	return Py_BuildValue("ii", PJ_EINVAL, PJSUA_INVALID_ID);
+
+    count = 0;
+    for (count=0; count<PyList_Size(pFileList) && 
+		  count<PJ_ARRAY_SIZE(files); ++count) 
+    {
+	files[count] = PyString_ToPJ(PyList_GetItem(pFileList, count));
+    }
+
+    status = pjsua_playlist_create(files, count, &label, options, &id);
+    
+    return Py_BuildValue("ii", status, id);
+}
+
+/*
+ * py_pjsua_player_get_conf_port
+ */
+static PyObject *py_pjsua_player_get_conf_port(PyObject *pSelf, 
+					       PyObject *pArgs)
+{    	
+    
+    int id, port_id;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }	
+    
+    port_id = pjsua_player_get_conf_port(id);
+    
+    return Py_BuildValue("i", port_id);
+}
+
+/*
+ * py_pjsua_player_set_pos
+ */
+static PyObject *py_pjsua_player_set_pos(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int samples;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &id, &samples)) {
+        return NULL;
+    }	
+    
+    if (samples < 0)
+	samples = 0;
+
+    status = pjsua_player_set_pos(id, samples);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_player_destroy
+ */
+static PyObject *py_pjsua_player_destroy(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }	
+    
+    status = pjsua_player_destroy(id);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_recorder_create
+ */
+static PyObject *py_pjsua_recorder_create(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id, options;
+    int max_size;
+    PyObject *pFilename, *pEncParam;
+    pj_str_t filename;
+    int enc_type;
+    
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OiOii", &pFilename, &enc_type, &pEncParam,
+			  &max_size, &options))
+    {
+        return NULL;
+    }
+
+    filename = PyString_ToPJ(pFilename);
+
+    status = pjsua_recorder_create(&filename, enc_type, NULL, max_size,
+				   options, &id);
+
+    return Py_BuildValue("ii", status, id);
+}
+
+/*
+ * py_pjsua_recorder_get_conf_port
+ */
+static PyObject *py_pjsua_recorder_get_conf_port(PyObject *pSelf, 
+						 PyObject *pArgs)
+{    	
+    
+    int id, port_id;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }	
+    
+    port_id = pjsua_recorder_get_conf_port(id);
+    
+    return Py_BuildValue("i", port_id);
+}
+
+/*
+ * py_pjsua_recorder_destroy
+ */
+static PyObject *py_pjsua_recorder_destroy(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int id;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &id)) {
+        return NULL;
+    }	
+    
+    status = pjsua_recorder_destroy(id);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_enum_snd_devs
+ */
+static PyObject *py_pjsua_enum_snd_devs(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *ret;
+    pjmedia_snd_dev_info info[SND_DEV_NUM];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    c = PJ_ARRAY_SIZE(info);
+    status = pjsua_enum_snd_devs(info, &c);
+    if (status != PJ_SUCCESS)
+	c = 0;
+    
+    ret = PyList_New(c);
+    for (i = 0; i < c; i++)  {
+        PyObj_pjmedia_snd_dev_info * obj;
+
+        obj = (PyObj_pjmedia_snd_dev_info *)
+	      pjmedia_snd_dev_info_new(&PyTyp_pjmedia_snd_dev_info, 
+				       NULL, NULL);
+        obj->default_samples_per_sec = info[i].default_samples_per_sec;
+        obj->input_count = info[i].input_count;
+        obj->output_count = info[i].output_count;
+        obj->name = PyString_FromString(info[i].name);
+
+        PyList_SetItem(ret, i, (PyObject *)obj);
+    }
+    
+    return (PyObject*)ret;
+}
+
+/*
+ * py_pjsua_get_snd_dev
+ */
+static PyObject *py_pjsua_get_snd_dev(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int capture_dev, playback_dev;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    status = pjsua_get_snd_dev(&capture_dev, &playback_dev);
+    
+    return Py_BuildValue("ii", capture_dev, playback_dev);
+}
+
+/*
+ * py_pjsua_set_snd_dev
+ */
+static PyObject *py_pjsua_set_snd_dev(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int capture_dev, playback_dev;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &capture_dev, &playback_dev)) {
+        return NULL;
+    }	
+    
+    status = pjsua_set_snd_dev(capture_dev, playback_dev);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_set_null_snd_dev
+ */
+static PyObject *py_pjsua_set_null_snd_dev(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int status;	
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    status = pjsua_set_null_snd_dev();
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_set_ec
+ */
+static PyObject *py_pjsua_set_ec(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int options;
+    int tail_ms;
+    int status;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "ii", &tail_ms, &options)) {
+        return NULL;
+    }	
+
+    status = pjsua_set_ec(tail_ms, options);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_get_ec_tail
+ */
+static PyObject *py_pjsua_get_ec_tail(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int status;	
+    unsigned tail_ms;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    status = pjsua_get_ec_tail(&tail_ms);
+    if (status != PJ_SUCCESS)
+	tail_ms = 0;
+    
+    return Py_BuildValue("i", tail_ms);
+}
+
+/*
+ * py_pjsua_enum_codecs
+ */
+static PyObject *py_pjsua_enum_codecs(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *ret;
+    pjsua_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    c = PJ_ARRAY_SIZE(info);
+    status = pjsua_enum_codecs(info, &c);
+    if (status != PJ_SUCCESS)
+	c = 0;
+    
+    ret = PyList_New(c);
+    for (i = 0; i < c; i++)  {
+        PyObj_pjsua_codec_info * obj;
+        obj = (PyObj_pjsua_codec_info *)
+	      codec_info_new(&PyTyp_pjsua_codec_info, NULL, NULL);
+        obj->codec_id = PyString_FromPJ(&info[i].codec_id);
+        obj->priority = info[i].priority;
+
+        PyList_SetItem(ret, i, (PyObject *)obj);
+    }
+
+    return (PyObject*)ret;
+}
+
+/*
+ * py_pjsua_codec_set_priority
+ */
+static PyObject *py_pjsua_codec_set_priority(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int status;	
+    PyObject *pCodecId;
+    pj_str_t codec_id;
+    int priority;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "Oi", &pCodecId, &priority)) {
+        return NULL;
+    }
+
+    codec_id = PyString_ToPJ(pCodecId);
+    if (priority < 0)
+	priority = 0;
+    if (priority > 255)
+	priority = 255;
+
+    status = pjsua_codec_set_priority(&codec_id, (pj_uint8_t)priority);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_codec_get_param
+ */
+static PyObject *py_pjsua_codec_get_param(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int status;	
+    PyObject *pCodecId;
+    pj_str_t codec_id;
+    pjmedia_codec_param param;
+    PyObj_pjmedia_codec_param *ret;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "O", &pCodecId)) {
+        return NULL;
+    }	
+
+    codec_id = PyString_ToPJ(pCodecId);
+
+    status = pjsua_codec_get_param(&codec_id, &param);
+    if (status != PJ_SUCCESS)
+	return Py_BuildValue("");
+
+    ret = (PyObj_pjmedia_codec_param *)
+	  pjmedia_codec_param_new(&PyTyp_pjmedia_codec_param, NULL, NULL);
+
+    ret->info->avg_bps = param.info.avg_bps;
+    ret->info->channel_cnt = param.info.channel_cnt;
+    ret->info->clock_rate = param.info.clock_rate;
+    ret->info->frm_ptime = param.info.frm_ptime;
+    ret->info->pcm_bits_per_sample = param.info.pcm_bits_per_sample;
+    ret->info->pt = param.info.pt;
+    ret->setting->cng = param.setting.cng;
+    //ret->setting->dec_fmtp_mode = param.setting.dec_fmtp_mode;
+    //ret->setting->enc_fmtp_mode = param.setting.enc_fmtp_mode;
+    ret->setting->frm_per_pkt = param.setting.frm_per_pkt;
+    ret->setting->penh = param.setting.penh;
+    ret->setting->plc = param.setting.plc;
+    ret->setting->vad = param.setting.vad;
+
+    return (PyObject*)ret;
+}
+
+
+/*
+ * py_pjsua_codec_set_param
+ */
+static PyObject *py_pjsua_codec_set_param(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int status;	
+    PyObject *pCodecId, *pCodecParam;
+    pj_str_t codec_id;
+    pjmedia_codec_param param;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "OO", &pCodecId, &pCodecParam)) {
+        return NULL;
+    }	
+
+    codec_id = PyString_ToPJ(pCodecId);
+
+    if (pCodecParam != Py_None) {
+	PyObj_pjmedia_codec_param *obj;
+
+        obj = (PyObj_pjmedia_codec_param *)pCodecParam;
+
+        param.info.avg_bps = obj->info->avg_bps;
+        param.info.channel_cnt = obj->info->channel_cnt;
+        param.info.clock_rate = obj->info->clock_rate;
+        param.info.frm_ptime = obj->info->frm_ptime;
+        param.info.pcm_bits_per_sample = obj->info->pcm_bits_per_sample;
+        param.info.pt = obj->info->pt;
+        param.setting.cng = obj->setting->cng;
+        //param.setting.dec_fmtp_mode = obj->setting->dec_fmtp_mode;
+        //param.setting.enc_fmtp_mode = obj->setting->enc_fmtp_mode;
+        param.setting.frm_per_pkt = obj->setting->frm_per_pkt;
+        param.setting.penh = obj->setting->penh;
+        param.setting.plc = obj->setting->plc;
+        param.setting.vad = obj->setting->vad;
+        status = pjsua_codec_set_param(&codec_id, &param);
+
+    } else {
+        status = pjsua_codec_set_param(&codec_id, NULL);
+    }
+
+    return Py_BuildValue("i", status);
+}
+
+static char pjsua_conf_get_max_ports_doc[] =
+    "int _pjsua.conf_get_max_ports () "
+    "Get maxinum number of conference ports.";
+static char pjsua_conf_get_active_ports_doc[] =
+    "int _pjsua.conf_get_active_ports () "
+    "Get current number of active ports in the bridge.";
+static char pjsua_enum_conf_ports_doc[] =
+    "int[] _pjsua.enum_conf_ports () "
+    "Enumerate all conference ports.";
+static char pjsua_conf_get_port_info_doc[] =
+    "_pjsua.Conf_Port_Info _pjsua.conf_get_port_info (int id) "
+    "Get information about the specified conference port";
+static char pjsua_conf_remove_port_doc[] =
+    "int _pjsua.conf_remove_port (int id) "
+    "Remove arbitrary slot from the conference bridge. "
+    "Application should only call this function "
+    "if it registered the port manually.";
+static char pjsua_conf_connect_doc[] =
+    "int _pjsua.conf_connect (int source, int sink) "
+    "Establish unidirectional media flow from souce to sink. "
+    "One source may transmit to multiple destinations/sink. "
+    "And if multiple sources are transmitting to the same sink, "
+    "the media will be mixed together. Source and sink may refer "
+    "to the same ID, effectively looping the media. "
+    "If bidirectional media flow is desired, application "
+    "needs to call this function twice, with the second "
+    "one having the arguments reversed.";
+static char pjsua_conf_disconnect_doc[] =
+    "int _pjsua.conf_disconnect (int source, int sink) "
+    "Disconnect media flow from the source to destination port.";
+static char pjsua_player_create_doc[] =
+    "int, int _pjsua.player_create (string filename, int options) "
+    "Create a file player, and automatically connect "
+    "this player to the conference bridge.";
+static char pjsua_player_get_conf_port_doc[] =
+    "int _pjsua.player_get_conf_port (int) "
+    "Get conference port ID associated with player.";
+static char pjsua_player_set_pos_doc[] =
+    "int _pjsua.player_set_pos (int id, int samples) "
+    "Set playback position.";
+static char pjsua_player_destroy_doc[] =
+    "int _pjsua.player_destroy (int id) "
+    "Close the file, remove the player from the bridge, "
+    "and free resources associated with the file player.";
+static char pjsua_recorder_create_doc[] =
+    "int, int _pjsua.recorder_create (string filename, "
+    "int enc_type, int enc_param, int max_size, int options) "
+    "Create a file recorder, and automatically connect this recorder "
+    "to the conference bridge. The recorder currently supports recording "
+    "WAV file, and on Windows, MP3 file. The type of the recorder to use "
+    "is determined by the extension of the file (e.g. '.wav' or '.mp3').";
+static char pjsua_recorder_get_conf_port_doc[] =
+    "int _pjsua.recorder_get_conf_port (int id) "
+    "Get conference port associated with recorder.";
+static char pjsua_recorder_destroy_doc[] =
+    "int _pjsua.recorder_destroy (int id) "
+    "Destroy recorder (this will complete recording).";
+static char pjsua_enum_snd_devs_doc[] =
+    "_pjsua.PJMedia_Snd_Dev_Info[] _pjsua.enum_snd_devs (int count) "
+    "Enum sound devices.";
+static char pjsua_get_snd_dev_doc[] =
+    "int, int _pjsua.get_snd_dev () "
+    "Get currently active sound devices. "
+    "If sound devices has not been created "
+    "(for example when pjsua_start() is not called), "
+    "it is possible that the function returns "
+    "PJ_SUCCESS with -1 as device IDs.";
+static char pjsua_set_snd_dev_doc[] =
+    "int _pjsua.set_snd_dev (int capture_dev, int playback_dev) "
+    "Select or change sound device. Application may call this function "
+    "at any time to replace current sound device.";
+static char pjsua_set_null_snd_dev_doc[] =
+    "int _pjsua.set_null_snd_dev () "
+    "Set pjsua to use null sound device. The null sound device only "
+    "provides the timing needed by the conference bridge, and will not "
+    "interract with any hardware.";
+static char pjsua_set_ec_doc[] =
+    "int _pjsua.set_ec (int tail_ms, int options) "
+    "Configure the echo canceller tail length of the sound port.";
+static char pjsua_get_ec_tail_doc[] =
+    "int _pjsua.get_ec_tail () "
+    "Get current echo canceller tail length.";
+static char pjsua_enum_codecs_doc[] =
+    "_pjsua.Codec_Info[] _pjsua.enum_codecs () "
+    "Enum all supported codecs in the system.";
+static char pjsua_codec_set_priority_doc[] =
+    "int _pjsua.codec_set_priority (string id, int priority) "
+    "Change codec priority.";
+static char pjsua_codec_get_param_doc[] =
+    "_pjsua.PJMedia_Codec_Param _pjsua.codec_get_param (string id) "
+    "Get codec parameters";
+static char pjsua_codec_set_param_doc[] =
+    "int _pjsua.codec_set_param (string id, "
+    "_pjsua.PJMedia_Codec_Param param) "
+    "Set codec parameters.";
+
+/* END OF LIB MEDIA */
+
+/* LIB CALL */
+
+/*
+ * py_pjsua_call_get_max_count
+ */
+static PyObject *py_pjsua_call_get_max_count(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int count;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    count = pjsua_call_get_max_count();
+    
+    return Py_BuildValue("i", count);
+}
+
+/*
+ * py_pjsua_call_get_count
+ */
+static PyObject *py_pjsua_call_get_count(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int count;	
+    
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    count = pjsua_call_get_count();
+    
+    return Py_BuildValue("i", count);
+}
+
+/*
+ * py_pjsua_enum_calls
+ */
+static PyObject *py_pjsua_enum_calls(PyObject *pSelf, PyObject *pArgs)
+{
+    pj_status_t status;
+    PyObject *ret;
+    pjsua_transport_id id[PJSUA_MAX_CALLS];
+    unsigned c, i;
+
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    c = PJ_ARRAY_SIZE(id);
+    status = pjsua_enum_calls(id, &c);
+    if (status != PJ_SUCCESS)
+	c = 0;
+    
+    ret = PyList_New(c);
+    for (i = 0; i < c; i++)  {     
+        PyList_SetItem(ret, i, Py_BuildValue("i", id[i]));
+    }
+    
+    return (PyObject*)ret;
+}
+
+/*
+ * py_pjsua_call_make_call
+ */
+static PyObject *py_pjsua_call_make_call(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int acc_id;
+    pj_str_t dst_uri;
+    PyObject *pDstUri, *pMsgData, *pUserData;
+	pjsua_call_setting option;
+    pjsua_msg_data msg_data;
+    int call_id;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+	pjsua_call_setting_default(&option);
+	if (!PyArg_ParseTuple(pArgs, "iOIOO", &acc_id, &pDstUri, &option.flag, 
+			  &pUserData, &pMsgData))
+    {
+        return NULL;
+    }
+	
+    dst_uri = PyString_ToPJ(pDstUri);
+    pjsua_msg_data_init(&msg_data);
+
+    if (pMsgData != Py_None) {
+	PyObj_pjsua_msg_data * omd;
+
+        omd = (PyObj_pjsua_msg_data *)pMsgData;
+
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    Py_XINCREF(pUserData);
+
+    status = pjsua_call_make_call(acc_id, &dst_uri, 
+				  &option, (void*)pUserData, 
+				  &msg_data, &call_id);	
+    if (pool != NULL)
+	pj_pool_release(pool);
+    
+    if (status != PJ_SUCCESS) {
+    	Py_XDECREF(pUserData);
+    }
+
+    return Py_BuildValue("ii", status, call_id);	
+}
+
+/*
+ * py_pjsua_call_is_active
+ */
+static PyObject *py_pjsua_call_is_active(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int is_active;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
+        return NULL;
+    }	
+    
+    is_active = pjsua_call_is_active(call_id);
+    
+    return Py_BuildValue("i", is_active);
+}
+
+/*
+ * py_pjsua_call_has_media
+ */
+static PyObject *py_pjsua_call_has_media(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int has_media;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
+        return NULL;
+    }	
+    
+    has_media = pjsua_call_has_media(call_id);
+
+    return Py_BuildValue("i", has_media);
+}
+
+/*
+ * py_pjsua_call_get_conf_port
+ */
+static PyObject* py_pjsua_call_get_conf_port(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int port_id;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
+        return NULL;
+    }
+
+    port_id = pjsua_call_get_conf_port(call_id);
+
+    return Py_BuildValue("i", port_id);
+}
+
+/*
+ * py_pjsua_call_get_info
+ */
+static PyObject* py_pjsua_call_get_info(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int status;
+    PyObj_pjsua_call_info *ret;
+    pjsua_call_info info;
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
+        return NULL;
+    }	
+    
+    status = pjsua_call_get_info(call_id, &info);
+    if (status != PJ_SUCCESS)
+	return Py_BuildValue("");
+
+    ret = (PyObj_pjsua_call_info *)call_info_new(&PyTyp_pjsua_call_info,
+						 NULL, NULL);
+    ret->acc_id = info.acc_id;
+    Py_XDECREF(ret->call_id);
+    ret->call_id = PyString_FromPJ(&info.call_id);
+    ret->conf_slot = info.conf_slot;
+    ret->connect_duration = info.connect_duration.sec * 1000 +
+			    info.connect_duration.msec;
+    ret->total_duration = info.total_duration.sec * 1000 +
+			  info.total_duration.msec;
+    ret->id = info.id;
+    ret->last_status = info.last_status;
+    Py_XDECREF(ret->last_status_text);
+    ret->last_status_text = PyString_FromPJ(&info.last_status_text);
+    Py_XDECREF(ret->local_contact);
+    ret->local_contact = PyString_FromPJ(&info.local_contact);
+    Py_XDECREF(ret->local_info);
+    ret->local_info = PyString_FromPJ(&info.local_info);
+    Py_XDECREF(ret->remote_contact);
+    ret->remote_contact = PyString_FromPJ(&info.remote_contact);
+    Py_XDECREF(ret->remote_info);
+    ret->remote_info = PyString_FromPJ(&info.remote_info);
+    ret->media_dir = info.media_dir;
+    ret->media_status = info.media_status;
+    ret->role = info.role;
+    ret->state = info.state;
+    Py_XDECREF(ret->state_text);
+    ret->state_text = PyString_FromPJ(&info.state_text);
+
+    return (PyObject*)ret;
+}
+
+/*
+ * py_pjsua_call_set_user_data
+ */
+static PyObject *py_pjsua_call_set_user_data(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    PyObject *pUserData, *old_user_data;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &pUserData)) {
+        return NULL;
+    }
+
+    old_user_data = (PyObject*) pjsua_call_get_user_data(call_id);
+
+    if (old_user_data == pUserData) {
+	return Py_BuildValue("i", PJ_SUCCESS);
+    }
+
+    Py_XINCREF(pUserData);
+    Py_XDECREF(old_user_data);
+
+    status = pjsua_call_set_user_data(call_id, (void*)pUserData);
+    
+    if (status != PJ_SUCCESS) {
+    	Py_XDECREF(pUserData);
+    }
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_get_user_data
+ */
+static PyObject *py_pjsua_call_get_user_data(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    PyObject *user_data;	
+    
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
+        return NULL;
+    }	
+    
+    user_data = (PyObject*)pjsua_call_get_user_data(call_id);
+    return user_data ? Py_BuildValue("O", user_data) : Py_BuildValue("");
+}
+
+/*
+ * py_pjsua_call_answer
+ */
+static PyObject *py_pjsua_call_answer(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    pj_str_t * reason, tmp_reason;
+    PyObject *pReason;
+    unsigned code;
+    pjsua_msg_data msg_data;
+    PyObject * omdObj;
+    pj_pool_t * pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &pReason, &omdObj)) {
+        return NULL;
+    }
+
+    if (pReason == Py_None) {
+        reason = NULL;
+    } else {
+	reason = &tmp_reason;
+        tmp_reason = PyString_ToPJ(pReason);
+    }
+
+    pjsua_msg_data_init(&msg_data);
+    if (omdObj != Py_None) {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+    
+    status = pjsua_call_answer(call_id, code, reason, &msg_data);	
+
+    if (pool)
+	pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_hangup
+ */
+static PyObject *py_pjsua_call_hangup(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    pj_str_t *reason, tmp_reason;
+    PyObject *pReason;
+    unsigned code;
+    pjsua_msg_data msg_data;
+    PyObject *omdObj;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &pReason, 
+			  &omdObj))
+    {
+        return NULL;
+    }
+
+    if (pReason == Py_None) {
+        reason = NULL;
+    } else {
+        reason = &tmp_reason;
+        tmp_reason = PyString_ToPJ(pReason);
+    }
+
+    pjsua_msg_data_init(&msg_data);
+    if (omdObj != Py_None)  {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+    
+    status = pjsua_call_hangup(call_id, code, reason, &msg_data);
+    if (pool)
+	pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_set_hold
+ */
+static PyObject *py_pjsua_call_set_hold(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;    
+    pjsua_msg_data msg_data;
+    PyObject *omdObj;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &omdObj)) {
+        return NULL;
+    }
+
+    pjsua_msg_data_init(&msg_data);
+    if (omdObj != Py_None) {
+	PyObj_pjsua_msg_data *omd;    
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_call_set_hold(call_id, &msg_data);
+
+    if (pool)
+        pj_pool_release(pool);
+
+    return Py_BuildValue("i",status);
+}
+
+/*
+ * py_pjsua_call_reinvite
+ */
+static PyObject *py_pjsua_call_reinvite(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    int unhold;
+    pjsua_msg_data msg_data;
+    PyObject *omdObj;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &unhold, &omdObj)) {
+        return NULL;
+    }
+
+    pjsua_msg_data_init(&msg_data);
+    if (omdObj != Py_None) {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_call_reinvite(call_id, unhold, &msg_data);
+
+    if (pool)
+        pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_update
+ */
+static PyObject *py_pjsua_call_update(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;    
+    int option;
+    pjsua_msg_data msg_data;
+    PyObject *omdObj;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &option, &omdObj)) {
+        return NULL;
+    }
+
+    pjsua_msg_data_init(&msg_data);
+    if (omdObj != Py_None) {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_call_update(call_id, option, &msg_data);	
+
+    if (pool)
+        pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_send_request
+ */
+static PyObject *py_pjsua_call_send_request(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;    
+    PyObject *pMethod;
+    pj_str_t method;
+    pjsua_msg_data msg_data;
+    PyObject *omdObj;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iOO", &call_id, &pMethod, &omdObj)) {
+        return NULL;
+    }
+
+    if (!PyString_Check(pMethod)) {
+	return NULL;
+    }
+
+    method = PyString_ToPJ(pMethod);
+    pjsua_msg_data_init(&msg_data);
+
+    if (omdObj != Py_None) {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_call_send_request(call_id, &method, &msg_data);	
+
+    if (pool)
+        pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_xfer
+ */
+static PyObject *py_pjsua_call_xfer(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    pj_str_t dest;
+    PyObject *pDstUri;
+    pjsua_msg_data msg_data;
+    PyObject *omdObj;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iOO", &call_id, &pDstUri, &omdObj)) {
+        return NULL;
+    }
+
+    if (!PyString_Check(pDstUri))
+	return NULL;
+
+    dest = PyString_ToPJ(pDstUri);
+    pjsua_msg_data_init(&msg_data);
+
+    if (omdObj != Py_None) {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_call_xfer(call_id, &dest, &msg_data);
+
+    if (pool)
+        pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_xfer_replaces
+ */
+static PyObject *py_pjsua_call_xfer_replaces(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    int dest_call_id;
+    unsigned options;    
+    pjsua_msg_data msg_data;
+    PyObject *omdObj;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiIO", &call_id, &dest_call_id, 
+			  &options, &omdObj))
+    {
+        return NULL;
+    }
+
+    pjsua_msg_data_init(&msg_data);
+
+    if (omdObj != Py_None) {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_call_xfer_replaces(call_id, dest_call_id, options, 
+				      &msg_data);
+
+    if (pool)
+	pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_dial_dtmf
+ */
+static PyObject *py_pjsua_call_dial_dtmf(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    PyObject *pDigits;
+    pj_str_t digits;
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &pDigits)) {
+        return NULL;
+    }
+
+    if (!PyString_Check(pDigits))
+	return Py_BuildValue("i", PJ_EINVAL);
+
+    digits = PyString_ToPJ(pDigits);
+    status = pjsua_call_dial_dtmf(call_id, &digits);
+    
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_send_im
+ */
+static PyObject *py_pjsua_call_send_im(PyObject *pSelf, PyObject *pArgs)
+{    
+    int status;
+    int call_id;
+    pj_str_t content;
+    pj_str_t * mime_type, tmp_mime_type;
+    PyObject *pMimeType, *pContent, *omdObj;
+    pjsua_msg_data msg_data;
+    int user_data;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iOOOi", &call_id, &pMimeType, &pContent, 
+			  &omdObj, &user_data))
+    {
+        return NULL;
+    }
+
+    if (!PyString_Check(pContent))
+	return Py_BuildValue("i", PJ_EINVAL);
+
+    content = PyString_ToPJ(pContent);
+
+    if (PyString_Check(pMimeType)) {
+        mime_type = &tmp_mime_type;
+        tmp_mime_type = PyString_ToPJ(pMimeType);
+    } else {
+	mime_type = NULL;   
+    }
+
+    pjsua_msg_data_init(&msg_data);
+    if (omdObj != Py_None) {
+	PyObj_pjsua_msg_data * omd;
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+    
+    status = pjsua_call_send_im(call_id, mime_type, &content, 
+				&msg_data, (void*)(long)user_data);
+
+    if (pool)
+        pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_send_typing_ind
+ */
+static PyObject *py_pjsua_call_send_typing_ind(PyObject *pSelf, 
+					       PyObject *pArgs)
+{    
+    int status;
+    int call_id;    
+    int is_typing;
+    pjsua_msg_data msg_data;
+    PyObject *omdObj;
+    pj_pool_t *pool = NULL;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &is_typing, &omdObj)) {
+        return NULL;
+    }
+	
+    pjsua_msg_data_init(&msg_data);
+    if (omdObj != Py_None) {
+	PyObj_pjsua_msg_data *omd;
+
+        omd = (PyObj_pjsua_msg_data *)omdObj;
+        msg_data.content_type = PyString_ToPJ(omd->content_type);
+        msg_data.msg_body = PyString_ToPJ(omd->msg_body);
+        pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
+        translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
+    }
+
+    status = pjsua_call_send_typing_ind(call_id, is_typing, &msg_data);	
+
+    if (pool)
+        pj_pool_release(pool);
+
+    return Py_BuildValue("i", status);
+}
+
+/*
+ * py_pjsua_call_hangup_all
+ */
+static PyObject *py_pjsua_call_hangup_all(PyObject *pSelf, PyObject *pArgs)
+{    	
+    PJ_UNUSED_ARG(pSelf);
+    PJ_UNUSED_ARG(pArgs);
+
+    pjsua_call_hangup_all();
+    
+    return Py_BuildValue("");
+}
+
+/*
+ * py_pjsua_call_dump
+ */
+static PyObject *py_pjsua_call_dump(PyObject *pSelf, PyObject *pArgs)
+{    	
+    int call_id;
+    int with_media;
+    PyObject *ret;
+    PyObject *pIndent;
+    char *buffer;
+    char *indent;
+    unsigned maxlen;    
+    int status;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "iiIO", &call_id, &with_media, 
+			  &maxlen, &pIndent))
+    {
+        return NULL;
+    }	
+
+    buffer = (char*) malloc(maxlen * sizeof(char));
+    indent = PyString_AsString(pIndent);
+    
+    status = pjsua_call_dump(call_id, with_media, buffer, maxlen, indent);
+    if (status != PJ_SUCCESS) {
+	free(buffer);
+	return PyString_FromString("");
+    }
+
+    ret = PyString_FromString(buffer);
+    free(buffer);
+    return (PyObject*)ret;
+}
+
+
+/*
+ * py_pjsua_dump
+ * Dump application states.
+ */
+static PyObject *py_pjsua_dump(PyObject *pSelf, PyObject *pArgs)
+{
+    int detail;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &detail)) {
+        return NULL;
+    }	
+
+    pjsua_dump(detail);
+
+    return Py_BuildValue("");
+}
+
+
+/*
+ * py_pj_strerror
+ */
+static PyObject *py_pj_strerror(PyObject *pSelf, PyObject *pArgs)
+{
+    int err;
+    char err_msg[PJ_ERR_MSG_SIZE];
+    pj_str_t ret;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "i", &err)) {
+        return NULL;
+    }
+    
+    ret = pj_strerror(err, err_msg, sizeof(err_msg));
+    
+    return PyString_FromStringAndSize(err_msg, ret.slen);
+}
+
+
+/*
+ * py_pj_parse_simple_sip
+ */
+static PyObject *py_pj_parse_simple_sip(PyObject *pSelf, PyObject *pArgs)
+{
+    const char *arg_uri;
+    pj_pool_t *pool;
+    char tmp[PJSIP_MAX_URL_SIZE];
+    pjsip_uri *uri;
+    pjsip_sip_uri *sip_uri;
+    PyObject *ret, *item;
+
+    PJ_UNUSED_ARG(pSelf);
+
+    if (!PyArg_ParseTuple(pArgs, "s", &arg_uri)) {
+        return NULL;
+    }
+    
+    strncpy(tmp, arg_uri, sizeof(tmp));
+    tmp[sizeof(tmp)-1] = '\0';
+
+    pool = pjsua_pool_create("py_pj_parse_simple_sip", 512, 512);
+    uri = pjsip_parse_uri(pool, tmp, strlen(tmp), 0);
+    
+    if (uri == NULL || (!PJSIP_URI_SCHEME_IS_SIP(uri) &&
+			!PJSIP_URI_SCHEME_IS_SIPS(uri))) {
+	pj_pool_release(pool);
+	return Py_BuildValue("");
+    }
+    
+    ret = PyTuple_New(5);
+    sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(uri);
+
+    /* Scheme */
+    item = PyString_FromPJ(pjsip_uri_get_scheme(uri));
+    PyTuple_SetItem(ret, 0, item);
+
+    /* Username */
+    item = PyString_FromPJ(&sip_uri->user);
+    PyTuple_SetItem(ret, 1, item);
+
+    /* Host */
+    item = PyString_FromPJ(&sip_uri->host);
+    PyTuple_SetItem(ret, 2, item);
+
+    /* Port */
+    if (sip_uri->port == 5060) {
+	sip_uri->port = 0;
+    }
+    item = Py_BuildValue("i", sip_uri->port);
+    PyTuple_SetItem(ret, 3, item);
+
+    /* Transport */
+    if (pj_stricmp2(&sip_uri->transport_param, "udp")) {
+	sip_uri->transport_param.ptr = "";
+	sip_uri->transport_param.slen = 0;
+    }
+    item = PyString_FromPJ(&sip_uri->transport_param);
+    PyTuple_SetItem(ret, 4, item);
+
+    pj_pool_release(pool);
+    return ret;
+}
+
+
+static char pjsua_call_get_max_count_doc[] =
+    "int _pjsua.call_get_max_count () "
+    "Get maximum number of calls configured in pjsua.";
+static char pjsua_call_get_count_doc[] =
+    "int _pjsua.call_get_count () "
+    "Get number of currently active calls.";
+static char pjsua_enum_calls_doc[] =
+    "int[] _pjsua.enum_calls () "
+    "Get maximum number of calls configured in pjsua.";
+static char pjsua_call_make_call_doc[] =
+    "int,int _pjsua.call_make_call (int acc_id, string dst_uri, int options,"
+    "int user_data, _pjsua.Msg_Data msg_data) "
+    "Make outgoing call to the specified URI using the specified account.";
+static char pjsua_call_is_active_doc[] =
+    "int _pjsua.call_is_active (int call_id) "
+    "Check if the specified call has active INVITE session and the INVITE "
+    "session has not been disconnected.";
+static char pjsua_call_has_media_doc[] =
+    "int _pjsua.call_has_media (int call_id) "
+    "Check if call has an active media session.";
+static char pjsua_call_get_conf_port_doc[] =
+    "int _pjsua.call_get_conf_port (int call_id) "
+    "Get the conference port identification associated with the call.";
+static char pjsua_call_get_info_doc[] =
+    "_pjsua.Call_Info _pjsua.call_get_info (int call_id) "
+    "Obtain detail information about the specified call.";
+static char pjsua_call_set_user_data_doc[] =
+    "int _pjsua.call_set_user_data (int call_id, int user_data) "
+    "Attach application specific data to the call.";
+static char pjsua_call_get_user_data_doc[] =
+    "int _pjsua.call_get_user_data (int call_id) "
+    "Get user data attached to the call.";
+static char pjsua_call_answer_doc[] =
+    "int _pjsua.call_answer (int call_id, int code, string reason, "
+    "_pjsua.Msg_Data msg_data) "
+    "Send response to incoming INVITE request.";
+static char pjsua_call_hangup_doc[] =
+    "int _pjsua.call_hangup (int call_id, int code, string reason, "
+    "_pjsua.Msg_Data msg_data) "
+    "Hangup call by using method that is appropriate according "
+    "to the call state.";
+static char pjsua_call_set_hold_doc[] =
+    "int _pjsua.call_set_hold (int call_id, _pjsua.Msg_Data msg_data) "
+    "Put the specified call on hold.";
+static char pjsua_call_reinvite_doc[] =
+    "int _pjsua.call_reinvite (int call_id, int unhold, "
+    "_pjsua.Msg_Data msg_data) "
+    "Send re-INVITE (to release hold).";
+static char pjsua_call_xfer_doc[] =
+    "int _pjsua.call_xfer (int call_id, string dest, "
+    "_pjsua.Msg_Data msg_data) "
+    "Initiate call transfer to the specified address. "
+    "This function will send REFER request to instruct remote call party "
+    "to initiate a new INVITE session to the specified destination/target.";
+static char pjsua_call_xfer_replaces_doc[] =
+    "int _pjsua.call_xfer_replaces (int call_id, int dest_call_id, "
+    "int options, _pjsua.Msg_Data msg_data) "
+    "Initiate attended call transfer. This function will send REFER request "
+    "to instruct remote call party to initiate new INVITE session to the URL "
+    "of dest_call_id. The party at dest_call_id then should 'replace' the call"
+    "with us with the new call from the REFER recipient.";
+static char pjsua_call_dial_dtmf_doc[] =
+    "int _pjsua.call_dial_dtmf (int call_id, string digits) "
+    "Send DTMF digits to remote using RFC 2833 payload formats.";
+static char pjsua_call_send_im_doc[] =
+    "int _pjsua.call_send_im (int call_id, string mime_type, string content,"
+    "_pjsua.Msg_Data msg_data, int user_data) "
+    "Send instant messaging inside INVITE session.";
+static char pjsua_call_send_typing_ind_doc[] =
+    "int _pjsua.call_send_typing_ind (int call_id, int is_typing, "
+    "_pjsua.Msg_Data msg_data) "
+    "Send IM typing indication inside INVITE session.";
+static char pjsua_call_hangup_all_doc[] =
+    "void _pjsua.call_hangup_all () "
+    "Terminate all calls.";
+static char pjsua_call_dump_doc[] =
+    "int _pjsua.call_dump (int call_id, int with_media, int maxlen, "
+    "string indent) "
+    "Dump call and media statistics to string.";
+
+/* END OF LIB CALL */
+
+/*
+ * Map of function names to functions
+ */
+static PyMethodDef py_pjsua_methods[] =
+{
+    {
+        "thread_register", py_pjsua_thread_register, METH_VARARGS, 
+         pjsua_thread_register_doc
+    },
+    {
+    	"perror", py_pjsua_perror, METH_VARARGS, pjsua_perror_doc
+    },
+    {
+    	"create", py_pjsua_create, METH_VARARGS, pjsua_create_doc
+    },
+    {
+    	"init", py_pjsua_init, METH_VARARGS, pjsua_init_doc
+    },
+    {
+    	"start", py_pjsua_start, METH_VARARGS, pjsua_start_doc
+    },
+    {
+    	"destroy", py_pjsua_destroy, METH_VARARGS, pjsua_destroy_doc
+    },
+    {
+    	"handle_events", py_pjsua_handle_events, METH_VARARGS,
+    	pjsua_handle_events_doc
+    },
+    {
+    	"verify_sip_url", py_pjsua_verify_sip_url, METH_VARARGS,
+    	pjsua_verify_sip_url_doc
+    },
+    {
+    	"reconfigure_logging", py_pjsua_reconfigure_logging, METH_VARARGS,
+    	pjsua_reconfigure_logging_doc
+    },
+    {
+    	"logging_config_default", py_pjsua_logging_config_default,
+    	METH_VARARGS, pjsua_logging_config_default_doc
+    },
+    {
+    	"config_default", py_pjsua_config_default, METH_VARARGS,
+    	pjsua_config_default_doc
+    },
+    {
+    	"media_config_default", py_pjsua_media_config_default, METH_VARARGS,
+    	pjsua_media_config_default_doc
+    },
+    
+    
+    {
+    	"msg_data_init", py_pjsua_msg_data_init, METH_VARARGS,
+    	pjsua_msg_data_init_doc
+    },
+    {
+        "transport_config_default", py_pjsua_transport_config_default, 
+        METH_VARARGS,pjsua_transport_config_default_doc
+    },
+    {
+        "transport_create", py_pjsua_transport_create, METH_VARARGS,
+        pjsua_transport_create_doc
+    },
+    {
+        "transport_enum_transports", py_pjsua_enum_transports, METH_VARARGS,
+        pjsua_enum_transports_doc
+    },
+    {
+        "transport_get_info", py_pjsua_transport_get_info, METH_VARARGS,
+        pjsua_transport_get_info_doc
+    },
+    {
+        "transport_set_enable", py_pjsua_transport_set_enable, METH_VARARGS,
+        pjsua_transport_set_enable_doc
+    },
+    {
+       "transport_close", py_pjsua_transport_close, METH_VARARGS,
+        pjsua_transport_close_doc
+    },
+    {
+        "acc_config_default", py_pjsua_acc_config_default, METH_VARARGS,
+        pjsua_acc_config_default_doc
+    },
+    {
+        "acc_get_count", py_pjsua_acc_get_count, METH_VARARGS,
+        pjsua_acc_get_count_doc
+    },
+    {
+        "acc_is_valid", py_pjsua_acc_is_valid, METH_VARARGS,
+        pjsua_acc_is_valid_doc
+    },
+    {
+        "acc_set_default", py_pjsua_acc_set_default, METH_VARARGS,
+        pjsua_acc_set_default_doc
+    },
+    {
+        "acc_get_default", py_pjsua_acc_get_default, METH_VARARGS,
+        pjsua_acc_get_default_doc
+    },
+    {
+        "acc_add", py_pjsua_acc_add, METH_VARARGS,
+        pjsua_acc_add_doc
+    },
+    {
+        "acc_add_local", py_pjsua_acc_add_local, METH_VARARGS,
+        pjsua_acc_add_local_doc
+    },
+    {
+        "acc_del", py_pjsua_acc_del, METH_VARARGS,
+        pjsua_acc_del_doc
+    },
+    {
+        "acc_set_user_data", py_pjsua_acc_set_user_data, METH_VARARGS,
+        "Accociate user data with the account"
+    },
+    {
+        "acc_get_user_data", py_pjsua_acc_get_user_data, METH_VARARGS,
+        "Get account's user data"
+    },
+    {
+        "acc_modify", py_pjsua_acc_modify, METH_VARARGS,
+        pjsua_acc_modify_doc
+    },
+    {
+        "acc_set_online_status", py_pjsua_acc_set_online_status, METH_VARARGS,
+        pjsua_acc_set_online_status_doc
+    },
+    {
+        "acc_set_online_status2", py_pjsua_acc_set_online_status2, METH_VARARGS,
+        pjsua_acc_set_online_status2_doc
+    },
+    {
+        "acc_set_registration", py_pjsua_acc_set_registration, METH_VARARGS,
+        pjsua_acc_set_registration_doc
+    },
+    {
+        "acc_get_info", py_pjsua_acc_get_info, METH_VARARGS,
+        pjsua_acc_get_info_doc
+    },
+    {
+	"acc_pres_notify", py_pjsua_acc_pres_notify, METH_VARARGS,
+	"Accept or reject subscription request"
+    },
+    {
+        "enum_accs", py_pjsua_enum_accs, METH_VARARGS,
+        pjsua_enum_accs_doc
+    },
+    {
+        "acc_enum_info", py_pjsua_acc_enum_info, METH_VARARGS,
+        pjsua_acc_enum_info_doc
+    },
+    {
+        "acc_set_transport", py_pjsua_acc_set_transport, METH_VARARGS,
+        "Lock transport to use the specified transport"
+    },
+    {
+        "buddy_config_default", py_pjsua_buddy_config_default, METH_VARARGS,
+        pjsua_buddy_config_default_doc
+    },
+    {
+        "get_buddy_count", py_pjsua_get_buddy_count, METH_VARARGS,
+        pjsua_get_buddy_count_doc
+    },
+    {
+        "buddy_is_valid", py_pjsua_buddy_is_valid, METH_VARARGS,
+        pjsua_buddy_is_valid_doc
+    },
+    {
+        "enum_buddies", py_pjsua_enum_buddies, METH_VARARGS,
+        pjsua_enum_buddies_doc
+    },    
+    {
+        "buddy_find", py_pjsua_buddy_find, METH_VARARGS,
+        "Find buddy with the specified URI"
+    },    
+    {
+        "buddy_get_info", py_pjsua_buddy_get_info, METH_VARARGS,
+        pjsua_buddy_get_info_doc
+    },
+    {
+        "buddy_add", py_pjsua_buddy_add, METH_VARARGS,
+        pjsua_buddy_add_doc
+    },
+    {
+        "buddy_del", py_pjsua_buddy_del, METH_VARARGS,
+        pjsua_buddy_del_doc
+    },
+    {
+        "buddy_set_user_data", py_pjsua_buddy_set_user_data, METH_VARARGS,
+        "Associate user data to the buddy object"
+    },
+    {
+        "buddy_get_user_data", py_pjsua_buddy_get_user_data, METH_VARARGS,
+        "Get buddy user data"
+    },
+    {
+        "buddy_subscribe_pres", py_pjsua_buddy_subscribe_pres, METH_VARARGS,
+        pjsua_buddy_subscribe_pres_doc
+    },
+    {
+        "pres_dump", py_pjsua_pres_dump, METH_VARARGS,
+        pjsua_pres_dump_doc
+    },
+    {
+        "im_send", py_pjsua_im_send, METH_VARARGS,
+        pjsua_im_send_doc
+    },
+    {
+        "im_typing", py_pjsua_im_typing, METH_VARARGS,
+        pjsua_im_typing_doc
+    },
+        {
+        "conf_get_max_ports", py_pjsua_conf_get_max_ports, METH_VARARGS,
+        pjsua_conf_get_max_ports_doc
+    },
+    {
+        "conf_get_active_ports", py_pjsua_conf_get_active_ports, METH_VARARGS,
+        pjsua_conf_get_active_ports_doc
+    },
+    {
+        "enum_conf_ports", py_pjsua_enum_conf_ports, METH_VARARGS,
+        pjsua_enum_conf_ports_doc
+    },
+    {
+        "conf_get_port_info", py_pjsua_conf_get_port_info, METH_VARARGS,
+        pjsua_conf_get_port_info_doc
+    },
+    {
+        "conf_remove_port", py_pjsua_conf_remove_port, METH_VARARGS,
+        pjsua_conf_remove_port_doc
+    },
+    {
+        "conf_connect", py_pjsua_conf_connect, METH_VARARGS,
+        pjsua_conf_connect_doc
+    },
+    {
+        "conf_disconnect", py_pjsua_conf_disconnect, METH_VARARGS,
+        pjsua_conf_disconnect_doc
+    },
+    {
+	"conf_set_tx_level", py_pjsua_conf_set_tx_level, METH_VARARGS,
+	"Adjust the signal level to be transmitted from the bridge to the" 
+	" specified port by making it louder or quieter"
+    },
+    {
+	"conf_set_rx_level", py_pjsua_conf_set_rx_level, METH_VARARGS,
+	"Adjust the signal level to be received from the specified port (to"
+	" the bridge) by making it louder or quieter"
+    },
+    {
+	"conf_get_signal_level", py_pjsua_conf_get_signal_level, METH_VARARGS,
+	"Get last signal level transmitted to or received from the specified port"
+    },
+    {
+        "player_create", py_pjsua_player_create, METH_VARARGS,
+        pjsua_player_create_doc
+    },
+    {
+        "playlist_create", py_pjsua_playlist_create, METH_VARARGS,
+        "Create WAV playlist"
+    },
+    {
+        "player_get_conf_port", py_pjsua_player_get_conf_port, METH_VARARGS,
+        pjsua_player_get_conf_port_doc
+    },
+    {
+        "player_set_pos", py_pjsua_player_set_pos, METH_VARARGS,
+        pjsua_player_set_pos_doc
+    },
+    {
+        "player_destroy", py_pjsua_player_destroy, METH_VARARGS,
+        pjsua_player_destroy_doc
+    },
+    {
+        "recorder_create", py_pjsua_recorder_create, METH_VARARGS,
+        pjsua_recorder_create_doc
+    },
+    {
+        "recorder_get_conf_port", py_pjsua_recorder_get_conf_port, METH_VARARGS,
+        pjsua_recorder_get_conf_port_doc
+    },
+    {
+        "recorder_destroy", py_pjsua_recorder_destroy, METH_VARARGS,
+        pjsua_recorder_destroy_doc
+    },
+    {
+        "enum_snd_devs", py_pjsua_enum_snd_devs, METH_VARARGS,
+        pjsua_enum_snd_devs_doc
+    },
+    {
+        "get_snd_dev", py_pjsua_get_snd_dev, METH_VARARGS,
+        pjsua_get_snd_dev_doc
+    },
+    {
+        "set_snd_dev", py_pjsua_set_snd_dev, METH_VARARGS,
+        pjsua_set_snd_dev_doc
+    },
+    {
+        "set_null_snd_dev", py_pjsua_set_null_snd_dev, METH_VARARGS,
+        pjsua_set_null_snd_dev_doc
+    },
+    {
+        "set_ec", py_pjsua_set_ec, METH_VARARGS,
+        pjsua_set_ec_doc
+    },
+    {
+        "get_ec_tail", py_pjsua_get_ec_tail, METH_VARARGS,
+        pjsua_get_ec_tail_doc
+    },
+    {
+        "enum_codecs", py_pjsua_enum_codecs, METH_VARARGS,
+        pjsua_enum_codecs_doc
+    },
+    {
+        "codec_set_priority", py_pjsua_codec_set_priority, METH_VARARGS,
+        pjsua_codec_set_priority_doc
+    },
+    {
+        "codec_get_param", py_pjsua_codec_get_param, METH_VARARGS,
+        pjsua_codec_get_param_doc
+    },
+    {
+        "codec_set_param", py_pjsua_codec_set_param, METH_VARARGS,
+        pjsua_codec_set_param_doc
+    },
+    {
+        "call_get_max_count", py_pjsua_call_get_max_count, METH_VARARGS,
+        pjsua_call_get_max_count_doc
+    },
+    {
+        "call_get_count", py_pjsua_call_get_count, METH_VARARGS,
+        pjsua_call_get_count_doc
+    },
+    {
+        "enum_calls", py_pjsua_enum_calls, METH_VARARGS,
+        pjsua_enum_calls_doc
+    },
+    {
+        "call_make_call", py_pjsua_call_make_call, METH_VARARGS,
+        pjsua_call_make_call_doc
+    },
+    {
+        "call_is_active", py_pjsua_call_is_active, METH_VARARGS,
+        pjsua_call_is_active_doc
+    },
+    {
+        "call_has_media", py_pjsua_call_has_media, METH_VARARGS,
+        pjsua_call_has_media_doc
+    },
+    {
+        "call_get_conf_port", py_pjsua_call_get_conf_port, METH_VARARGS,
+        pjsua_call_get_conf_port_doc
+    },
+    {
+        "call_get_info", py_pjsua_call_get_info, METH_VARARGS,
+        pjsua_call_get_info_doc
+    },
+    {
+        "call_set_user_data", py_pjsua_call_set_user_data, METH_VARARGS,
+        pjsua_call_set_user_data_doc
+    },
+    {
+        "call_get_user_data", py_pjsua_call_get_user_data, METH_VARARGS,
+        pjsua_call_get_user_data_doc
+    },
+    {
+        "call_answer", py_pjsua_call_answer, METH_VARARGS,
+        pjsua_call_answer_doc
+    },
+    {
+        "call_hangup", py_pjsua_call_hangup, METH_VARARGS,
+        pjsua_call_hangup_doc
+    },
+    {
+        "call_set_hold", py_pjsua_call_set_hold, METH_VARARGS,
+        pjsua_call_set_hold_doc
+    },
+    {
+        "call_reinvite", py_pjsua_call_reinvite, METH_VARARGS,
+        pjsua_call_reinvite_doc
+    },
+    {
+        "call_update", py_pjsua_call_update, METH_VARARGS,
+        "Send UPDATE"
+    },
+    {
+        "call_xfer", py_pjsua_call_xfer, METH_VARARGS,
+        pjsua_call_xfer_doc
+    },
+    {
+        "call_xfer_replaces", py_pjsua_call_xfer_replaces, METH_VARARGS,
+        pjsua_call_xfer_replaces_doc
+    },
+    {
+        "call_dial_dtmf", py_pjsua_call_dial_dtmf, METH_VARARGS,
+        pjsua_call_dial_dtmf_doc
+    },
+    {
+        "call_send_im", py_pjsua_call_send_im, METH_VARARGS,
+        pjsua_call_send_im_doc
+    },
+    {
+        "call_send_typing_ind", py_pjsua_call_send_typing_ind, METH_VARARGS,
+        pjsua_call_send_typing_ind_doc
+    },
+    {
+        "call_hangup_all", py_pjsua_call_hangup_all, METH_VARARGS,
+        pjsua_call_hangup_all_doc
+    },
+    {
+        "call_dump", py_pjsua_call_dump, METH_VARARGS,
+        pjsua_call_dump_doc
+    },
+    {
+        "call_send_request", py_pjsua_call_send_request, METH_VARARGS,
+        "Send arbitrary request"
+    },
+    {
+	"dump", py_pjsua_dump, METH_VARARGS, "Dump application state"
+    },
+    {
+	"strerror", py_pj_strerror, METH_VARARGS, "Get error message"
+    },
+    {
+	"parse_simple_uri", py_pj_parse_simple_sip, METH_VARARGS, "Parse URI"
+    },
+
+    
+    {NULL, NULL} /* end of function list */
+};
+
+
+
+/*
+ * Mapping C structs from and to Python objects & initializing object
+ */
+DL_EXPORT(void)
+init_pjsua(void)
+{
+    PyObject* m = NULL;
+#define ADD_CONSTANT(mod,name)	PyModule_AddIntConstant(mod,#name,name)
+
+    
+    PyEval_InitThreads();
+
+    if (PyType_Ready(&PyTyp_pjsua_callback) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_config) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_logging_config) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_msg_data) < 0)
+        return;
+    PyTyp_pjsua_media_config.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjsua_media_config) < 0)
+        return;
+    PyTyp_pjsip_cred_info.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjsip_cred_info) < 0)
+        return;
+    PyTyp_pjsip_rx_data.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjsip_rx_data) < 0)
+        return;
+
+    /* LIB TRANSPORT */
+
+    if (PyType_Ready(&PyTyp_pjsua_transport_config) < 0)
+        return;
+    
+    if (PyType_Ready(&PyTyp_pjsua_transport_info) < 0)
+        return;
+    
+    /* END OF LIB TRANSPORT */
+
+    /* LIB ACCOUNT */
+
+    
+    if (PyType_Ready(&PyTyp_pjsua_acc_config) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_acc_info) < 0)
+        return;
+
+    /* END OF LIB ACCOUNT */
+
+    /* LIB BUDDY */
+
+    if (PyType_Ready(&PyTyp_pjsua_buddy_config) < 0)
+        return;
+    if (PyType_Ready(&PyTyp_pjsua_buddy_info) < 0)
+        return;
+
+    /* END OF LIB BUDDY */
+
+    /* LIB MEDIA */
+  
+    if (PyType_Ready(&PyTyp_pjsua_codec_info) < 0)
+        return;
+
+    if (PyType_Ready(&PyTyp_pjsua_conf_port_info) < 0)
+        return;
+
+    if (PyType_Ready(&PyTyp_pjmedia_snd_dev_info) < 0)
+        return;
+
+    PyTyp_pjmedia_codec_param_info.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjmedia_codec_param_info) < 0)
+        return;
+    PyTyp_pjmedia_codec_param_setting.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&PyTyp_pjmedia_codec_param_setting) < 0)
+        return;
+
+    if (PyType_Ready(&PyTyp_pjmedia_codec_param) < 0)
+        return;
+
+    /* END OF LIB MEDIA */
+
+    /* LIB CALL */
+
+    if (PyType_Ready(&PyTyp_pjsua_call_info) < 0)
+        return;
+
+    /* END OF LIB CALL */
+
+    m = Py_InitModule3(
+        "_pjsua", py_pjsua_methods, "PJSUA-lib module for python"
+    );
+
+    Py_INCREF(&PyTyp_pjsua_callback);
+    PyModule_AddObject(m, "Callback", (PyObject *)&PyTyp_pjsua_callback);
+
+    Py_INCREF(&PyTyp_pjsua_config);
+    PyModule_AddObject(m, "Config", (PyObject *)&PyTyp_pjsua_config);
+
+    Py_INCREF(&PyTyp_pjsua_media_config);
+    PyModule_AddObject(m, "Media_Config", (PyObject *)&PyTyp_pjsua_media_config);
+
+    Py_INCREF(&PyTyp_pjsua_logging_config);
+    PyModule_AddObject(m, "Logging_Config", (PyObject *)&PyTyp_pjsua_logging_config);
+
+    Py_INCREF(&PyTyp_pjsua_msg_data);
+    PyModule_AddObject(m, "Msg_Data", (PyObject *)&PyTyp_pjsua_msg_data);
+
+    Py_INCREF(&PyTyp_pjsip_cred_info);
+    PyModule_AddObject(m, "Pjsip_Cred_Info",
+        (PyObject *)&PyTyp_pjsip_cred_info
+    );
+
+    Py_INCREF(&PyTyp_pjsip_rx_data);
+    PyModule_AddObject(m, "Pjsip_Rx_Data",
+        (PyObject *)&PyTyp_pjsip_rx_data
+    );
+
+    /* LIB TRANSPORT */
+
+    Py_INCREF(&PyTyp_pjsua_transport_config);
+    PyModule_AddObject
+        (m, "Transport_Config", (PyObject *)&PyTyp_pjsua_transport_config);
+    
+    Py_INCREF(&PyTyp_pjsua_transport_info);
+    PyModule_AddObject(m, "Transport_Info", (PyObject *)&PyTyp_pjsua_transport_info);
+    
+
+    /* END OF LIB TRANSPORT */
+
+    /* LIB ACCOUNT */
+
+    
+    Py_INCREF(&PyTyp_pjsua_acc_config);
+    PyModule_AddObject(m, "Acc_Config", (PyObject *)&PyTyp_pjsua_acc_config);
+    Py_INCREF(&PyTyp_pjsua_acc_info);
+    PyModule_AddObject(m, "Acc_Info", (PyObject *)&PyTyp_pjsua_acc_info);
+
+    /* END OF LIB ACCOUNT */
+
+    /* LIB BUDDY */
+    
+    Py_INCREF(&PyTyp_pjsua_buddy_config);
+    PyModule_AddObject(m, "Buddy_Config", (PyObject *)&PyTyp_pjsua_buddy_config);
+    Py_INCREF(&PyTyp_pjsua_buddy_info);
+    PyModule_AddObject(m, "Buddy_Info", (PyObject *)&PyTyp_pjsua_buddy_info);
+
+    /* END OF LIB BUDDY */
+
+    /* LIB MEDIA */
+
+    Py_INCREF(&PyTyp_pjsua_codec_info);
+    PyModule_AddObject(m, "Codec_Info", (PyObject *)&PyTyp_pjsua_codec_info);
+    Py_INCREF(&PyTyp_pjsua_conf_port_info);
+    PyModule_AddObject(m, "Conf_Port_Info", (PyObject *)&PyTyp_pjsua_conf_port_info);
+    Py_INCREF(&PyTyp_pjmedia_snd_dev_info);
+    PyModule_AddObject(m, "PJMedia_Snd_Dev_Info", 
+	(PyObject *)&PyTyp_pjmedia_snd_dev_info);
+    Py_INCREF(&PyTyp_pjmedia_codec_param_info);
+    PyModule_AddObject(m, "PJMedia_Codec_Param_Info", 
+	(PyObject *)&PyTyp_pjmedia_codec_param_info);
+    Py_INCREF(&PyTyp_pjmedia_codec_param_setting);
+    PyModule_AddObject(m, "PJMedia_Codec_Param_Setting", 
+	(PyObject *)&PyTyp_pjmedia_codec_param_setting);
+    Py_INCREF(&PyTyp_pjmedia_codec_param);
+    PyModule_AddObject(m, "PJMedia_Codec_Param", 
+	(PyObject *)&PyTyp_pjmedia_codec_param);
+
+    /* END OF LIB MEDIA */
+
+    /* LIB CALL */
+
+    Py_INCREF(&PyTyp_pjsua_call_info);
+    PyModule_AddObject(m, "Call_Info", (PyObject *)&PyTyp_pjsua_call_info);
+
+    /* END OF LIB CALL */
+
+
+    /*
+     * Add various constants.
+     */
+    /* Skip it.. */
+
+#undef ADD_CONSTANT
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/_pjsua.def b/jni/libpjsip/sources/pjsip-apps/src/python/_pjsua.def
new file mode 100644
index 0000000..9b150a9
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/_pjsua.def
@@ -0,0 +1,2 @@
+EXPORTS
+	init_pjsua
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/_pjsua.h b/jni/libpjsip/sources/pjsip-apps/src/python/_pjsua.h
new file mode 100644
index 0000000..207b471
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/_pjsua.h
@@ -0,0 +1,3718 @@
+/* $Id: _pjsua.h 4609 2013-10-02 03:19:54Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 __PY_PJSUA_H__
+#define __PY_PJSUA_H__
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include <Python.h>
+#include <structmember.h>
+#include <pjsua-lib/pjsua.h>
+
+
+PJ_INLINE(pj_str_t) PyString_ToPJ(const PyObject *obj)
+{
+    pj_str_t str;
+
+    if (obj && PyString_Check(obj)) {
+	str.ptr = PyString_AS_STRING(obj);
+	str.slen = PyString_GET_SIZE(obj);
+    } else {
+	str.ptr = NULL;
+	str.slen = 0;
+    }
+
+    return str;
+}
+
+PJ_INLINE(PyObject*) PyString_FromPJ(const pj_str_t *str)
+{
+    return PyString_FromStringAndSize(str->ptr, str->slen);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsip_cred_info
+ */
+typedef struct
+{
+    PyObject_HEAD
+
+    /* Type-specific fields go here. */
+    PyObject *realm;
+    PyObject *scheme;
+    PyObject *username;
+    int	      data_type;
+    PyObject *data;
+    
+} PyObj_pjsip_cred_info;
+
+/*
+ * cred_info_dealloc
+ * deletes a cred info from memory
+ */
+static void PyObj_pjsip_cred_info_delete(PyObj_pjsip_cred_info* self)
+{
+    Py_XDECREF(self->realm);
+    Py_XDECREF(self->scheme);
+    Py_XDECREF(self->username);
+    Py_XDECREF(self->data);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsip_cred_info_import(PyObj_pjsip_cred_info *obj,
+					 const pjsip_cred_info *cfg)
+{
+    Py_XDECREF(obj->realm);
+    obj->realm = PyString_FromPJ(&cfg->realm);
+    Py_XDECREF(obj->scheme);
+    obj->scheme = PyString_FromPJ(&cfg->scheme);
+    Py_XDECREF(obj->username);
+    obj->username = PyString_FromPJ(&cfg->username);
+    obj->data_type = cfg->data_type;
+    Py_XDECREF(obj->data);
+    obj->data = PyString_FromPJ(&cfg->data);
+}
+
+static void PyObj_pjsip_cred_info_export(pjsip_cred_info *cfg,
+					 PyObj_pjsip_cred_info *obj)
+{
+    cfg->realm	= PyString_ToPJ(obj->realm);
+    cfg->scheme	= PyString_ToPJ(obj->scheme);
+    cfg->username = PyString_ToPJ(obj->username);
+    cfg->data_type = obj->data_type;
+    cfg->data	= PyString_ToPJ(obj->data);
+}
+
+
+/*
+ * cred_info_new
+ * constructor for cred_info object
+ */
+static PyObject * PyObj_pjsip_cred_info_new(PyTypeObject *type, 
+					    PyObject *args,
+					    PyObject *kwds)
+{
+    PyObj_pjsip_cred_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsip_cred_info *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->realm = PyString_FromString("");
+        self->scheme = PyString_FromString("");
+        self->username = PyString_FromString("");
+	self->data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
+        self->data = PyString_FromString("");
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsip_cred_info_members
+ */
+static PyMemberDef PyObj_pjsip_cred_info_members[] =
+{
+    {
+        "realm", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_cred_info, realm), 0,
+        "Realm"
+    },
+    {
+        "scheme", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_cred_info, scheme), 0,
+        "Scheme"
+    },
+    {
+        "username", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_cred_info, username), 0,
+        "User name"
+    },
+    {
+        "data", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_cred_info, data), 0,
+        "The data, which can be a plaintext password or a hashed digest, "
+	"depending on the value of data_type"
+    },
+    {
+        "data_type", T_INT, 
+	offsetof(PyObj_pjsip_cred_info, data_type), 0,
+        "Type of data"
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+/*
+ * PyTyp_pjsip_cred_info
+ */
+static PyTypeObject PyTyp_pjsip_cred_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Pjsip_Cred_Info",      /*tp_name*/
+    sizeof(PyObj_pjsip_cred_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsip_cred_info_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJSIP credential information", /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsip_cred_info_members,  /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsip_cred_info_new,      /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_callback
+ * C/python typewrapper for callback struct
+ */
+typedef struct PyObj_pjsua_callback
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    PyObject * on_call_state;
+    PyObject * on_incoming_call;
+    PyObject * on_call_media_state;
+    PyObject * on_dtmf_digit;
+    PyObject * on_call_transfer_request;
+    PyObject * on_call_transfer_status;
+    PyObject * on_call_replace_request;
+    PyObject * on_call_replaced;
+    PyObject * on_reg_state;
+    PyObject * on_incoming_subscribe;
+    PyObject * on_buddy_state;
+    PyObject * on_pager;
+    PyObject * on_pager_status;
+    PyObject * on_typing;
+    PyObject * on_mwi_info;
+} PyObj_pjsua_callback;
+
+
+/*
+ * PyObj_pjsua_callback_delete
+ * destructor function for callback struct
+ */
+static void PyObj_pjsua_callback_delete(PyObj_pjsua_callback* self)
+{
+    Py_XDECREF(self->on_call_state);
+    Py_XDECREF(self->on_incoming_call);
+    Py_XDECREF(self->on_call_media_state);
+    Py_XDECREF(self->on_dtmf_digit);
+    Py_XDECREF(self->on_call_transfer_request);
+    Py_XDECREF(self->on_call_transfer_status);
+    Py_XDECREF(self->on_call_replace_request);
+    Py_XDECREF(self->on_call_replaced);
+    Py_XDECREF(self->on_reg_state);
+    Py_XDECREF(self->on_incoming_subscribe);
+    Py_XDECREF(self->on_buddy_state);
+    Py_XDECREF(self->on_pager);
+    Py_XDECREF(self->on_pager_status);
+    Py_XDECREF(self->on_typing);
+    Py_XDECREF(self->on_mwi_info);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * PyObj_pjsua_callback_new
+ * * declares constructor for callback struct
+ */
+static PyObject * PyObj_pjsua_callback_new(PyTypeObject *type, 
+					   PyObject *args,
+					   PyObject *kwds)
+{
+    PyObj_pjsua_callback *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_callback *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->on_call_state = Py_BuildValue("");
+        self->on_incoming_call = Py_BuildValue("");
+        self->on_call_media_state = Py_BuildValue("");
+        self->on_dtmf_digit = Py_BuildValue("");
+        self->on_call_transfer_request = Py_BuildValue("");
+        self->on_call_transfer_status = Py_BuildValue("");
+        self->on_call_replace_request = Py_BuildValue("");
+        self->on_call_replaced = Py_BuildValue("");
+        self->on_reg_state = Py_BuildValue("");
+        self->on_incoming_subscribe = Py_BuildValue("");
+        self->on_buddy_state = Py_BuildValue("");
+        self->on_pager = Py_BuildValue("");
+        self->on_pager_status = Py_BuildValue("");
+        self->on_typing = Py_BuildValue("");
+	self->on_mwi_info = Py_BuildValue("");
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_callback_members
+ * declares available functions for callback object
+ */
+static PyMemberDef PyObj_pjsua_callback_members[] =
+{
+    {
+        "on_call_state", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_callback, on_call_state), 0, 
+	"Notify application when invite state has changed. Application may "
+        "then query the call info to get the detail call states."
+    },
+    {
+        "on_incoming_call", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_incoming_call), 0,
+        "Notify application on incoming call."
+    },
+    {
+        "on_call_media_state", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_media_state), 0,
+        "Notify application when media state in the call has changed. Normal "
+        "application would need to implement this callback, e.g. to connect "
+        "the call's media to sound device."
+    },
+    {
+	"on_dtmf_digit", T_OBJECT_EX,
+	offsetof(PyObj_pjsua_callback, on_dtmf_digit), 0,
+	"Notify application upon receiving incoming DTMF digit."
+    },
+    {
+        "on_call_transfer_request", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_transfer_request), 0,
+        "Notify application on call being transfered. "
+	"Application can decide to accept/reject transfer request "
+	"by setting the code (default is 200). When this callback "
+	"is not defined, the default behavior is to accept the "
+	"transfer."
+    },
+    {
+        "on_call_transfer_status", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_transfer_status), 0,
+        "Notify application of the status of previously sent call "
+        "transfer request. Application can monitor the status of the "
+        "call transfer request, for example to decide whether to "
+        "terminate existing call."
+    },
+    {
+        "on_call_replace_request", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_replace_request), 0,
+        "Notify application about incoming INVITE with Replaces header. "
+        "Application may reject the request by setting non-2xx code."
+    },
+    {
+        "on_call_replaced", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_call_replaced), 0,
+	"Notify application that an existing call has been replaced with "
+	"a new call. This happens when PJSUA-API receives incoming INVITE "
+	"request with Replaces header."
+	" "
+	"After this callback is called, normally PJSUA-API will disconnect "
+	"old_call_id and establish new_call_id."
+    },
+    {
+        "on_reg_state", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_reg_state), 0,
+        "Notify application when registration status has changed. Application "
+        "may then query the account info to get the registration details."
+    },
+    {
+        "on_incoming_subscribe", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_incoming_subscribe), 0,
+        "Notification when incoming SUBSCRIBE request is received."
+    },
+    {
+        "on_buddy_state", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_buddy_state), 0,
+        "Notify application when the buddy state has changed. Application may "
+        "then query the buddy into to get the details."
+    },
+    {
+        "on_pager", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_callback, on_pager), 0,
+        "Notify application on incoming pager (i.e. MESSAGE request). "
+        "Argument call_id will be -1 if MESSAGE request is not related to an "
+        "existing call."
+    },
+    {
+        "on_pager_status", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_callback, on_pager_status), 0,
+        "Notify application about the delivery status of outgoing pager "
+        "request."
+    },
+    {
+        "on_typing", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_callback, on_typing), 0,
+        "Notify application about typing indication."
+    },
+    {
+        "on_mwi_info", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_callback, on_mwi_info), 0,
+        "Notify application about MWI indication."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjsua_callback
+ * callback class definition
+ */
+static PyTypeObject PyTyp_pjsua_callback =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,					/*ob_size*/
+    "_pjsua.Callback",		/*tp_name*/
+    sizeof(PyObj_pjsua_callback),	/*tp_basicsize*/
+    0,					/*tp_itemsize*/
+    (destructor)PyObj_pjsua_callback_delete,   /*tp_dealloc*/
+    0,                             	/*tp_print*/
+    0,                             	/*tp_getattr*/
+    0,                             	/*tp_setattr*/
+    0,                             	/*tp_compare*/
+    0,                             	/*tp_repr*/
+    0,                             	/*tp_as_number*/
+    0,                             	/*tp_as_sequence*/
+    0,                             	/*tp_as_mapping*/
+    0,                             	/*tp_hash */
+    0,                             	/*tp_call*/
+    0,                             	/*tp_str*/
+    0,                             	/*tp_getattro*/
+    0,                             	/*tp_setattro*/
+    0,                             	/*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,            	/*tp_flags*/
+    "This structure describes application callback "
+    "to receive various event notifications from "
+    "PJSUA-API",			/* tp_doc */
+    0,                           	/* tp_traverse */
+    0,                           	/* tp_clear */
+    0,                           	/* tp_richcompare */
+    0,                           	/* tp_weaklistoffset */
+    0,                           	/* tp_iter */
+    0,                           	/* tp_iternext */
+    0,                 			/* tp_methods */
+    PyObj_pjsua_callback_members,       /* tp_members */
+    0,                             	/* tp_getset */
+    0,                             	/* tp_base */
+    0,                             	/* tp_dict */
+    0,                             	/* tp_descr_get */
+    0,                             	/* tp_descr_set */
+    0,                             	/* tp_dictoffset */
+    0,          			/* tp_init */
+    0,                             	/* tp_alloc */
+    PyObj_pjsua_callback_new,           /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_media_config
+ * C/Python wrapper for pjsua_media_config object
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    unsigned clock_rate;
+    unsigned snd_clock_rate;
+    unsigned channel_count;
+    unsigned audio_frame_ptime;
+    int	     snd_auto_close_time;
+    unsigned max_media_ports;
+    int	     has_ioqueue;
+    unsigned thread_cnt;
+    unsigned quality;
+    unsigned ptime;
+    int	     no_vad;
+    unsigned ilbc_mode;
+    unsigned tx_drop_pct;
+    unsigned rx_drop_pct;
+    unsigned ec_options;
+    unsigned ec_tail_len;
+    int	     jb_min;
+    int	     jb_max;
+    int	     enable_ice;
+    int	     enable_turn;
+    PyObject *turn_server;
+    int	     turn_conn_type;
+    PyObject *turn_realm;
+    PyObject *turn_username;
+    int	     turn_passwd_type;
+    PyObject *turn_passwd;
+} PyObj_pjsua_media_config;
+
+
+/*
+ * PyObj_pjsua_media_config_members
+ * declares attributes accessible from both C and Python for media_config file
+ */
+static PyMemberDef PyObj_pjsua_media_config_members[] =
+{
+    {
+        "clock_rate", T_INT, 
+	offsetof(PyObj_pjsua_media_config, clock_rate), 0,
+        "Clock rate to be applied to the conference bridge. If value is zero, "
+        "default clock rate will be used (16KHz)."
+    },
+    {
+        "snd_clock_rate", T_INT, 
+	offsetof(PyObj_pjsua_media_config, snd_clock_rate), 0,
+        "Specify different clock rate of sound device, otherwise 0."
+    },
+    {
+        "channel_count", T_INT, 
+	offsetof(PyObj_pjsua_media_config, channel_count), 0,
+        "Specify channel count (default 1)."
+    },
+    {
+        "audio_frame_ptime", T_INT, 
+	offsetof(PyObj_pjsua_media_config, audio_frame_ptime), 0,
+        "Audio frame length in milliseconds."
+    },
+    {
+        "snd_auto_close_time", T_INT, 
+	offsetof(PyObj_pjsua_media_config, snd_auto_close_time), 0,
+        "Sound idle time before it's closed."
+    },
+    {
+        "max_media_ports", T_INT,
+        offsetof(PyObj_pjsua_media_config, max_media_ports), 0,
+        "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."
+    },
+    {
+        "has_ioqueue", T_INT, 
+	offsetof(PyObj_pjsua_media_config, has_ioqueue), 0,
+        "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."
+    },
+    {
+        "thread_cnt", T_INT, 
+	offsetof(PyObj_pjsua_media_config, thread_cnt), 0,
+        "Specify the number of worker threads to handle incoming RTP packets. "
+        "A value of one is recommended for most applications."
+    },
+    {
+        "quality", T_INT, 
+	offsetof(PyObj_pjsua_media_config, quality), 0,
+        "The media quality also sets speex codec quality/complexity to the "
+        "number."
+    },
+    {
+        "ptime", T_INT, 
+	offsetof(PyObj_pjsua_media_config, ptime), 0,
+        "Specify default ptime."
+    },
+    {
+        "no_vad", T_INT, 
+	offsetof(PyObj_pjsua_media_config, no_vad), 0,
+        "Disable VAD?"
+    },
+    {
+        "ilbc_mode", T_INT, 
+	offsetof(PyObj_pjsua_media_config, ilbc_mode), 0,
+        "iLBC mode (20 or 30)."
+    },
+    {
+        "tx_drop_pct", T_INT, 
+	offsetof(PyObj_pjsua_media_config, tx_drop_pct), 0,
+        "Percentage of RTP packet to drop in TX direction (to simulate packet "
+        "lost)."
+    },
+    {
+        "rx_drop_pct", T_INT, 
+	offsetof(PyObj_pjsua_media_config, rx_drop_pct), 0,
+        "Percentage of RTP packet to drop in RX direction (to simulate packet "
+        "lost)."},
+    {
+        "ec_options", T_INT, 
+	offsetof(PyObj_pjsua_media_config, ec_options), 0,
+        "Echo canceller options (see pjmedia_echo_create())"
+    },
+    {
+        "ec_tail_len", T_INT, 
+	offsetof(PyObj_pjsua_media_config, ec_tail_len), 0,
+        "Echo canceller tail length, in miliseconds."
+    },
+    {
+        "jb_min", T_INT, 
+	offsetof(PyObj_pjsua_media_config, jb_min), 0,
+        "Jitter buffer minimum size in milliseconds."
+    },
+    {
+        "jb_max", T_INT, 
+	offsetof(PyObj_pjsua_media_config, jb_max), 0,
+        "Jitter buffer maximum size in milliseconds."
+    },
+    {
+	"enable_ice", T_INT,
+	offsetof(PyObj_pjsua_media_config, enable_ice), 0,
+        "Enable ICE."
+    },
+    {
+	"enable_turn", T_INT,
+	offsetof(PyObj_pjsua_media_config, enable_turn), 0,
+        "Enable TURN."
+    },
+    {
+    	"turn_server", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_media_config, turn_server), 0,
+    	"Specify the TURN server."
+    },
+    {
+	"turn_conn_type", T_INT,
+	offsetof(PyObj_pjsua_media_config, turn_conn_type), 0,
+        "Specify TURN connection type."
+    },
+    {
+    	"turn_realm", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_media_config, turn_realm), 0,
+    	"Specify the TURN realm."
+    },
+    {
+    	"turn_username", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_media_config, turn_username), 0,
+    	"Specify the TURN username."
+    },
+    {
+	"turn_passwd_type", T_INT,
+	offsetof(PyObj_pjsua_media_config, turn_passwd_type), 0,
+        "Specify TURN password type."
+    },
+    {
+    	"turn_passwd", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_media_config, turn_passwd), 0,
+    	"Specify the TURN password."
+    },
+
+    {NULL}  /* Sentinel */
+};
+
+
+static PyObject *PyObj_pjsua_media_config_new(PyTypeObject *type, 
+					      PyObject *args, 
+					      PyObject *kwds)
+{
+    PyObj_pjsua_media_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_media_config*)type->tp_alloc(type, 0);
+    if (self != NULL) {
+	self->turn_server = PyString_FromString("");
+	self->turn_realm = PyString_FromString("");
+	self->turn_username = PyString_FromString("");
+	self->turn_passwd = PyString_FromString("");
+    }
+
+    return (PyObject *)self;
+}
+
+static void PyObj_pjsua_media_config_delete(PyObj_pjsua_media_config * self)
+{
+    Py_XDECREF(self->turn_server);
+    Py_XDECREF(self->turn_realm);
+    Py_XDECREF(self->turn_username);
+    Py_XDECREF(self->turn_passwd);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static void PyObj_pjsua_media_config_import(PyObj_pjsua_media_config *obj,
+					    const pjsua_media_config *cfg)
+{
+    obj->clock_rate	    = cfg->clock_rate;
+    obj->snd_clock_rate	    = cfg->snd_clock_rate;
+    obj->channel_count	    = cfg->channel_count;
+    obj->audio_frame_ptime  = cfg->audio_frame_ptime;
+    obj->snd_auto_close_time= cfg->snd_auto_close_time;
+    obj->max_media_ports    = cfg->max_media_ports;
+    obj->has_ioqueue	    = cfg->has_ioqueue;
+    obj->thread_cnt	    = cfg->thread_cnt;
+    obj->quality	    = cfg->quality;
+    obj->ptime		    = cfg->ptime;
+    obj->no_vad		    = cfg->no_vad;
+    obj->ilbc_mode	    = cfg->ilbc_mode;
+    obj->jb_min		    = cfg->jb_min_pre;
+    obj->jb_max		    = cfg->jb_max;
+    obj->tx_drop_pct	    = cfg->tx_drop_pct;
+    obj->rx_drop_pct	    = cfg->rx_drop_pct;
+    obj->ec_options	    = cfg->ec_options;
+    obj->ec_tail_len	    = cfg->ec_tail_len;
+    obj->enable_ice	    = cfg->enable_ice;
+    obj->enable_turn	    = cfg->enable_turn;
+    Py_XDECREF(obj->turn_server);
+    obj->turn_server	    = PyString_FromPJ(&cfg->turn_server);
+    obj->turn_conn_type	    = cfg->turn_conn_type;
+    if (cfg->turn_auth_cred.type == PJ_STUN_AUTH_CRED_STATIC) {
+	const pj_stun_auth_cred *cred = &cfg->turn_auth_cred;
+
+	Py_XDECREF(obj->turn_realm);
+	obj->turn_realm	= PyString_FromPJ(&cred->data.static_cred.realm);
+	Py_XDECREF(obj->turn_username);
+	obj->turn_username = PyString_FromPJ(&cred->data.static_cred.username);
+	obj->turn_passwd_type = cred->data.static_cred.data_type;
+	Py_XDECREF(obj->turn_passwd);
+	obj->turn_passwd = PyString_FromPJ(&cred->data.static_cred.data);
+    } else {
+	Py_XDECREF(obj->turn_realm);
+	obj->turn_realm	= PyString_FromString("");
+	Py_XDECREF(obj->turn_username);
+	obj->turn_username = PyString_FromString("");
+	obj->turn_passwd_type = 0;
+	Py_XDECREF(obj->turn_passwd);
+	obj->turn_passwd = PyString_FromString("");
+    }
+}
+
+static void PyObj_pjsua_media_config_export(pjsua_media_config *cfg,
+					    const PyObj_pjsua_media_config *obj)
+{
+    cfg->clock_rate	    = obj->clock_rate;
+    cfg->snd_clock_rate	    = obj->snd_clock_rate;
+    cfg->channel_count	    = obj->channel_count;
+    cfg->audio_frame_ptime  = obj->audio_frame_ptime;
+    cfg->snd_auto_close_time=obj->snd_auto_close_time;
+    cfg->max_media_ports    = obj->max_media_ports;
+    cfg->has_ioqueue	    = obj->has_ioqueue;
+    cfg->thread_cnt	    = obj->thread_cnt;
+    cfg->quality	    = obj->quality;
+    cfg->ptime		    = obj->ptime;
+    cfg->no_vad		    = obj->no_vad;
+    cfg->jb_min_pre	    = obj->jb_min;
+    cfg->jb_max		    = obj->jb_max;
+    cfg->ilbc_mode	    = obj->ilbc_mode;
+    cfg->tx_drop_pct	    = obj->tx_drop_pct;
+    cfg->rx_drop_pct	    = obj->rx_drop_pct;
+    cfg->ec_options	    = obj->ec_options;
+    cfg->ec_tail_len	    = obj->ec_tail_len;
+    cfg->enable_ice	    = obj->enable_ice;
+    cfg->enable_turn	    = obj->enable_turn;
+
+    if (cfg->enable_turn) {
+	cfg->turn_server = PyString_ToPJ(obj->turn_server);
+	cfg->turn_conn_type = obj->turn_conn_type;
+	cfg->turn_auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
+	cfg->turn_auth_cred.data.static_cred.realm = PyString_ToPJ(obj->turn_realm);
+	cfg->turn_auth_cred.data.static_cred.username = PyString_ToPJ(obj->turn_username);
+	cfg->turn_auth_cred.data.static_cred.data_type= obj->turn_passwd_type;
+	cfg->turn_auth_cred.data.static_cred.data = PyString_ToPJ(obj->turn_passwd);
+    }
+}
+
+
+/*
+ * PyTyp_pjsua_media_config
+ */
+static PyTypeObject PyTyp_pjsua_media_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Media_Config",        /*tp_name*/
+    sizeof(PyObj_pjsua_media_config),/*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_media_config_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Media Config objects",         /*tp_doc*/
+    0,                              /*tp_traverse*/
+    0,                              /*tp_clear*/
+    0,                              /*tp_richcompare*/
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_media_config_members, /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_media_config_new,   /* tp_new */
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_config
+ * attribute list for config object
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    unsigned		  max_calls;
+    unsigned		  thread_cnt;
+    PyObject		 *outbound_proxy;
+    PyObject	         *stun_domain;
+    PyObject		 *stun_host;
+    PyListObject	 *nameserver;
+    PyObj_pjsua_callback *cb;
+    PyObject		 *user_agent;
+} PyObj_pjsua_config;
+
+
+static void PyObj_pjsua_config_delete(PyObj_pjsua_config* self)
+{
+    Py_XDECREF(self->outbound_proxy);
+    Py_XDECREF(self->stun_domain);
+    Py_XDECREF(self->stun_host);
+    Py_XDECREF(self->nameserver);
+    Py_XDECREF(self->cb);
+    Py_XDECREF(self->user_agent);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_config_import(PyObj_pjsua_config *obj,
+				      const pjsua_config *cfg)
+{
+    unsigned i;
+
+    obj->max_calls	= cfg->max_calls;
+    obj->thread_cnt	= cfg->thread_cnt;
+    Py_XDECREF(obj->outbound_proxy);
+    if (cfg->outbound_proxy_cnt)
+	obj->outbound_proxy = PyString_FromPJ(&cfg->outbound_proxy[0]);
+    else
+	obj->outbound_proxy = PyString_FromString("");
+
+    Py_XDECREF(obj->stun_domain);
+    obj->stun_domain	= PyString_FromPJ(&cfg->stun_domain);
+    Py_XDECREF(obj->stun_host);
+    obj->stun_host	= PyString_FromPJ(&cfg->stun_host);
+    Py_XDECREF(obj->nameserver);
+    obj->nameserver = (PyListObject *)PyList_New(0);
+    for (i=0; i<cfg->nameserver_count; ++i) {
+	PyObject * str;
+	str = PyString_FromPJ(&cfg->nameserver[i]);
+	PyList_Append((PyObject *)obj->nameserver, str);
+    }
+    Py_XDECREF(obj->user_agent);
+    obj->user_agent	= PyString_FromPJ(&cfg->user_agent);
+}
+
+
+static void PyObj_pjsua_config_export(pjsua_config *cfg,
+				      PyObj_pjsua_config *obj)
+{
+    unsigned i;
+
+    cfg->max_calls	= obj->max_calls;
+    cfg->thread_cnt	= obj->thread_cnt;
+    if (PyString_Size(obj->outbound_proxy) > 0) {
+	cfg->outbound_proxy_cnt = 1;
+	cfg->outbound_proxy[0] = PyString_ToPJ(obj->outbound_proxy);
+    } else {
+	cfg->outbound_proxy_cnt = 0;
+    }
+    cfg->nameserver_count = PyList_Size((PyObject*)obj->nameserver);
+    if (cfg->nameserver_count > PJ_ARRAY_SIZE(cfg->nameserver))
+	cfg->nameserver_count = PJ_ARRAY_SIZE(cfg->nameserver);
+    for (i = 0; i < cfg->nameserver_count; i++) {
+	PyObject *item = PyList_GetItem((PyObject *)obj->nameserver,i);
+        cfg->nameserver[i] = PyString_ToPJ(item);
+    }
+    cfg->stun_domain	= PyString_ToPJ(obj->stun_domain);
+    cfg->stun_host	= PyString_ToPJ(obj->stun_host);
+    cfg->user_agent	= PyString_ToPJ(obj->user_agent);
+
+}
+
+
+static PyObject *PyObj_pjsua_config_new(PyTypeObject *type, 
+					PyObject *args, 
+					PyObject *kwds)
+{
+    PyObj_pjsua_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_config *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->user_agent = PyString_FromString("");
+        self->outbound_proxy = PyString_FromString("");
+	self->stun_domain = PyString_FromString("");
+	self->stun_host = PyString_FromString("");
+        self->cb = (PyObj_pjsua_callback *)
+		   PyType_GenericNew(&PyTyp_pjsua_callback, NULL, NULL);
+    }
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_config_members
+ * attribute list accessible from Python/C
+ */
+static PyMemberDef PyObj_pjsua_config_members[] =
+{
+    {
+    	"max_calls", T_INT, 
+	offsetof(PyObj_pjsua_config, max_calls), 0,
+    	"Maximum calls to support (default: 4) "
+    },
+    {
+    	"thread_cnt", T_INT, 
+	offsetof(PyObj_pjsua_config, thread_cnt), 0,
+    	"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."
+    },
+    {
+    	"outbound_proxy", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_config, outbound_proxy), 0,
+    	"SIP URL of the outbound proxy (optional)"
+    },
+    {
+    	"stun_domain", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_config, stun_domain), 0,
+    	"Domain of the STUN server (optional). STUN server will be resolved "
+	"using DNS SRV resolution only when nameserver is configured. "
+	"Alternatively, if DNS SRV resolution for STUN is not desired, "
+	"application can specify the STUN server hostname or IP address "
+	"in stun_host attribute."
+    },
+    {
+    	"stun_host", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_config, stun_host), 0,
+    	"Hostname or IP address of the STUN server (optional)."
+    },
+    {
+    	"nameserver", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_config, nameserver), 0,
+    	"IP address of the nameserver."
+    },
+    {
+    	"cb", T_OBJECT_EX, offsetof(PyObj_pjsua_config, cb), 0,
+    	"Application callback."
+    },
+    {
+    	"user_agent", T_OBJECT_EX, offsetof(PyObj_pjsua_config, user_agent), 0,
+    	"User agent string (default empty)"
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjsua_config
+ * type wrapper for config class
+ */
+static PyTypeObject PyTyp_pjsua_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "_pjsua.Config",         /*tp_name*/
+    sizeof(PyObj_pjsua_config),/*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)PyObj_pjsua_config_delete,/*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "Config object",           /* tp_doc */
+    0,                         /* tp_traverse */
+    0,                         /* tp_clear */
+    0,                         /* tp_richcompare */
+    0,                         /* tp_weaklistoffset */
+    0,                         /* tp_iter */
+    0,                         /* tp_iternext */
+    0,                         /* tp_methods */
+    PyObj_pjsua_config_members,/* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    0,                         /* tp_init */
+    0,                         /* tp_alloc */
+    PyObj_pjsua_config_new,    /* tp_new */
+
+};
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_logging_config
+ * configuration class for logging_config object
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    int		 msg_logging;
+    unsigned	 level;
+    unsigned	 console_level;
+    unsigned	 decor;
+    PyObject	*log_filename;
+    PyObject	*cb;
+} PyObj_pjsua_logging_config;
+
+
+/*
+ * PyObj_pjsua_logging_config_delete
+ * deletes a logging config from memory
+ */
+static void PyObj_pjsua_logging_config_delete(PyObj_pjsua_logging_config* self)
+{
+    Py_XDECREF(self->log_filename);
+    Py_XDECREF(self->cb);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_logging_config_import(PyObj_pjsua_logging_config *obj,
+					      const pjsua_logging_config *cfg)
+{
+    obj->msg_logging	= cfg->msg_logging;
+    obj->level		= cfg->level;
+    obj->console_level	= cfg->console_level;
+    obj->decor		= cfg->decor;
+    Py_XDECREF(obj->log_filename);
+    obj->log_filename = PyString_FromPJ(&cfg->log_filename);
+}
+
+static void PyObj_pjsua_logging_config_export(pjsua_logging_config *cfg,
+					      PyObj_pjsua_logging_config *obj)
+{
+    cfg->msg_logging	= obj->msg_logging;
+    cfg->level		= obj->level;
+    cfg->console_level	= obj->console_level;
+    cfg->decor		= obj->decor;
+    cfg->log_filename	= PyString_ToPJ(obj->log_filename);
+}
+
+
+/*
+ * PyObj_pjsua_logging_config_new
+ * constructor for logging_config object
+ */
+static PyObject * PyObj_pjsua_logging_config_new(PyTypeObject *type, 
+						 PyObject *args,
+					         PyObject *kwds)
+{
+    PyObj_pjsua_logging_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_logging_config *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->log_filename = PyString_FromString("");
+        self->cb = Py_BuildValue("");
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_logging_config_members
+ */
+static PyMemberDef PyObj_pjsua_logging_config_members[] =
+{
+    {
+    	"msg_logging", T_INT, 
+	offsetof(PyObj_pjsua_logging_config, msg_logging), 0,
+    	"Log incoming and outgoing SIP message? Yes!"
+    },
+    {
+    	"level", T_INT, 
+	offsetof(PyObj_pjsua_logging_config, level), 0,
+    	"Input verbosity level. Value 5 is reasonable."
+    },
+    {
+    	"console_level", T_INT, 
+	offsetof(PyObj_pjsua_logging_config, console_level),
+    	0, "Verbosity level for console. Value 4 is reasonable."
+    },
+    {
+    	"decor", T_INT, 
+	 offsetof(PyObj_pjsua_logging_config, decor), 0,
+    	"Log decoration"
+    },
+    {
+    	"log_filename", T_OBJECT_EX,
+    	offsetof(PyObj_pjsua_logging_config, log_filename), 0,
+    	"Optional log filename"
+    },
+    {
+    	"cb", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_logging_config, cb), 0,
+    	"Optional callback function to be called to write log to application "
+    	"specific device. This function will be called forlog messages on "
+    	"input verbosity level."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_logging_config
+ */
+static PyTypeObject PyTyp_pjsua_logging_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Logging_Config",      /*tp_name*/
+    sizeof(PyObj_pjsua_logging_config),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_logging_config_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Logging Config objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_logging_config_members,/* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_logging_config_new, /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_msg_data
+ * typewrapper for MessageData class
+ * !modified @ 061206
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    PyObject * hdr_list;
+    PyObject * content_type;
+    PyObject * msg_body;
+} PyObj_pjsua_msg_data;
+
+
+/*
+ * PyObj_pjsua_msg_data_delete
+ * deletes a msg_data
+ * !modified @ 061206
+ */
+static void PyObj_pjsua_msg_data_delete(PyObj_pjsua_msg_data* self)
+{
+    Py_XDECREF(self->hdr_list);
+    Py_XDECREF(self->content_type);
+    Py_XDECREF(self->msg_body);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * PyObj_pjsua_msg_data_new
+ * constructor for msg_data object
+ * !modified @ 061206
+ */
+static PyObject * PyObj_pjsua_msg_data_new(PyTypeObject *type, 
+					   PyObject *args,
+					   PyObject *kwds)
+{
+    PyObj_pjsua_msg_data *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_msg_data *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->hdr_list = PyList_New(0);
+        self->content_type = PyString_FromString("");
+        self->msg_body = PyString_FromString("");
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_msg_data_members
+ * !modified @ 061206
+ */
+static PyMemberDef PyObj_pjsua_msg_data_members[] =
+{
+    {
+        "hdr_list", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_msg_data, hdr_list), 0, 
+	"Additional message headers as linked list of strings."
+    }, 
+    {
+	"content_type", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_msg_data, content_type), 0, 
+	"MIME type of optional message body."
+    },
+    {
+    	"msg_body", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_msg_data, msg_body), 0,
+    	"Optional message body."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjsua_msg_data
+ */
+static PyTypeObject PyTyp_pjsua_msg_data =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "_pjsua.Msg_Data",       /*tp_name*/
+    sizeof(PyObj_pjsua_msg_data),   /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)PyObj_pjsua_msg_data_delete,/*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    "msg_data objects",        /* tp_doc */
+    0,                         /* tp_traverse */
+    0,                         /* tp_clear */
+    0,                         /* tp_richcompare */
+    0,                         /* tp_weaklistoffset */
+    0,                         /* tp_iter */
+    0,                         /* tp_iternext */
+    0,                         /* tp_methods */
+    PyObj_pjsua_msg_data_members,          /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    0,                         /* tp_init */
+    0,                         /* tp_alloc */
+    PyObj_pjsua_msg_data_new,                 /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_transport_config
+ * Transport configuration for creating UDP transports for both SIP
+ * and media.
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    unsigned	port;
+    PyObject   *public_addr;
+    PyObject   *bound_addr;
+    pj_qos_type  qos_type;
+    pj_uint8_t  qos_params_flags;
+    pj_uint8_t  qos_params_dscp_val;
+    pj_uint8_t  qos_params_so_prio;
+    pj_qos_wmm_prio  qos_params_wmm_prio;
+
+} PyObj_pjsua_transport_config;
+
+
+/*
+ * PyObj_pjsua_transport_config_delete
+ * deletes a transport config from memory
+ */
+static void PyObj_pjsua_transport_config_delete(PyObj_pjsua_transport_config* self)
+{
+    Py_XDECREF(self->public_addr);    
+    Py_XDECREF(self->bound_addr);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_transport_config_export(pjsua_transport_config *cfg,
+						PyObj_pjsua_transport_config *obj)
+{
+    pjsua_transport_config_default(cfg);
+    cfg->public_addr	= PyString_ToPJ(obj->public_addr);
+    cfg->bound_addr	= PyString_ToPJ(obj->bound_addr);
+    cfg->port		= obj->port;
+    cfg->qos_type	= obj->qos_type;
+    cfg->qos_params.flags	= obj->qos_params_flags;
+    cfg->qos_params.dscp_val	= obj->qos_params_dscp_val;
+    cfg->qos_params.so_prio	= obj->qos_params_so_prio;
+    cfg->qos_params.wmm_prio	= obj->qos_params_wmm_prio;
+}
+
+static void PyObj_pjsua_transport_config_import(PyObj_pjsua_transport_config *obj,
+						const pjsua_transport_config *cfg)
+{
+    Py_XDECREF(obj->public_addr);    
+    obj->public_addr = PyString_FromPJ(&cfg->public_addr);
+
+    Py_XDECREF(obj->bound_addr);    
+    obj->bound_addr = PyString_FromPJ(&cfg->bound_addr);
+
+    obj->port		= cfg->port;
+    obj->qos_type	= cfg->qos_type;
+    obj->qos_params_flags	= cfg->qos_params.flags;
+    obj->qos_params_dscp_val	= cfg->qos_params.dscp_val;
+    obj->qos_params_so_prio	= cfg->qos_params.so_prio;
+    obj->qos_params_wmm_prio	= cfg->qos_params.wmm_prio;
+
+}
+
+
+/*
+ * PyObj_pjsua_transport_config_new
+ * constructor for transport_config object
+ */
+static PyObject * PyObj_pjsua_transport_config_new(PyTypeObject *type, 
+						   PyObject *args,
+						   PyObject *kwds)
+{
+    PyObj_pjsua_transport_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_transport_config *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->public_addr = PyString_FromString("");
+        self->bound_addr = PyString_FromString("");
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_transport_config_members
+ */
+static PyMemberDef PyObj_pjsua_transport_config_members[] =
+{
+    {
+        "port", T_INT, 
+	offsetof(PyObj_pjsua_transport_config, port), 0,
+        "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."
+    },
+    {
+        "public_addr", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_transport_config, public_addr), 0,
+        "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."		
+    },    
+    {
+        "bound_addr", T_OBJECT_EX, 
+        offsetof(PyObj_pjsua_transport_config, bound_addr), 0,
+        "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)."		
+    },    
+    {
+        "qos_type", T_INT,
+        offsetof(PyObj_pjsua_transport_config, qos_type), 0,
+        "High level traffic classification."
+        "Enumerator:"
+        "  0: PJ_QOS_TYPE_BEST_EFFORT"
+        "       Best effort traffic (default value). Any QoS function calls with "
+        "       specifying this value are effectively no-op"
+        "  1: PJ_QOS_TYPE_BACKGROUND"
+        "       Background traffic."
+        "  2: PJ_QOS_TYPE_VIDEO"
+        "       Video traffic."
+        "  3: PJ_QOS_TYPE_VOICE"
+        "       Voice traffic."
+        "  4: PJ_QOS_TYPE_CONTROL"
+        "       Control traffic."
+    },
+    {
+        "qos_params_flags", T_INT,
+        offsetof(PyObj_pjsua_transport_config, qos_params_flags), 0,
+        "Determines which values to set, bitmask of pj_qos_flag."
+        "   PJ_QOS_PARAM_HAS_DSCP = 1"
+        "   PJ_QOS_PARAM_HAS_SO_PRIO = 2"
+        "   PJ_QOS_PARAM_HAS_WMM = 4"
+    },
+    {
+        "qos_params_dscp_val", T_INT,
+        offsetof(PyObj_pjsua_transport_config, qos_params_dscp_val), 0,
+        "The 6 bits DSCP value to set."
+        "Example: 46=EF, 26=AF31, 24=CS3..."
+    },
+    {
+        "qos_params_so_prio", T_INT,
+        offsetof(PyObj_pjsua_transport_config, qos_params_so_prio), 0,
+        "Socket SO_PRIORITY value."
+    },
+    {
+        "qos_params_wmm_prio", T_INT,
+        offsetof(PyObj_pjsua_transport_config, qos_params_wmm_prio), 0,
+        "Standard WMM priorities."
+        "Enumerator:"
+        "  0: PJ_QOS_WMM_PRIO_BULK_EFFORT"
+        "       Bulk effort priority"
+        "  1: PJ_QOS_WMM_PRIO_BULK"
+        "       Bulk priority."
+        "  2: PJ_QOS_WMM_PRIO_VIDEO"
+        "       Video priority"
+        "  3: PJ_QOS_WMM_PRIO_VOICE"
+        "       Voice priority."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_transport_config
+ */
+static PyTypeObject PyTyp_pjsua_transport_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Transport_Config",    /*tp_name*/
+    sizeof(PyObj_pjsua_transport_config),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_transport_config_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Transport setting",	    /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_transport_config_members,/* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_transport_config_new,/* tp_new */
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_transport_info
+ * Transport info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    int		 id;
+    int		 type;
+    PyObject	*type_name;
+    PyObject	*info;
+    unsigned	 flag;
+    PyObject	*addr;
+    unsigned	 port;
+    unsigned	 usage_count;
+} PyObj_pjsua_transport_info;
+
+
+/*
+ * PyObj_pjsua_transport_info_delete
+ * deletes a transport info from memory
+ */
+static void PyObj_pjsua_transport_info_delete(PyObj_pjsua_transport_info* self)
+{
+    Py_XDECREF(self->type_name); 
+    Py_XDECREF(self->info);
+    Py_XDECREF(self->addr);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_transport_info_import(PyObj_pjsua_transport_info *obj,
+					      const pjsua_transport_info *info)
+{
+    obj->id	    = info->id;
+    obj->type	    = info->type;
+    obj->type_name  = PyString_FromPJ(&info->type_name);
+    obj->info	    = PyString_FromPJ(&info->info);
+    obj->flag	    = info->flag;
+    obj->addr	    = PyString_FromPJ(&info->local_name.host);
+    obj->port	    = info->local_name.port;
+    obj->usage_count= info->usage_count;
+}
+
+/*
+ * PyObj_pjsua_transport_info_new
+ * constructor for transport_info object
+ */
+static PyObject * PyObj_pjsua_transport_info_new(PyTypeObject *type, 
+						 PyObject *args,
+						 PyObject *kwds)
+{
+    PyObj_pjsua_transport_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_transport_info *)type->tp_alloc(type, 0);
+    if (self != NULL)
+    {
+        self->type_name = PyString_FromString("");
+        self->info = PyString_FromString(""); 
+        self->addr = PyString_FromString("");
+    }
+
+    return (PyObject *)self;
+}
+
+
+/*
+ * PyObj_pjsua_transport_info_members
+ */
+static PyMemberDef PyObj_pjsua_transport_info_members[] =
+{
+    {
+        "id", T_INT, 
+	offsetof(PyObj_pjsua_transport_info, id), 0,
+        "PJSUA transport identification."
+    },
+    {
+        "type", T_INT, 
+	offsetof(PyObj_pjsua_transport_info, type), 0,
+        "Transport type."
+    },
+    {
+        "type_name", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_transport_info, type_name), 0,
+        "Transport type name."
+    },
+    {
+        "info", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_transport_info, info), 0,
+        "Transport string info/description."
+    },
+    {
+        "flag", T_INT, 
+	offsetof(PyObj_pjsua_transport_info, flag), 0,
+        "Transport flag (see ##pjsip_transport_flags_e)."
+    },
+    {
+        "addr", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_transport_info, addr), 0,
+        "Published address (or transport address name)."
+    },
+    {
+        "port", T_INT,
+        offsetof(PyObj_pjsua_transport_info, port), 0,
+        "Published port number."
+    },
+    {
+        "usage_count", T_INT, 
+	offsetof(PyObj_pjsua_transport_info, usage_count), 0,
+        "Current number of objects currently referencing this transport."
+    },    
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjsua_transport_info
+ */
+static PyTypeObject PyTyp_pjsua_transport_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Transport_Info",      /*tp_name*/
+    sizeof(PyObj_pjsua_transport_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_transport_info_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Transport Info objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_transport_info_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_transport_info_new, /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjsua_acc_config
+ * Acc Config
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    int		     priority;	
+    PyObject	    *id;
+    PyObject	    *reg_uri;
+    int		     publish_enabled;
+    int		     mwi_enabled;
+    PyObject	    *force_contact;
+    PyListObject    *proxy;
+    unsigned	     reg_timeout;
+    unsigned	     reg_delay_before_refresh;
+    PyListObject    *cred_info;
+    int		     transport_id;
+    int		     auth_initial_send;
+    PyObject	    *auth_initial_algorithm;
+    PyObject	    *pidf_tuple_id;
+    PyObject	    *contact_params;
+    PyObject	    *contact_uri_params;
+    int		     require_100rel;
+    int		     use_timer;
+    unsigned	     timer_se;
+    unsigned	     timer_min_se;
+    int		     allow_contact_rewrite;
+    int		     ka_interval;
+    PyObject	    *ka_data;
+    unsigned	     use_srtp;
+    unsigned	     srtp_secure_signaling;
+    PyObject	    *rtp_transport_cfg;
+} PyObj_pjsua_acc_config;
+
+
+/*
+ * PyObj_pjsua_acc_config_delete
+ * deletes a acc_config from memory
+ */
+static void PyObj_pjsua_acc_config_delete(PyObj_pjsua_acc_config* self)
+{
+    Py_XDECREF(self->id); 
+    Py_XDECREF(self->reg_uri);
+    Py_XDECREF(self->force_contact);	
+    Py_XDECREF(self->proxy);
+    Py_XDECREF(self->cred_info);
+    Py_XDECREF(self->auth_initial_algorithm);
+    Py_XDECREF(self->pidf_tuple_id);
+    Py_XDECREF(self->contact_params);
+    Py_XDECREF(self->contact_uri_params);
+    Py_XDECREF(self->ka_data);
+    Py_XDECREF(self->rtp_transport_cfg);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_acc_config_import(PyObj_pjsua_acc_config *obj,
+					  const pjsua_acc_config *cfg)
+{
+    PyObj_pjsua_transport_config *tconf;
+    unsigned i;
+
+    obj->priority   = cfg->priority;
+    Py_XDECREF(obj->id);
+    obj->id	    = PyString_FromPJ(&cfg->id);
+    Py_XDECREF(obj->reg_uri);
+    obj->reg_uri    = PyString_FromPJ(&cfg->reg_uri);
+    obj->publish_enabled = cfg->publish_enabled;
+    obj->mwi_enabled = cfg->mwi_enabled;
+    Py_XDECREF(obj->force_contact);
+    obj->force_contact = PyString_FromPJ(&cfg->force_contact);
+    Py_XDECREF(obj->proxy);
+    obj->proxy = (PyListObject *)PyList_New(0);
+    for (i=0; i<cfg->proxy_cnt; ++i) {
+	PyObject * str;
+	str = PyString_FromPJ(&cfg->proxy[i]);
+	PyList_Append((PyObject *)obj->proxy, str);
+    }
+
+    obj->reg_timeout = cfg->reg_timeout;
+    obj->reg_delay_before_refresh = cfg->reg_delay_before_refresh;
+
+    Py_XDECREF(obj->cred_info);
+    obj->cred_info = (PyListObject *)PyList_New(0);
+    for (i=0; i<cfg->cred_count; ++i) {
+	PyObj_pjsip_cred_info * ci;
+
+	ci = (PyObj_pjsip_cred_info *)
+	     PyObj_pjsip_cred_info_new(&PyTyp_pjsip_cred_info,NULL,NULL);
+	PyObj_pjsip_cred_info_import(ci, &cfg->cred_info[i]);
+	PyList_Append((PyObject *)obj->cred_info, (PyObject *)ci);
+    }
+
+    obj->transport_id = cfg->transport_id;
+
+    obj->auth_initial_send = cfg->auth_pref.initial_auth;
+    Py_XDECREF(obj->auth_initial_algorithm);
+    obj->auth_initial_algorithm = PyString_FromPJ(&cfg->auth_pref.algorithm);
+    Py_XDECREF(obj->pidf_tuple_id);
+    obj->pidf_tuple_id = PyString_FromPJ(&cfg->pidf_tuple_id);
+    Py_XDECREF(obj->contact_params);
+    obj->contact_params = PyString_FromPJ(&cfg->contact_params);
+    Py_XDECREF(obj->contact_uri_params);
+    obj->contact_uri_params = PyString_FromPJ(&cfg->contact_uri_params);
+    obj->require_100rel = cfg->require_100rel;
+    obj->use_timer = cfg->use_timer;
+    obj->timer_se = cfg->timer_setting.sess_expires;
+    obj->timer_min_se = cfg->timer_setting.min_se;
+    obj->allow_contact_rewrite = cfg->allow_contact_rewrite;
+    obj->ka_interval = cfg->ka_interval;
+    Py_XDECREF(obj->ka_data);
+    obj->ka_data = PyString_FromPJ(&cfg->ka_data);
+    obj->use_srtp = cfg->use_srtp;
+    obj->srtp_secure_signaling = cfg->srtp_secure_signaling;
+
+    Py_XDECREF(obj->rtp_transport_cfg);
+    tconf = (PyObj_pjsua_transport_config*)
+	    PyObj_pjsua_transport_config_new(&PyTyp_pjsua_transport_config,
+					     NULL, NULL);
+    PyObj_pjsua_transport_config_import(tconf, &cfg->rtp_cfg);
+    obj->rtp_transport_cfg = (PyObject *) tconf;
+}
+
+static void PyObj_pjsua_acc_config_export(pjsua_acc_config *cfg,
+					  PyObj_pjsua_acc_config *obj)
+{
+    PyObj_pjsua_transport_config *tconf;
+    unsigned i;
+
+    cfg->priority   = obj->priority;
+    cfg->id	    = PyString_ToPJ(obj->id);
+    cfg->reg_uri    = PyString_ToPJ(obj->reg_uri);
+    cfg->publish_enabled = obj->publish_enabled;
+    cfg->mwi_enabled = obj->mwi_enabled;
+    cfg->force_contact = PyString_ToPJ(obj->force_contact);
+
+    cfg->proxy_cnt = PyList_Size((PyObject*)obj->proxy);
+    if (cfg->proxy_cnt > PJ_ARRAY_SIZE(cfg->proxy))
+	cfg->proxy_cnt = PJ_ARRAY_SIZE(cfg->proxy);
+    for (i = 0; i < cfg->proxy_cnt; i++) {
+	PyObject *item = PyList_GetItem((PyObject *)obj->proxy, i);
+        cfg->proxy[i] = PyString_ToPJ(item);
+    }
+
+    cfg->reg_timeout = obj->reg_timeout;
+    cfg->reg_delay_before_refresh = obj->reg_delay_before_refresh;
+
+    cfg->cred_count = PyList_Size((PyObject*)obj->cred_info);
+    if (cfg->cred_count > PJ_ARRAY_SIZE(cfg->cred_info))
+	cfg->cred_count = PJ_ARRAY_SIZE(cfg->cred_info);
+    for (i = 0; i < cfg->cred_count; i++) {
+	PyObj_pjsip_cred_info *ci;
+	ci = (PyObj_pjsip_cred_info*)
+	     PyList_GetItem((PyObject *)obj->cred_info, i);
+	PyObj_pjsip_cred_info_export(&cfg->cred_info[i], ci);
+    }
+
+    cfg->transport_id = obj->transport_id;
+    cfg->auth_pref.initial_auth = obj->auth_initial_send;
+    cfg->auth_pref.algorithm = PyString_ToPJ(obj->auth_initial_algorithm);
+    cfg->pidf_tuple_id = PyString_ToPJ(obj->pidf_tuple_id);
+    cfg->contact_params = PyString_ToPJ(obj->contact_params);
+    cfg->contact_uri_params = PyString_ToPJ(obj->contact_uri_params);
+    cfg->require_100rel = obj->require_100rel;
+    cfg->use_timer = obj->use_timer;
+    cfg->timer_setting.sess_expires = obj->timer_se;
+    cfg->timer_setting.min_se = obj->timer_min_se;
+    cfg->allow_contact_rewrite = obj->allow_contact_rewrite;
+    cfg->ka_interval = obj->ka_interval;
+    cfg->ka_data = PyString_ToPJ(obj->ka_data);
+    cfg->use_srtp = obj->use_srtp;
+    cfg->srtp_secure_signaling = obj->srtp_secure_signaling;
+
+    tconf = (PyObj_pjsua_transport_config*)obj->rtp_transport_cfg;
+    PyObj_pjsua_transport_config_export(&cfg->rtp_cfg, tconf);
+}
+
+
+/*
+ * PyObj_pjsua_acc_config_new
+ * constructor for acc_config object
+ */
+static PyObject * PyObj_pjsua_acc_config_new(PyTypeObject *type, 
+					     PyObject *args,
+					     PyObject *kwds)
+{
+    PyObj_pjsua_acc_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_acc_config *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->id = PyString_FromString("");
+        self->reg_uri = PyString_FromString("");
+        self->force_contact = PyString_FromString("");
+	self->proxy = (PyListObject *)PyList_New(0);
+	self->cred_info = (PyListObject *)PyList_New(0);
+	self->auth_initial_algorithm = PyString_FromString("");
+	self->pidf_tuple_id = PyString_FromString("");
+	self->contact_params = PyString_FromString("");
+	self->contact_uri_params = PyString_FromString("");
+	self->ka_data = PyString_FromString("");
+    }
+
+    return (PyObject *)self;
+}
+
+
+
+/*
+ * PyObj_pjsua_acc_config_members
+ */
+static PyMemberDef PyObj_pjsua_acc_config_members[] =
+{
+    {
+        "priority", T_INT, offsetof(PyObj_pjsua_acc_config, priority), 0,
+        "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. "
+    },
+    {
+        "id", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, id), 0,
+        "The full SIP URL for the account. "
+        "The value can take name address or URL format, "
+        "and will look something like 'sip:account@serviceprovider'. "
+        "This field is mandatory."
+    },
+    {
+        "reg_uri", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, reg_uri), 0,
+        "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. "
+    },
+    {
+        "publish_enabled", T_INT, 
+        offsetof(PyObj_pjsua_acc_config, publish_enabled), 0,
+        "Publish presence? "
+    },
+    {
+        "mwi_enabled", T_INT, 
+        offsetof(PyObj_pjsua_acc_config, mwi_enabled), 0,
+        "Enable MWI subscription "
+    },
+    {
+        "force_contact", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, force_contact), 0,
+        "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. "
+    },
+    {
+        "proxy", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, proxy), 0,
+        "Optional URI of the proxies to be visited for all outgoing requests "
+	"that are using this account (REGISTER, INVITE, etc). Application need "
+	"to specify these proxies if the service provider requires "
+	"that requests destined towards its network should go through certain "
+	"proxies first (for example, border controllers)."
+    },
+    {
+        "reg_timeout", T_INT, 
+	offsetof(PyObj_pjsua_acc_config, reg_timeout), 0,
+        "Optional interval for registration, in seconds. "
+        "If the value is zero, default interval will be used "
+        "(PJSUA_REG_INTERVAL, 55 seconds). "
+    },
+    {
+        "reg_delay_before_refresh", T_INT, 
+	offsetof(PyObj_pjsua_acc_config, reg_delay_before_refresh), 0,
+        "Specify the number of seconds to refresh the client registration"
+        "before the registration expires."
+        "(PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH, 5 seconds). "
+    },
+    {
+        "cred_info", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_config, cred_info), 0,
+        "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."
+    },
+    {
+	"transport_id", T_INT,
+	offsetof(PyObj_pjsua_acc_config, transport_id), 0,
+	"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."
+    },
+    {
+	"auth_initial_send", T_INT,
+	offsetof(PyObj_pjsua_acc_config, auth_initial_send), 0,
+	"Send empty initial authorization header."
+    },
+    {
+	"auth_initial_algorithm", T_OBJECT_EX,
+	offsetof(PyObj_pjsua_acc_config, auth_initial_algorithm), 0,
+	"Specify algorithm in empty initial authorization header."
+    },
+    {
+	"pidf_tuple_id", T_OBJECT_EX,
+	offsetof(PyObj_pjsua_acc_config, pidf_tuple_id), 0,
+	"PIDF tuple id."
+    },
+    {
+	"contact_params", T_OBJECT_EX,
+	offsetof(PyObj_pjsua_acc_config, contact_params), 0,
+	"Additional parameters for Contact header."
+    },
+    {
+	"contact_uri_params", T_OBJECT_EX,
+	offsetof(PyObj_pjsua_acc_config, contact_uri_params), 0,
+	"Additional parameters for Contact URI."
+    },
+    {
+	"require_100rel", T_INT,
+	offsetof(PyObj_pjsua_acc_config, require_100rel), 0,
+	"Require reliable provisional response."
+    },
+    {
+	"use_timer", T_INT,
+	offsetof(PyObj_pjsua_acc_config, use_timer), 0,
+	"Use SIP session timers? (default=1)"
+	"0:inactive, 1:optional, 2:mandatory, 3:always"
+    },
+    {
+	"timer_se", T_INT,
+	offsetof(PyObj_pjsua_acc_config, timer_se), 0,
+	"Session timer expiration period, in seconds."
+    },
+    {
+	"timer_min_se", T_INT,
+	offsetof(PyObj_pjsua_acc_config, timer_min_se), 0,
+	"Session timer minimum expiration period, in seconds."
+    },
+    {
+	"allow_contact_rewrite", T_INT,
+	offsetof(PyObj_pjsua_acc_config, allow_contact_rewrite), 0,
+	"Re-REGISTER if behind symmetric NAT."
+    },
+    {
+	"ka_interval", T_INT,
+	offsetof(PyObj_pjsua_acc_config, ka_interval), 0,
+	"Keep-alive interval."
+    },
+    {
+	"ka_data", T_OBJECT_EX,
+	offsetof(PyObj_pjsua_acc_config, ka_data), 0,
+	"Keep-alive data."
+    },
+    {
+	"use_srtp", T_INT,
+	offsetof(PyObj_pjsua_acc_config, use_srtp), 0,
+	"Specify SRTP usage."
+    },
+    {
+	"srtp_secure_signaling", T_INT,
+	offsetof(PyObj_pjsua_acc_config, srtp_secure_signaling), 0,
+	"Specify if SRTP requires secure signaling to be used."
+    },
+    {
+	"rtp_transport_cfg", T_OBJECT_EX,
+	offsetof(PyObj_pjsua_acc_config, rtp_transport_cfg), 0,
+	"Transport configuration for RTP."
+    },
+
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_acc_config
+ */
+static PyTypeObject PyTyp_pjsua_acc_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Acc_Config",	    /*tp_name*/
+    sizeof(PyObj_pjsua_acc_config), /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_acc_config_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Account settings",		    /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_acc_config_members, /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_acc_config_new,     /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_acc_info
+ * Acc Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    int		 id;	
+    int		 is_default;
+    PyObject	*acc_uri;
+    int		 has_registration;
+    int		 expires;
+    int		 status;
+    PyObject	*status_text;
+    int		 online_status;	
+    PyObject	*online_status_text;
+} PyObj_pjsua_acc_info;
+
+
+/*
+ * PyObj_pjsua_acc_info_delete
+ * deletes a acc_info from memory
+ */
+static void PyObj_pjsua_acc_info_delete(PyObj_pjsua_acc_info* self)
+{
+    Py_XDECREF(self->acc_uri);
+    Py_XDECREF(self->status_text);
+    Py_XDECREF(self->online_status_text);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_acc_info_import(PyObj_pjsua_acc_info *obj,
+					const pjsua_acc_info *info)
+{
+    obj->id	    = info->id;
+    obj->is_default = info->is_default;
+    Py_XDECREF(obj->acc_uri);
+    obj->acc_uri    = PyString_FromPJ(&info->acc_uri);
+    obj->has_registration = info->has_registration;
+    obj->expires    = info->expires;
+    obj->status	    = info->status;
+    Py_XDECREF(obj->status_text);
+    obj->status_text= PyString_FromPJ(&info->status_text);
+    obj->online_status = info->online_status;
+    Py_XDECREF(obj->online_status_text);
+    obj->online_status_text = PyString_FromPJ(&info->online_status_text);
+}
+
+
+/*
+ * PyObj_pjsua_acc_info_new
+ * constructor for acc_info object
+ */
+static PyObject * PyObj_pjsua_acc_info_new(PyTypeObject *type, 
+					   PyObject *args,
+					   PyObject *kwds)
+{
+    PyObj_pjsua_acc_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_acc_info *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->acc_uri = PyString_FromString("");
+	self->status_text = PyString_FromString("");
+	self->online_status_text = PyString_FromString("");
+    }
+
+    return (PyObject *)self;
+}
+
+/*
+ * acc_info_members
+ */
+static PyMemberDef acc_info_members[] =
+{
+    {
+        "id", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, id), 0,
+        "The account ID."
+    },
+    {
+        "is_default", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, is_default), 0,
+        "Flag to indicate whether this is the default account. "
+    },
+    {
+        "acc_uri", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_info, acc_uri), 0,
+        "Account URI"
+    },
+    {
+        "has_registration", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, has_registration), 0,
+        "Flag to tell whether this account has registration setting "
+        "(reg_uri is not empty)."
+    },
+    {
+        "expires", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, expires), 0,
+        "An up to date expiration interval for account registration session."
+    },
+    {
+        "status", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, status), 0,
+        "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. "
+    },
+    {
+        "status_text", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_acc_info, status_text), 0,
+        "String describing the registration status."
+    },
+    {
+        "online_status", T_INT, 
+	offsetof(PyObj_pjsua_acc_info, online_status), 0,
+        "Presence online status for this account. "
+    },
+    {
+        "online_status_text", T_OBJECT_EX, 
+	offsetof(PyObj_pjsua_acc_info, online_status_text), 0,
+        "Presence online status text."
+    },
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_acc_info
+ */
+static PyTypeObject PyTyp_pjsua_acc_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Acc_Info",		    /*tp_name*/
+    sizeof(PyObj_pjsua_acc_info),   /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_acc_info_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Account info",		    /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    NULL,                           /* tp_methods */
+    acc_info_members,		    /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_acc_info_new,       /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjsua_buddy_config
+ * Buddy Config
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+    PyObject	*uri;
+    int		 subscribe;
+} PyObj_pjsua_buddy_config;
+
+
+/*
+ * PyObj_pjsua_buddy_config_delete
+ * deletes a buddy_config from memory
+ */
+static void PyObj_pjsua_buddy_config_delete(PyObj_pjsua_buddy_config* self)
+{
+    Py_XDECREF(self->uri);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_buddy_config_import(PyObj_pjsua_buddy_config *obj,
+					    const pjsua_buddy_config *cfg)
+{
+    Py_XDECREF(obj->uri);
+    obj->uri = PyString_FromPJ(&cfg->uri);
+    obj->subscribe = cfg->subscribe;
+}
+
+
+static void PyObj_pjsua_buddy_config_export(pjsua_buddy_config *cfg,
+					    PyObj_pjsua_buddy_config *obj)
+{
+    cfg->uri = PyString_ToPJ(obj->uri);
+    cfg->subscribe = obj->subscribe;
+    cfg->user_data = NULL;
+}
+
+
+/*
+ * PyObj_pjsua_buddy_config_new
+ * constructor for buddy_config object
+ */
+static PyObject *PyObj_pjsua_buddy_config_new(PyTypeObject *type, 
+					      PyObject *args,
+					      PyObject *kwds)
+{
+    PyObj_pjsua_buddy_config *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_buddy_config *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->uri = PyString_FromString("");
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * PyObj_pjsua_buddy_config_members
+ */
+static PyMemberDef PyObj_pjsua_buddy_config_members[] =
+{
+    
+    {
+        "uri", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_buddy_config, uri), 0,
+        "TBuddy URL or name address."        
+    },
+    
+    {
+        "subscribe", T_INT, 
+        offsetof(PyObj_pjsua_buddy_config, subscribe), 0,
+        "Specify whether presence subscription should start immediately. "
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_buddy_config
+ */
+static PyTypeObject PyTyp_pjsua_buddy_config =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Buddy_Config",        /*tp_name*/
+    sizeof(PyObj_pjsua_buddy_config),/*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_buddy_config_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Buddy config",		    /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_buddy_config_members,/* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_buddy_config_new,   /* tp_new */
+
+};
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsua_buddy_info
+ * Buddy Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    int		 id;
+    PyObject	*uri;
+    PyObject	*contact;
+    int		 status;
+    PyObject	*status_text;
+    int		 monitor_pres;
+    int		 activity;
+    int		 sub_state;
+    PyObject	*sub_term_reason;
+} PyObj_pjsua_buddy_info;
+
+
+/*
+ * PyObj_pjsua_buddy_info_delete
+ * deletes a buddy_info from memory
+ * !modified @ 071206
+ */
+static void PyObj_pjsua_buddy_info_delete(PyObj_pjsua_buddy_info* self)
+{
+    Py_XDECREF(self->uri);
+    Py_XDECREF(self->contact);
+    Py_XDECREF(self->status_text);
+    Py_XDECREF(self->sub_term_reason);
+    
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsua_buddy_info_import(PyObj_pjsua_buddy_info *obj,
+					  const pjsua_buddy_info *info)
+{
+    obj->id = info->id;
+    Py_XDECREF(obj->uri);
+    obj->uri = PyString_FromPJ(&info->uri);
+    Py_XDECREF(obj->contact);
+    obj->contact = PyString_FromPJ(&info->contact);
+    obj->status = info->status;
+    Py_XDECREF(obj->status_text);
+    obj->status_text = PyString_FromPJ(&info->status_text);
+    obj->monitor_pres = info->monitor_pres;
+    obj->activity = info->rpid.activity;
+    obj->sub_state = info->sub_state;
+    Py_XDECREF(obj->sub_term_reason);
+    obj->sub_term_reason = PyString_FromPJ(&info->sub_term_reason);
+}
+
+
+/*
+ * PyObj_pjsua_buddy_info_new
+ * constructor for buddy_info object
+ * !modified @ 071206
+ */
+static PyObject * PyObj_pjsua_buddy_info_new(PyTypeObject *type, 
+					     PyObject *args,
+					     PyObject *kwds)
+{
+    PyObj_pjsua_buddy_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_buddy_info *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->uri = PyString_FromString("");
+	self->contact = PyString_FromString("");
+	self->status_text = PyString_FromString("");
+	self->sub_term_reason = PyString_FromString("");
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * PyObj_pjsua_buddy_info_members
+ * !modified @ 071206
+ */
+static PyMemberDef PyObj_pjsua_buddy_info_members[] =
+{
+    {
+        "id", T_INT, 
+        offsetof(PyObj_pjsua_buddy_info, id), 0,
+        "The buddy ID."
+    },
+    {
+        "uri", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_buddy_info, uri), 0,
+        "The full URI of the buddy, as specified in the configuration. "        
+    },
+    {
+        "contact", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_buddy_info, contact), 0,
+        "Buddy's Contact, only available when presence subscription "
+        "has been established to the buddy."        
+    },
+    {
+        "status", T_INT, 
+        offsetof(PyObj_pjsua_buddy_info, status), 0,
+        "Buddy's online status. "
+    },
+    {
+        "status_text", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_buddy_info, status_text), 0,
+        "Text to describe buddy's online status."        
+    },
+    {
+        "monitor_pres", T_INT, 
+        offsetof(PyObj_pjsua_buddy_info, monitor_pres), 0,
+        "Flag to indicate that we should monitor the presence information "
+        "for this buddy (normally yes, unless explicitly disabled). "
+    },
+    {
+        "activity", T_INT, 
+        offsetof(PyObj_pjsua_buddy_info, activity), 0,
+        "Activity type. "
+    },
+    {
+        "sub_state", T_INT, 
+        offsetof(PyObj_pjsua_buddy_info, sub_state), 0,
+        "Subscription state."
+    },
+    {
+        "sub_term_reason", T_INT, 
+        offsetof(PyObj_pjsua_buddy_info, sub_term_reason), 0,
+        "Subscription termination reason."
+    },
+    
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_buddy_info
+ */
+static PyTypeObject PyTyp_pjsua_buddy_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Buddy_Info",	    /*tp_name*/
+    sizeof(PyObj_pjsua_buddy_info), /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsua_buddy_info_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Buddy Info object",	    /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsua_buddy_info_members, /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsua_buddy_info_new,     /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjsua_codec_info
+ * Codec Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    PyObject * codec_id;
+    pj_uint8_t priority;    
+} PyObj_pjsua_codec_info;
+
+
+/*
+ * codec_info_dealloc
+ * deletes a codec_info from memory
+ */
+static void codec_info_dealloc(PyObj_pjsua_codec_info* self)
+{
+    Py_XDECREF(self->codec_id);    
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * codec_info_new
+ * constructor for codec_info object
+ */
+static PyObject * codec_info_new(PyTypeObject *type, PyObject *args,
+                                 PyObject *kwds)
+{
+    PyObj_pjsua_codec_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_codec_info *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->codec_id = PyString_FromString("");
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * codec_info_members
+ * !modified @ 071206
+ */
+static PyMemberDef codec_info_members[] =
+{    
+    {
+        "codec_id", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_codec_info, codec_id), 0,
+        "Codec unique identification."        
+    },
+    {
+        "priority", T_INT, 
+        offsetof(PyObj_pjsua_codec_info, priority), 0,
+        "Codec priority (integer 0-255)."
+    },
+
+    {NULL}  /* Sentinel */
+};
+
+/*
+ * PyTyp_pjsua_codec_info
+ */
+static PyTypeObject PyTyp_pjsua_codec_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Codec_Info",	    /*tp_name*/
+    sizeof(PyObj_pjsua_codec_info), /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)codec_info_dealloc, /*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Codec Info",		    /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    codec_info_members,		    /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    codec_info_new,		    /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjsua_conf_port_info
+ * Conf Port Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    int		 slot_id;
+    PyObject	*name;
+    unsigned	 clock_rate;
+    unsigned	 channel_count;
+    unsigned	 samples_per_frame;
+    unsigned	 bits_per_sample;
+    PyObject	*listeners;
+
+} PyObj_pjsua_conf_port_info;
+
+
+/*
+ * conf_port_info_dealloc
+ * deletes a conf_port_info from memory
+ */
+static void conf_port_info_dealloc(PyObj_pjsua_conf_port_info* self)
+{
+    Py_XDECREF(self->name);    
+    Py_XDECREF(self->listeners);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * conf_port_info_new
+ * constructor for conf_port_info object
+ */
+static PyObject * conf_port_info_new(PyTypeObject *type, PyObject *args,
+                                     PyObject *kwds)
+{
+    PyObj_pjsua_conf_port_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_conf_port_info *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->name = PyString_FromString("");
+	self->listeners = PyList_New(0);
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * conf_port_info_members
+ */
+static PyMemberDef conf_port_info_members[] =
+{   
+    {
+        "slot_id", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, slot_id), 0,
+        "Conference port number."
+    },
+    {
+        "name", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_conf_port_info, name), 0,
+        "Port name"        
+    },
+    {
+        "clock_rate", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, clock_rate), 0,
+        "Clock rate"
+    },
+    {
+        "channel_count", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, channel_count), 0,
+        "Number of channels."
+    },
+    {
+        "samples_per_frame", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, samples_per_frame), 0,
+        "Samples per frame "
+    },
+    {
+        "bits_per_sample", T_INT, 
+        offsetof(PyObj_pjsua_conf_port_info, bits_per_sample), 0,
+        "Bits per sample"
+    },
+    {
+        "listeners", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_conf_port_info, listeners), 0,
+        "Array of listeners (in other words, ports where this port "
+	"is transmitting to"
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_conf_port_info
+ */
+static PyTypeObject PyTyp_pjsua_conf_port_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Conf_Port_Info",	    /*tp_name*/
+    sizeof(PyObj_pjsua_conf_port_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)conf_port_info_dealloc,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Conf Port Info objects",       /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    conf_port_info_members,         /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    conf_port_info_new,             /* tp_new */
+
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjmedia_snd_dev_info
+ * PJMedia Snd Dev Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+        
+    unsigned  input_count;
+    unsigned  output_count;
+    unsigned  default_samples_per_sec;    
+    PyObject *name;
+
+} PyObj_pjmedia_snd_dev_info;
+
+/*
+ * pjmedia_snd_dev_info_dealloc
+ * deletes a pjmedia_snd_dev_info from memory
+ */
+static void pjmedia_snd_dev_info_dealloc(PyObj_pjmedia_snd_dev_info* self)
+{
+    Py_XDECREF(self->name);        
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+/*
+ * pjmedia_snd_dev_info_new
+ * constructor for pjmedia_snd_dev_info object
+ */
+static PyObject * pjmedia_snd_dev_info_new(PyTypeObject *type, 
+					   PyObject *args,
+					   PyObject *kwds)
+{
+    PyObj_pjmedia_snd_dev_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjmedia_snd_dev_info *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->name = PyString_FromString("");	
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * pjmedia_snd_dev_info_members
+ */
+static PyMemberDef pjmedia_snd_dev_info_members[] =
+{
+    {
+        "input_count", T_INT, 
+        offsetof(PyObj_pjmedia_snd_dev_info, input_count), 0,
+        "Max number of input channels"
+    },
+    {
+        "output_count", T_INT, 
+        offsetof(PyObj_pjmedia_snd_dev_info, output_count), 0,
+        "Max number of output channels"
+    },
+    {
+        "default_samples_per_sec", T_INT, 
+        offsetof(PyObj_pjmedia_snd_dev_info, default_samples_per_sec), 0,
+        "Default sampling rate."
+    },
+    {
+        "name", T_OBJECT_EX,
+        offsetof(PyObj_pjmedia_snd_dev_info, name), 0,
+        "Device name"        
+    },
+        
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjmedia_snd_dev_info
+ */
+static PyTypeObject PyTyp_pjmedia_snd_dev_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.PJMedia_Snd_Dev_Info",  /*tp_name*/
+    sizeof(PyObj_pjmedia_snd_dev_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)pjmedia_snd_dev_info_dealloc,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJMedia Snd Dev Info object",  /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    pjmedia_snd_dev_info_members,   /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    pjmedia_snd_dev_info_new,       /* tp_new */
+
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjmedia_codec_param_info
+ * PJMedia Codec Param Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    unsigned	clock_rate;
+    unsigned	channel_cnt;
+    pj_uint32_t avg_bps;
+    pj_uint16_t frm_ptime;
+    pj_uint8_t  pcm_bits_per_sample;
+    pj_uint8_t  pt;	
+
+} PyObj_pjmedia_codec_param_info;
+
+
+
+/*
+ * pjmedia_codec_param_info_members
+ */
+static PyMemberDef pjmedia_codec_param_info_members[] =
+{
+    {
+        "clock_rate", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, clock_rate), 0,
+        "Sampling rate in Hz"
+    },
+    {
+        "channel_cnt", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, channel_cnt), 0,
+        "Channel count"
+    },
+    {
+        "avg_bps", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, avg_bps), 0,
+        "Average bandwidth in bits/sec"
+    },
+    {
+        "frm_ptime", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, frm_ptime), 0,
+        "Base frame ptime in msec."
+    },
+    {
+        "pcm_bits_per_sample", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, pcm_bits_per_sample), 0,
+        "Bits/sample in the PCM side"
+    },
+    {
+        "pt", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_info, pt), 0,
+        "Payload type"
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjmedia_codec_param_info
+ */
+static PyTypeObject PyTyp_pjmedia_codec_param_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.PJMedia_Codec_Param_Info",      /*tp_name*/
+    sizeof(PyObj_pjmedia_codec_param_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    0,				    /*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJMedia Codec Param Info objects",/* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    pjmedia_codec_param_info_members,/* tp_members */
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjmedia_codec_param_setting
+ * PJMedia Codec Param Setting
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    pj_uint8_t  frm_per_pkt; 
+    unsigned    vad;
+    unsigned    cng;
+    unsigned    penh;
+    unsigned    plc;
+#if 0
+    pj_uint8_t  enc_fmtp_mode;
+    pj_uint8_t  dec_fmtp_mode; 
+#endif
+
+} PyObj_pjmedia_codec_param_setting;
+
+
+
+/*
+ * pjmedia_codec_param_setting_members
+ */
+static PyMemberDef pjmedia_codec_param_setting_members[] =
+{
+    {
+        "frm_per_pkt", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, frm_per_pkt), 0,
+        "Number of frames per packet"
+    },
+    {
+        "vad", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, vad), 0,
+        "Voice Activity Detector"
+    },
+    {
+        "cng", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, cng), 0,
+        "Comfort Noise Generator"
+    },
+    {
+        "penh", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, penh), 0,
+        "Perceptual Enhancement"
+    },
+    {
+        "plc", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, plc), 0,
+        "Packet loss concealment"
+    },
+#if 0	// no longer valid with latest modification in codec
+    {
+        "enc_fmtp_mode", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, enc_fmtp_mode), 0,
+        "Mode param in fmtp (def:0)"
+    },
+    {
+        "dec_fmtp_mode", T_INT, 
+        offsetof(PyObj_pjmedia_codec_param_setting, dec_fmtp_mode), 0,
+        "Mode param in fmtp (def:0)"
+    },
+#endif
+    
+    {NULL}  /* Sentinel */
+};
+
+
+/*
+ * PyTyp_pjmedia_codec_param_setting
+ */
+static PyTypeObject PyTyp_pjmedia_codec_param_setting =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.PJMedia_Codec_Param_Setting",/*tp_name*/
+    sizeof(PyObj_pjmedia_codec_param_setting),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    0,				    /*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJMedia Codec Param Setting",  /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    pjmedia_codec_param_setting_members,/* tp_members */
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+
+/*
+ * PyObj_pjmedia_codec_param
+ * PJMedia Codec Param
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    PyObj_pjmedia_codec_param_info * info;
+    PyObj_pjmedia_codec_param_setting * setting;
+
+} PyObj_pjmedia_codec_param;
+
+/*
+ * pjmedia_codec_param_dealloc
+ * deletes a pjmedia_codec_param from memory
+ */
+static void pjmedia_codec_param_dealloc(PyObj_pjmedia_codec_param* self)
+{
+    Py_XDECREF(self->info);        
+    Py_XDECREF(self->setting);        
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+/*
+ * pjmedia_codec_param_new
+ * constructor for pjmedia_codec_param object
+ */
+static PyObject * pjmedia_codec_param_new(PyTypeObject *type, 
+					  PyObject *args,
+					  PyObject *kwds)
+{
+    PyObj_pjmedia_codec_param *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjmedia_codec_param *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->info = (PyObj_pjmedia_codec_param_info *)
+		     PyType_GenericNew(&PyTyp_pjmedia_codec_param_info, 
+				       NULL, NULL);
+	self->setting = (PyObj_pjmedia_codec_param_setting *)
+			PyType_GenericNew(&PyTyp_pjmedia_codec_param_setting,
+					  NULL, NULL);
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * pjmedia_codec_param_members
+ */
+static PyMemberDef pjmedia_codec_param_members[] =
+{   
+    
+    {
+        "info", T_OBJECT_EX,
+        offsetof(PyObj_pjmedia_codec_param, info), 0,
+        "The 'info' part of codec param describes the capability of the codec,"
+        " and the value should NOT be changed by application."        
+    },
+    {
+        "setting", T_OBJECT_EX,
+        offsetof(PyObj_pjmedia_codec_param, setting), 0, 
+        "The 'setting' part of codec param describes various settings to be "
+        "applied to the codec. When the codec param is retrieved from the "
+        "codec or codec factory, the values of these will be filled by "
+        "the capability of the codec. Any features that are supported by "
+        "the codec (e.g. vad or plc) will be turned on, so that application "
+        "can query which capabilities are supported by the codec. "
+        "Application may change the settings here before instantiating "
+        "the codec/stream."        
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+/*
+ * PyTyp_pjmedia_codec_param
+ */
+static PyTypeObject PyTyp_pjmedia_codec_param =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.PJMedia_Codec_Param",   /*tp_name*/
+    sizeof(PyObj_pjmedia_codec_param),/*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)pjmedia_codec_param_dealloc,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJMedia Codec Param",	    /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    pjmedia_codec_param_members,    /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    pjmedia_codec_param_new,        /* tp_new */
+
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PyObj_pjsua_call_info
+ * Call Info
+ */
+typedef struct
+{
+    PyObject_HEAD
+    /* Type-specific fields go here. */ 
+    
+    int		 id;
+    int		 role;
+    int		 acc_id;
+    PyObject	*local_info;
+    PyObject	*local_contact;
+    PyObject	*remote_info;
+    PyObject	*remote_contact;
+    PyObject	*call_id;
+    int		 state;
+    PyObject	*state_text;
+    int		 last_status;
+    PyObject	*last_status_text;
+    int		 media_status;
+    int		 media_dir;
+    int		 conf_slot;
+    int		 connect_duration;
+    int		 total_duration;
+
+} PyObj_pjsua_call_info;
+
+
+/*
+ * call_info_dealloc
+ * deletes a call_info from memory
+ */
+static void call_info_dealloc(PyObj_pjsua_call_info* self)
+{
+    Py_XDECREF(self->local_info);
+    Py_XDECREF(self->local_contact);
+    Py_XDECREF(self->remote_info);
+    Py_XDECREF(self->remote_contact);
+    Py_XDECREF(self->call_id);
+    Py_XDECREF(self->state_text);
+    Py_XDECREF(self->last_status_text);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+/*
+ * call_info_new
+ * constructor for call_info object
+ */
+static PyObject * call_info_new(PyTypeObject *type, PyObject *args,
+                                    PyObject *kwds)
+{
+    PyObj_pjsua_call_info *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsua_call_info *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->local_info = PyString_FromString("");
+	self->local_contact = PyString_FromString("");
+	self->remote_info = PyString_FromString("");
+	self->remote_contact = PyString_FromString("");
+	self->call_id = PyString_FromString("");
+	self->state_text = PyString_FromString("");
+	self->last_status_text = PyString_FromString("");
+    }
+    return (PyObject *)self;
+}
+
+/*
+ * call_info_members
+ */
+static PyMemberDef call_info_members[] =
+{   
+    {
+        "id", T_INT, 
+        offsetof(PyObj_pjsua_call_info, id), 0,
+        "Call identification"
+    },
+    {
+        "role", T_INT, 
+        offsetof(PyObj_pjsua_call_info, role), 0,
+        "Initial call role (UAC == caller)"
+    },
+    {
+        "acc_id", T_INT, 
+        offsetof(PyObj_pjsua_call_info, acc_id), 0,
+        "The account ID where this call belongs."
+    },
+    {
+        "local_info", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, local_info), 0,
+        "Local URI"        
+    },
+    {
+        "local_contact", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, local_contact), 0,
+        "Local Contact"        
+    },
+    {
+        "remote_info", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, remote_info), 0,
+        "Remote URI"        
+    },
+    {
+        "remote_contact", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, remote_contact), 0,
+        "Remote Contact"        
+    },
+    {
+        "call_id", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, call_id), 0,
+        "Dialog Call-ID string"        
+    },
+    {
+        "state", T_INT, 
+        offsetof(PyObj_pjsua_call_info, state), 0,
+        "Call state"
+    },
+    {
+        "state_text", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, state_text), 0,
+        "Text describing the state "        
+    },
+    {
+        "last_status", T_INT, 
+        offsetof(PyObj_pjsua_call_info, last_status), 0,
+        "Last status code heard, which can be used as cause code"
+    },
+    {
+        "last_status_text", T_OBJECT_EX,
+        offsetof(PyObj_pjsua_call_info, last_status_text), 0,
+        "The reason phrase describing the status."        
+    },
+    {
+        "media_status", T_INT, 
+        offsetof(PyObj_pjsua_call_info, media_status), 0,
+        "Call media status."
+    },
+    {
+        "media_dir", T_INT, 
+        offsetof(PyObj_pjsua_call_info, media_dir), 0,
+        "Media direction"
+    },
+    {
+        "conf_slot", T_INT, 
+        offsetof(PyObj_pjsua_call_info, conf_slot), 0,
+        "The conference port number for the call"
+    },
+    {
+        "connect_duration", T_INT,
+        offsetof(PyObj_pjsua_call_info, connect_duration), 0,
+        "Up-to-date call connected duration(zero when call is not established)"
+    },
+    {
+        "total_duration", T_INT,
+        offsetof(PyObj_pjsua_call_info, total_duration), 0,
+        "Total call duration, including set-up time"        
+    },
+    
+    {NULL}  /* Sentinel */
+};
+
+
+
+
+/*
+ * PyTyp_pjsua_call_info
+ */
+static PyTypeObject PyTyp_pjsua_call_info =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Call_Info",		    /*tp_name*/
+    sizeof(PyObj_pjsua_call_info),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)call_info_dealloc,  /*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "Call Info",		    /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    call_info_members,		    /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    call_info_new,		    /* tp_new */
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * PyObj_pjsip_rx_data
+ */
+typedef struct
+{
+    PyObject_HEAD
+
+    /* Type-specific fields go here. */
+    PyObject *msg_info_buffer;  // string
+    PyObject *msg_info_info;	// string
+
+} PyObj_pjsip_rx_data;
+
+/*
+ * PyObj_pjsip_rx_data_dealloc
+ * deletes rx_data from memory
+ */
+static void PyObj_pjsip_rx_data_delete(PyObj_pjsip_rx_data* self)
+{
+    Py_XDECREF(self->msg_info_buffer);
+    Py_XDECREF(self->msg_info_info);
+
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static void PyObj_pjsip_rx_data_import(PyObj_pjsip_rx_data *obj, pjsip_rx_data *rx_data)
+{
+    Py_XDECREF(obj->msg_info_buffer);
+    obj->msg_info_buffer = PyString_FromString(rx_data->msg_info.msg_buf);
+    Py_XDECREF(obj->msg_info_info);
+    obj->msg_info_info = PyString_FromString(pjsip_rx_data_get_info(rx_data));
+}
+
+
+/*
+ * PyObj_pjsip_rx_data_new
+ * constructor for PyObj_pjsip_rx_data object
+ */
+static PyObject * PyObj_pjsip_rx_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObj_pjsip_rx_data *self;
+
+    PJ_UNUSED_ARG(args);
+    PJ_UNUSED_ARG(kwds);
+
+    self = (PyObj_pjsip_rx_data *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->msg_info_buffer = PyString_FromString("");
+        self->msg_info_info   = PyString_FromString("");
+    }
+
+    return (PyObject *)self;
+}
+
+
+
+/*
+ * PyObj_pjsip_rx_data_members
+ */
+static PyMemberDef PyObj_pjsip_rx_data_members[] =
+{
+    {
+        "msg_info_buffer", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_rx_data, msg_info_buffer), 0,
+        "Entire SIP-Message"
+    },
+    {
+        "msg_info_info", T_OBJECT_EX,
+        offsetof(PyObj_pjsip_rx_data, msg_info_info), 0,
+        "Message Info"
+    },
+
+    {NULL}  /* Sentinel */
+};
+
+/*
+ * PyTyp_pjsip_rx_data
+ */
+static PyTypeObject PyTyp_pjsip_rx_data =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,                              /*ob_size*/
+    "_pjsua.Pjsip_Rx_Data",			/*tp_name*/
+    sizeof(PyObj_pjsip_rx_data),  /*tp_basicsize*/
+    0,                              /*tp_itemsize*/
+    (destructor)PyObj_pjsip_rx_data_delete,/*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+    0,                              /*tp_call*/
+    0,                              /*tp_str*/
+    0,                              /*tp_getattro*/
+    0,                              /*tp_setattro*/
+    0,                              /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,             /*tp_flags*/
+    "PJSIP request data information", /* tp_doc */
+    0,                              /* tp_traverse */
+    0,                              /* tp_clear */
+    0,                              /* tp_richcompare */
+    0,                              /* tp_weaklistoffset */
+    0,                              /* tp_iter */
+    0,                              /* tp_iternext */
+    0,                              /* tp_methods */
+    PyObj_pjsip_rx_data_members,  /* tp_members */
+    0,                              /* tp_getset */
+    0,                              /* tp_base */
+    0,                              /* tp_dict */
+    0,                              /* tp_descr_get */
+    0,                              /* tp_descr_set */
+    0,                              /* tp_dictoffset */
+    0,                              /* tp_init */
+    0,                              /* tp_alloc */
+    PyObj_pjsip_rx_data_new,      /* tp_new */
+
+};
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif	/* __PY_PJSUA_H__ */
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/helper.mak b/jni/libpjsip/sources/pjsip-apps/src/python/helper.mak
new file mode 100644
index 0000000..f9fdf34
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/helper.mak
@@ -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
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/pjsua.py b/jni/libpjsip/sources/pjsip-apps/src/python/pjsua.py
new file mode 100644
index 0000000..093c2be
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/pjsua.py
@@ -0,0 +1,2946 @@
+# $Id: pjsua.py 4611 2013-10-08 04:48:11Z bennylp $
+#
+# Object oriented PJSUA wrapper.
+#
+# Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+#
+# 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 
+#
+
+"""Multimedia communication client library based on SIP protocol.
+
+This implements a fully featured multimedia communication client 
+library based on PJSIP stack (http://www.pjsip.org)
+
+
+1. FEATURES
+
+  - Session Initiation Protocol (SIP) features:
+     - Basic registration and call
+     - Multiple accounts
+     - Call hold, attended and unattended call transfer
+     - Presence
+     - Instant messaging
+     - Multiple SIP accounts
+  - Media features:
+     - Audio
+     - Conferencing
+     - Narrowband and wideband
+     - Codecs: PCMA, PCMU, GSM, iLBC, Speex, G.722, L16
+     - RTP/RTCP
+     - Secure RTP (SRTP)
+     - WAV playback, recording, and playlist
+  - NAT traversal features
+     - Symmetric RTP
+     - STUN
+     - TURN
+     - ICE
+ 
+
+2. USING
+
+See http://www.pjsip.org/trac/wiki/Python_SIP_Tutorial for a more thorough
+tutorial. The paragraphs below explain basic tasks on using this module.
+
+
+"""
+import _pjsua
+import thread
+import threading
+import weakref
+import time
+
+class Error:
+    """Error exception class.
+    
+    Member documentation:
+
+    op_name  -- name of the operation that generated this error.
+    obj      -- the object that generated this error.
+    err_code -- the error code.
+
+    """
+    op_name = ""
+    obj = None
+    err_code = -1
+    _err_msg = ""
+
+    def __init__(self, op_name, obj, err_code, err_msg=""):
+        self.op_name = op_name
+        self.obj = obj
+        self.err_code = err_code
+        self._err_msg = err_msg
+
+    def err_msg(self):
+        "Retrieve the description of the error."
+        if self._err_msg != "":
+            return self._err_msg
+        self._err_msg = Lib.strerror(self.err_code)
+        return self._err_msg
+
+    def __str__(self):
+        return "Object: " + str(self.obj) + ", operation=" + self.op_name + \
+               ", error=" + self.err_msg()
+
+# 
+# Constants
+#
+
+class TransportType:
+    """SIP transport type constants.
+    
+    Member documentation:
+    UNSPECIFIED -- transport type is unknown or unspecified
+    UDP         -- UDP transport
+    TCP         -- TCP transport
+    TLS         -- TLS transport
+    IPV6        -- this is not a transport type but rather a flag
+                   to select the IPv6 version of a transport
+    UDP_IPV6    -- IPv6 UDP transport
+    TCP_IPV6    -- IPv6 TCP transport
+    """
+    UNSPECIFIED = 0
+    UDP = 1
+    TCP = 2
+    TLS = 3
+    IPV6 = 128
+    UDP_IPV6 = UDP + IPV6
+    TCP_IPV6 = TCP + IPV6
+
+class TransportFlag:
+    """Transport flags to indicate the characteristics of the transport.
+    
+    Member documentation:
+    
+    RELIABLE    -- transport is reliable.
+    SECURE      -- transport is secure.
+    DATAGRAM    -- transport is datagram based.
+    
+    """
+    RELIABLE = 1
+    SECURE = 2
+    DATAGRAM = 4
+
+class CallRole:
+    """Call role constants.
+    
+    Member documentation:
+
+    CALLER  -- role is caller
+    CALLEE  -- role is callee
+
+    """
+    CALLER = 0
+    CALLEE = 1
+
+class CallState:
+    """Call state constants.
+    
+    Member documentation:
+
+    NULL            -- call is not initialized.
+    CALLING         -- initial INVITE is sent.
+    INCOMING        -- initial INVITE is received.
+    EARLY           -- provisional response has been sent or received.
+    CONNECTING      -- 200/OK response has been sent or received.
+    CONFIRMED       -- ACK has been sent or received.
+    DISCONNECTED    -- call is disconnected.
+    """
+    NULL = 0
+    CALLING = 1
+    INCOMING = 2
+    EARLY = 3
+    CONNECTING = 4
+    CONFIRMED = 5
+    DISCONNECTED = 6
+
+
+class MediaState:
+    """Call media state constants.
+    
+    Member documentation:
+
+    NULL        -- media is not available.
+    ACTIVE      -- media is active.
+    LOCAL_HOLD  -- media is put on-hold by local party.
+    REMOTE_HOLD -- media is put on-hold by remote party.
+    ERROR       -- media error (e.g. ICE negotiation failure).
+    """
+    NULL = 0
+    ACTIVE = 1
+    LOCAL_HOLD = 2
+    REMOTE_HOLD = 3
+    ERROR = 4
+
+
+class MediaDir:
+    """Media direction constants.
+    
+    Member documentation:
+
+    NULL              -- media is not active
+    ENCODING          -- media is active in transmit/encoding direction only.
+    DECODING          -- media is active in receive/decoding direction only
+    ENCODING_DECODING -- media is active in both directions.
+    """
+    NULL = 0
+    ENCODING = 1
+    DECODING = 2
+    ENCODING_DECODING = 3
+
+
+class PresenceActivity:
+    """Presence activities constants.
+    
+    Member documentation:
+
+    UNKNOWN -- the person activity is unknown
+    AWAY    -- the person is currently away
+    BUSY    -- the person is currently engaging in other activity
+    """
+    UNKNOWN = 0
+    AWAY = 1
+    BUSY = 2
+
+
+class SubscriptionState:
+    """Presence subscription state constants.
+
+    """
+    NULL = 0
+    SENT = 1
+    ACCEPTED = 2
+    PENDING = 3
+    ACTIVE = 4
+    TERMINATED = 5
+    UNKNOWN = 6
+
+
+class TURNConnType:
+    """These constants specifies the connection type to TURN server.
+    
+    Member documentation:
+    UDP     -- use UDP transport.
+    TCP     -- use TCP transport.
+    TLS     -- use TLS transport.
+    """
+    UDP = 17
+    TCP = 6
+    TLS = 255
+
+
+class UAConfig:
+    """User agent configuration to be specified in Lib.init().
+    
+    Member documentation:
+
+    max_calls   -- maximum number of calls to be supported.
+    nameserver  -- list of nameserver hostnames or IP addresses. Nameserver
+                   must be configured if DNS SRV resolution is desired.
+    stun_domain -- if nameserver is configured, this can be used to query
+                   the STUN server with DNS SRV.
+    stun_host   -- the hostname or IP address of the STUN server. This will
+                   also be used if DNS SRV resolution for stun_domain fails.
+    user_agent  -- Optionally specify the user agent name.
+    """
+    max_calls = 4
+    nameserver = []
+    stun_domain = ""
+    stun_host = ""
+    user_agent = "pjsip python"
+    
+    def _cvt_from_pjsua(self, cfg):
+        self.max_calls = cfg.max_calls
+        self.thread_cnt = cfg.thread_cnt
+        self.nameserver = cfg.nameserver
+        self.stun_domain = cfg.stun_domain
+        self.stun_host = cfg.stun_host
+        self.user_agent = cfg.user_agent
+
+    def _cvt_to_pjsua(self):
+        cfg = _pjsua.config_default()
+        cfg.max_calls = self.max_calls
+        cfg.thread_cnt = 0
+        cfg.nameserver = self.nameserver
+        cfg.stun_domain = self.stun_domain
+        cfg.stun_host = self.stun_host
+        cfg.user_agent = self.user_agent
+        return cfg
+
+
+class LogConfig:
+    """Logging configuration to be specified in Lib.init().
+    
+    Member documentation:
+
+    msg_logging   -- specify if SIP messages should be logged. Set to
+                     True.
+    level         -- specify the input verbosity level.
+    console_level -- specify the output verbosity level.
+    decor         -- specify log decoration.
+    filename      -- specify the log filename.
+    callback      -- specify callback to be called to write the logging
+                     messages. Sample function:
+
+                     def log_cb(level, str, len):
+                        print str,
+
+    """
+    msg_logging = True
+    level = 5
+    console_level = 5
+    decor = 0
+    filename = ""
+    callback = None
+    
+    def __init__(self, level=-1, filename="", callback=None,
+                 console_level=-1):
+        self._cvt_from_pjsua(_pjsua.logging_config_default())
+        if level != -1:
+            self.level = level
+        if filename != "":
+            self.filename = filename
+        if callback != None:
+            self.callback = callback
+        if console_level != -1:
+            self.console_level = console_level
+
+    def _cvt_from_pjsua(self, cfg):
+        self.msg_logging = cfg.msg_logging
+        self.level = cfg.level
+        self.console_level = cfg.console_level
+        self.decor = cfg.decor
+        self.filename = cfg.log_filename
+        self.callback = cfg.cb
+
+    def _cvt_to_pjsua(self):
+        cfg = _pjsua.logging_config_default()
+        cfg.msg_logging = self.msg_logging
+        cfg.level = self.level
+        cfg.console_level = self.console_level
+        cfg.decor = self.decor
+        cfg.log_filename = self.filename
+        cfg.cb = self.callback
+        return cfg
+
+
+class MediaConfig:
+    """Media configuration to be specified in Lib.init().
+    
+    Member documentation:
+    
+    clock_rate          -- specify the core clock rate of the audio,
+                           most notably the conference bridge.
+    snd_clock_rate      -- optionally specify different clock rate for
+                           the sound device.
+    snd_auto_close_time -- specify the duration in seconds when the
+                           sound device should be closed after inactivity
+                           period.
+    channel_count       -- specify the number of channels to open the sound
+                           device and the conference bridge.
+    audio_frame_ptime   -- specify the length of audio frames in millisecond.
+    max_media_ports     -- specify maximum number of audio ports to be
+                           supported by the conference bridge.
+    quality             -- specify the audio quality setting (1-10)
+    ptime               -- specify the audio packet length of transmitted
+                           RTP packet.
+    no_vad              -- disable Voice Activity Detector (VAD) or Silence
+                           Detector (SD)
+    ilbc_mode           -- specify iLBC codec mode (must be 30 for now)
+    tx_drop_pct         -- randomly drop transmitted RTP packets (for
+                           simulation). Number is in percent.
+    rx_drop_pct         -- randomly drop received RTP packets (for
+                           simulation). Number is in percent.
+    ec_options          -- Echo Canceller option (specify zero).
+    ec_tail_len         -- specify Echo Canceller tail length in milliseconds.
+                           Value zero will disable the echo canceller.
+    jb_min              -- specify the minimum jitter buffer size in
+                           milliseconds. Put -1 for default.
+    jb_max              -- specify the maximum jitter buffer size in
+                           milliseconds. Put -1 for default.
+    enable_ice          -- enable Interactive Connectivity Establishment (ICE)
+    enable_turn         -- enable TURN relay. TURN server settings must also
+                           be configured.
+    turn_server         -- specify the domain or hostname or IP address of
+                           the TURN server, in "host[:port]" format.
+    turn_conn_type      -- specify connection type to the TURN server, from
+                           the TURNConnType constant.
+    turn_cred           -- specify AuthCred for the TURN credential.
+    """
+    clock_rate = 16000
+    snd_clock_rate = 0
+    snd_auto_close_time = 5
+    channel_count = 1
+    audio_frame_ptime = 20
+    max_media_ports = 32
+    quality = 6
+    ptime = 0
+    no_vad = False
+    ilbc_mode = 30
+    tx_drop_pct = 0
+    rx_drop_pct = 0
+    ec_options = 0
+    ec_tail_len = 256
+    jb_min = -1
+    jb_max = -1
+    enable_ice = True
+    enable_turn = False
+    turn_server = ""
+    turn_conn_type = TURNConnType.UDP
+    turn_cred = None
+     
+    def __init__(self):
+        default = _pjsua.media_config_default()
+        self._cvt_from_pjsua(default)
+
+    def _cvt_from_pjsua(self, cfg):
+        self.clock_rate = cfg.clock_rate
+        self.snd_clock_rate = cfg.snd_clock_rate
+        self.snd_auto_close_time = cfg.snd_auto_close_time
+        self.channel_count = cfg.channel_count
+        self.audio_frame_ptime = cfg.audio_frame_ptime
+        self.max_media_ports = cfg.max_media_ports
+        self.quality = cfg.quality
+        self.ptime = cfg.ptime
+        self.no_vad = cfg.no_vad
+        self.ilbc_mode = cfg.ilbc_mode
+        self.tx_drop_pct = cfg.tx_drop_pct
+        self.rx_drop_pct = cfg.rx_drop_pct
+        self.ec_options = cfg.ec_options
+        self.ec_tail_len = cfg.ec_tail_len
+        self.jb_min = cfg.jb_min
+        self.jb_max = cfg.jb_max
+        self.enable_ice = cfg.enable_ice
+        self.enable_turn = cfg.enable_turn
+        self.turn_server = cfg.turn_server
+        self.turn_conn_type = cfg.turn_conn_type
+        if cfg.turn_username:
+            self.turn_cred = AuthCred(cfg.turn_realm, cfg.turn_username,
+                                      cfg.turn_passwd, cfg.turn_passwd_type)
+        else:
+            self.turn_cred = None
+
+    def _cvt_to_pjsua(self):
+        cfg = _pjsua.media_config_default()
+        cfg.clock_rate = self.clock_rate
+        cfg.snd_clock_rate = self.snd_clock_rate
+        cfg.snd_auto_close_time = self.snd_auto_close_time
+        cfg.channel_count = self.channel_count
+        cfg.audio_frame_ptime = self.audio_frame_ptime
+        cfg.max_media_ports = self.max_media_ports
+        cfg.quality = self.quality
+        cfg.ptime = self.ptime
+        cfg.no_vad = self.no_vad
+        cfg.ilbc_mode = self.ilbc_mode
+        cfg.tx_drop_pct = self.tx_drop_pct
+        cfg.rx_drop_pct = self.rx_drop_pct
+        cfg.ec_options = self.ec_options
+        cfg.ec_tail_len = self.ec_tail_len
+        cfg.jb_min = self.jb_min
+        cfg.jb_max = self.jb_max
+        cfg.enable_ice = self.enable_ice
+        cfg.enable_turn = self.enable_turn
+        cfg.turn_server = self.turn_server
+        cfg.turn_conn_type = self.turn_conn_type
+        if self.turn_cred:
+            cfg.turn_realm = self.turn_cred.realm
+            cfg.turn_username = self.turn_cred.username
+            cfg.turn_passwd_type = self.turn_cred.passwd_type
+            cfg.turn_passwd = self.turn_cred.passwd
+        return cfg
+
+
+class TransportConfig:
+    """SIP transport configuration class.
+    
+    Member configuration:
+
+    port        -- port number.
+    bound_addr  -- optionally specify the address to bind the socket to.
+                   Default is empty to bind to INADDR_ANY.
+    public_addr -- optionally override the published address for this
+                   transport. If empty, the default behavior is to get
+                   the public address from STUN or from the selected
+                   local interface. Format is "host:port".
+    qos_type    -- High level traffic classification.
+                   Enumerator:
+                     0: PJ_QOS_TYPE_BEST_EFFORT
+                          Best effort traffic (default value). Any QoS function calls with 
+                          specifying this value are effectively no-op
+                     1: PJ_QOS_TYPE_BACKGROUND
+                          Background traffic.
+                     2: PJ_QOS_TYPE_VIDEO
+                          Video traffic.
+                     3: PJ_QOS_TYPE_VOICE
+                          Voice traffic.
+                     4: PJ_QOS_TYPE_CONTROL
+                          Control traffic.
+    qos_params_flags    -- Determines which values to set, bitmask of pj_qos_flag.
+                             PJ_QOS_PARAM_HAS_DSCP = 1
+                             PJ_QOS_PARAM_HAS_SO_PRIO = 2
+                             PJ_QOS_PARAM_HAS_WMM = 4
+    qos_params_dscp_val -- The 6 bits DSCP value to set.
+    qos_params_so_prio  -- Socket SO_PRIORITY value.
+    qos_params_wmm_prio -- Standard WMM priorities.
+                            Enumerator:
+                              0: PJ_QOS_WMM_PRIO_BULK_EFFORT: Bulk effort priority
+                              1: PJ_QOS_WMM_PRIO_BULK: Bulk priority.
+                              2: PJ_QOS_WMM_PRIO_VIDEO: Video priority
+                              3: PJ_QOS_WMM_PRIO_VOICE: Voice priority.
+    """
+    port = 0
+    bound_addr = ""
+    public_addr = ""
+    
+    qos_type = 0
+    qos_params_flags = 0
+    qos_params_dscp_val = 0
+    qos_params_so_prio = 0
+    qos_params_wmm_prio = 0
+    
+    
+
+    def __init__(self, port=0, 
+                 bound_addr="", public_addr=""):
+        self.port = port
+        self.bound_addr = bound_addr
+        self.public_addr = public_addr
+
+    def _cvt_from_pjsua(self, cfg):
+        self.port = cfg.port
+        self.bound_addr = cfg.bound_addr
+        self.public_addr = cfg.public_addr
+        self.qos_type = cfg.qos_type
+        self.qos_params_flags = cfg.qos_params_flags
+        self.qos_params_dscp_val = cfg.qos_params_dscp_val
+        self.qos_params_so_prio = cfg.qos_params_so_prio
+        self.qos_params_wmm_prio = cfg.qos_params_wmm_prio
+
+    def _cvt_to_pjsua(self):
+        cfg = _pjsua.transport_config_default()
+        cfg.port = self.port
+        cfg.bound_addr = self.bound_addr
+        cfg.public_addr = self.public_addr
+        cfg.qos_type = self.qos_type
+        cfg.qos_params_flags = self.qos_params_flags
+        cfg.qos_params_dscp_val = self.qos_params_dscp_val
+        cfg.qos_params_so_prio = self.qos_params_so_prio
+        cfg.qos_params_wmm_prio = self.qos_params_wmm_prio
+
+        return cfg
+
+
+class TransportInfo:
+    """SIP transport info.
+    
+    Member documentation:
+
+    type        -- transport type, from TransportType constants.
+    description -- longer description for this transport.
+    is_reliable -- True if transport is reliable.
+    is_secure   -- True if transport is secure.
+    is_datagram -- True if transport is datagram based.
+    host        -- the IP address of this transport.
+    port        -- the port number.
+    ref_cnt     -- number of objects referencing this transport.
+    """
+    type = ""
+    description = ""
+    is_reliable = False
+    is_secure = False
+    is_datagram = False
+    host = ""
+    port = 0
+    ref_cnt = 0
+    
+    def __init__(self, ti):
+        self.type = ti.type_name
+        self.description = ti.info
+        self.is_reliable = (ti.flag & TransportFlag.RELIABLE)
+        self.is_secure = (ti.flag & TransportFlag.SECURE)
+        self.is_datagram = (ti.flag & TransportFlag.DATAGRAM)
+        self.host = ti.addr
+        self.port = ti.port
+        self.ref_cnt = ti.usage_count
+    
+    
+class Transport:
+    "SIP transport class."
+    _id = -1
+    _lib = None
+    _obj_name = ""
+
+    def __init__(self, lib, id):
+        self._lib = weakref.proxy(lib)
+        self._id = id
+        self._obj_name = "{Transport " + self.info().description + "}"
+        _Trace((self, 'created'))
+
+    def __del__(self):
+        _Trace((self, 'destroyed'))
+        
+    def __str__(self):
+        return self._obj_name
+
+    def info(self):
+        """Get TransportInfo.
+        """
+        lck = self._lib.auto_lock()
+        ti = _pjsua.transport_get_info(self._id)
+        if not ti:
+            self._lib._err_check("info()", self, -1, "Invalid transport")
+        return TransportInfo(ti)
+
+    def enable(self):
+        """Enable this transport."""
+        lck = self._lib.auto_lock()
+        err = _pjsua.transport_set_enable(self._id, True)
+        self._lib._err_check("enable()", self, err)
+
+    def disable(self):
+        """Disable this transport."""
+        lck = self._lib.auto_lock()
+        err = _pjsua.transport_set_enable(self._id, 0)
+        self._lib._err_check("disable()", self, err)
+
+    def close(self, force=False):
+        """Close and destroy this transport.
+
+        Keyword argument:
+        force   -- force deletion of this transport (not recommended).
+        """
+        lck = self._lib.auto_lock()
+        err = _pjsua.transport_close(self._id, force)
+        self._lib._err_check("close()", self, err)
+
+
+class SIPUri:
+    """Helper class to parse the most important components of SIP URI.
+
+    Member documentation:
+
+    scheme    -- URI scheme ("sip" or "sips")
+    user      -- user part of the URI (may be empty)
+    host      -- host name part
+    port      -- optional port number (zero if port is not specified).
+    transport -- transport parameter, or empty if transport is not
+                 specified.
+
+    """
+    scheme = ""
+    user = ""
+    host = ""
+    port = 0
+    transport = ""
+
+    def __init__(self, uri=None):
+        if uri:
+            self.decode(uri)
+
+    def decode(self, uri):
+        """Parse SIP URL.
+
+        Keyword argument:
+        uri -- the URI string.
+
+        """
+        self.scheme, self.user, self.host, self.port, self.transport = \
+            _pjsua.parse_simple_uri(uri)
+
+    def encode(self):
+        """Encode this object into SIP URI string.
+
+        Return:
+            URI string.
+
+        """
+        output = self.scheme + ":"
+        if self.user and len(self.user):
+            output = output + self.user + "@"
+        output = output + self.host
+        if self.port:
+            output = output + ":" + output(self.port)
+        if self.transport:
+            output = output + ";transport=" + self.transport
+        return output
+
+
+class AuthCred:
+    """Authentication credential for SIP or TURN account.
+    
+    Member documentation:
+
+    scheme      -- authentication scheme (default is "Digest")
+    realm       -- realm
+    username    -- username
+    passwd_type -- password encoding (zero for plain-text)
+    passwd      -- the password
+    """
+    scheme = "Digest"
+    realm = "*"
+    username = ""
+    passwd_type = 0
+    passwd = ""
+
+    def __init__(self, realm, username, passwd, scheme="Digest", passwd_type=0):
+        self.scheme = scheme
+        self.realm = realm
+        self.username = username
+        self.passwd_type = passwd_type
+        self.passwd = passwd
+
+
+class AccountConfig:
+    """ This describes account configuration to create an account.
+
+    Member documentation:
+
+    priority                -- account priority for matching incoming
+                               messages.
+    id                      -- SIP URI of this account. This setting is
+                               mandatory.
+    force_contact           -- force to use this URI as Contact URI. Setting
+                               this value is generally not recommended.
+    reg_uri                 -- specify the registrar URI. Mandatory if
+                               registration is required.
+    reg_timeout             -- specify the SIP registration refresh interval
+                               in seconds.
+    require_100rel          -- specify if reliable provisional response is
+                               to be enforced (with Require header).
+    publish_enabled         -- specify if PUBLISH should be used. When
+                               enabled, the PUBLISH will be sent to the
+                               registrar.
+    pidf_tuple_id           -- optionally specify the tuple ID in outgoing
+                               PIDF document.
+    proxy                   -- list of proxy URI.
+    auth_cred               -- list of AuthCred containing credentials to
+                               authenticate against the registrars and
+                               the proxies.
+    auth_initial_send       -- specify if empty Authorization header should be
+                               sent. May be needed for IMS.
+    auth_initial_algorithm  -- when auth_initial_send is enabled, optionally
+                               specify the authentication algorithm to use.
+                               Valid values are "md5", "akav1-md5", or
+                               "akav2-md5". 
+    transport_id            -- optionally specify the transport ID to be used
+                               by this account. Shouldn't be needed unless
+                               for specific requirements (e.g. in multi-homed
+                               scenario).
+    allow_contact_rewrite   -- specify whether the account should learn its
+                               Contact address from REGISTER response and 
+                               update the registration accordingly. Default is
+                               True.
+    ka_interval             -- specify the interval to send NAT keep-alive 
+                               packet.
+    ka_data                 -- specify the NAT keep-alive packet contents.
+    use_srtp                -- specify the SRTP usage policy. Valid values
+                               are: 0=disable, 1=optional, 2=mandatory.
+                               Default is 0.
+    srtp_secure_signaling   -- specify the signaling security level required
+                               by SRTP. Valid values are: 0=no secure 
+                               transport is required, 1=hop-by-hop secure
+                               transport such as TLS is required, 2=end-to-
+                               end secure transport is required (i.e. "sips").
+    rtp_transport_cfg       -- the rtp-transport-configuration that is usede, when
+                               a rtp-connection is being established.
+    """
+    priority = 0
+    id = ""
+    force_contact = ""
+    reg_uri = ""
+    reg_timeout = 0
+    require_100rel = False
+    publish_enabled = False
+    pidf_tuple_id = ""
+    proxy = []
+    auth_cred = []
+    auth_initial_send = False
+    auth_initial_algorithm = ""
+    transport_id = -1
+    allow_contact_rewrite = True
+    ka_interval = 15
+    ka_data = "\r\n"
+    use_srtp = 0
+    srtp_secure_signaling = 1
+    rtp_transport_cfg = None
+
+    def __init__(self, domain="", username="", password="", 
+                 display="", registrar="", proxy=""):
+        """
+        Construct account config. If domain argument is specified, 
+        a typical configuration will be built.
+
+        Keyword arguments:
+        domain    -- domain name of the server.
+        username  -- user name.
+        password  -- plain-text password.
+        display   -- optional display name for the user name.
+        registrar -- the registrar URI. If domain name is specified
+                     and this argument is empty, the registrar URI
+                     will be constructed from the domain name.
+        proxy     -- the proxy URI. If domain name is specified
+                     and this argument is empty, the proxy URI
+                     will be constructed from the domain name.
+
+        """
+        default = _pjsua.acc_config_default()
+        self._cvt_from_pjsua(default)
+        if domain!="":
+            self.build_config(domain, username, password,
+                              display, registrar, proxy)
+        self.rtp_transport_cfg = TransportConfig()
+
+    def build_config(self, domain, username, password, display="",
+                     registrar="", proxy="", rtp_transport_cfg = None):
+        """
+        Construct account config. If domain argument is specified, 
+        a typical configuration will be built.
+
+        Keyword arguments:
+        domain    -- domain name of the server.
+        username  -- user name.
+        password  -- plain-text password.
+        display   -- optional display name for the user name.
+        registrar -- the registrar URI. If domain name is specified
+                     and this argument is empty, the registrar URI
+                     will be constructed from the domain name.
+        proxy     -- the proxy URI. If domain name is specified
+                     and this argument is empty, the proxy URI
+                     will be constructed from the domain name.
+
+        """
+        if display != "":
+            display = display + " "
+        userpart = username
+        if userpart != "":
+            userpart = userpart + "@"
+        self.id = display + "<sip:" + userpart + domain + ">"
+        self.reg_uri = registrar
+        if self.reg_uri == "":
+            self.reg_uri = "sip:" + domain
+        if proxy == "":
+            proxy = "sip:" + domain + ";lr"
+        if proxy.find(";lr") == -1:
+            proxy = proxy + ";lr"
+        self.proxy.append(proxy)
+        if username != "":
+            self.auth_cred.append(AuthCred("*", username, password))
+        
+        if (rtp_transport_cfg is not None):
+            self.rtp_transport_cfg = rtp_transport_cfg
+        else:
+            self.rtp_transport_cfg = TransportConfig()
+    
+    def _cvt_from_pjsua(self, cfg):
+        self.priority = cfg.priority
+        self.id = cfg.id
+        self.force_contact = cfg.force_contact
+        self.reg_uri = cfg.reg_uri
+        self.reg_timeout = cfg.reg_timeout
+        self.require_100rel = cfg.require_100rel
+        self.publish_enabled = cfg.publish_enabled
+        self.pidf_tuple_id = cfg.pidf_tuple_id
+        self.proxy = cfg.proxy
+        for cred in cfg.cred_info:
+            self.auth_cred.append(AuthCred(cred.realm, cred.username, 
+                                           cred.data, cred.scheme,
+                                           cred.data_type))
+        self.auth_initial_send = cfg.auth_initial_send
+        self.auth_initial_algorithm = cfg.auth_initial_algorithm
+        self.transport_id = cfg.transport_id
+        self.allow_contact_rewrite = cfg.allow_contact_rewrite
+        self.ka_interval = cfg.ka_interval
+        self.ka_data = cfg.ka_data
+        self.use_srtp = cfg.use_srtp
+        self.srtp_secure_signaling = cfg.srtp_secure_signaling
+        if (self.rtp_transport_cfg is not None):
+            self.rtp_transport_cfg._cvt_from_pjsua(cfg.rtp_transport_cfg)
+
+    def _cvt_to_pjsua(self):
+        cfg = _pjsua.acc_config_default()
+        cfg.priority = self.priority
+        cfg.id = self.id
+        cfg.force_contact = self.force_contact
+        cfg.reg_uri = self.reg_uri
+        cfg.reg_timeout = self.reg_timeout
+        cfg.require_100rel = self.require_100rel
+        cfg.publish_enabled = self.publish_enabled
+        cfg.pidf_tuple_id = self.pidf_tuple_id
+        cfg.proxy = self.proxy
+        for cred in self.auth_cred:
+            c = _pjsua.Pjsip_Cred_Info()
+            c.realm = cred.realm
+            c.scheme = cred.scheme
+            c.username = cred.username
+            c.data_type = cred.passwd_type
+            c.data = cred.passwd
+            cfg.cred_info.append(c)
+            
+        cfg.auth_initial_send = self.auth_initial_send
+        cfg.auth_initial_algorithm = self.auth_initial_algorithm
+        cfg.transport_id = self.transport_id
+        cfg.allow_contact_rewrite = self.allow_contact_rewrite
+        cfg.ka_interval = self.ka_interval
+        cfg.ka_data = self.ka_data
+        cfg.use_srtp = self.use_srtp
+        cfg.srtp_secure_signaling = self.srtp_secure_signaling
+
+        if (self.rtp_transport_cfg is not None):
+            cfg.rtp_transport_cfg = self.rtp_transport_cfg._cvt_to_pjsua()
+        
+        return cfg
+ 
+ 
+# Account information
+class AccountInfo:
+    """This describes Account info. Application retrives account info
+    with Account.info().
+
+    Member documentation:
+
+    is_default      -- True if this is the default account.
+    uri             -- the account URI.
+    reg_active      -- True if registration is active for this account.
+    reg_expires     -- contains the current registration expiration value,
+                       in seconds.
+    reg_status      -- the registration status. If the value is less than
+                       700, it specifies SIP status code. Value greater than
+                       this specifies the error code.
+    reg_reason      -- contains the registration status text (e.g. the
+                       error message).
+    online_status   -- the account's presence online status, True if it's 
+                       publishing itself as online.
+    online_text     -- the account's presence status text.
+
+    """
+    is_default = False
+    uri = ""
+    reg_active = False
+    reg_expires = -1
+    reg_status = 0
+    reg_reason = ""
+    online_status = False
+    online_text = ""
+
+    def __init__(self, ai):
+        self.is_default = ai.is_default
+        self.uri = ai.acc_uri
+        self.reg_active = ai.has_registration
+        self.reg_expires = ai.expires
+        self.reg_status = ai.status
+        self.reg_reason = ai.status_text
+        self.online_status = ai.online_status
+        self.online_text = ai.online_status_text
+
+# Account callback
+class AccountCallback:
+    """Class to receive notifications on account's events.
+
+    Derive a class from this class and register it to the Account object
+    using Account.set_callback() to start receiving events from the Account
+    object.
+
+    Member documentation:
+
+    account     -- the Account object.
+
+    """
+    account = None
+
+    def __init__(self, account=None):
+        self._set_account(account)
+
+    def __del__(self):
+        pass
+
+    def _set_account(self, account):
+        if account:
+            self.account = weakref.proxy(account)
+        else:
+            self.account = None
+
+    def on_reg_state(self):
+        """Notification that the registration status has changed.
+        """
+        pass
+
+    def on_incoming_call(self, call):
+        """Notification about incoming call.
+
+        Application should implement one of on_incoming_call() or
+	on_incoming_call2(), otherwise, the default behavior is to
+        reject the call with default status code. Note that if both are
+	implemented, only on_incoming_call2() will be called.
+
+        Keyword arguments:
+        call    -- the new incoming call
+        """
+        call.hangup()
+
+    def on_incoming_call2(self, call, rdata):
+        """Notification about incoming call, with received SIP message info.
+
+        Application should implement one of on_incoming_call() or
+	on_incoming_call2(), otherwise, the default behavior is to
+        reject the call with default status code. Note that if both are
+	implemented, only on_incoming_call2() will be called.
+
+        Keyword arguments:
+        call    -- the new incoming call
+        rdata   -- the received message
+        """
+        call.hangup()
+	
+    def on_incoming_subscribe(self, buddy, from_uri, contact_uri, pres_obj):
+        """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)
+
+        Keyword arguments:
+        buddy       -- The buddy object, if buddy is found. Otherwise
+                       the value is None.
+        from_uri    -- The URI string of the sender.
+        pres_obj    -- Opaque presence subscription object, which is
+                       needed by Account.pres_notify()
+
+        Return:
+            Tuple (code, reason), where:
+             code:      The status code. If code is >= 300, the
+                        request is rejected. If code is 200, the
+                        request is accepted and NOTIFY will be sent
+                        automatically. If code is 202, application
+                        must accept or reject the request later with
+                        Account.press_notify().
+             reason:    Optional reason phrase, or None to use the
+                        default reasoh phrase for the status code.
+        """
+        return (200, None)
+
+    def on_pager(self, from_uri, contact, mime_type, body):
+        """
+        Notification that incoming instant message is received on
+        this account.
+
+        Keyword arguments:
+        from_uri   -- sender's URI
+        contact    -- sender's Contact URI
+        mime_type  -- MIME type of the instant message body
+        body       -- the instant message body
+
+        """
+        pass
+
+    def on_pager_status(self, to_uri, body, im_id, code, reason):
+        """
+        Notification about the delivery status of previously sent
+        instant message.
+
+        Keyword arguments:
+        to_uri  -- the destination URI of the message
+        body    -- the message body
+        im_id   -- message ID
+        code    -- SIP status code
+        reason  -- SIP reason phrase
+
+        """
+        pass
+
+    def on_typing(self, from_uri, contact, is_typing):
+        """
+        Notification that remote is typing or stop typing.
+
+        Keyword arguments:
+        buddy     -- Buddy object for the sender, if found. Otherwise
+                     this will be None
+        from_uri  -- sender's URI of the indication
+        contact   -- sender's contact URI
+        is_typing -- boolean to indicate whether remote is currently
+                     typing an instant message.
+
+        """
+        pass
+
+    def on_mwi_info(self, body):
+        """
+        Notification about change in Message Summary / Message Waiting
+	Indication (RFC 3842) status. MWI subscription must be enabled
+	in the account config to receive this notification.
+
+        Keyword arguments:
+        body      -- String containing message body as received in the
+                     NOTIFY request.
+
+        """
+        pass
+
+
+
+class Account:
+    """This describes SIP account class.
+
+    PJSUA accounts provide identity (or identities) of the user who is 
+    currently using the application. In SIP terms, the identity is used 
+    as the From header in outgoing requests.
+
+    Account may or may not have client registration associated with it. 
+    An account is also associated with route set and some authentication 
+    credentials, which are used when sending SIP request messages using 
+    the account. An account also has presence's online status, which 
+    will be reported to remote peer when they subscribe to the account's 
+    presence, or which is published to a presence server if presence 
+    publication is enabled for the account.
+
+    Account is created with Lib.create_account(). At least one account 
+    MUST be created. If no user association is required, application can 
+    create a userless account by calling Lib.create_account_for_transport().
+    A userless account identifies local endpoint instead of a particular 
+    user, and it correspond with a particular transport instance.
+
+    Also one account must be set as the default account, which is used as 
+    the account to use when PJSUA fails to match a request with any other
+    accounts.
+
+    """
+    _id = -1        
+    _lib = None
+    _cb = AccountCallback(None)
+    _obj_name = ""
+
+    def __init__(self, lib, id, cb=None):
+        """Construct this class. This is normally called by Lib class and
+        not by application.
+
+        Keyword arguments:
+        lib -- the Lib instance.
+        id  -- the pjsua account ID.
+        cb  -- AccountCallback instance to receive events from this Account.
+               If callback is not specified here, it must be set later
+               using set_callback().
+        """
+        self._id = id
+        self._lib = weakref.ref(lib)
+        self._obj_name = "{Account " + self.info().uri + "}"
+        self.set_callback(cb)
+        _pjsua.acc_set_user_data(self._id, self)
+        _Trace((self, 'created'))
+
+    def __del__(self):
+        if self._id != -1:
+            _pjsua.acc_set_user_data(self._id, 0)
+        _Trace((self, 'destroyed'))
+
+    def __str__(self):
+        return self._obj_name
+
+    def info(self):
+        """Retrieve AccountInfo for this account.
+        """
+        lck = self._lib().auto_lock()
+        ai = _pjsua.acc_get_info(self._id)
+        if ai==None:
+            self._lib()._err_check("info()", self, -1, "Invalid account")
+        return AccountInfo(ai)
+
+    def is_valid(self):
+        """
+        Check if this account is still valid.
+
+        """
+        lck = self._lib().auto_lock()
+        return _pjsua.acc_is_valid(self._id)
+
+    def set_callback(self, cb):
+        """Register callback to receive notifications from this object.
+
+        Keyword argument:
+        cb  -- AccountCallback instance.
+
+        """
+        if cb:
+            self._cb = cb
+        else:
+            self._cb = AccountCallback(self)
+        self._cb._set_account(self)
+
+    def set_default(self):
+        """ Set this account as default account to send outgoing requests
+        and as the account to receive incoming requests when more exact
+        matching criteria fails.
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.acc_set_default(self._id)
+        self._lib()._err_check("set_default()", self, err)
+
+    def is_default(self):
+        """ Check if this account is the default account.
+
+        """
+        lck = self._lib().auto_lock()
+        def_id = _pjsua.acc_get_default()
+        return self.is_valid() and def_id==self._id
+
+    def delete(self):
+        """ Delete this account.
+        
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.acc_set_user_data(self._id, 0)
+        self._lib()._err_check("delete()", self, err)
+        err = _pjsua.acc_del(self._id)
+        self._lib()._err_check("delete()", self, err)
+        self._id = -1
+
+    def set_basic_status(self, is_online):
+        """ Set basic presence status of this account.
+
+        Keyword argument:
+        is_online   -- boolean to indicate basic presence availability.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.acc_set_online_status(self._id, is_online)
+        self._lib()._err_check("set_basic_status()", self, err)
+
+    def set_presence_status(self, is_online, 
+                            activity=PresenceActivity.UNKNOWN, 
+                            pres_text="", rpid_id=""):
+        """ Set presence status of this account. 
+        
+        Keyword arguments:
+        is_online   -- boolean to indicate basic presence availability
+        activity    -- value from PresenceActivity
+        pres_text   -- optional string to convey additional information about
+                       the activity (such as "On the phone")
+        rpid_id     -- optional string to be placed as RPID ID. 
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.acc_set_online_status2(self._id, is_online, activity,
+                                            pres_text, rpid_id)
+        self._lib()._err_check("set_presence_status()", self, err)
+
+    def set_registration(self, renew):
+        """Manually renew registration or unregister from the server.
+
+        Keyword argument:
+        renew   -- boolean to indicate whether registration is renewed.
+                   Setting this value for False will trigger unregistration.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.acc_set_registration(self._id, renew)
+        self._lib()._err_check("set_registration()", self, err)
+
+    def set_transport(self, transport):
+        """Set this account to only use the specified transport to send
+        outgoing requests.
+
+        Keyword argument:
+        transport   -- Transport object.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.acc_set_transport(self._id, transport._id)
+        self._lib()._err_check("set_transport()", self, err)
+
+    def make_call(self, dst_uri, cb=None, hdr_list=None):
+        """Make outgoing call to the specified URI.
+
+        Keyword arguments:
+        dst_uri  -- Destination SIP URI.
+        cb       -- CallCallback instance to be installed to the newly
+                    created Call object. If this CallCallback is not
+                    specified (i.e. None is given), it must be installed
+                    later using call.set_callback().
+        hdr_list -- Optional list of headers to be sent with outgoing
+                    INVITE
+
+        Return:
+            Call instance.
+        """
+        lck = self._lib().auto_lock()
+        call = Call(self._lib(), -1, cb)
+        err, cid = _pjsua.call_make_call(self._id, dst_uri, 0, 
+                                         call, Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("make_call()", self, err)
+        call.attach_to_id(cid)
+        return call
+
+    def add_buddy(self, uri, cb=None):
+        """Add new buddy.
+
+        Keyword argument:
+        uri     -- SIP URI of the buddy
+        cb      -- BuddyCallback instance to be installed to the newly
+                   created Buddy object. If this callback is not specified
+                   (i.e. None is given), it must be installed later using
+                   buddy.set_callback().
+
+        Return:
+            Buddy object
+        """
+        lck = self._lib().auto_lock()
+        buddy_cfg = _pjsua.buddy_config_default()
+        buddy_cfg.uri = uri
+        buddy_cfg.subscribe = False
+        err, buddy_id = _pjsua.buddy_add(buddy_cfg)
+        self._lib()._err_check("add_buddy()", self, err)
+        buddy = Buddy(self._lib(), buddy_id, self, cb)
+        return buddy
+
+    def pres_notify(self, pres_obj, state, reason="", hdr_list=None):
+        """Send NOTIFY to inform account presence status or to terminate
+        server side presence subscription.
+        
+        Keyword arguments:
+        pres_obj    -- The subscription object from on_incoming_subscribe()
+                       callback
+        state       -- Subscription state, from SubscriptionState
+        reason      -- Optional reason phrase.
+        hdr_list    -- Optional header list.
+        """
+        lck = self._lib().auto_lock()
+        _pjsua.acc_pres_notify(self._id, pres_obj, state, reason, 
+                               Lib._create_msg_data(hdr_list))
+    
+    def send_pager(self, uri, text, im_id=0, content_type="text/plain", \
+                   hdr_list=None):
+        """Send instant message to arbitrary URI.
+
+        Keyword arguments:
+        text         -- Instant message to be sent
+        uri          -- URI to send the Instant Message to.
+        im_id        -- Optional instant message ID to identify this
+                        instant message when delivery status callback
+                        is called.
+        content_type -- MIME type identifying the instant message
+        hdr_list     -- Optional list of headers to be sent with the
+                        request.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.im_send(self._id, uri, \
+                             content_type, text, \
+                             Lib._create_msg_data(hdr_list), \
+                             im_id)
+        self._lib()._err_check("send_pager()", self, err)
+
+class CallCallback:
+    """Class to receive event notification from Call objects. 
+
+    Use Call.set_callback() method to install instance of this callback 
+    class to receive event notifications from the call object.
+
+    Member documentation:
+
+    call    -- the Call object.
+
+    """
+    call = None
+
+    def __init__(self, call=None):
+        self._set_call(call)
+
+    def __del__(self):
+        pass
+
+    def _set_call(self, call):
+        if call:
+            self.call = weakref.proxy(call)
+        else:
+            self.call = None
+
+    def on_state(self):
+        """Notification that the call's state has changed.
+
+        """
+        pass
+
+    def on_media_state(self):
+        """Notification that the call's media state has changed.
+
+        """
+        pass
+
+    def on_dtmf_digit(self, digits):
+        """Notification on incoming DTMF digits.
+
+        Keyword argument:
+        digits  -- string containing the received digits.
+
+        """
+        pass
+
+    def on_transfer_request(self, dst, code):
+        """Notification that call is being transfered by remote party. 
+
+        Application can decide to accept/reject transfer request by returning
+        code greater than or equal to 500. The default behavior is to accept 
+        the transfer by returning 202.
+
+        Keyword arguments:
+        dst     -- string containing the destination URI
+        code    -- the suggested status code to return to accept the request.
+
+        Return:
+        the callback should return 202 to accept the request, or 300-699 to
+        reject the request.
+
+        """
+        return code
+
+    def on_transfer_status(self, code, reason, final, cont):
+        """
+        Notification about the status of previous call transfer request. 
+
+        Keyword arguments:
+        code    -- SIP status code to indicate completion status.
+        text    -- SIP status reason phrase.
+        final   -- if True then this is a final status and no further
+                   notifications will be sent for this call transfer
+                   status.
+        cont    -- suggested return value.
+
+        Return:
+        If the callback returns false then no further notification will
+        be sent for the transfer request for this call.
+
+        """
+        return cont
+
+    def on_replace_request(self, code, reason):
+        """Notification when incoming INVITE with Replaces header is received. 
+
+        Application may reject the request by returning value greather than
+        or equal to 500. The default behavior is to accept the request.
+
+        Keyword arguments:
+        code    -- default status code to return
+        reason  -- default reason phrase to return
+
+        Return:
+        The callback should return (code, reason) tuple.
+
+        """
+        return code, reason
+
+    def on_replaced(self, new_call):
+        """
+        Notification that this call will be replaced with new_call. 
+        After this callback is called, this call will be disconnected.
+
+        Keyword arguments:
+        new_call    -- the new call that will replace this call.
+        """
+        pass
+
+    def on_pager(self, mime_type, body):
+        """
+        Notification that incoming instant message is received on
+        this call.
+
+        Keyword arguments:
+        mime_type  -- MIME type of the instant message body.
+        body       -- the instant message body.
+
+        """
+        pass
+
+    def on_pager_status(self, body, im_id, code, reason):
+        """
+        Notification about the delivery status of previously sent
+        instant message.
+
+        Keyword arguments:
+        body    -- message body
+        im_id   -- message ID
+        code    -- SIP status code
+        reason  -- SIP reason phrase
+
+        """
+        pass
+
+    def on_typing(self, is_typing):
+        """
+        Notification that remote is typing or stop typing.
+
+        Keyword arguments:
+        is_typing -- boolean to indicate whether remote is currently
+                     typing an instant message.
+
+        """
+        pass
+
+
+class CallInfo:
+    """This structure contains various information about Call.
+
+    Application may retrieve this information with Call.info().
+
+    Member documentation:
+
+    role            -- CallRole
+    account         -- Account object.
+    uri             -- SIP URI of local account.
+    contact         -- local Contact URI.
+    remote_uri      -- remote SIP URI.
+    remote_contact  -- remote Contact URI
+    sip_call_id     -- call's Call-ID identification
+    state           -- CallState
+    state_text      -- state text.
+    last_code       -- last SIP status code
+    last_reason     -- text phrase for last_code
+    media_state     -- MediaState
+    media_dir       -- MediaDir
+    conf_slot       -- conference slot number for this call.
+    call_time       -- call's connected duration in seconds.
+    total_time      -- total call duration in seconds.
+    """
+    role = CallRole.CALLER
+    account = None
+    uri = ""
+    contact = ""
+    remote_uri = ""
+    remote_contact = ""
+    sip_call_id = ""
+    state = CallState.NULL
+    state_text = ""
+    last_code = 0
+    last_reason = ""
+    media_state = MediaState.NULL
+    media_dir = MediaDir.NULL
+    conf_slot = -1
+    call_time = 0
+    total_time = 0
+
+    def __init__(self, lib=None, ci=None):
+        if lib and ci:
+            self._cvt_from_pjsua(lib, ci)
+
+    def _cvt_from_pjsua(self, lib, ci):
+        self.role = ci.role
+        self.account = lib._lookup_account(ci.acc_id)
+        self.uri = ci.local_info
+        self.contact = ci.local_contact
+        self.remote_uri = ci.remote_info
+        self.remote_contact = ci.remote_contact
+        self.sip_call_id = ci.call_id
+        self.state = ci.state
+        self.state_text = ci.state_text
+        self.last_code = ci.last_status
+        self.last_reason = ci.last_status_text
+        self.media_state = ci.media_status
+        self.media_dir = ci.media_dir
+        self.conf_slot = ci.conf_slot
+        self.call_time = ci.connect_duration / 1000
+        self.total_time = ci.total_duration / 1000
+
+
+class Call:
+    """This class represents SIP call.
+
+    Application initiates outgoing call with Account.make_call(), and
+    incoming calls are reported in AccountCallback.on_incoming_call().
+    """
+    _id = -1
+    _cb = None
+    _lib = None
+    _obj_name = ""
+
+    def __init__(self, lib, call_id, cb=None):
+        self._lib = weakref.ref(lib)
+        self.set_callback(cb)
+        self.attach_to_id(call_id)
+        _Trace((self, 'created'))
+
+    def __del__(self):
+        if self._id != -1:
+            _pjsua.call_set_user_data(self._id, 0)
+        _Trace((self, 'destroyed'))
+
+    def __str__(self):
+        return self._obj_name
+
+    def attach_to_id(self, call_id):
+        lck = self._lib().auto_lock()
+        if self._id != -1:
+            _pjsua.call_set_user_data(self._id, 0)
+        self._id = call_id
+        if self._id != -1:
+            _pjsua.call_set_user_data(self._id, self)
+            self._obj_name = "{Call " + self.info().remote_uri + "}"
+        else:
+            self._obj_name = "{Call object}"
+
+    def set_callback(self, cb):
+        """
+        Set callback object to retrieve event notifications from this call.
+
+        Keyword arguments:
+        cb  -- CallCallback instance.
+        """
+        if cb:
+            self._cb = cb
+        else:
+            self._cb = CallCallback(self)
+        self._cb._set_call(self)
+
+    def info(self):
+        """
+        Get the CallInfo.
+        """
+        lck = self._lib().auto_lock()
+        ci = _pjsua.call_get_info(self._id)
+        if not ci:
+            self._lib()._err_check("info", self, -1, "Invalid call")
+        call_info = CallInfo(self._lib(), ci)
+        return call_info
+
+    def is_valid(self):
+        """
+        Check if this call is still valid.
+        """
+        lck = self._lib().auto_lock()
+        return _pjsua.call_is_active(self._id)
+
+    def dump_status(self, with_media=True, indent="", max_len=1024):
+        """
+        Dump the call status.
+        """
+        lck = self._lib().auto_lock()
+        return _pjsua.call_dump(self._id, with_media, max_len, indent)
+
+    def answer(self, code=200, reason="", hdr_list=None):
+        """
+        Send provisional or final response to incoming call.
+
+        Keyword arguments:
+        code     -- SIP status code.
+        reason   -- Reason phrase. Put empty to send default reason
+                    phrase for the status code.
+        hdr_list -- Optional list of headers to be sent with the
+                    INVITE response.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_answer(self._id, code, reason, 
+                                   Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("answer()", self, err)
+
+    def hangup(self, code=603, reason="", hdr_list=None):
+        """
+        Terminate the call.
+
+        Keyword arguments:
+        code     -- SIP status code.
+        reason   -- Reason phrase. Put empty to send default reason
+                    phrase for the status code.
+        hdr_list -- Optional list of headers to be sent with the
+                    message.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_hangup(self._id, code, reason, 
+                                   Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("hangup()", self, err)
+
+    def hold(self, hdr_list=None):
+        """
+        Put the call on hold.
+
+        Keyword arguments:
+        hdr_list -- Optional list of headers to be sent with the
+                    message.
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_set_hold(self._id, Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("hold()", self, err)
+
+    def unhold(self, hdr_list=None):
+        """
+        Release the call from hold.
+
+        Keyword arguments:
+        hdr_list -- Optional list of headers to be sent with the
+                    message.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_reinvite(self._id, True, 
+                                     Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("unhold()", self, err)
+
+    def reinvite(self, hdr_list=None):
+        """
+        Send re-INVITE and optionally offer new codecs to use.
+
+        Keyword arguments:
+        hdr_list   -- Optional list of headers to be sent with the
+                      message.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_reinvite(self._id, True, 
+                                     Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("reinvite()", self, err)
+
+    def update(self, hdr_list=None, options=0):
+        """
+        Send UPDATE and optionally offer new codecs to use.
+
+        Keyword arguments:
+        hdr_list   -- Optional list of headers to be sent with the
+                      message.
+        options    -- Must be zero for now.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_update(self._id, options, 
+                                   Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("update()", self, err)
+
+    def transfer(self, dest_uri, hdr_list=None):
+        """
+        Transfer the call to new destination.
+
+        Keyword arguments:
+        dest_uri -- Specify the SIP URI to transfer the call to.
+        hdr_list -- Optional list of headers to be sent with the
+                    message.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_xfer(self._id, dest_uri, 
+                                 Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("transfer()", self, err)
+
+    def transfer_to_call(self, call, hdr_list=None, options=0):
+        """
+        Attended call transfer.
+
+        Keyword arguments:
+        call     -- The Call object to transfer call to.
+        hdr_list -- Optional list of headers to be sent with the
+                    message.
+        options  -- Must be zero for now.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_xfer_replaces(self._id, call._id, options,
+                                          Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("transfer_to_call()", self, err)
+
+    def dial_dtmf(self, digits):
+        """
+        Send DTMF digits with RTP event package.
+
+        Keyword arguments:
+        digits  -- DTMF digit string.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_dial_dtmf(self._id, digits)
+        self._lib()._err_check("dial_dtmf()", self, err)
+
+    def send_request(self, method, hdr_list=None, content_type=None,
+                     body=None):
+        """
+        Send arbitrary request to remote call. 
+        
+        This is useful for example to send INFO request. Note that this 
+        function should not be used to send request that will change the 
+        call state such as CANCEL or BYE.
+
+        Keyword arguments:
+        method       -- SIP method name.
+        hdr_list     -- Optional header list to be sent with the request.
+        content_type -- Content type to describe the body, if the body
+                        is present
+        body         -- Optional SIP message body.
+
+        """
+        lck = self._lib().auto_lock()
+        if hdr_list or body:
+            msg_data = _pjsua.Msg_Data()
+            if hdr_list:
+                msg_data.hdr_list = hdr_list
+            if content_type:
+                msg_data.content_type = content_type
+            if body:
+                msg_data.msg_body = body
+        else:
+            msg_data = None
+                
+        err = _pjsua.call_send_request(self._id, method, msg_data)
+        self._lib()._err_check("send_request()", self, err)
+
+    def send_pager(self, text, im_id=0, content_type="text/plain", 
+    		   hdr_list=None):
+        """Send instant message inside a call.
+
+        Keyword arguments:
+        text         -- Instant message to be sent
+        im_id        -- Optional instant message ID to identify this
+                        instant message when delivery status callback
+                        is called.
+        content_type -- MIME type identifying the instant message
+        hdr_list     -- Optional list of headers to be sent with the
+                        request.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.call_send_im(self._id, \
+                             content_type, text, \
+                             Lib._create_msg_data(hdr_list), \
+                             im_id)
+        self._lib()._err_check("send_pager()", self, err)
+
+  
+class BuddyInfo:
+    """This class contains information about Buddy. Application may 
+    retrieve this information by calling Buddy.info().
+
+    Member documentation:
+
+    uri             -- the Buddy URI.
+    contact         -- the Buddy Contact URI, if available.
+    online_status   -- the presence online status.
+    online_text     -- the presence online status text.
+    activity        -- the PresenceActivity
+    subscribed      -- specify whether buddy's presence status is currently
+                       being subscribed.
+    sub_state       -- SubscriptionState
+    sub_term_reason -- The termination reason string of the last presence
+                       subscription to this buddy, if any.
+    """
+    uri = ""
+    contact = ""
+    online_status = 0
+    online_text = ""
+    activity = PresenceActivity.UNKNOWN
+    subscribed = False
+    sub_state = SubscriptionState.NULL
+    sub_term_reason = ""
+
+    def __init__(self, pjsua_bi=None):
+        if pjsua_bi:
+            self._cvt_from_pjsua(pjsua_bi)
+
+    def _cvt_from_pjsua(self, inf):
+        self.uri = inf.uri
+        self.contact = inf.contact
+        self.online_status = inf.status
+        self.online_text = inf.status_text
+        self.activity = inf.activity
+        self.subscribed = inf.monitor_pres
+        self.sub_state = inf.sub_state
+        self.sub_term_reason = inf.sub_term_reason
+
+
+class BuddyCallback:
+    """This class can be used to receive notifications about Buddy's
+    presence status change. Application needs to derive a class from
+    this class, and register the instance with Buddy.set_callback().
+
+    Member documentation:
+
+    buddy   -- the Buddy object.
+    """
+    buddy = None
+
+    def __init__(self, buddy=None):
+        self._set_buddy(buddy)
+
+    def _set_buddy(self, buddy):
+        if buddy:
+            self.buddy = weakref.proxy(buddy)
+        else:
+            self.buddy = None
+
+    def on_state(self):
+        """
+        Notification that buddy's presence state has changed. Application
+        may then retrieve the new status with Buddy.info() function.
+        """
+        pass
+   
+    def on_pager(self, mime_type, body):
+        """Notification that incoming instant message is received from
+        this buddy.
+
+        Keyword arguments:
+        mime_type  -- MIME type of the instant message body
+        body       -- the instant message body
+
+        """
+        pass
+
+    def on_pager_status(self, body, im_id, code, reason):
+        """Notification about the delivery status of previously sent
+        instant message.
+
+        Keyword arguments:
+        body    -- the message body
+        im_id   -- message ID
+        code    -- SIP status code
+        reason  -- SIP reason phrase
+
+        """
+        pass
+
+    def on_typing(self, is_typing):
+        """Notification that remote is typing or stop typing.
+
+        Keyword arguments:
+        is_typing -- boolean to indicate whether remote is currently
+                     typing an instant message.
+
+        """
+        pass
+
+
+class Buddy:
+    """A Buddy represents person or remote agent.
+
+    This class provides functions to subscribe to buddy's presence and
+    to send or receive instant messages from the buddy.
+    """
+    _id = -1
+    _lib = None
+    _cb = None
+    _obj_name = ""
+    _acc = None
+
+    def __init__(self, lib, id, account, cb):
+        self._id = id
+        self._lib = weakref.ref(lib)
+        self._acc = weakref.ref(account)
+        self._obj_name = "{Buddy " + self.info().uri + "}"
+        self.set_callback(cb)
+        _pjsua.buddy_set_user_data(self._id, self)
+        _Trace((self, 'created'))
+
+    def __del__(self):
+        if self._id != -1:
+            _pjsua.buddy_set_user_data(self._id, 0)
+        _Trace((self, 'destroyed'))
+
+    def __str__(self):
+        return self._obj_name
+
+    def info(self):
+        """
+        Get buddy info as BuddyInfo.
+        """
+        lck = self._lib().auto_lock()
+        return BuddyInfo(_pjsua.buddy_get_info(self._id))
+
+    def set_callback(self, cb):
+        """Install callback to receive notifications from this object.
+
+        Keyword argument:
+        cb  -- BuddyCallback instance.
+        """
+        if cb:
+            self._cb = cb
+        else:
+            self._cb = BuddyCallback(self)
+        self._cb._set_buddy(self)
+
+    def subscribe(self):
+        """
+        Subscribe to buddy's presence status notification.
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.buddy_subscribe_pres(self._id, True)
+        self._lib()._err_check("subscribe()", self, err)
+
+    def unsubscribe(self):
+        """
+        Unsubscribe from buddy's presence status notification.
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.buddy_subscribe_pres(self._id, False)
+        self._lib()._err_check("unsubscribe()", self, err)
+
+    def delete(self):
+        """
+        Remove this buddy from the buddy list.
+        """
+        lck = self._lib().auto_lock()
+        if self._id != -1:
+            _pjsua.buddy_set_user_data(self._id, 0)
+        err = _pjsua.buddy_del(self._id)
+        self._lib()._err_check("delete()", self, err)
+
+    def send_pager(self, text, im_id=0, content_type="text/plain", \
+                   hdr_list=None):
+        """Send instant message to remote buddy.
+
+        Keyword arguments:
+        text         -- Instant message to be sent
+        im_id        -- Optional instant message ID to identify this
+                        instant message when delivery status callback
+                        is called.
+        content_type -- MIME type identifying the instant message
+        hdr_list     -- Optional list of headers to be sent with the
+                        request.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.im_send(self._acc()._id, self.info().uri, \
+                             content_type, text, \
+                             Lib._create_msg_data(hdr_list), \
+                             im_id)
+        self._lib()._err_check("send_pager()", self, err)
+
+    def send_typing_ind(self, is_typing=True, hdr_list=None):
+        """Send typing indication to remote buddy.
+
+        Keyword argument:
+        is_typing -- boolean to indicate wheter user is typing.
+        hdr_list  -- Optional list of headers to be sent with the
+                     request.
+
+        """
+        lck = self._lib().auto_lock()
+        err = _pjsua.im_typing(self._acc()._id, self.info().uri, \
+                               is_typing, Lib._create_msg_data(hdr_list))
+        self._lib()._err_check("send_typing_ind()", self, err)
+
+
+
+# Sound device info
+class SoundDeviceInfo:
+    """This described the sound device info.
+
+    Member documentation:
+    name                -- device name.
+    input_channels      -- number of capture channels supported.
+    output_channels     -- number of playback channels supported.
+    default_clock_rate  -- default sampling rate.
+    """
+    name = ""
+    input_channels = 0
+    output_channels = 0
+    default_clock_rate = 0
+
+    def __init__(self, sdi):
+        self.name = sdi.name
+        self.input_channels = sdi.input_count
+        self.output_channels = sdi.output_count
+        self.default_clock_rate = sdi.default_samples_per_sec
+
+
+# Codec info
+class CodecInfo:
+    """This describes codec info.
+
+    Member documentation:
+    name            -- codec name
+    priority        -- codec priority (0-255)
+    clock_rate      -- clock rate
+    channel_count   -- number of channels
+    avg_bps         -- average bandwidth in bits per second
+    frm_ptime       -- base frame length in milliseconds
+    ptime           -- RTP frame length in milliseconds.
+    pt              -- payload type.
+    vad_enabled     -- specify if Voice Activity Detection is currently
+                       enabled.
+    plc_enabled     -- specify if Packet Lost Concealment is currently
+                       enabled.
+    """
+    name = ""
+    priority = 0
+    clock_rate = 0
+    channel_count = 0
+    avg_bps = 0
+    frm_ptime = 0
+    ptime = 0
+    pt = 0
+    vad_enabled = False
+    plc_enabled = False
+
+    def __init__(self, codec_info, codec_param):
+        self.name = codec_info.codec_id
+        self.priority = codec_info.priority
+        self.clock_rate = codec_param.info.clock_rate
+        self.channel_count = codec_param.info.channel_cnt
+        self.avg_bps = codec_param.info.avg_bps
+        self.frm_ptime = codec_param.info.frm_ptime
+        self.ptime = codec_param.info.frm_ptime * \
+                        codec_param.setting.frm_per_pkt
+        self.ptime = codec_param.info.pt
+        self.vad_enabled = codec_param.setting.vad
+        self.plc_enabled = codec_param.setting.plc
+
+    def _cvt_to_pjsua(self):
+        ci = _pjsua.Codec_Info()
+        ci.codec_id = self.name
+        ci.priority = self.priority
+        return ci
+
+
+# Codec parameter
+class CodecParameter:
+    """This specifies various parameters that can be configured for codec.
+
+    Member documentation:
+
+    ptime       -- specify the outgoing RTP packet length in milliseconds.
+    vad_enabled -- specify if VAD should be enabled.
+    plc_enabled -- specify if PLC should be enabled.
+    """
+    ptime = 0
+    vad_enabled = False
+    plc_enabled = False
+    _codec_param = None
+    
+    def __init__(self, codec_param):
+        self.ptime = codec_param.info.frm_ptime * \
+                        codec_param.setting.frm_per_pkt
+        self.vad_enabled = codec_param.setting.vad
+        self.plc_enabled = codec_param.setting.plc
+        self._codec_param = codec_param
+
+    def _cvt_to_pjsua(self):
+        self._codec_param.setting.frm_per_pkt = self.ptime / \
+                                                self._codec_param.info.frm_ptime
+        self._codec_param.setting.vad = self.vad_enabled
+        self._codec_param.setting.plc = self.plc_enabled
+        return self._codec_param
+
+
+# Library mutex
+class _LibMutex:
+    def __init__(self, lck):
+        self._lck = lck
+        self._lck.acquire()
+	#_Trace(('lock acquired',))
+
+    def __del__(self):
+        try:
+            self._lck.release()
+	    #_Trace(('lock released',))
+        except:
+	    #_Trace(('lock release error',))
+            pass
+
+
+# PJSUA Library
+_lib = None
+enable_trace = False
+
+class Lib:
+    """Library instance.
+    
+    """
+    _quit = False
+    _has_thread = False
+    _lock = None
+
+    def __init__(self):
+        global _lib
+        if _lib:
+            raise Error("__init()__", None, -1, 
+                        "Library instance already exist")
+
+        self._lock = threading.RLock()
+        err = _pjsua.create()
+        self._err_check("_pjsua.create()", None, err)
+        _lib = self
+
+    def __del__(self):
+        _pjsua.destroy()
+        del self._lock
+        _Trace(('Lib destroyed',))
+
+    def __str__(self):
+        return "Lib"
+
+    @staticmethod
+    def instance():
+        """Return singleton instance of Lib.
+        """
+        return _lib
+
+    def init(self, ua_cfg=None, log_cfg=None, media_cfg=None):
+        """
+        Initialize pjsua with the specified configurations.
+
+        Keyword arguments:
+        ua_cfg      -- optional UAConfig instance
+        log_cfg     -- optional LogConfig instance
+        media_cfg   -- optional MediaConfig instance
+
+        """
+        if not ua_cfg: ua_cfg = UAConfig()
+        if not log_cfg: log_cfg = LogConfig()
+        if not media_cfg: media_cfg = MediaConfig()
+
+        py_ua_cfg = ua_cfg._cvt_to_pjsua()
+        py_ua_cfg.cb.on_call_state = _cb_on_call_state
+        py_ua_cfg.cb.on_incoming_call = _cb_on_incoming_call
+        py_ua_cfg.cb.on_call_media_state = _cb_on_call_media_state
+        py_ua_cfg.cb.on_dtmf_digit = _cb_on_dtmf_digit
+        py_ua_cfg.cb.on_call_transfer_request = _cb_on_call_transfer_request
+        py_ua_cfg.cb.on_call_transfer_status = _cb_on_call_transfer_status
+        py_ua_cfg.cb.on_call_replace_request = _cb_on_call_replace_request
+        py_ua_cfg.cb.on_call_replaced = _cb_on_call_replaced
+        py_ua_cfg.cb.on_reg_state = _cb_on_reg_state
+        py_ua_cfg.cb.on_incoming_subscribe = _cb_on_incoming_subscribe
+        py_ua_cfg.cb.on_buddy_state = _cb_on_buddy_state
+        py_ua_cfg.cb.on_pager = _cb_on_pager
+        py_ua_cfg.cb.on_pager_status = _cb_on_pager_status
+        py_ua_cfg.cb.on_typing = _cb_on_typing
+	py_ua_cfg.cb.on_mwi_info = _cb_on_mwi_info;
+
+        err = _pjsua.init(py_ua_cfg, log_cfg._cvt_to_pjsua(), 
+                          media_cfg._cvt_to_pjsua())
+        self._err_check("init()", self, err)
+
+    def destroy(self):
+        """Destroy the library, and pjsua."""
+        global _lib
+        if self._has_thread:
+            self._quit = 1
+            loop = 0
+            while self._quit != 2 and loop < 400:
+                self.handle_events(5)
+                loop = loop + 1
+                time.sleep(0.050)
+        _pjsua.destroy()
+        _lib = None
+
+    def start(self, with_thread=True):
+        """Start the library. 
+
+        Keyword argument:
+        with_thread -- specify whether the module should create worker
+                       thread.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.start()
+        self._err_check("start()", self, err)
+        self._has_thread = with_thread
+        if self._has_thread:
+            thread.start_new(_worker_thread_main, (0,))
+
+    def handle_events(self, timeout=50):
+        """Poll the events from underlying pjsua library.
+        
+        Application must poll the stack periodically if worker thread
+        is disable when starting the library.
+
+        Keyword argument:
+        timeout -- in milliseconds.
+
+        """
+        lck = self.auto_lock()
+        return _pjsua.handle_events(timeout)
+
+    def thread_register(self, name):
+	"""Register external threads (threads that are not created by PJSIP,
+	such as threads that are created by Python API) to PJSIP.
+
+	The call must be made from the new thread before calling any pjlib 
+	functions.
+
+	Keyword arguments:
+	name	-- Non descriptive name for the thread
+	"""
+	dummy = 1
+	err = _pjsua.thread_register(name, dummy)
+	self._err_check("thread_register()", self, err)
+
+    def verify_sip_url(self, sip_url):
+        """Verify that the specified string is a valid URI. 
+        
+        Keyword argument:
+        sip_url -- the URL string.
+        
+        Return:
+            0 is the the URI is valid, otherwise the appropriate error 
+            code is returned.
+
+        """
+        lck = self.auto_lock()
+        return _pjsua.verify_sip_url(sip_url)
+
+    def create_transport(self, type, cfg=None):
+        """Create SIP transport instance of the specified type. 
+        
+        Keyword arguments:
+        type    -- transport type from TransportType constant.
+        cfg     -- TransportConfig instance
+
+        Return:
+            Transport object
+
+        """
+        lck = self.auto_lock()
+        if not cfg: cfg=TransportConfig()
+        err, tp_id = _pjsua.transport_create(type, cfg._cvt_to_pjsua())
+        self._err_check("create_transport()", self, err)
+        return Transport(self, tp_id)
+
+    def create_account(self, acc_config, set_default=True, cb=None):
+        """
+        Create a new local pjsua account using the specified configuration.
+
+        Keyword arguments:
+        acc_config  -- AccountConfig
+        set_default -- boolean to specify whether to use this as the
+                       default account.
+        cb          -- AccountCallback instance.
+
+        Return:
+            Account instance
+
+        """
+        lck = self.auto_lock()
+        err, acc_id = _pjsua.acc_add(acc_config._cvt_to_pjsua(), set_default)
+        self._err_check("create_account()", self, err)
+        return Account(self, acc_id, cb)
+
+    def create_account_for_transport(self, transport, set_default=True,
+                                     cb=None):
+        """Create a new local pjsua transport for the specified transport.
+
+        Keyword arguments:
+        transport   -- the Transport instance.
+        set_default -- boolean to specify whether to use this as the
+                       default account.
+        cb          -- AccountCallback instance.
+
+        Return:
+            Account instance
+
+        """
+        lck = self.auto_lock()
+        err, acc_id = _pjsua.acc_add_local(transport._id, set_default)
+        self._err_check("create_account_for_transport()", self, err)
+        return Account(self, acc_id, cb)
+
+    def hangup_all(self):
+        """Hangup all calls.
+
+        """
+        lck = self.auto_lock()
+        _pjsua.call_hangup_all()
+
+    # Sound device API
+
+    def enum_snd_dev(self):
+        """Enumerate sound devices in the system.
+
+        Return:
+            list of SoundDeviceInfo. The index of the element specifies
+            the device ID for the device.
+        """
+        lck = self.auto_lock()
+        sdi_list = _pjsua.enum_snd_devs()
+        info = []
+        for sdi in sdi_list:
+            info.append(SoundDeviceInfo(sdi))
+        return info
+
+    def get_snd_dev(self):
+        """Get the device IDs of current sound devices used by pjsua.
+
+        Return:
+            (capture_dev_id, playback_dev_id) tuple
+        """
+        lck = self.auto_lock()
+        return _pjsua.get_snd_dev()
+
+    def set_snd_dev(self, capture_dev, playback_dev):
+        """Change the current sound devices.
+
+        Keyword arguments:
+        capture_dev  -- the device ID of capture device to be used
+        playback_dev -- the device ID of playback device to be used.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.set_snd_dev(capture_dev, playback_dev)
+        self._err_check("set_current_sound_devices()", self, err)
+    
+    def set_null_snd_dev(self):
+        """Disable the sound devices. This is useful if the system
+        does not have sound device installed.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.set_null_snd_dev()
+        self._err_check("set_null_snd_dev()", self, err)
+
+    
+    # Conference bridge
+
+    def conf_get_max_ports(self):
+        """Get the conference bridge capacity.
+
+        Return:
+            conference bridge capacity.
+
+        """
+        lck = self.auto_lock()
+        return _pjsua.conf_get_max_ports()
+
+    def conf_connect(self, src_slot, dst_slot):
+        """Establish unidirectional media flow from souce to sink. 
+        
+        One source may transmit to multiple destinations/sink. And if 
+        multiple sources are transmitting to the same sink, the media 
+        will be mixed together. Source and sink may refer to the same ID, 
+        effectively looping the media.
+
+        If bidirectional media flow is desired, application needs to call
+        this function twice, with the second one having the arguments 
+        reversed.
+
+        Keyword arguments:
+        src_slot    -- integer to identify the conference slot number of
+                       the source/transmitter.
+        dst_slot    -- integer to identify the conference slot number of    
+                       the destination/receiver.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.conf_connect(src_slot, dst_slot)
+        self._err_check("conf_connect()", self, err)
+    
+    def conf_disconnect(self, src_slot, dst_slot):
+        """Disconnect media flow from the source to destination port.
+
+        Keyword arguments:
+        src_slot    -- integer to identify the conference slot number of
+                       the source/transmitter.
+        dst_slot    -- integer to identify the conference slot number of    
+                       the destination/receiver.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.conf_disconnect(src_slot, dst_slot)
+        self._err_check("conf_disconnect()", self, err)
+
+    def conf_set_tx_level(self, slot, level):
+        """Adjust the signal level to be transmitted from the bridge to 
+        the specified port by making it louder or quieter.
+
+        Keyword arguments:
+        slot        -- integer to identify the conference slot number.
+        level       -- Signal level adjustment. Value 1.0 means no level
+                       adjustment, while value 0 means to mute the port.
+        """
+        lck = self.auto_lock()
+        err = _pjsua.conf_set_tx_level(slot, level)
+        self._err_check("conf_set_tx_level()", self, err)
+        
+    def conf_set_rx_level(self, slot, level):
+        """Adjust the signal level to be received from the specified port
+        (to the bridge) by making it louder or quieter.
+
+        Keyword arguments:
+        slot        -- integer to identify the conference slot number.
+        level       -- Signal level adjustment. Value 1.0 means no level
+                       adjustment, while value 0 means to mute the port.
+        """
+        lck = self.auto_lock()
+        err = _pjsua.conf_set_rx_level(slot, level)
+        self._err_check("conf_set_rx_level()", self, err)
+        
+    def conf_get_signal_level(self, slot):
+        """Get last signal level transmitted to or received from the 
+        specified port. The signal levels are float values from 0.0 to 1.0,
+        with 0.0 indicates no signal, and 1.0 indicates the loudest signal
+        level.
+
+        Keyword arguments:
+        slot        -- integer to identify the conference slot number.
+
+        Return value:
+            (tx_level, rx_level) tuple.
+        """
+        lck = self.auto_lock()
+        err, tx_level, rx_level = _pjsua.conf_get_signal_level(slot)
+        self._err_check("conf_get_signal_level()", self, err)
+        return (tx_level, rx_level)
+        
+
+
+    # Codecs API
+
+    def enum_codecs(self):
+        """Return list of codecs supported by pjsua.
+
+        Return:
+            list of CodecInfo
+
+        """
+        lck = self.auto_lock()
+        ci_list = _pjsua.enum_codecs()
+        codec_info = []
+        for ci in ci_list:
+            cp = _pjsua.codec_get_param(ci.codec_id)
+            if cp:
+                codec_info.append(CodecInfo(ci, cp))
+        return codec_info
+
+    def set_codec_priority(self, name, priority):
+        """Change the codec priority.
+
+        Keyword arguments:
+        name     -- Codec name
+        priority -- Codec priority, which range is 0-255.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.codec_set_priority(name, priority)
+        self._err_check("set_codec_priority()", self, err)
+
+    def get_codec_parameter(self, name):
+        """Get codec parameter for the specified codec.
+
+        Keyword arguments:
+        name    -- codec name.
+
+        """
+        lck = self.auto_lock()
+        cp = _pjsua.codec_get_param(name)
+        if not cp:
+            self._err_check("get_codec_parameter()", self, -1, 
+                            "Invalid codec name")
+        return CodecParameter(cp)
+
+    def set_codec_parameter(self, name, param):
+        """Modify codec parameter for the specified codec.
+
+        Keyword arguments:
+        name    -- codec name
+        param   -- codec parameter.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.codec_set_param(name, param._cvt_to_pjsua())
+        self._err_check("set_codec_parameter()", self, err)
+    
+    # WAV playback and recording
+
+    def create_player(self, filename, loop=False):
+        """Create WAV file player.
+
+        Keyword arguments
+        filename    -- WAV file name
+        loop        -- boolean to specify whether playback should
+                       automatically restart upon EOF
+        Return:
+            WAV player ID
+
+        """
+        lck = self.auto_lock()
+        opt = 0
+        if not loop:
+            opt = opt + 1
+        err, player_id = _pjsua.player_create(filename, opt)
+        self._err_check("create_player()", self, err)
+        return player_id
+        
+    def player_get_slot(self, player_id):
+        """Get the conference port ID for the specified player.
+
+        Keyword arguments:
+        player_id  -- the WAV player ID
+        
+        Return:
+            Conference slot number for the player
+
+        """
+        lck = self.auto_lock()
+        slot = _pjsua.player_get_conf_port(player_id)
+        if slot < 0:
+                self._err_check("player_get_slot()", self, -1, 
+                                "Invalid player id")
+        return slot
+
+    def player_set_pos(self, player_id, pos):
+        """Set WAV playback position.
+
+        Keyword arguments:
+        player_id   -- WAV player ID
+        pos         -- playback position, in samples
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.player_set_pos(player_id, pos)
+        self._err_check("player_set_pos()", self, err)
+        
+    def player_destroy(self, player_id):
+        """Destroy the WAV player.
+
+        Keyword arguments:
+        player_id   -- the WAV player ID.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.player_destroy(player_id)
+        self._err_check("player_destroy()", self, err)
+
+    def create_playlist(self, filelist, label="playlist", loop=True):
+        """Create WAV playlist.
+
+        Keyword arguments:
+        filelist    -- List of WAV file names.
+        label       -- Optional name to be assigned to the playlist
+                       object (useful for logging)
+        loop        -- boolean to specify whether playback should
+                       automatically restart upon EOF
+
+        Return:
+            playlist_id
+        """
+        lck = self.auto_lock()
+        opt = 0
+        if not loop:
+            opt = opt + 1
+        err, playlist_id = _pjsua.playlist_create(label, filelist, opt)
+        self._err_check("create_playlist()", self, err)
+        return playlist_id 
+
+    def playlist_get_slot(self, playlist_id):
+        """Get the conference port ID for the specified playlist.
+
+        Keyword arguments:
+        playlist_id  -- the WAV playlist ID
+        
+        Return:
+            Conference slot number for the playlist
+
+        """
+        lck = self.auto_lock()
+        slot = _pjsua.player_get_conf_port(playlist_id)
+        if slot < 0:
+                self._err_check("playlist_get_slot()", self, -1, 
+                                "Invalid playlist id")
+        return slot
+
+    def playlist_destroy(self, playlist_id):
+        """Destroy the WAV playlist.
+
+        Keyword arguments:
+        playlist_id   -- the WAV playlist ID.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.player_destroy(playlist_id)
+        self._err_check("playlist_destroy()", self, err)
+
+    def create_recorder(self, filename):
+        """Create WAV file recorder.
+
+        Keyword arguments
+        filename    -- WAV file name
+
+        Return:
+            WAV recorder ID
+
+        """
+        lck = self.auto_lock()
+        err, rec_id = _pjsua.recorder_create(filename, 0, None, -1, 0)
+        self._err_check("create_recorder()", self, err)
+        return rec_id
+        
+    def recorder_get_slot(self, rec_id):
+        """Get the conference port ID for the specified recorder.
+
+        Keyword arguments:
+        rec_id  -- the WAV recorder ID
+        
+        Return:
+            Conference slot number for the recorder
+
+        """
+        lck = self.auto_lock()
+        slot = _pjsua.recorder_get_conf_port(rec_id)
+        if slot < 1:
+            self._err_check("recorder_get_slot()", self, -1, 
+                            "Invalid recorder id")
+        return slot
+
+    def recorder_destroy(self, rec_id):
+        """Destroy the WAV recorder.
+
+        Keyword arguments:
+        rec_id   -- the WAV recorder ID.
+
+        """
+        lck = self.auto_lock()
+        err = _pjsua.recorder_destroy(rec_id)
+        self._err_check("recorder_destroy()", self, err)
+
+
+    # Internal functions
+
+    @staticmethod
+    def strerror(err):
+        return _pjsua.strerror(err)
+    
+    def _err_check(self, op_name, obj, err_code, err_msg=""):
+        if err_code != 0:
+            raise Error(op_name, obj, err_code, err_msg)
+
+    @staticmethod
+    def _create_msg_data(hdr_list):
+        if not hdr_list:
+            return None
+        msg_data = _pjsua.Msg_Data()
+        msg_data.hdr_list = hdr_list
+        return msg_data
+    
+    def auto_lock(self):
+        return _LibMutex(self._lock)
+
+    # Internal dictionary manipulation for calls, accounts, and buddies
+
+    def _lookup_call(self, call_id):
+        return _pjsua.call_get_user_data(call_id)
+
+    def _lookup_account(self, acc_id):
+        return _pjsua.acc_get_user_data(acc_id)
+
+    def _lookup_buddy(self, buddy_id, uri=None):
+        if buddy_id != -1:
+            buddy = _pjsua.buddy_get_user_data(buddy_id)
+        elif uri:
+            buddy_id = _pjsua.buddy_find(uri)
+            if buddy_id != -1:
+                buddy = _pjsua.buddy_get_user_data(buddy_id)
+            else:
+                buddy = None
+        else:
+            buddy = None
+            
+        return buddy 
+
+    # Account allbacks
+
+    def _cb_on_reg_state(self, acc_id):
+        acc = self._lookup_account(acc_id)
+        if acc:
+            acc._cb.on_reg_state()
+
+    def _cb_on_incoming_subscribe(self, acc_id, buddy_id, from_uri, 
+                                  contact_uri, pres_obj):
+        acc = self._lookup_account(acc_id)
+        if acc:
+            buddy = self._lookup_buddy(buddy_id)
+            return acc._cb.on_incoming_subscribe(buddy, from_uri, contact_uri,
+                                                 pres_obj)
+        else:
+            return (404, None)
+
+    def _cb_on_incoming_call(self, acc_id, call_id, rdata):
+        acc = self._lookup_account(acc_id)
+        if acc:
+            if 'on_incoming_call2' in acc._cb.__class__.__dict__:
+                acc._cb.on_incoming_call2( Call(self, call_id), rdata )
+            else:
+                acc._cb.on_incoming_call( Call(self, call_id) )
+        else:
+            _pjsua.call_hangup(call_id, 603, None, None)
+
+    # Call callbacks 
+
+    def _cb_on_call_state(self, call_id):
+        call = self._lookup_call(call_id)
+        if call:
+            if call._id == -1:
+                call.attach_to_id(call_id)
+            done = (call.info().state == CallState.DISCONNECTED)
+            call._cb.on_state()
+            if done:
+                _pjsua.call_set_user_data(call_id, 0)
+        else:
+            pass
+
+    def _cb_on_call_media_state(self, call_id):
+        call = self._lookup_call(call_id)
+        if call:
+            call._cb.on_media_state()
+
+    def _cb_on_dtmf_digit(self, call_id, digits):
+        call = self._lookup_call(call_id)
+        if call:
+            call._cb.on_dtmf_digit(digits)
+
+    def _cb_on_call_transfer_request(self, call_id, dst, code):
+        call = self._lookup_call(call_id)
+        if call:
+            return call._cb.on_transfer_request(dst, code)
+        else:
+            return 603
+
+    def _cb_on_call_transfer_status(self, call_id, code, text, final, cont):
+        call = self._lookup_call(call_id)
+        if call:
+            return call._cb.on_transfer_status(code, text, final, cont)
+        else:
+            return cont
+
+    def _cb_on_call_replace_request(self, call_id, rdata, code, reason):
+        call = self._lookup_call(call_id)
+        if call:
+            return call._cb.on_replace_request(code, reason)
+        else:
+            return code, reason
+
+    def _cb_on_call_replaced(self, old_call_id, new_call_id):
+        old_call = self._lookup_call(old_call_id)
+        new_call = self._lookup_call(new_call_id)
+        if old_call and new_call:
+            old_call._cb.on_replaced(new_call)
+
+    def _cb_on_pager(self, call_id, from_uri, to_uri, contact, mime_type, 
+                     body, acc_id):
+        call = None
+        if call_id != -1:
+            call = self._lookup_call(call_id)
+        if call:
+            call._cb.on_pager(mime_type, body)
+        else:
+            acc = self._lookup_account(acc_id)
+            buddy = self._lookup_buddy(-1, from_uri)
+            if buddy:
+                buddy._cb.on_pager(mime_type, body)
+            else:
+                acc._cb.on_pager(from_uri, contact, mime_type, body)
+
+    def _cb_on_pager_status(self, call_id, to_uri, body, user_data, 
+                            code, reason, acc_id):
+        call = None
+        if call_id != -1:
+            call = self._lookup_call(call_id)
+        if call:
+            call._cb.on_pager_status(body, user_data, code, reason)
+        else:
+            acc = self._lookup_account(acc_id)
+            buddy = self._lookup_buddy(-1, to_uri)
+            if buddy:
+                buddy._cb.on_pager_status(body, user_data, code, reason)
+            else:
+                acc._cb.on_pager_status(to_uri, body, user_data, code, reason)
+
+    def _cb_on_typing(self, call_id, from_uri, to_uri, contact, is_typing, 
+                      acc_id):
+        call = None
+        if call_id != -1:
+            call = self._lookup_call(call_id)
+        if call:
+            call._cb.on_typing(is_typing)
+        else:
+            acc = self._lookup_account(acc_id)
+            buddy = self._lookup_buddy(-1, from_uri)
+            if buddy:
+                buddy._cb.on_typing(is_typing)
+            else:
+                acc._cb.on_typing(from_uri, contact, is_typing)
+
+    def _cb_on_mwi_info(self, acc_id, body):
+        acc = self._lookup_account(acc_id)
+        if acc:
+            return acc._cb.on_mwi_info(body)
+
+    def _cb_on_buddy_state(self, buddy_id):
+        buddy = self._lookup_buddy(buddy_id)
+        if buddy:
+            buddy._cb.on_state()
+
+#
+# Internal
+#
+
+def _cb_on_call_state(call_id, e):
+    _lib._cb_on_call_state(call_id)
+
+def _cb_on_incoming_call(acc_id, call_id, rdata):
+    _lib._cb_on_incoming_call(acc_id, call_id, rdata)
+
+def _cb_on_call_media_state(call_id):
+    _lib._cb_on_call_media_state(call_id)
+
+def _cb_on_dtmf_digit(call_id, digits):
+    _lib._cb_on_dtmf_digit(call_id, digits)
+
+def _cb_on_call_transfer_request(call_id, dst, code):
+    return _lib._cb_on_call_transfer_request(call_id, dst, code)
+
+def _cb_on_call_transfer_status(call_id, code, reason, final, cont):
+    return _lib._cb_on_call_transfer_status(call_id, code, reason, 
+                                             final, cont)
+def _cb_on_call_replace_request(call_id, rdata, code, reason):
+    return _lib._cb_on_call_replace_request(call_id, rdata, code, reason)
+
+def _cb_on_call_replaced(old_call_id, new_call_id):
+    _lib._cb_on_call_replaced(old_call_id, new_call_id)
+
+def _cb_on_reg_state(acc_id):
+    _lib._cb_on_reg_state(acc_id)
+
+def _cb_on_incoming_subscribe(acc_id, buddy_id, from_uri, contact_uri, pres):
+    return _lib._cb_on_incoming_subscribe(acc_id, buddy_id, from_uri, 
+                                          contact_uri, pres)
+
+def _cb_on_buddy_state(buddy_id):
+    _lib._cb_on_buddy_state(buddy_id)
+
+def _cb_on_pager(call_id, from_uri, to, contact, mime_type, body, acc_id):
+    _lib._cb_on_pager(call_id, from_uri, to, contact, mime_type, body, acc_id)
+
+def _cb_on_pager_status(call_id, to, body, user_data, status, reason, acc_id):
+    _lib._cb_on_pager_status(call_id, to, body, user_data, 
+                             status, reason, acc_id)
+
+def _cb_on_typing(call_id, from_uri, to, contact, is_typing, acc_id):
+    _lib._cb_on_typing(call_id, from_uri, to, contact, is_typing, acc_id)
+
+def _cb_on_mwi_info(acc_id, body):
+    _lib._cb_on_mwi_info(acc_id, body)
+
+# Worker thread
+def _worker_thread_main(arg):
+    global _lib
+    _Trace(('worker thread started..',))
+    thread_desc = 0;
+    err = _pjsua.thread_register("python worker", thread_desc)
+    _lib._err_check("thread_register()", _lib, err)
+    while _lib and _lib._quit == 0:
+        _lib.handle_events(1)
+	time.sleep(0.050)
+    if _lib:
+        _lib._quit = 2
+    _Trace(('worker thread exited..',))
+
+def _Trace(args):
+    global enable_trace
+    if enable_trace:
+        print "** ",
+        for arg in args:
+            print arg,
+        print " **"
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/samples/call.py b/jni/libpjsip/sources/pjsip-apps/src/python/samples/call.py
new file mode 100644
index 0000000..60f9065
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/samples/call.py
@@ -0,0 +1,169 @@
+# $Id: call.py 2171 2008-07-24 09:01:33Z bennylp $
+#
+# SIP call sample.
+#
+# Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+#
+# 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 
+#
+import sys
+import pjsua as pj
+
+LOG_LEVEL=3
+current_call = None
+
+# Logging callback
+def log_cb(level, str, len):
+    print str,
+
+
+# Callback to receive events from account
+class MyAccountCallback(pj.AccountCallback):
+
+    def __init__(self, account=None):
+        pj.AccountCallback.__init__(self, account)
+
+    # Notification on incoming call
+    def on_incoming_call(self, call):
+        global current_call 
+        if current_call:
+            call.answer(486, "Busy")
+            return
+            
+        print "Incoming call from ", call.info().remote_uri
+        print "Press 'a' to answer"
+
+        current_call = call
+
+        call_cb = MyCallCallback(current_call)
+        current_call.set_callback(call_cb)
+
+        current_call.answer(180)
+
+        
+# Callback to receive events from Call
+class MyCallCallback(pj.CallCallback):
+
+    def __init__(self, call=None):
+        pj.CallCallback.__init__(self, call)
+
+    # Notification when call state has changed
+    def on_state(self):
+        global current_call
+        print "Call with", self.call.info().remote_uri,
+        print "is", self.call.info().state_text,
+        print "last code =", self.call.info().last_code, 
+        print "(" + self.call.info().last_reason + ")"
+        
+        if self.call.info().state == pj.CallState.DISCONNECTED:
+            current_call = None
+            print 'Current call is', current_call
+
+    # Notification when call's media state has changed.
+    def on_media_state(self):
+        if self.call.info().media_state == pj.MediaState.ACTIVE:
+            # Connect the call to sound device
+            call_slot = self.call.info().conf_slot
+            pj.Lib.instance().conf_connect(call_slot, 0)
+            pj.Lib.instance().conf_connect(0, call_slot)
+            print "Media is now active"
+        else:
+            print "Media is inactive"
+
+# Function to make call
+def make_call(uri):
+    try:
+        print "Making call to", uri
+        return acc.make_call(uri, cb=MyCallCallback())
+    except pj.Error, e:
+        print "Exception: " + str(e)
+        return None
+        
+
+# Create library instance
+lib = pj.Lib()
+
+try:
+    # Init library with default config and some customized
+    # logging config.
+    lib.init(log_cfg = pj.LogConfig(level=LOG_LEVEL, callback=log_cb))
+
+    # Create UDP transport which listens to any available port
+    transport = lib.create_transport(pj.TransportType.UDP, 
+                                     pj.TransportConfig(0))
+    print "\nListening on", transport.info().host, 
+    print "port", transport.info().port, "\n"
+    
+    # Start the library
+    lib.start()
+
+    # Create local account
+    acc = lib.create_account_for_transport(transport, cb=MyAccountCallback())
+
+    # If argument is specified then make call to the URI
+    if len(sys.argv) > 1:
+        lck = lib.auto_lock()
+        current_call = make_call(sys.argv[1])
+        print 'Current call is', current_call
+        del lck
+
+    my_sip_uri = "sip:" + transport.info().host + \
+                 ":" + str(transport.info().port)
+
+    # Menu loop
+    while True:
+        print "My SIP URI is", my_sip_uri
+        print "Menu:  m=make call, h=hangup call, a=answer call, q=quit"
+
+        input = sys.stdin.readline().rstrip("\r\n")
+        if input == "m":
+            if current_call:
+                print "Already have another call"
+                continue
+            print "Enter destination URI to call: ", 
+            input = sys.stdin.readline().rstrip("\r\n")
+            if input == "":
+                continue
+            lck = lib.auto_lock()
+            current_call = make_call(input)
+            del lck
+
+        elif input == "h":
+            if not current_call:
+                print "There is no call"
+                continue
+            current_call.hangup()
+
+        elif input == "a":
+            if not current_call:
+                print "There is no call"
+                continue
+            current_call.answer(200)
+
+        elif input == "q":
+            break
+
+    # Shutdown the library
+    transport = None
+    acc.delete()
+    acc = None
+    lib.destroy()
+    lib = None
+
+except pj.Error, e:
+    print "Exception: " + str(e)
+    lib.destroy()
+    lib = None
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/samples/presence.py b/jni/libpjsip/sources/pjsip-apps/src/python/samples/presence.py
new file mode 100644
index 0000000..afeaeab
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/samples/presence.py
@@ -0,0 +1,175 @@
+# $Id: presence.py 2171 2008-07-24 09:01:33Z bennylp $
+#
+# Presence and instant messaging
+#
+# Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+#
+# 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 
+#
+import sys
+import pjsua as pj
+
+LOG_LEVEL = 3
+pending_pres = None
+pending_uri = None
+
+def log_cb(level, str, len):
+    print str,
+
+class MyAccountCallback(pj.AccountCallback):
+    def __init__(self, account=None):
+        pj.AccountCallback.__init__(self, account)
+
+    def on_incoming_subscribe(self, buddy, from_uri, contact_uri, pres):
+        global pending_pres, pending_uri
+        # Allow buddy to subscribe to our presence
+        if buddy:
+            return (200, None)
+        print 'Incoming SUBSCRIBE request from', from_uri
+        print 'Press "A" to accept and add, "R" to reject the request'
+        pending_pres = pres
+        pending_uri = from_uri
+        return (202, None)
+
+
+class MyBuddyCallback(pj.BuddyCallback):
+    def __init__(self, buddy=None):
+        pj.BuddyCallback.__init__(self, buddy)
+
+    def on_state(self):
+        print "Buddy", self.buddy.info().uri, "is",
+        print self.buddy.info().online_text
+
+    def on_pager(self, mime_type, body):
+        print "Instant message from", self.buddy.info().uri, 
+        print "(", mime_type, "):"
+        print body
+
+    def on_pager_status(self, body, im_id, code, reason):
+        if code >= 300:
+            print "Message delivery failed for message",
+            print body, "to", self.buddy.info().uri, ":", reason
+
+    def on_typing(self, is_typing):
+        if is_typing:
+            print self.buddy.info().uri, "is typing"
+        else:
+            print self.buddy.info().uri, "stops typing"
+
+
+lib = pj.Lib()
+
+try:
+    # Init library with default config and some customized
+    # logging config.
+    lib.init(log_cfg = pj.LogConfig(level=LOG_LEVEL, callback=log_cb))
+
+    # Create UDP transport which listens to any available port
+    transport = lib.create_transport(pj.TransportType.UDP, 
+                                     pj.TransportConfig(0))
+    print "\nListening on", transport.info().host, 
+    print "port", transport.info().port, "\n"
+    
+    # Start the library
+    lib.start()
+
+    # Create local account
+    acc = lib.create_account_for_transport(transport, cb=MyAccountCallback())
+    acc.set_basic_status(True)
+    
+    my_sip_uri = "sip:" + transport.info().host + \
+                 ":" + str(transport.info().port)
+
+    buddy = None
+
+    # Menu loop
+    while True:
+        print "My SIP URI is", my_sip_uri
+        print "Menu:  a=add buddy, d=delete buddy, t=toggle", \
+              " online status, i=send IM, q=quit"
+
+        input = sys.stdin.readline().rstrip("\r\n")
+        if input == "a":
+            # Add buddy
+            print "Enter buddy URI: ", 
+            input = sys.stdin.readline().rstrip("\r\n")
+            if input == "":
+                continue
+
+            buddy = acc.add_buddy(input, cb=MyBuddyCallback())
+            buddy.subscribe()
+
+        elif input == "t":
+            acc.set_basic_status(not acc.info().online_status)
+
+        elif input == "i":
+            if not buddy:
+                print "Add buddy first"
+                continue
+
+            buddy.send_typing_ind(True)
+
+            print "Type the message: ", 
+            input = sys.stdin.readline().rstrip("\r\n")
+            if input == "":
+                buddy.send_typing_ind(False)
+                continue
+            
+            buddy.send_pager(input)
+        
+        elif input == "d":
+            if buddy:
+                buddy.delete()
+                buddy = None
+            else:
+                print 'No buddy was added'
+
+        elif input == "A":
+            if pending_pres:
+                acc.pres_notify(pending_pres, pj.SubscriptionState.ACTIVE)
+                buddy = acc.add_buddy(pending_uri, cb=MyBuddyCallback())
+                buddy.subscribe()
+                pending_pres = None
+                pending_uri = None
+            else:
+                print "No pending request"
+
+        elif input == "R":
+            if pending_pres:
+                acc.pres_notify(pending_pres, pj.SubscriptionState.TERMINATED,
+                                "rejected")
+                pending_pres = None
+                pending_uri = None
+            else:
+                print "No pending request"
+
+        elif input == "q":
+            break
+
+    # Shutdown the library
+    acc.delete()
+    acc = None
+    if pending_pres:
+        acc.pres_notify(pending_pres, pj.SubscriptionState.TERMINATED,
+                        "rejected")
+    transport = None
+    lib.destroy()
+    lib = None
+
+except pj.Error, e:
+    print "Exception: " + str(e)
+    lib.destroy()
+    lib = None
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/samples/registration.py b/jni/libpjsip/sources/pjsip-apps/src/python/samples/registration.py
new file mode 100644
index 0000000..06670da
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/samples/registration.py
@@ -0,0 +1,70 @@
+# $Id: registration.py 2171 2008-07-24 09:01:33Z bennylp $
+#
+# SIP account and registration sample. In this sample, the program
+# will block to wait until registration is complete
+#
+# Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+#
+# 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 
+#
+import sys
+import pjsua as pj
+import threading
+
+
+def log_cb(level, str, len):
+    print str,
+
+class MyAccountCallback(pj.AccountCallback):
+    sem = None
+
+    def __init__(self, account):
+        pj.AccountCallback.__init__(self, account)
+
+    def wait(self):
+        self.sem = threading.Semaphore(0)
+        self.sem.acquire()
+
+    def on_reg_state(self):
+        if self.sem:
+            if self.account.info().reg_status >= 200:
+                self.sem.release()
+
+lib = pj.Lib()
+
+try:
+    lib.init(log_cfg = pj.LogConfig(level=4, callback=log_cb))
+    lib.create_transport(pj.TransportType.UDP, pj.TransportConfig(5080))
+    lib.start()
+
+    acc = lib.create_account(pj.AccountConfig("pjsip.org", "bennylp", "***"))
+
+    acc_cb = MyAccountCallback(acc)
+    acc.set_callback(acc_cb)
+    acc_cb.wait()
+
+    print "\n"
+    print "Registration complete, status=", acc.info().reg_status, \
+          "(" + acc.info().reg_reason + ")"
+    print "\nPress ENTER to quit"
+    sys.stdin.readline()
+
+    lib.destroy()
+    lib = None
+
+except pj.Error, e:
+    print "Exception: " + str(e)
+    lib.destroy()
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/samples/simplecall.py b/jni/libpjsip/sources/pjsip-apps/src/python/samples/simplecall.py
new file mode 100644
index 0000000..40ac28f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/samples/simplecall.py
@@ -0,0 +1,88 @@
+# $Id: simplecall.py 2171 2008-07-24 09:01:33Z bennylp $
+#
+# SIP account and registration sample. In this sample, the program
+# will block to wait until registration is complete
+#
+# Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+#
+# 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 
+#
+import sys
+import pjsua as pj
+
+# Logging callback
+def log_cb(level, str, len):
+    print str,
+
+# Callback to receive events from Call
+class MyCallCallback(pj.CallCallback):
+    def __init__(self, call=None):
+        pj.CallCallback.__init__(self, call)
+
+    # Notification when call state has changed
+    def on_state(self):
+        print "Call is ", self.call.info().state_text,
+        print "last code =", self.call.info().last_code, 
+        print "(" + self.call.info().last_reason + ")"
+        
+    # Notification when call's media state has changed.
+    def on_media_state(self):
+        global lib
+        if self.call.info().media_state == pj.MediaState.ACTIVE:
+            # Connect the call to sound device
+            call_slot = self.call.info().conf_slot
+            lib.conf_connect(call_slot, 0)
+            lib.conf_connect(0, call_slot)
+            print "Hello world, I can talk!"
+
+
+# Check command line argument
+if len(sys.argv) != 2:
+    print "Usage: simplecall.py <dst-URI>"
+    sys.exit(1)
+
+try:
+    # Create library instance
+    lib = pj.Lib()
+
+    # Init library with default config
+    lib.init(log_cfg = pj.LogConfig(level=3, callback=log_cb))
+
+    # Create UDP transport which listens to any available port
+    transport = lib.create_transport(pj.TransportType.UDP)
+    
+    # Start the library
+    lib.start()
+
+    # Create local/user-less account
+    acc = lib.create_account_for_transport(transport)
+
+    # Make call
+    call = acc.make_call(sys.argv[1], MyCallCallback())
+
+    # Wait for ENTER before quitting
+    print "Press <ENTER> to quit"
+    input = sys.stdin.readline().rstrip("\r\n")
+
+    # We're done, shutdown the library
+    lib.destroy()
+    lib = None
+
+except pj.Error, e:
+    print "Exception: " + str(e)
+    lib.destroy()
+    lib = None
+    sys.exit(1)
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/setup-vc.py b/jni/libpjsip/sources/pjsip-apps/src/python/setup-vc.py
new file mode 100644
index 0000000..cab1498
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/setup-vc.py
@@ -0,0 +1,80 @@
+# $Id: setup-vc.py 4122 2012-05-14 11:04:46Z bennylp $
+#
+# pjsua Setup script for Visual Studio
+#
+# Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+#
+# 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
+
+# Find 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 + '"'
+
+
+# Check that extension has been built
+if not os.access('../../lib/_pjsua.pyd', os.R_OK):
+    print 'Error: file "../../lib/_pjsua.pyd" does not exist!'
+    print ''
+    print 'Please build the extension with Visual Studio first'
+    print 'For more info, see http://trac.pjsip.org/repos/wiki/Python_SIP_Tutorial'
+    sys.exit(1)
+
+setup(name="pjsua",
+      version=pj_version,
+      description='SIP User Agent Library based on PJSIP',
+      url='http://trac.pjsip.org/repos/wiki/Python_SIP_Tutorial',
+      data_files=[('lib/site-packages', ['../../lib/_pjsua.pyd'])],
+      py_modules=["pjsua"]
+     )
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/python/setup.py b/jni/libpjsip/sources/pjsip-apps/src/python/setup.py
new file mode 100644
index 0000000..9eaed9d
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/python/setup.py
@@ -0,0 +1,114 @@
+# $Id: setup.py 4232 2012-08-20 06:01:41Z ming $
+#
+# pjsua Setup script.
+#
+# Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+#
+# 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 -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 -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 = []
+f = os.popen("make -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"]
+    version = platform.mac_ver()[0].split(".")    
+    # OS X Lion (10.7.x) or above support
+    if version[0] == '10' and int(version[1]) >= 7:
+        extra_link_args += ["-framework", "AudioUnit"]
+else:
+    extra_link_args = []
+
+
+setup(name="pjsua", 
+      version=pj_version,
+      description='SIP User Agent Library based on PJSIP',
+      url='http://trac.pjsip.org/repos/wiki/Python_SIP_Tutorial',
+      ext_modules = [Extension("_pjsua", 
+                               ["_pjsua.c"], 
+                               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=["pjsua"]
+     )
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/aectest.c b/jni/libpjsip/sources/pjsip-apps/src/samples/aectest.c
new file mode 100644
index 0000000..8991fec
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/aectest.c
@@ -0,0 +1,304 @@
+/* $Id: aectest.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+/**
+ * \page page_pjmedia_samples_aectest_c Samples: AEC Test (aectest.c)
+ *
+ * Play a file to speaker, run AEC, and record the microphone input
+ * to see if echo is coming.
+ *
+ * This file is pjsip-apps/src/samples/aectest.c
+ *
+ * \includelineno aectest.c
+ */
+#include <pjmedia.h>
+#include <pjlib-util.h>	/* pj_getopt */
+#include <pjlib.h>
+
+#define THIS_FILE   "aectest.c"
+#define PTIME	    20
+#define TAIL_LENGTH 200
+
+static const char *desc = 
+" FILE		    						    \n"
+"		    						    \n"
+"  aectest.c	    						    \n"
+"		    						    \n"
+" PURPOSE	    						    \n"
+"		    						    \n"
+"  Test the AEC effectiveness.					    \n"
+"		    						    \n"
+" USAGE		    						    \n"
+"		    						    \n"
+"  aectest [options] <PLAY.WAV> <REC.WAV> <OUTPUT.WAV>		    \n"
+"		    						    \n"
+"  <PLAY.WAV>   is the signal played to the speaker.		    \n"
+"  <REC.WAV>    is the signal captured from the microphone.	    \n"
+"  <OUTPUT.WAV> is the output file to store the test result	    \n"
+"\n"
+" options:\n"
+"  -d  The delay between playback and capture in ms, at least 25 ms.\n"
+"      Default is 25 ms. See note below.                            \n"
+"  -l  Set the echo tail length in ms. Default is 200 ms	    \n"
+"  -r  Set repeat count (default=1)                                 \n"
+"  -a  Algorithm: 0=default, 1=speex, 3=echo suppress		    \n"
+"  -i  Interactive						    \n"
+"\n"
+" Note that for the AEC internal buffering mechanism, it is required\n"
+" that the echoed signal (in REC.WAV) is delayed from the           \n"
+" corresponding reference signal (in PLAY.WAV) at least as much as  \n"
+" frame time + PJMEDIA_WSOLA_DELAY_MSEC. In this application, frame \n"
+" time is 20 ms and default PJMEDIA_WSOLA_DELAY_MSEC is 5 ms, hence \n"
+" 25 ms delay is the minimum value.                                 \n";
+
+/* 
+ * Sample session:
+ *
+ * -d 100 -a 1 ../bin/orig8.wav ../bin/echo8.wav ../bin/result8.wav 
+ */
+
+static void app_perror(const char *sender, const char *title, pj_status_t st)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(st, errmsg, sizeof(errmsg));
+    PJ_LOG(3,(sender, "%s: %s", title, errmsg));
+}
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t	  *pool;
+    pjmedia_port  *wav_play;
+    pjmedia_port  *wav_rec;
+    pjmedia_port  *wav_out;
+    pj_status_t status;
+    pjmedia_echo_state *ec;
+    pjmedia_frame play_frame, rec_frame;
+    unsigned opt = 0;
+    unsigned latency_ms = 25;
+    unsigned tail_ms = TAIL_LENGTH;
+    pj_timestamp t0, t1;
+    int i, repeat=1, interactive=0, c;
+
+    pj_optind = 0;
+    while ((c=pj_getopt(argc, argv, "d:l:a:r:i")) !=-1) {
+	switch (c) {
+	case 'd':
+	    latency_ms = atoi(pj_optarg);
+	    if (latency_ms < 25) {
+		puts("Invalid delay");
+		puts(desc);
+	    }
+	    break;
+	case 'l':
+	    tail_ms = atoi(pj_optarg);
+	    break;
+	case 'a':
+	    {
+		int alg = atoi(pj_optarg);
+		switch (alg) {
+		case 0:
+		    opt = 0;
+		case 1:
+		    opt = PJMEDIA_ECHO_SPEEX;
+		    break;
+		case 3:
+		    opt = PJMEDIA_ECHO_SIMPLE;
+		    break;
+		default:
+		    puts("Invalid algorithm");
+		    puts(desc);
+		    return 1;
+		}
+	    }
+	    break;
+	case 'r':
+	    repeat = atoi(pj_optarg);
+	    if (repeat < 1) {
+		puts("Invalid repeat count");
+		puts(desc);
+		return 1;
+	    }
+	    break;
+	case 'i':
+	    interactive = 1;
+	    break;
+	}
+    }
+
+    if (argc - pj_optind != 3) {
+	puts("Error: missing argument(s)");
+	puts(desc);
+	return 1;
+    }
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "wav",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    /* Open wav_play */
+    status = pjmedia_wav_player_port_create(pool, argv[pj_optind], PTIME, 
+					    PJMEDIA_FILE_NO_LOOP, 0, 
+					    &wav_play);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error opening playback WAV file", status);
+	return 1;
+    }
+    
+    /* Open recorded wav */
+    status = pjmedia_wav_player_port_create(pool, argv[pj_optind+1], PTIME, 
+					    PJMEDIA_FILE_NO_LOOP, 0, 
+					    &wav_rec);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error opening recorded WAV file", status);
+	return 1;
+    }
+
+    /* play and rec WAVs must have the same clock rate */
+    if (PJMEDIA_PIA_SRATE(&wav_play->info) != PJMEDIA_PIA_SRATE(&wav_rec->info)) {
+	puts("Error: clock rate mismatch in the WAV files");
+	return 1;
+    }
+
+    /* .. and channel count */
+    if (PJMEDIA_PIA_CCNT(&wav_play->info) != PJMEDIA_PIA_CCNT(&wav_rec->info)) {
+	puts("Error: clock rate mismatch in the WAV files");
+	return 1;
+    }
+
+    /* Create output wav */
+    status = pjmedia_wav_writer_port_create(pool, argv[pj_optind+2],
+					    PJMEDIA_PIA_SRATE(&wav_play->info),
+					    PJMEDIA_PIA_CCNT(&wav_play->info),
+					    PJMEDIA_PIA_SPF(&wav_play->info),
+					    PJMEDIA_PIA_BITS(&wav_play->info),
+					    0, 0, &wav_out);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error opening output WAV file", status);
+	return 1;
+    }
+
+    /* Create echo canceller */
+    status = pjmedia_echo_create2(pool, PJMEDIA_PIA_SRATE(&wav_play->info),
+				  PJMEDIA_PIA_CCNT(&wav_play->info),
+				  PJMEDIA_PIA_SPF(&wav_play->info),
+				  tail_ms, latency_ms,
+				  opt, &ec);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error creating EC", status);
+	return 1;
+    }
+
+
+    /* Processing loop */
+    play_frame.buf = pj_pool_alloc(pool, PJMEDIA_PIA_SPF(&wav_play->info)<<1);
+    rec_frame.buf = pj_pool_alloc(pool, PJMEDIA_PIA_SPF(&wav_play->info)<<1);
+    pj_get_timestamp(&t0);
+    for (i=0; i < repeat; ++i) {
+	for (;;) {
+	    play_frame.size = PJMEDIA_PIA_SPF(&wav_play->info) << 1;
+	    status = pjmedia_port_get_frame(wav_play, &play_frame);
+	    if (status != PJ_SUCCESS)
+		break;
+
+	    status = pjmedia_echo_playback(ec, (short*)play_frame.buf);
+
+	    rec_frame.size = PJMEDIA_PIA_SPF(&wav_play->info) << 1;
+	    status = pjmedia_port_get_frame(wav_rec, &rec_frame);
+	    if (status != PJ_SUCCESS)
+		break;
+
+	    status = pjmedia_echo_capture(ec, (short*)rec_frame.buf, 0);
+
+	    //status = pjmedia_echo_cancel(ec, (short*)rec_frame.buf, 
+	    //			     (short*)play_frame.buf, 0, NULL);
+
+	    pjmedia_port_put_frame(wav_out, &rec_frame);
+	}
+
+	pjmedia_wav_player_port_set_pos(wav_play, 0);
+	pjmedia_wav_player_port_set_pos(wav_rec, 0);
+    }
+    pj_get_timestamp(&t1);
+
+    i = (int)pjmedia_wav_writer_port_get_pos(wav_out) / sizeof(pj_int16_t) * 1000 / 
+	 (PJMEDIA_PIA_SRATE(&wav_out->info) * PJMEDIA_PIA_CCNT(&wav_out->info));
+    PJ_LOG(3,(THIS_FILE, "Processed %3d.%03ds audio",
+	      i / 1000, i % 1000));
+    PJ_LOG(3,(THIS_FILE, "Completed in %u msec\n", pj_elapsed_msec(&t0, &t1)));
+
+    /* Destroy file port(s) */
+    status = pjmedia_port_destroy( wav_play );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    status = pjmedia_port_destroy( wav_rec );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    status = pjmedia_port_destroy( wav_out );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Destroy ec */
+    pjmedia_echo_destroy(ec);
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+    if (interactive) {
+	char s[10], *dummy;
+	puts("ENTER to quit");
+	dummy = fgets(s, sizeof(s), stdin);
+    }
+
+    /* Done. */
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/auddemo.c b/jni/libpjsip/sources/pjsip-apps/src/samples/auddemo.c
new file mode 100644
index 0000000..c4e3562
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/auddemo.c
@@ -0,0 +1,582 @@
+/* $Id: auddemo.c 3664 2011-07-19 03:42:28Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 <pjmedia-audiodev/audiodev.h>
+#include <pjmedia-audiodev/audiotest.h>
+#include <pjmedia.h>
+#include <pjlib.h>
+#include <pjlib-util.h>
+
+#define THIS_FILE	"auddemo.c"
+#define MAX_DEVICES	64
+#define WAV_FILE	"auddemo.wav"
+
+
+static unsigned dev_count;
+static unsigned playback_lat = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;
+static unsigned capture_lat = PJMEDIA_SND_DEFAULT_REC_LATENCY;
+
+static void app_perror(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));	
+    printf( "%s: %s (err=%d)\n",
+	    title, errmsg, status);
+}
+
+static void list_devices(void)
+{
+    unsigned i;
+    pj_status_t status;
+    
+    dev_count = pjmedia_aud_dev_count();
+    if (dev_count == 0) {
+	PJ_LOG(3,(THIS_FILE, "No devices found"));
+	return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Found %d devices:", dev_count));
+
+    for (i=0; i<dev_count; ++i) {
+	pjmedia_aud_dev_info info;
+
+	status = pjmedia_aud_dev_get_info(i, &info);
+	if (status != PJ_SUCCESS)
+	    continue;
+
+	PJ_LOG(3,(THIS_FILE," %2d: %s [%s] (%d/%d)",
+	          i, info.driver, info.name, info.input_count, info.output_count));
+    }
+}
+
+static const char *decode_caps(unsigned caps)
+{
+    static char text[200];
+    unsigned i;
+
+    text[0] = '\0';
+
+    for (i=0; i<31; ++i) {
+	if ((1 << i) & caps) {
+	    const char *capname;
+	    capname = pjmedia_aud_dev_cap_name((pjmedia_aud_dev_cap)(1 << i), 
+					       NULL);
+	    strcat(text, capname);
+	    strcat(text, " ");
+	}
+    }
+
+    return text;
+}
+
+static void show_dev_info(unsigned index)
+{
+#define H   "%-20s"
+    pjmedia_aud_dev_info info;
+    char formats[200];
+    pj_status_t status;
+
+    if (index >= dev_count) {
+	PJ_LOG(1,(THIS_FILE, "Error: invalid index %u", index));
+	return;
+    }
+
+    status = pjmedia_aud_dev_get_info(index, &info);
+    if (status != PJ_SUCCESS) {
+	app_perror("pjmedia_aud_dev_get_info() error", status);
+	return;
+    }
+
+    PJ_LOG(3, (THIS_FILE, "Device at index %u:", index));
+    PJ_LOG(3, (THIS_FILE, "-------------------------"));
+
+    PJ_LOG(3, (THIS_FILE, H": %u (0x%x)", "ID", index, index));
+    PJ_LOG(3, (THIS_FILE, H": %s", "Name", info.name));
+    PJ_LOG(3, (THIS_FILE, H": %s", "Driver", info.driver));
+    PJ_LOG(3, (THIS_FILE, H": %u", "Input channels", info.input_count));
+    PJ_LOG(3, (THIS_FILE, H": %u", "Output channels", info.output_count));
+    PJ_LOG(3, (THIS_FILE, H": %s", "Capabilities", decode_caps(info.caps)));
+
+    formats[0] = '\0';
+    if (info.caps & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) {
+	unsigned i;
+
+	for (i=0; i<info.ext_fmt_cnt; ++i) {
+	    char bitrate[32];
+
+	    switch (info.ext_fmt[i].id) {
+	    case PJMEDIA_FORMAT_L16:
+		strcat(formats, "L16/");
+		break;
+	    case PJMEDIA_FORMAT_PCMA:
+		strcat(formats, "PCMA/");
+		break;
+	    case PJMEDIA_FORMAT_PCMU:
+		strcat(formats, "PCMU/");
+		break;
+	    case PJMEDIA_FORMAT_AMR:
+		strcat(formats, "AMR/");
+		break;
+	    case PJMEDIA_FORMAT_G729:
+		strcat(formats, "G729/");
+		break;
+	    case PJMEDIA_FORMAT_ILBC:
+		strcat(formats, "ILBC/");
+		break;
+	    default:
+		strcat(formats, "unknown/");
+		break;
+	    }
+	    sprintf(bitrate, "%u", info.ext_fmt[i].det.aud.avg_bps);
+	    strcat(formats, bitrate);
+	    strcat(formats, " ");
+	}
+    }
+    PJ_LOG(3, (THIS_FILE, H": %s", "Extended formats", formats));
+
+#undef H
+}
+
+static void test_device(pjmedia_dir dir, unsigned rec_id, unsigned play_id, 
+			unsigned clock_rate, unsigned ptime, 
+			unsigned chnum)
+{
+    pjmedia_aud_param param;
+    pjmedia_aud_test_results result;
+    pj_status_t status;
+
+    if (dir & PJMEDIA_DIR_CAPTURE) {
+	status = pjmedia_aud_dev_default_param(rec_id, &param);
+    } else {
+	status = pjmedia_aud_dev_default_param(play_id, &param);
+    }
+
+    if (status != PJ_SUCCESS) {
+	app_perror("pjmedia_aud_dev_default_param()", status);
+	return;
+    }
+
+    param.dir = dir;
+    param.rec_id = rec_id;
+    param.play_id = play_id;
+    param.clock_rate = clock_rate;
+    param.channel_count = chnum;
+    param.samples_per_frame = clock_rate * chnum * ptime / 1000;
+
+    /* Latency settings */
+    param.flags |= (PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY | 
+		    PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY);
+    param.input_latency_ms = capture_lat;
+    param.output_latency_ms = playback_lat;
+
+    PJ_LOG(3,(THIS_FILE, "Performing test.."));
+
+    status = pjmedia_aud_test(&param, &result);
+    if (status != PJ_SUCCESS) {
+	app_perror("Test has completed with error", status);
+	return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Done. Result:"));
+
+    if (dir & PJMEDIA_DIR_CAPTURE) {
+	if (result.rec.frame_cnt==0) {
+	    PJ_LOG(1,(THIS_FILE, "Error: no frames captured!"));
+	} else {
+	    PJ_LOG(3,(THIS_FILE, "  %-20s: interval (min/max/avg/dev)=%u/%u/%u/%u, burst=%u",
+		      "Recording result",
+		      result.rec.min_interval,
+		      result.rec.max_interval,
+		      result.rec.avg_interval,
+		      result.rec.dev_interval,
+		      result.rec.max_burst));
+	}
+    }
+
+    if (dir & PJMEDIA_DIR_PLAYBACK) {
+	if (result.play.frame_cnt==0) {
+	    PJ_LOG(1,(THIS_FILE, "Error: no playback!"));
+	} else {
+	    PJ_LOG(3,(THIS_FILE, "  %-20s: interval (min/max/avg/dev)=%u/%u/%u/%u, burst=%u",
+		      "Playback result",
+		      result.play.min_interval,
+		      result.play.max_interval,
+		      result.play.avg_interval,
+		      result.play.dev_interval,
+		      result.play.max_burst));
+	}
+    }
+
+    if (dir==PJMEDIA_DIR_CAPTURE_PLAYBACK) {
+	if (result.rec_drift_per_sec == 0) {
+	    PJ_LOG(3,(THIS_FILE, " No clock drift detected"));
+	} else {
+	    const char *which = result.rec_drift_per_sec>=0 ? "faster" : "slower";
+	    unsigned drift = result.rec_drift_per_sec>=0 ? 
+				result.rec_drift_per_sec :
+				-result.rec_drift_per_sec;
+
+	    PJ_LOG(3,(THIS_FILE, " Clock drifts detected. Capture device "
+				 "is running %d samples per second %s "
+				 "than the playback device",
+				 drift, which));
+	}
+    }
+}
+
+
+static pj_status_t wav_rec_cb(void *user_data, pjmedia_frame *frame)
+{
+    return pjmedia_port_put_frame((pjmedia_port*)user_data, frame);
+}
+
+static void record(unsigned rec_index, const char *filename)
+{
+    pj_pool_t *pool = NULL;
+    pjmedia_port *wav = NULL;
+    pjmedia_aud_param param;
+    pjmedia_aud_stream *strm = NULL;
+    char line[10], *dummy;
+    pj_status_t status;
+
+    if (filename == NULL)
+	filename = WAV_FILE;
+
+    pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(), "wav",
+			  1000, 1000, NULL);
+
+    status = pjmedia_wav_writer_port_create(pool, filename, 16000, 
+					    1, 320, 16, 0, 0, &wav);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error creating WAV file", status);
+	goto on_return;
+    }
+
+    status = pjmedia_aud_dev_default_param(rec_index, &param);
+    if (status != PJ_SUCCESS) {
+	app_perror("pjmedia_aud_dev_default_param()", status);
+	goto on_return;
+    }
+
+    param.dir = PJMEDIA_DIR_CAPTURE;
+    param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
+    param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
+    param.channel_count = PJMEDIA_PIA_CCNT(&wav->info);
+    param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info);
+
+    status = pjmedia_aud_stream_create(&param, &wav_rec_cb, NULL, wav,
+				       &strm);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error opening the sound device", status);
+	goto on_return;
+    }
+
+    status = pjmedia_aud_stream_start(strm);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error starting the sound device", status);
+	goto on_return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Recording started, press ENTER to stop"));
+    dummy = fgets(line, sizeof(line), stdin);
+
+on_return:
+    if (strm) {
+	pjmedia_aud_stream_stop(strm);
+	pjmedia_aud_stream_destroy(strm);
+    }
+    if (wav)
+	pjmedia_port_destroy(wav);
+    if (pool)
+	pj_pool_release(pool);
+}
+
+
+static pj_status_t wav_play_cb(void *user_data, pjmedia_frame *frame)
+{
+    return pjmedia_port_get_frame((pjmedia_port*)user_data, frame);
+}
+
+
+static void play_file(unsigned play_index, const char *filename)
+{
+    pj_pool_t *pool = NULL;
+    pjmedia_port *wav = NULL;
+    pjmedia_aud_param param;
+    pjmedia_aud_stream *strm = NULL;
+    char line[10], *dummy;
+    pj_status_t status;
+
+    if (filename == NULL)
+	filename = WAV_FILE;
+
+    pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(), "wav",
+			  1000, 1000, NULL);
+
+    status = pjmedia_wav_player_port_create(pool, filename, 20, 0, 0, &wav);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error opening WAV file", status);
+	goto on_return;
+    }
+
+    status = pjmedia_aud_dev_default_param(play_index, &param);
+    if (status != PJ_SUCCESS) {
+	app_perror("pjmedia_aud_dev_default_param()", status);
+	goto on_return;
+    }
+
+    param.dir = PJMEDIA_DIR_PLAYBACK;
+    param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
+    param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
+    param.channel_count = PJMEDIA_PIA_CCNT(&wav->info);
+    param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info);
+
+    status = pjmedia_aud_stream_create(&param, NULL, &wav_play_cb, wav,
+				       &strm);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error opening the sound device", status);
+	goto on_return;
+    }
+
+    status = pjmedia_aud_stream_start(strm);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error starting the sound device", status);
+	goto on_return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Playback started, press ENTER to stop"));
+    dummy = fgets(line, sizeof(line), stdin);
+
+on_return:
+    if (strm) {
+	pjmedia_aud_stream_stop(strm);
+	pjmedia_aud_stream_destroy(strm);
+    }
+    if (wav)
+	pjmedia_port_destroy(wav);
+    if (pool)
+	pj_pool_release(pool);
+}
+
+
+static void print_menu(void)
+{
+    puts("");
+    puts("Audio demo menu:");
+    puts("-------------------------------");
+    puts("  l                        List devices");
+    puts("  R                        Refresh devices");
+    puts("  i ID                     Show device info for device ID");
+    puts("  t RID PID CR PTIM [CH]   Perform test on the device:");
+    puts("                             RID:  record device ID (-1 for no)");
+    puts("                             PID:  playback device ID (-1 for no)");
+    puts("                             CR:   clock rate");
+    puts("                             PTIM: ptime in ms");
+    puts("                             CH:   # of channels");
+    puts("  r RID [FILE]             Record capture device RID to WAV file");
+    puts("  p PID [FILE]             Playback WAV file to device ID PID");
+    puts("  d [RLAT PLAT]            Get/set sound device latencies (in ms):");
+    puts("                             Specify no param to get current latencies setting");
+    puts("                             RLAT: record latency (-1 for default)");
+    puts("                             PLAT: playback latency (-1 for default)");
+    puts("  v                        Toggle log verbosity");
+    puts("  q                        Quit");
+    puts("");
+    printf("Enter selection: ");
+    fflush(stdout);
+}
+
+int main()
+{
+    pj_caching_pool cp;
+    pj_bool_t done = PJ_FALSE;
+    pj_status_t status;
+
+    /* Init pjlib */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status==PJ_SUCCESS, 1);
+    
+    pj_log_set_decor(PJ_LOG_HAS_NEWLINE);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    status = pjmedia_aud_subsys_init(&cp.factory);
+    if (status != PJ_SUCCESS) {
+	app_perror("pjmedia_aud_subsys_init()", status);
+	pj_caching_pool_destroy(&cp);
+	pj_shutdown();
+	return 1;
+    }
+
+    list_devices();
+
+    while (!done) {
+	char line[80];
+
+	print_menu();
+
+	if (fgets(line, sizeof(line), stdin)==NULL)
+	    break;
+
+	switch (line[0]) {
+	case 'l':
+	    list_devices();
+	    break;
+
+	case 'R':
+	    pjmedia_aud_dev_refresh();
+	    puts("Audio device list refreshed.");
+	    break;
+
+	case 'i':
+	    {
+		unsigned dev_index;
+		if (sscanf(line+2, "%u", &dev_index) != 1) {
+		    puts("error: device ID required");
+		    break;
+		}
+		show_dev_info(dev_index);
+	    }
+	    break;
+
+	case 't':
+	    {
+		pjmedia_dir dir;
+		int rec_id, play_id;
+		unsigned clock_rate, ptime, chnum;
+		int cnt;
+
+		cnt = sscanf(line+2, "%d %d %u %u %u", &rec_id, &play_id, 
+			     &clock_rate, &ptime, &chnum);
+		if (cnt < 4) {
+		    puts("error: not enough parameters");
+		    break;
+		}
+		if (clock_rate < 8000 || clock_rate > 128000) {
+		    puts("error: invalid clock rate");
+		    break;
+		}
+		if (ptime < 10 || ptime > 500) {
+		    puts("error: invalid ptime");
+		    break;
+		}
+		if (cnt==5) {
+		    if (chnum < 1 || chnum > 4) {
+			puts("error: invalid number of channels");
+			break;
+		    }
+		} else {
+		    chnum = 1;
+		}
+
+		if (rec_id >= 0 && rec_id < (int)dev_count) {
+		    if (play_id >= 0 && play_id < (int)dev_count)
+			dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
+		    else
+			dir = PJMEDIA_DIR_CAPTURE;
+		} else if (play_id >= 0 && play_id < (int)dev_count) {
+		    dir = PJMEDIA_DIR_PLAYBACK;
+		} else {
+		    puts("error: at least one valid device index required");
+		    break;
+		}
+
+		test_device(dir, rec_id, play_id, clock_rate, ptime, chnum);
+		
+	    }
+	    break;
+
+	case 'r':
+	    /* record */
+	    {
+		int index;
+		char filename[80];
+		int count;
+
+		count = sscanf(line+2, "%d %s", &index, filename);
+		if (count==1)
+		    record(index, NULL);
+		else if (count==2)
+		    record(index, filename);
+		else
+		    puts("error: invalid command syntax");
+	    }
+	    break;
+
+	case 'p':
+	    /* playback */
+	    {
+		int index;
+		char filename[80];
+		int count;
+
+		count = sscanf(line+2, "%d %s", &index, filename);
+		if (count==1)
+		    play_file(index, NULL);
+		else if (count==2)
+		    play_file(index, filename);
+		else
+		    puts("error: invalid command syntax");
+	    }
+	    break;
+
+	case 'd':
+	    /* latencies */
+	    {
+		int rec_lat, play_lat;
+
+		if (sscanf(line+2, "%d %d", &rec_lat, &play_lat) == 2) {
+		    capture_lat = (unsigned) 
+			 (rec_lat>=0? rec_lat:PJMEDIA_SND_DEFAULT_REC_LATENCY);
+		    playback_lat = (unsigned)
+			 (play_lat >= 0? play_lat : PJMEDIA_SND_DEFAULT_PLAY_LATENCY);
+		    printf("Recording latency=%ums, playback latency=%ums",
+			   capture_lat, playback_lat);
+		} else {
+		    printf("Current latencies: record=%ums, playback=%ums",
+			   capture_lat, playback_lat);
+		}
+		puts("");
+	    }
+	    break;
+
+	case 'v':
+	    if (pj_log_get_level() <= 3) {
+		pj_log_set_level(5);
+		puts("Logging set to detail");
+	    } else {
+		pj_log_set_level(3);
+		puts("Logging set to quiet");
+	    }
+	    break;
+
+	case 'q':
+	    done = PJ_TRUE;
+	    break;
+	}
+    }
+
+    pj_caching_pool_destroy(&cp);
+    pj_shutdown();
+    return 0;
+}
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/aviplay.c b/jni/libpjsip/sources/pjsip-apps/src/samples/aviplay.c
new file mode 100644
index 0000000..018a308
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/aviplay.c
@@ -0,0 +1,560 @@
+/* $Id: aviplay.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2010-2011 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 <pjmedia.h>
+#include <pjmedia/converter.h>
+#include <pjmedia-codec.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+/**
+ * \page page_pjmedia_samples_aviplay_c Samples: Playing AVI File to
+ * Video and Sound Devices
+ *
+ * This is a very simple example to use the @ref PJMEDIA_FILE_PLAY,
+ * @ref PJMED_SND_PORT, and @ref PJMEDIA_VID_PORT. In this example, we
+ * open the file, video, and sound devices, then connect the file to both
+ * video and sound devices to play the contents of the file.
+ *
+ *
+ * This file is pjsip-apps/src/samples/aviplay.c
+ *
+ * \includelineno aviplay.c
+ */
+
+
+/*
+ * aviplay.c
+ *
+ * PURPOSE:
+ *  Play a AVI file to video and sound devices.
+ *
+ * USAGE:
+ *  aviplay FILE.AVI
+ */
+
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+
+
+/* For logging purpose. */
+#define THIS_FILE   "aviplay.c"
+
+static const char *desc = 
+" FILE		    						    \n"
+"		    						    \n"
+"  aviplay.c	    						    \n"
+"		    						    \n"
+" PURPOSE	    						    \n"
+"		    						    \n"
+"  Demonstrate how to play a AVI file.				    \n"
+"		    						    \n"
+" USAGE		    						    \n"
+"		    						    \n"
+"  aviplay FILE.AVI						    \n";
+
+struct codec_fmt {
+    pj_uint32_t         pjmedia_id;
+    const char         *codec_id;
+    /* Do we need to convert the decoded frame? */
+    pj_bool_t           need_conversion;
+    /* If conversion is needed, dst_fmt indicates the destination format */
+    pjmedia_format_id   dst_fmt;
+} codec_fmts[] = {{PJMEDIA_FORMAT_MJPEG, "mjpeg",
+                   PJ_TRUE , PJMEDIA_FORMAT_I420},
+                  {PJMEDIA_FORMAT_H263 , "h263" ,
+                   PJ_FALSE, 0},
+                  {PJMEDIA_FORMAT_MPEG4, "mp4v"}, 
+                  {PJMEDIA_FORMAT_H264 , "h264"}
+                 };
+
+typedef struct avi_port_t
+{
+    pjmedia_vid_port   *vid_port;
+    pjmedia_snd_port   *snd_port;
+    pj_bool_t           is_running;
+    pj_bool_t           is_quitting;
+} avi_port_t;
+
+typedef struct codec_port_data_t
+{
+    pjmedia_vid_codec   *codec;
+    pjmedia_port        *src_port;
+    pj_uint8_t          *enc_buf;
+    pj_size_t            enc_buf_size;
+    
+    pjmedia_converter   *conv;
+} codec_port_data_t;
+
+static pj_status_t avi_event_cb(pjmedia_event *event,
+                                void *user_data)
+{
+    avi_port_t *ap = (avi_port_t *)user_data;
+    
+    switch (event->type) {
+    case PJMEDIA_EVENT_WND_CLOSED:
+        ap->is_quitting = PJ_TRUE;
+        break;
+    case PJMEDIA_EVENT_MOUSE_BTN_DOWN:
+        if (ap->is_running) {
+            pjmedia_vid_port_stop(ap->vid_port);
+            if (ap->snd_port)
+                pjmedia_aud_stream_stop(
+                    pjmedia_snd_port_get_snd_stream(ap->snd_port));
+        } else {
+            pjmedia_vid_port_start(ap->vid_port);
+            if (ap->snd_port)
+                pjmedia_aud_stream_start(
+                    pjmedia_snd_port_get_snd_stream(ap->snd_port));
+        }
+        ap->is_running = !ap->is_running;
+        break;
+    default:
+        return PJ_SUCCESS;
+    }
+    
+    /* We handled the event on our own, so return non-PJ_SUCCESS here */
+    return -1;
+}
+
+static pj_status_t codec_get_frame(pjmedia_port *port,
+			           pjmedia_frame *frame)
+{
+    codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata;
+    pjmedia_vid_codec *codec = port_data->codec;
+    pjmedia_frame enc_frame;
+    pj_status_t status;
+    
+    enc_frame.buf = port_data->enc_buf;
+    enc_frame.size = port_data->enc_buf_size;
+    
+    if (port_data->conv) {
+        pj_size_t frame_size = frame->size;
+	
+        status = pjmedia_port_get_frame(port_data->src_port, frame);
+        if (status != PJ_SUCCESS) goto on_error;
+	
+        status = pjmedia_vid_codec_decode(codec, 1, frame,
+                                          (unsigned)frame->size, &enc_frame);
+        if (status != PJ_SUCCESS) goto on_error;
+	
+        frame->size = frame_size;
+        status = pjmedia_converter_convert(port_data->conv, &enc_frame, frame);
+        if (status != PJ_SUCCESS) goto on_error;
+	
+        return PJ_SUCCESS;
+    }
+    
+    status = pjmedia_port_get_frame(port_data->src_port, &enc_frame);
+    if (status != PJ_SUCCESS) goto on_error;
+    
+    status = pjmedia_vid_codec_decode(codec, 1, &enc_frame,
+                                      (unsigned)frame->size, frame);
+    if (status != PJ_SUCCESS) goto on_error;
+    
+    return PJ_SUCCESS;
+    
+on_error:
+    pj_perror(3, THIS_FILE, status, "codec_get_frame() error");
+    return status;
+}
+
+static int aviplay(pj_pool_t *pool, const char *fname)
+{
+    pjmedia_vid_port *renderer=NULL;
+    pjmedia_vid_port_param param;
+    const pjmedia_video_format_info *vfi;
+    pjmedia_video_format_detail *vfd;
+    pjmedia_snd_port *snd_port = NULL;
+    pj_status_t status;
+    int rc = 0;
+    pjmedia_avi_streams *avi_streams;
+    pjmedia_avi_stream *vid_stream, *aud_stream;
+    pjmedia_port *vid_port = NULL, *aud_port = NULL;
+    pjmedia_vid_codec *codec=NULL;
+    avi_port_t avi_port;
+    
+    pj_bzero(&avi_port, sizeof(avi_port));
+    
+    status = pjmedia_avi_player_create_streams(pool, fname, 0, &avi_streams);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(2,("", status, "    Error playing %s", fname));
+	rc = 210; goto on_return;
+    }
+    
+    vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
+                                                         0,
+                                                         PJMEDIA_TYPE_VIDEO);
+    vid_port = pjmedia_avi_stream_get_port(vid_stream);
+    
+    if (vid_port) {
+        pjmedia_vid_port_param_default(&param);
+	
+        status = pjmedia_vid_dev_default_param(pool,
+                                               PJMEDIA_VID_DEFAULT_RENDER_DEV,
+                                               &param.vidparam);
+        if (status != PJ_SUCCESS) {
+    	    rc = 220; goto on_return;
+        }
+	
+        /* Create renderer, set it to active  */
+        param.active = PJ_TRUE;
+        param.vidparam.dir = PJMEDIA_DIR_RENDER;
+        vfd = pjmedia_format_get_video_format_detail(&vid_port->info.fmt,
+                                                     PJ_TRUE);
+        pjmedia_format_init_video(&param.vidparam.fmt, 
+                                  vid_port->info.fmt.id,
+                                  vfd->size.w, vfd->size.h,
+                                  vfd->fps.num, vfd->fps.denum);
+	
+        vfi = pjmedia_get_video_format_info(
+                  pjmedia_video_format_mgr_instance(),
+                  vid_port->info.fmt.id);
+        /* Check whether the frame is encoded */
+        if (!vfi || vfi->bpp == 0) {
+            /* Yes, prepare codec */
+            pj_str_t codec_id_st;
+            unsigned info_cnt = 1, i, k;
+            const pjmedia_vid_codec_info *codec_info;
+            pj_str_t port_name = {"codec", 5};
+            pj_uint8_t *enc_buf = NULL;
+            pj_size_t enc_buf_size = 0;
+            pjmedia_vid_dev_info rdr_info;
+            pjmedia_port codec_port;
+            codec_port_data_t codec_port_data;
+            pjmedia_vid_codec_param codec_param;
+            struct codec_fmt *codecp = NULL;
+	    
+            /* Lookup codec */
+            for (i = 0; i < sizeof(codec_fmts)/sizeof(codec_fmts[0]); i++) {
+                if (vid_port->info.fmt.id == codec_fmts[i].pjmedia_id) {
+                    codecp = &codec_fmts[i];
+                    break;
+                }
+            }
+            if (!codecp) {
+                rc = 242; goto on_return;
+            }
+            pj_cstr(&codec_id_st, codecp->codec_id);
+            status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
+                                                             &codec_id_st, 
+                                                             &info_cnt, 
+                                                             &codec_info,
+                                                             NULL);
+            if (status != PJ_SUCCESS) {
+                rc = 245; goto on_return;
+            }
+            status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
+                                                             &codec_param);
+            if (status != PJ_SUCCESS) {
+                rc = 246; goto on_return;
+            }
+	    
+            pjmedia_format_copy(&codec_param.enc_fmt, &param.vidparam.fmt);
+
+            pjmedia_vid_dev_get_info(param.vidparam.rend_id, &rdr_info);
+            for (i=0; i<codec_info->dec_fmt_id_cnt; ++i) {
+                for (k=0; k<rdr_info.fmt_cnt; ++k) {
+                    if (codec_info->dec_fmt_id[i]==(int)rdr_info.fmt[k].id)
+                    {
+                        param.vidparam.fmt.id = codec_info->dec_fmt_id[i];
+                        i = codec_info->dec_fmt_id_cnt;
+                        break;
+                    }
+                }
+            }
+	    
+            /* Open codec */
+            status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
+                                                       &codec);
+            if (status != PJ_SUCCESS) {
+                rc = 250; goto on_return;
+            }
+	    
+            status = pjmedia_vid_codec_init(codec, pool);
+            if (status != PJ_SUCCESS) {
+                rc = 251; goto on_return;
+            }
+	    
+            pjmedia_format_copy(&codec_param.dec_fmt, &param.vidparam.fmt);
+            codec_param.dir = PJMEDIA_DIR_DECODING;
+            codec_param.packing = PJMEDIA_VID_PACKING_WHOLE;
+            status = pjmedia_vid_codec_open(codec, &codec_param);
+            if (status != PJ_SUCCESS) {
+                rc = 252; goto on_return;
+            }
+	    
+            /* Alloc encoding buffer */
+            enc_buf_size =  codec_param.dec_fmt.det.vid.size.w *
+	    codec_param.dec_fmt.det.vid.size.h * 4
+	    + 16; /*< padding, just in case */
+            enc_buf = pj_pool_alloc(pool,enc_buf_size);
+	    
+            /* Init codec port */
+            pj_bzero(&codec_port, sizeof(codec_port));
+            status = pjmedia_port_info_init2(&codec_port.info, &port_name,
+                                             0x1234,
+                                             PJMEDIA_DIR_ENCODING, 
+                                             &codec_param.dec_fmt);
+            if (status != PJ_SUCCESS) {
+                rc = 260; goto on_return;
+            }
+            pj_bzero(&codec_port_data, sizeof(codec_port_data));
+            codec_port_data.codec = codec;
+            codec_port_data.src_port = vid_port;
+            codec_port_data.enc_buf = enc_buf;
+            codec_port_data.enc_buf_size = enc_buf_size;
+	    
+            codec_port.get_frame = &codec_get_frame;
+            codec_port.port_data.pdata = &codec_port_data;
+	    
+            /* Check whether we need to convert the decoded frame */
+            if (codecp->need_conversion) {
+                pjmedia_conversion_param conv_param;
+		
+                pjmedia_format_copy(&conv_param.src, &param.vidparam.fmt);
+                pjmedia_format_copy(&conv_param.dst, &param.vidparam.fmt);
+                conv_param.dst.id = codecp->dst_fmt;
+                param.vidparam.fmt.id = conv_param.dst.id;
+		
+                status = pjmedia_converter_create(NULL, pool, &conv_param,
+                                                  &codec_port_data.conv);
+                if (status != PJ_SUCCESS) {
+                    rc = 270; goto on_return;
+                }
+            }
+	    
+            status = pjmedia_vid_port_create(pool, &param, &renderer);
+            if (status != PJ_SUCCESS) {
+                rc = 230; goto on_return;
+            }
+	    
+            status = pjmedia_vid_port_connect(renderer, &codec_port,
+                                              PJ_FALSE);
+        } else {
+            status = pjmedia_vid_port_create(pool, &param, &renderer);
+            if (status != PJ_SUCCESS) {
+                rc = 230; goto on_return;
+            }
+	    
+            /* Connect avi port to renderer */
+            status = pjmedia_vid_port_connect(renderer, vid_port,
+                                              PJ_FALSE);
+        }
+	
+        if (status != PJ_SUCCESS) {
+            rc = 240; goto on_return;
+        }
+    }
+    
+    aud_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
+                                                         0,
+                                                         PJMEDIA_TYPE_AUDIO);
+    aud_port = pjmedia_avi_stream_get_port(aud_stream);
+    
+    if (aud_port) {
+        /* Create sound player port. */
+        status = pjmedia_snd_port_create_player( 
+		 pool,				    /* pool		    */
+		 -1,				    /* use default dev.	    */
+		 PJMEDIA_PIA_SRATE(&aud_port->info),/* clock rate.	    */
+		 PJMEDIA_PIA_CCNT(&aud_port->info), /* # of channels.	    */
+		 PJMEDIA_PIA_SPF(&aud_port->info),  /* samples per frame.   */
+		 PJMEDIA_PIA_BITS(&aud_port->info), /* bits per sample.	    */
+		 0,				    /* options		    */
+		 &snd_port			    /* returned port	    */
+		 );
+        if (status != PJ_SUCCESS) {
+            rc = 310; goto on_return;
+        }
+	
+        /* Connect file port to the sound player.
+         * Stream playing will commence immediately.
+         */
+        status = pjmedia_snd_port_connect(snd_port, aud_port);
+        if (status != PJ_SUCCESS) {
+            rc = 330; goto on_return;
+        }
+    }
+    
+    if (vid_port) {
+        pjmedia_vid_dev_cb cb;
+	
+        pj_bzero(&cb, sizeof(cb));
+        avi_port.snd_port = snd_port;
+        avi_port.vid_port = renderer;
+        avi_port.is_running = PJ_TRUE;
+        pjmedia_vid_port_set_cb(renderer, &cb, &avi_port);
+
+        /* subscribe events */
+        pjmedia_event_subscribe(NULL, &avi_event_cb, &avi_port,
+                                renderer);
+
+        if (snd_port) {
+            /* Synchronize video rendering and audio playback */
+            pjmedia_vid_port_set_clock_src(
+                renderer,
+                pjmedia_snd_port_get_clock_src(
+                    snd_port, PJMEDIA_DIR_PLAYBACK));
+        }
+                                              
+	
+        /* Start video streaming.. */
+        status = pjmedia_vid_port_start(renderer);
+        if (status != PJ_SUCCESS) {
+            rc = 270; goto on_return;
+        }
+    }
+    
+    while (!avi_port.is_quitting) {
+        pj_thread_sleep(100);
+    }
+
+on_return:
+    if (snd_port) {
+        pjmedia_snd_port_disconnect(snd_port);
+        /* Without this sleep, Windows/DirectSound will repeteadly
+         * play the last frame during destroy.
+         */
+        pj_thread_sleep(100);
+        pjmedia_snd_port_destroy(snd_port);
+    }
+    if (renderer) {
+        pjmedia_event_unsubscribe(NULL, &avi_event_cb, &avi_port,
+                                  renderer);
+        pjmedia_vid_port_destroy(renderer);
+    }
+    if (aud_port)
+        pjmedia_port_destroy(aud_port);
+    if (vid_port)
+        pjmedia_port_destroy(vid_port);
+    if (codec) {
+        pjmedia_vid_codec_close(codec);
+        pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
+    }
+    
+    return rc;
+}
+
+
+static int main_func(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pj_pool_t *pool;
+    int rc = 0;
+    pj_status_t status = PJ_SUCCESS;
+    
+    if (argc != 2) {
+    	puts("Error: filename required");
+	puts(desc);
+	return 1;
+    }
+
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "AVI",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
+    pjmedia_converter_mgr_create(pool, NULL);
+    pjmedia_event_mgr_create(pool, 0, NULL);
+    pjmedia_vid_codec_mgr_create(pool, NULL);
+    
+    status = pjmedia_vid_dev_subsys_init(&cp.factory);
+    if (status != PJ_SUCCESS)
+        goto on_return;
+    
+    status = pjmedia_aud_subsys_init(&cp.factory);
+    if (status != PJ_SUCCESS) {
+        goto on_return;
+    }
+    
+#if PJMEDIA_HAS_FFMPEG_VID_CODEC
+    status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory);
+    if (status != PJ_SUCCESS)
+	goto on_return;    
+#endif
+
+    rc = aviplay(pool, argv[1]);
+    
+    /* 
+     * File should be playing and looping now 
+     */
+
+    /* Without this sleep, Windows/DirectSound will repeteadly
+     * play the last frame during destroy.
+     */
+    pj_thread_sleep(100);
+
+on_return:    
+#if PJMEDIA_HAS_FFMPEG_VID_CODEC
+    pjmedia_codec_ffmpeg_vid_deinit();
+#endif
+    pjmedia_aud_subsys_shutdown();
+    pjmedia_vid_dev_subsys_shutdown();
+    
+    pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance());
+    pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance());
+    pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance());
+    pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance());    
+    
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+    /* Done. */
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    return pj_run_app(&main_func, argc, argv, 0);
+}
+
+#else
+
+int main(int argc, char *argv[])
+{
+    PJ_UNUSED_ARG(argc);
+    PJ_UNUSED_ARG(argv);
+    puts("Error: this sample requires video capability (PJMEDIA_HAS_VIDEO == 1)");
+    return -1;
+}
+
+#endif /* PJMEDIA_HAS_VIDEO */
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/clidemo.c b/jni/libpjsip/sources/pjsip-apps/src/samples/clidemo.c
new file mode 100644
index 0000000..7de31c9
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/clidemo.c
@@ -0,0 +1,262 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2010 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
+ */
+
+/*
+ * Sample CLI application
+ */
+#include <pjlib-util/cli.h>
+#include <pjlib-util/cli_imp.h>
+#include <pjlib-util/cli_console.h>
+#include <pjlib-util/cli_telnet.h>
+#include <pjlib-util/errno.h>
+#include <pjlib.h>
+
+#define THIS_FILE	"clidemo.c"
+
+/* Set this to 1 if you want to let the system assign a port
+ * for the CLI telnet daemon.
+ * Default: 1
+ */
+#define USE_RANDOM_PORT 1
+
+struct cmd_xml_t {
+    char * xml;
+    pj_cli_cmd_handler handler;
+};
+
+/*
+ * Declaration of system specific main loop, which will be defined in
+ * a separate file.
+ */
+pj_status_t app_main(pj_cli_t *cli);
+
+#define print_msg(arg) \
+    do { \
+        unsigned d = pj_log_get_decor(); \
+        pj_log_set_decor(0); \
+        PJ_LOG(1, arg); \
+        pj_log_set_decor(d); \
+    } while (0)
+
+static pj_cli_t *cli = NULL;
+
+/* Handler for sayhello command */
+static pj_status_t sayhello(pj_cli_cmd_val *cval)
+{
+    print_msg(("", "Hello %.*s!\r\n", 
+              (int)cval->argv[1].slen, cval->argv[1].ptr));
+    return PJ_SUCCESS;
+}
+
+/* Handler for saybye command */
+static pj_status_t saybye(pj_cli_cmd_val *cval)
+{
+    print_msg(("", "Bye %.*s!\r\n",
+              (int)cval->argv[1].slen, cval->argv[1].ptr));
+    return PJ_SUCCESS;
+}
+
+/* Handler for say command */
+static pj_status_t say(pj_cli_cmd_val *cval)
+{
+    print_msg(("", "%.*s %.*s\r\n",
+              (int)cval->argv[1].slen, cval->argv[1].ptr,
+              (int)cval->argv[2].slen, cval->argv[2].ptr));
+    return PJ_SUCCESS;
+}
+
+static pj_status_t quit_app(pj_cli_cmd_val *cval)
+{
+    PJ_UNUSED_ARG(cval);
+    pj_cli_quit(cval->sess->fe->cli, cval->sess, PJ_FALSE);
+
+    return PJ_CLI_EEXIT;
+}
+
+static void get_codec_list(pj_cli_dyn_choice_param *param)
+{
+    if (param->arg_id == 3) {
+	param->cnt = 2;
+	pj_strdup2(param->pool, &param->choice[0].value, "iLbc");
+	pj_strdup2(param->pool, &param->choice[0].desc, "iLbc Codec");
+	pj_strdup2(param->pool, &param->choice[1].value, "g729");
+	pj_strdup2(param->pool, &param->choice[1].desc, "g729 Codec");
+    }
+}
+
+static struct cmd_xml_t cmd_xmls[] = {
+    {"<CMD name='sayhello' id='1' sc='  ,h , ,, sh  ,' desc='Will say hello'>"
+     "    <ARG name='whom' type='text' desc='Whom to say hello to'/>"
+     "</CMD>",
+     &sayhello},
+    {"<CMD name='saybye' id='2' sc='b,sb' desc='Will say bye'>"
+     "    <ARG name='whom' type='text' desc='Whom to say bye to'/>"
+     "</CMD>",
+     &saybye},
+    {"<CMD name='saymsg' id='3' sc='s' desc='Will say something'>"
+     "    <ARG name='msg' type='text' desc='Message to say'/>"
+     "    <ARG name='whom' type='text' desc='Whom to say to'/>"
+     "</CMD>",
+     &say},
+    {"<CMD name='vid' id='1' desc='Video Command'>"
+     "   <CMD name='help' id='2' desc='Show Help' />"
+     "   <CMD name='enable' id='3' desc='Enable Video' />"
+     "   <CMD name='disable' id='4' desc='Disable Video' />"
+     "   <CMD name='call' id='5' desc='Video call' >"
+     "            <CMD name='add' id='6' desc='Add Call' />"
+     "            <CMD name='cap' id='7' desc='Capture Call' >"
+     "               <ARG name='streamno' type='int' desc='Stream No' id='1'/>"
+     "               <ARG name='devid' type='int' desc='Device Id' id='2'/>"
+     "            </CMD>"
+     "   </CMD>"     
+     "</CMD>",
+     NULL},
+    {"<CMD name='disable_codec' id='8' desc='Disable codec'>"
+     "	<ARG name='codec_list' type='choice' id='3' desc='Codec list'>"
+     "	    <CHOICE value='g711' desc='G711 Codec'/>"
+     "	    <CHOICE value='g722' desc='G722 Codec'/>"
+     "	</ARG>"
+     "</CMD>",
+     NULL},
+    {"<CMD name='quit_app' id='999' sc='qa' desc='Quit the application'>"
+     "</CMD>",
+     &quit_app},
+};
+
+static void log_writer(int level, const char *buffer, int len)
+{
+    if (cli)
+        pj_cli_write_log(cli, level, buffer, len);
+}
+
+int main()
+{
+    pj_caching_pool cp;
+    pj_cli_cfg cli_cfg;
+    pj_cli_telnet_cfg tcfg;
+    pj_str_t xml;
+    pj_status_t status;
+    int i;        
+
+    pj_init();
+    pj_caching_pool_init(&cp, NULL, 0);
+    pjlib_util_init();
+
+    /*
+     * Create CLI app.
+     */
+    pj_cli_cfg_default(&cli_cfg);
+    cli_cfg.pf = &cp.factory;
+    cli_cfg.name = pj_str("mycliapp");
+    cli_cfg.title = pj_str("My CLI Application");
+
+    status = pj_cli_create(&cli_cfg, &cli);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    /*
+     * Register some commands.
+     */
+    for (i = 0; i < sizeof(cmd_xmls)/sizeof(cmd_xmls[0]); i++) {
+        xml = pj_str(cmd_xmls[i].xml);	
+        status = pj_cli_add_cmd_from_xml(cli, NULL, &xml, 
+	    cmd_xmls[i].handler, NULL, get_codec_list);
+        if (status != PJ_SUCCESS)
+	    goto on_return;
+    }
+
+    /*
+     * Start telnet daemon
+     */
+    pj_cli_telnet_cfg_default(&tcfg);
+//    tcfg.passwd = pj_str("pjsip");
+#if USE_RANDOM_PORT
+    tcfg.port = 0;
+#else
+    tcfg.port = 2233;
+#endif    
+    tcfg.prompt_str = pj_str("CoolWater% ");
+    status = pj_cli_telnet_create(cli, &tcfg, NULL);
+    if (status != PJ_SUCCESS)
+	goto on_return;
+
+    /*
+     * Run the system specific main loop.
+     */
+    status = app_main(cli);
+
+on_return:
+
+    /*
+     * Destroy
+     */
+    pj_cli_destroy(cli);
+    cli = NULL;
+    pj_caching_pool_destroy(&cp);
+    pj_shutdown();
+
+    return (status != PJ_SUCCESS ? 1 : 0);
+}
+
+
+/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxx main_console.c xxxxxxxxxxxxxxxxxxxxxxxxxxxx */
+/*
+ * Simple implementation of app_main() for console targets
+ */
+pj_status_t app_main(pj_cli_t *cli)
+{
+    pj_status_t status;
+    pj_cli_sess *sess;
+    pj_cli_console_cfg console_cfg;
+
+    pj_cli_console_cfg_default(&console_cfg);
+    console_cfg.prompt_str = pj_str("HotWater> ");
+    
+    /*
+     * Create the console front end
+     */
+    status = pj_cli_console_create(cli, &console_cfg, &sess, NULL);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    pj_log_set_log_func(&log_writer);
+
+    /*
+     * Main loop.
+     */
+    for (;;) {
+	char cmdline[PJ_CLI_MAX_CMDBUF];
+        pj_status_t status;
+
+        status = pj_cli_console_process(sess, &cmdline[0], sizeof(cmdline));
+	if (status != PJ_SUCCESS)
+	    break;
+
+	//pj_ansi_strcpy(cmdline, "sayhello {Teluu Inc.}");	
+	if (status == PJ_CLI_EEXIT) {
+	    /* exit is called */
+	    break;
+	} else if (status != PJ_SUCCESS) {
+	    /* Something wrong with the cmdline */
+	    PJ_PERROR(1,(THIS_FILE, status, "Exec error"));
+	}
+    }
+
+    return PJ_SUCCESS;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/confbench.c b/jni/libpjsip/sources/pjsip-apps/src/samples/confbench.c
new file mode 100644
index 0000000..b91aebb
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/confbench.c
@@ -0,0 +1,348 @@
+/* $Id: confbench.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+/**
+ * \page page_pjmedia_samples_confbench_c Samples: Benchmarking Conference Bridge
+ *
+ * Benchmarking pjmedia (conference bridge+resample). For my use only,
+ * and it only works in Win32.
+ *
+ * This file is pjsip-apps/src/samples/confbench.c
+ *
+ * \includelineno confbench.c
+ */
+
+
+#include <pjmedia.h>
+#include <pjlib-util.h>	/* pj_getopt */
+#include <pjlib.h>
+#include <stdlib.h>	/* atoi() */
+#include <stdio.h>
+#include <windows.h>
+
+/* For logging purpose. */
+#define THIS_FILE   "confsample.c"
+
+
+/* Configurable:
+ *   LARGE_SET will create in total of about 232 ports.
+ *   HAS_RESAMPLE will activate resampling on about half
+ *     the port.
+ */
+#define TEST_SET	    LARGE_SET
+#define HAS_RESAMPLE	    0
+
+
+#define SMALL_SET	    16
+#define LARGE_SET	    100
+
+
+#define PORT_COUNT	    254
+#define CLOCK_RATE	    16000
+#define SAMPLES_PER_FRAME   (CLOCK_RATE/100)
+#if HAS_RESAMPLE
+#  define SINE_CLOCK	    32000
+#else
+#  define SINE_CLOCK	    CLOCK_RATE
+#endif
+#define SINE_PTIME	    20
+#define DURATION	    10
+
+#define SINE_COUNT	    TEST_SET
+#define NULL_COUNT	    TEST_SET
+#define IDLE_COUNT	    32
+
+
+static void app_perror(const char *sender, const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(1,(sender, "%s: %s", title, errmsg));
+}
+
+
+struct Times
+{
+    FILETIME	    kernel_time;
+    ULARGE_INTEGER  u_kernel_time;
+    FILETIME	    user_time;
+    ULARGE_INTEGER  u_user_time;
+    ULARGE_INTEGER  u_total;
+};
+
+static void process(struct Times *t)
+{
+    pj_memcpy(&t->u_kernel_time, &t->kernel_time, sizeof(FILETIME));
+    pj_memcpy(&t->u_user_time, &t->user_time, sizeof(FILETIME));
+    t->u_total.QuadPart = t->u_kernel_time.QuadPart + t->u_user_time.QuadPart;
+}
+
+static void benchmark(void)
+{
+    FILETIME creation_time, exit_time;
+    struct Times start, end;
+    DWORD ts, te;
+    LARGE_INTEGER elapsed;
+    BOOL rc;
+    int i;
+    double pct;
+
+    puts("Test started!"); fflush(stdout);
+
+    ts = GetTickCount();
+    rc = GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time,
+			 &start.kernel_time, &start.user_time);
+    for (i=DURATION; i>0; --i) {
+	printf("\r%d ", i); fflush(stdout);
+	pj_thread_sleep(1000);
+    }
+    rc = GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time,
+			 &end.kernel_time, &end.user_time);
+    te = GetTickCount();
+
+    process(&start);
+    process(&end);
+
+    elapsed.QuadPart = end.u_total.QuadPart - start.u_total.QuadPart;
+
+    pct = elapsed.QuadPart * 100.0 / ((te-ts)*10000.0);
+
+    printf("CPU usage=%6.4f%%\n", pct); fflush(stdout);
+}
+
+
+
+/* Struct attached to sine generator */
+typedef struct
+{
+    pj_int16_t	*samples;	/* Sine samples.    */
+} port_data;
+
+
+/* This callback is called to feed more samples */
+static pj_status_t sine_get_frame( pjmedia_port *port, 
+				   pjmedia_frame *frame)
+{
+    port_data *sine = port->port_data.pdata;
+    pj_int16_t *samples = frame->buf;
+    unsigned i, left, right;
+    pj_size_t count;
+
+    /* Get number of samples */
+    count = frame->size / 2 / PJMEDIA_PIA_CCNT(&port->info);
+
+    left = 0;
+    right = 0;
+
+    for (i=0; i<count; ++i) {
+	*samples++ = sine->samples[left];
+	++left;
+
+	if (PJMEDIA_PIA_CCNT(&port->info) == 2) {
+	    *samples++ = sine->samples[right];
+	    right += 2; /* higher pitch so we can distinguish left and right. */
+	    if (right >= count)
+		right = 0;
+	}
+    }
+
+    /* Must set frame->type correctly, otherwise the sound device
+     * will refuse to play.
+     */
+    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+
+    return PJ_SUCCESS;
+}
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+/*
+ * Create a media port to generate sine wave samples.
+ */
+static pj_status_t create_sine_port(pj_pool_t *pool,
+				    unsigned sampling_rate,
+				    unsigned channel_count,
+				    pjmedia_port **p_port)
+{
+    pjmedia_port *port;
+    unsigned i;
+    unsigned count;
+    pj_str_t port_name;
+    port_data *sine;
+
+    PJ_ASSERT_RETURN(pool && channel_count > 0 && channel_count <= 2, 
+		     PJ_EINVAL);
+
+    port = pj_pool_zalloc(pool, sizeof(pjmedia_port));
+    PJ_ASSERT_RETURN(port != NULL, PJ_ENOMEM);
+
+    /* Fill in port info. */
+    port_name = pj_str("sine generator");
+    pjmedia_port_info_init(&port->info, &port_name,
+			   12345, sampling_rate, channel_count, 16, 
+			   sampling_rate * SINE_PTIME / 1000 * channel_count);
+    
+    /* Set the function to feed frame */
+    port->get_frame = &sine_get_frame;
+
+    /* Create sine port data */
+    port->port_data.pdata = sine = pj_pool_zalloc(pool, sizeof(port_data));
+
+    /* Create samples */
+    count = PJMEDIA_PIA_SPF(&port->info) / channel_count;
+    sine->samples = pj_pool_alloc(pool, count * sizeof(pj_int16_t));
+    PJ_ASSERT_RETURN(sine->samples != NULL, PJ_ENOMEM);
+
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<count; i++ )
+    {
+        sine->samples[i] = (pj_int16_t) (10000.0 * 
+		sin(((double)i/(double)count) * M_PI * 8.) );
+    }
+
+    *p_port = port;
+
+    return PJ_SUCCESS;
+}
+
+int main()
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_conf *conf;
+    int i;
+    pjmedia_port *sine_port[SINE_COUNT], *null_port, *conf_port;
+    pjmedia_port *nulls[NULL_COUNT];
+    unsigned null_slots[NULL_COUNT];
+    pjmedia_master_port *master_port;
+    pj_status_t status;
+
+
+    pj_log_set_level(3);
+
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "wav",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+
+    status = pjmedia_conf_create( pool,
+				  PORT_COUNT,
+				  CLOCK_RATE,
+				  1, SAMPLES_PER_FRAME, 16,
+				  PJMEDIA_CONF_NO_DEVICE,
+				  &conf);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to create conference bridge", status);
+	return 1;
+    }
+
+    printf("Resampling is %s\n", (HAS_RESAMPLE?"active":"disabled"));
+
+    /* Create Null ports */
+    printf("Creating %d null ports..\n", NULL_COUNT);
+    for (i=0; i<NULL_COUNT; ++i) {
+	status = pjmedia_null_port_create(pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME*2, 16, &nulls[i]);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+	status = pjmedia_conf_add_port(conf, pool, nulls[i], NULL, &null_slots[i]);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    }
+
+    /* Create sine ports. */
+    printf("Creating %d sine generator ports..\n", SINE_COUNT);
+    for (i=0; i<SINE_COUNT; ++i) {
+	unsigned j, slot;
+
+	/* Load the WAV file to file port. */
+	status = create_sine_port(pool, SINE_CLOCK, 1, &sine_port[i]);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+	/* Add the file port to conference bridge */
+	status = pjmedia_conf_add_port( conf,		/* The bridge	    */
+					pool,		/* pool		    */
+					sine_port[i],	/* port to connect  */
+					NULL,		/* Use port's name  */
+					&slot		/* ptr for slot #   */
+					);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to add conference port", status);
+	    return 1;
+	}
+
+	status = pjmedia_conf_connect_port(conf, slot, 0, 0);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+	for (j=0; j<NULL_COUNT; ++j) {
+	    status = pjmedia_conf_connect_port(conf, slot, null_slots[j], 0);
+	    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+	}
+    }
+
+    /* Create idle ports */
+    printf("Creating %d idle ports..\n", IDLE_COUNT);
+    for (i=0; i<IDLE_COUNT; ++i) {
+	pjmedia_port *dummy;
+	status = pjmedia_null_port_create(pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME, 16, &dummy);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+	status = pjmedia_conf_add_port(conf, pool, dummy, NULL, NULL);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    }
+
+    /* Create null port */
+    status = pjmedia_null_port_create(pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME, 16,
+				      &null_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    conf_port = pjmedia_conf_get_master_port(conf);
+
+    /* Create master port */
+    status = pjmedia_master_port_create(pool, null_port, conf_port, 0, &master_port);
+
+
+    pjmedia_master_port_start(master_port);
+
+    puts("Waiting to settle.."); fflush(stdout);
+    pj_thread_sleep(5000);
+
+
+    benchmark();
+
+
+    /* Done. */
+    return 0;
+}
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/confsample.c b/jni/libpjsip/sources/pjsip-apps/src/samples/confsample.c
new file mode 100644
index 0000000..79b3a9a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/confsample.c
@@ -0,0 +1,609 @@
+/* $Id: confsample.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 <pjmedia.h>
+#include <pjlib-util.h>	/* pj_getopt */
+#include <pjlib.h>
+
+#include <stdlib.h>	/* atoi() */
+#include <stdio.h>
+
+#include "util.h"
+
+/**
+ * \page page_pjmedia_samples_confsample_c Samples: Using Conference Bridge
+ *
+ * Sample to mix multiple files in the conference bridge and play the
+ * result to sound device.
+ *
+ * This file is pjsip-apps/src/samples/confsample.c
+ *
+ * \includelineno confsample.c
+ */
+
+
+/* For logging purpose. */
+#define THIS_FILE   "confsample.c"
+
+
+/* Shall we put recorder in the conference */
+#define RECORDER    1
+
+
+static const char *desc = 
+ " FILE:								    \n"
+ "									    \n"
+ "  confsample.c							    \n"
+ "									    \n"
+ " PURPOSE:								    \n"
+ "									    \n"
+ "  Demonstrate how to use conference bridge.				    \n"
+ "									    \n"
+ " USAGE:								    \n"
+ "									    \n"
+ "  confsample [options] [file1.wav] [file2.wav] ...			    \n"
+ "									    \n"
+ " options:								    \n"
+ SND_USAGE
+ "									    \n"
+ "  fileN.wav are optional WAV files to be connected to the conference      \n"
+ "  bridge. The WAV files MUST have single channel (mono) and 16 bit PCM    \n"
+ "  samples. It can have arbitrary sampling rate.			    \n"
+ "									    \n"
+ " DESCRIPTION:								    \n"
+ "									    \n"
+ "  Here we create a conference bridge, with at least one port (port zero   \n"
+ "  is always created for the sound device).				    \n"
+ "									    \n"
+ "  If WAV files are specified, the WAV file player ports will be connected \n"
+ "  to slot starting from number one in the bridge. The WAV files can have  \n"
+ "  arbitrary sampling rate; the bridge will convert it to its clock rate.  \n"
+ "  However, the files MUST have a single audio channel only (i.e. mono).  \n";
+
+
+ 
+/* 
+ * Prototypes: 
+ */
+
+/* List the ports in the conference bridge */
+static void conf_list(pjmedia_conf *conf, pj_bool_t detail);
+
+/* Display VU meter */
+static void monitor_level(pjmedia_conf *conf, int slot, int dir, int dur);
+
+
+/* Show usage */
+static void usage(void)
+{
+    puts("");
+    puts(desc);
+}
+
+
+
+/* Input simple string */
+static pj_bool_t input(const char *title, char *buf, pj_size_t len)
+{
+    char *p;
+
+    printf("%s (empty to cancel): ", title); fflush(stdout);
+    if (fgets(buf, (int)len, stdin) == NULL)
+	return PJ_FALSE;
+
+    /* Remove trailing newlines. */
+    for (p=buf; ; ++p) {
+	if (*p=='\r' || *p=='\n') *p='\0';
+	else if (!*p) break;
+    }
+
+    if (!*buf)
+	return PJ_FALSE;
+    
+    return PJ_TRUE;
+}
+
+
+/*****************************************************************************
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    int dev_id = -1;
+    int clock_rate = CLOCK_RATE;
+    int channel_count = NCHANNELS;
+    int samples_per_frame = NSAMPLES;
+    int bits_per_sample = NBITS;
+
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_conf *conf;
+
+    int i, port_count, file_count;
+    pjmedia_port **file_port;	/* Array of file ports */
+    pjmedia_port *rec_port = NULL;  /* Wav writer port */
+
+    char tmp[10];
+    pj_status_t status;
+
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Get command line options. */
+    if (get_snd_options(THIS_FILE, argc, argv, &dev_id, &clock_rate,
+			&channel_count, &samples_per_frame, &bits_per_sample))
+    {
+	usage();
+	return 1;
+    }
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool to allocate memory */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "wav",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+
+    file_count = argc - pj_optind;
+    port_count = file_count + 1 + RECORDER;
+
+    /* Create the conference bridge. 
+     * With default options (zero), the bridge will create an instance of
+     * sound capture and playback device and connect them to slot zero.
+     */
+    status = pjmedia_conf_create( pool,	    /* pool to use	    */
+				  port_count,/* number of ports	    */
+				  clock_rate,
+				  channel_count,
+				  samples_per_frame,
+				  bits_per_sample,
+				  0,	    /* options		    */
+				  &conf	    /* result		    */
+				  );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to create conference bridge", status);
+	return 1;
+    }
+
+#if RECORDER
+    status = pjmedia_wav_writer_port_create(  pool, "confrecord.wav",
+					      clock_rate, channel_count,
+					      samples_per_frame, 
+					      bits_per_sample, 0, 0, 
+					      &rec_port);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to create WAV writer", status);
+	return 1;
+    }
+
+    pjmedia_conf_add_port(conf, pool, rec_port, NULL, NULL);
+#endif
+
+
+    /* Create file ports. */
+    file_port = pj_pool_alloc(pool, file_count * sizeof(pjmedia_port*));
+
+    for (i=0; i<file_count; ++i) {
+
+	/* Load the WAV file to file port. */
+	status = pjmedia_wav_player_port_create( 
+			pool,		    /* pool.	    */
+			argv[i+pj_optind],  /* filename	    */
+			0,		    /* use default ptime */
+			0,		    /* flags	    */
+			0,		    /* buf size	    */
+			&file_port[i]	    /* result	    */
+			);
+	if (status != PJ_SUCCESS) {
+	    char title[80];
+	    pj_ansi_sprintf(title, "Unable to use %s", argv[i+pj_optind]);
+	    app_perror(THIS_FILE, title, status);
+	    usage();
+	    return 1;
+	}
+
+	/* Add the file port to conference bridge */
+	status = pjmedia_conf_add_port( conf,		/* The bridge	    */
+					pool,		/* pool		    */
+					file_port[i],	/* port to connect  */
+					NULL,		/* Use port's name  */
+					NULL		/* ptr for slot #   */
+					);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to add conference port", status);
+	    return 1;
+	}
+    }
+
+
+    /* 
+     * All ports are set up in the conference bridge.
+     * But at this point, no media will be flowing since no ports are
+     * "connected". User must connect the port manually.
+     */
+
+
+    /* Dump memory usage */
+    dump_pool_usage(THIS_FILE, &cp);
+
+    /* Sleep to allow log messages to flush */
+    pj_thread_sleep(100);
+
+
+    /*
+     * UI Menu: 
+     */
+    for (;;) {
+	char tmp1[10];
+	char tmp2[10];
+	char *err;
+	int src, dst, level, dur;
+
+	puts("");
+	conf_list(conf, 0);
+	puts("");
+	puts("Menu:");
+	puts("  s    Show ports details");
+	puts("  c    Connect one port to another");
+	puts("  d    Disconnect port connection");
+	puts("  t    Adjust signal level transmitted (tx) to a port");
+	puts("  r    Adjust signal level received (rx) from a port");
+	puts("  v    Display VU meter for a particular port");
+	puts("  q    Quit");
+	puts("");
+	
+	printf("Enter selection: "); fflush(stdout);
+
+	if (fgets(tmp, sizeof(tmp), stdin) == NULL)
+	    break;
+
+	switch (tmp[0]) {
+	case 's':
+	    puts("");
+	    conf_list(conf, 1);
+	    break;
+
+	case 'c':
+	    puts("");
+	    puts("Connect source port to destination port");
+	    if (!input("Enter source port number", tmp1, sizeof(tmp1)) )
+		continue;
+	    src = strtol(tmp1, &err, 10);
+	    if (*err || src < 0 || src >= port_count) {
+		puts("Invalid slot number");
+		continue;
+	    }
+
+	    if (!input("Enter destination port number", tmp2, sizeof(tmp2)) )
+		continue;
+	    dst = strtol(tmp2, &err, 10);
+	    if (*err || dst < 0 || dst >= port_count) {
+		puts("Invalid slot number");
+		continue;
+	    }
+
+	    status = pjmedia_conf_connect_port(conf, src, dst, 0);
+	    if (status != PJ_SUCCESS)
+		app_perror(THIS_FILE, "Error connecting port", status);
+	    
+	    break;
+
+	case 'd':
+	    puts("");
+	    puts("Disconnect port connection");
+	    if (!input("Enter source port number", tmp1, sizeof(tmp1)) )
+		continue;
+	    src = strtol(tmp1, &err, 10);
+	    if (*err || src < 0 || src >= port_count) {
+		puts("Invalid slot number");
+		continue;
+	    }
+
+	    if (!input("Enter destination port number", tmp2, sizeof(tmp2)) )
+		continue;
+	    dst = strtol(tmp2, &err, 10);
+	    if (*err || dst < 0 || dst >= port_count) {
+		puts("Invalid slot number");
+		continue;
+	    }
+
+	    status = pjmedia_conf_disconnect_port(conf, src, dst);
+	    if (status != PJ_SUCCESS)
+		app_perror(THIS_FILE, "Error connecting port", status);
+	    
+
+	    break;
+
+	case 't':
+	    puts("");
+	    puts("Adjust transmit level of a port");
+	    if (!input("Enter port number", tmp1, sizeof(tmp1)) )
+		continue;
+	    src = strtol(tmp1, &err, 10);
+	    if (*err || src < 0 || src >= port_count) {
+		puts("Invalid slot number");
+		continue;
+	    }
+
+	    if (!input("Enter level (-128 to >127, 0 for normal)", 
+			      tmp2, sizeof(tmp2)) )
+		continue;
+	    level = strtol(tmp2, &err, 10);
+	    if (*err || level < -128) {
+		puts("Invalid level");
+		continue;
+	    }
+
+	    status = pjmedia_conf_adjust_tx_level( conf, src, level);
+	    if (status != PJ_SUCCESS)
+		app_perror(THIS_FILE, "Error adjusting level", status);
+	    break;
+
+
+	case 'r':
+	    puts("");
+	    puts("Adjust receive level of a port");
+	    if (!input("Enter port number", tmp1, sizeof(tmp1)) )
+		continue;
+	    src = strtol(tmp1, &err, 10);
+	    if (*err || src < 0 || src >= port_count) {
+		puts("Invalid slot number");
+		continue;
+	    }
+
+	    if (!input("Enter level (-128 to >127, 0 for normal)", 
+			      tmp2, sizeof(tmp2)) )
+		continue;
+	    level = strtol(tmp2, &err, 10);
+	    if (*err || level < -128) {
+		puts("Invalid level");
+		continue;
+	    }
+
+	    status = pjmedia_conf_adjust_rx_level( conf, src, level);
+	    if (status != PJ_SUCCESS)
+		app_perror(THIS_FILE, "Error adjusting level", status);
+	    break;
+
+	case 'v':
+	    puts("");
+	    puts("Display VU meter");
+	    if (!input("Enter port number to monitor", tmp1, sizeof(tmp1)) )
+		continue;
+	    src = strtol(tmp1, &err, 10);
+	    if (*err || src < 0 || src >= port_count) {
+		puts("Invalid slot number");
+		continue;
+	    }
+
+	    if (!input("Enter r for rx level or t for tx level", tmp2, sizeof(tmp2)))
+		continue;
+	    if (tmp2[0] != 'r' && tmp2[0] != 't') {
+		puts("Invalid option");
+		continue;
+	    }
+
+	    if (!input("Duration to monitor (in seconds)", tmp1, sizeof(tmp1)) )
+		continue;
+	    dur = strtol(tmp1, &err, 10);
+	    if (*err) {
+		puts("Invalid duration number");
+		continue;
+	    }
+
+	    monitor_level(conf, src, tmp2[0], dur);
+	    break;
+
+	case 'q':
+	    goto on_quit;
+
+	default:
+	    printf("Invalid input character '%c'\n", tmp[0]);
+	    break;
+	}
+    }
+
+on_quit:
+    
+    /* Start deinitialization: */
+
+    /* Destroy conference bridge */
+    status = pjmedia_conf_destroy( conf );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Destroy file ports */
+    for (i=0; i<file_count; ++i) {
+	status = pjmedia_port_destroy( file_port[i]);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    }
+
+    /* Destroy recorder port */
+    if (rec_port)
+	pjmedia_port_destroy(rec_port);
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+    /* Done. */
+    return 0;
+}
+
+
+/*
+ * List the ports in conference bridge
+ */
+static void conf_list(pjmedia_conf *conf, int detail)
+{
+    enum { MAX_PORTS = 32 };
+    unsigned i, count;
+    pjmedia_conf_port_info info[MAX_PORTS];
+
+    printf("Conference ports:\n");
+
+    count = PJ_ARRAY_SIZE(info);
+    pjmedia_conf_get_ports_info(conf, &count, info);
+
+    for (i=0; i<count; ++i) {
+	char txlist[4*MAX_PORTS];
+	unsigned j;
+	pjmedia_conf_port_info *port_info = &info[i];	
+	
+	txlist[0] = '\0';
+	for (j=0; j<port_info->listener_cnt; ++j) {
+	    char s[10];
+	    pj_ansi_sprintf(s, "#%d ", port_info->listener_slots[j]);
+	    pj_ansi_strcat(txlist, s);
+
+	}
+
+	if (txlist[0] == '\0') {
+	    txlist[0] = '-';
+	    txlist[1] = '\0';
+	}
+
+	if (!detail) {
+	    printf("Port #%02d %-25.*s  transmitting to: %s\n", 
+		   port_info->slot, 
+		   (int)port_info->name.slen, 
+		   port_info->name.ptr,
+		   txlist);
+	} else {
+	    unsigned tx_level, rx_level;
+
+	    pjmedia_conf_get_signal_level(conf, port_info->slot,
+					  &tx_level, &rx_level);
+
+	    printf("Port #%02d:\n"
+		   "  Name                    : %.*s\n"
+		   "  Sampling rate           : %d Hz\n"
+		   "  Samples per frame       : %d\n"
+		   "  Frame time              : %d ms\n"
+		   "  Signal level adjustment : tx=%d, rx=%d\n"
+		   "  Current signal level    : tx=%u, rx=%u\n"
+		   "  Transmitting to ports   : %s\n\n",
+		   port_info->slot,
+		   (int)port_info->name.slen,
+		   port_info->name.ptr,
+		   port_info->clock_rate,
+		   port_info->samples_per_frame,
+		   port_info->samples_per_frame*1000/port_info->clock_rate,
+		   port_info->tx_adj_level,
+		   port_info->rx_adj_level,
+		   tx_level,
+		   rx_level,
+		   txlist);
+	}
+
+    }
+    puts("");
+}
+
+
+/*
+ * Display VU meter
+ */
+static void monitor_level(pjmedia_conf *conf, int slot, int dir, int dur)
+{
+    enum { SLEEP = 20, SAMP_CNT = 2};
+    pj_status_t status;
+    int i, total_count;
+    unsigned level, samp_cnt;
+
+
+    puts("");
+    printf("Displaying VU meter for port %d for about %d seconds\n",
+	   slot, dur);
+
+    total_count = dur * 1000 / SLEEP;
+
+    level = 0;
+    samp_cnt = 0;
+
+    for (i=0; i<total_count; ++i) {
+	unsigned tx_level, rx_level;
+	int j, length;
+	char meter[21];
+
+	/* Poll the volume every 20 msec */
+	status = pjmedia_conf_get_signal_level(conf, slot, 
+					       &tx_level, &rx_level);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to read level", status);
+	    return;
+	}
+
+	level += (dir=='r' ? rx_level : tx_level);
+	++samp_cnt;
+
+	/* Accumulate until we have enough samples */
+	if (samp_cnt < SAMP_CNT) {
+	    pj_thread_sleep(SLEEP);
+	    continue;
+	}
+
+	/* Get average */
+	level = level / samp_cnt;
+
+	/* Draw bar */
+	length = 20 * level / 255;
+	for (j=0; j<length; ++j)
+	    meter[j] = '#';
+	for (; j<20; ++j)
+	    meter[j] = ' ';
+	meter[20] = '\0';
+
+	printf("Port #%02d %cx level: [%s] %d  \r",
+	       slot, dir, meter, level);
+
+	/* Next.. */
+	samp_cnt = 0;
+	level = 0;
+
+	pj_thread_sleep(SLEEP);
+    }
+
+    puts("");
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/debug.cpp b/jni/libpjsip/sources/pjsip-apps/src/samples/debug.cpp
new file mode 100644
index 0000000..9928c7e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/debug.cpp
@@ -0,0 +1,32 @@
+/* $Id: debug.cpp 4704 2014-01-16 05:30:46Z ming $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/*
+ * PURPOSE:
+ *   The purpose of this file is to allow debugging of a sample application
+ *   using MSVC IDE.
+ */
+
+/* To debug a sample application, include the source file here.
+ * E.g.:
+ *  #include "playfile.c"
+ */
+#include "icedemo.c"
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/encdec.c b/jni/libpjsip/sources/pjsip-apps/src/samples/encdec.c
new file mode 100644
index 0000000..9ded990
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/encdec.c
@@ -0,0 +1,263 @@
+/* $Id: encdec.c 3664 2011-07-19 03:42:28Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+ /**
+ * \page page_pjmedia_samples_encdec_c Samples: Encoding and Decoding
+ *
+ * This sample shows how to use codec.
+ *
+ * This file is pjsip-apps/src/samples/encdec.c
+ *
+ * \includelineno encdec.c
+ */
+
+#include <pjlib.h>
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+
+#define THIS_FILE   "encdec.c"
+
+static const char *desc = 
+ " encdec								\n"
+ "									\n"
+ " PURPOSE:								\n"
+ "  Encode input WAV with a codec, and decode the result to another WAV \n"
+ "\n"
+ "\n"
+ " USAGE:								\n"
+ "  encdec codec input.wav output.wav                                   \n"
+ "\n"
+ "\n"
+ " where:\n"
+ "  codec         Set the codec name.                                   \n"
+ "  input.wav     Set the input WAV filename.                           \n"
+ "  output.wav    Set the output WAV filename.                          \n"
+
+ "\n"
+;
+
+//#undef PJ_TRACE
+//#define PJ_TRACE 1
+
+#ifndef PJ_TRACE
+#	define PJ_TRACE 0
+#endif
+
+#if PJ_TRACE
+#   define TRACE_(expr)	    PJ_LOG(4,expr)
+#else
+#   define TRACE_(expr)
+#endif
+
+
+static void err(const char *op, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(3,("", "%s error: %s", op, errmsg));
+}
+
+#define CHECK(op)   do { \
+			status = op; \
+			if (status != PJ_SUCCESS) { \
+			    err(#op, status); \
+			    return status; \
+			} \
+		    } \
+		    while (0)
+
+static pjmedia_endpt *mept;
+static unsigned file_msec_duration;
+
+static pj_status_t enc_dec_test(const char *codec_id,
+				const char *filein,
+			        const char *fileout)
+{
+    pj_pool_t *pool;
+    pjmedia_codec_mgr *cm;
+    pjmedia_codec *codec;
+    const pjmedia_codec_info *pci;
+    pjmedia_codec_param param;
+    unsigned cnt, samples_per_frame;
+    pj_str_t tmp;
+    pjmedia_port *wavin, *wavout;
+    unsigned lost_pct;
+    pj_status_t status;
+
+#define T   file_msec_duration/1000, file_msec_duration%1000
+    
+    pool = pjmedia_endpt_create_pool(mept, "encdec", 1000, 1000);
+
+    cm = pjmedia_endpt_get_codec_mgr(mept);
+
+#ifdef LOST_PCT
+    lost_pct = LOST_PCT;
+#else
+    lost_pct = 0;
+#endif
+    
+    cnt = 1;
+    CHECK( pjmedia_codec_mgr_find_codecs_by_id(cm, pj_cstr(&tmp, codec_id), 
+					       &cnt, &pci, NULL) );
+    CHECK( pjmedia_codec_mgr_get_default_param(cm, pci, &param) );
+
+    samples_per_frame = param.info.clock_rate * param.info.frm_ptime / 1000;
+
+    /* Control VAD */
+    param.setting.vad = 1;
+
+    /* Open wav for reading */
+    CHECK( pjmedia_wav_player_port_create(pool, filein, 
+					  param.info.frm_ptime, 
+					  PJMEDIA_FILE_NO_LOOP, 0, &wavin) );
+
+    /* Open wav for writing */
+    CHECK( pjmedia_wav_writer_port_create(pool, fileout,
+					  param.info.clock_rate, 
+					  param.info.channel_cnt,
+					  samples_per_frame,
+					  16, 0, 0, &wavout) );
+
+    /* Alloc codec */
+    CHECK( pjmedia_codec_mgr_alloc_codec(cm, pci, &codec) );
+    CHECK( pjmedia_codec_init(codec, pool) );
+    CHECK( pjmedia_codec_open(codec, &param) );
+    
+    for (;;) {
+	pjmedia_frame frm_pcm, frm_bit, out_frm, frames[4];
+	pj_int16_t pcmbuf[320];
+	pj_timestamp ts;
+	pj_uint8_t bitstream[160];
+
+	frm_pcm.buf = (char*)pcmbuf;
+	frm_pcm.size = samples_per_frame * 2;
+
+	/* Read from WAV */
+	if (pjmedia_port_get_frame(wavin, &frm_pcm) != PJ_SUCCESS)
+	    break;
+	if (frm_pcm.type != PJMEDIA_FRAME_TYPE_AUDIO)
+	    break;;
+
+	/* Update duration */
+	file_msec_duration += samples_per_frame * 1000 / 
+			      param.info.clock_rate;
+
+	/* Encode */
+	frm_bit.buf = bitstream;
+	frm_bit.size = sizeof(bitstream);
+	CHECK(pjmedia_codec_encode(codec, &frm_pcm, sizeof(bitstream), 
+	                           &frm_bit));
+
+	/* On DTX, write zero frame to wavout to maintain duration */
+	if (frm_bit.size == 0 || frm_bit.type != PJMEDIA_FRAME_TYPE_AUDIO) {
+	    out_frm.buf = (char*)pcmbuf;
+	    out_frm.size = 160;
+	    CHECK( pjmedia_port_put_frame(wavout, &out_frm) );
+	    TRACE_((THIS_FILE, "%d.%03d read: %u, enc: %u",
+		    T, frm_pcm.size, frm_bit.size));
+	    continue;
+	}
+	
+	/* Parse the bitstream (not really necessary for this case
+	 * since we always decode 1 frame, but it's still good
+	 * for testing)
+	 */
+	ts.u64 = 0;
+	cnt = PJ_ARRAY_SIZE(frames);
+	CHECK( pjmedia_codec_parse(codec, bitstream, frm_bit.size, &ts, &cnt, 
+			           frames) );
+	CHECK( (cnt==1 ? PJ_SUCCESS : -1) );
+
+	/* Decode or simulate packet loss */
+	out_frm.buf = (char*)pcmbuf;
+	out_frm.size = sizeof(pcmbuf);
+	
+	if ((pj_rand() % 100) < (int)lost_pct) {
+	    /* Simulate loss */
+	    CHECK( pjmedia_codec_recover(codec, sizeof(pcmbuf), &out_frm) );
+	    TRACE_((THIS_FILE, "%d.%03d Packet lost", T));
+	} else {
+	    /* Decode */
+	    CHECK( pjmedia_codec_decode(codec, &frames[0], sizeof(pcmbuf), 
+				     &out_frm) );
+	}
+
+	/* Write to WAV */
+	CHECK( pjmedia_port_put_frame(wavout, &out_frm) );
+
+	TRACE_((THIS_FILE, "%d.%03d read: %u, enc: %u, dec/write: %u",
+		T, frm_pcm.size, frm_bit.size, out_frm.size));
+    }
+
+    /* Close wavs */
+    pjmedia_port_destroy(wavout);
+    pjmedia_port_destroy(wavin);
+
+    /* Close codec */
+    pjmedia_codec_close(codec);
+    pjmedia_codec_mgr_dealloc_codec(cm, codec);
+
+    /* Release pool */
+    pj_pool_release(pool);
+
+    return PJ_SUCCESS;
+}
+
+
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pj_time_val t0, t1;
+    pj_status_t status;
+
+    if (argc != 4) {
+	puts(desc);
+	return 1;
+    }
+
+    CHECK( pj_init() );
+    
+    pj_caching_pool_init(&cp, NULL, 0);
+
+    CHECK( pjmedia_endpt_create(&cp.factory, NULL, 1, &mept) );
+
+    /* Register all codecs */
+    CHECK( pjmedia_codec_register_audio_codecs(mept, NULL) );
+
+    pj_gettimeofday(&t0);
+    status = enc_dec_test(argv[1], argv[2], argv[3]);
+    pj_gettimeofday(&t1);
+    PJ_TIME_VAL_SUB(t1, t0);
+
+    pjmedia_endpt_destroy(mept);
+    pj_caching_pool_destroy(&cp);
+    pj_shutdown();
+
+    if (status == PJ_SUCCESS) {
+	puts("");
+	puts("Success");
+	printf("Duration: %ds.%03d\n", file_msec_duration/1000, 
+				       file_msec_duration%1000);
+	printf("Time: %lds.%03ld\n", t1.sec, t1.msec);
+    }
+
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/footprint.c b/jni/libpjsip/sources/pjsip-apps/src/samples/footprint.c
new file mode 100644
index 0000000..241ba1e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/footprint.c
@@ -0,0 +1,654 @@
+/* $Id: footprint.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/**
+ * The purpose of this file is to show the typical footprint of
+ * the application when various PJSIP/PJMEDIA components are used.
+ *
+ * This file will not be build as samples, but instead it is build
+ * by get-footprint.py Python script in pjsip-apps/build directory.
+ */
+
+#include <pjsip_ua.h>
+#include <pjsip_simple.h>
+#include <pjsip.h>
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+#include <pjnath.h>
+#include <stdlib.h>
+
+/* All flags: */
+#if 0
+#define HAS_PJLIB
+
+#define HAS_PJLIB_STUN
+#define HAS_PJLIB_GETOPT
+#define HAS_PJLIB_XML
+#define HAS_PJLIB_SCANNER
+#define HAS_PJLIB_DNS
+#define HAS_PJLIB_RESOLVER
+#define HAS_PJLIB_SRV_RESOLVER
+
+#define HAS_PJLIB_CRC32
+#define HAS_PJLIB_HMAC_MD5
+#define HAS_PJLIB_HMAC_SHA1
+
+#define HAS_PJSIP_CORE_MSG_ELEM
+#define HAS_PJSIP_CORE
+#define HAS_PJSIP_CORE_MSG_UTIL
+
+#define HAS_PJSIP_UDP_TRANSPORT
+#define HAS_PJSIP_TCP_TRANSPORT
+#define HAS_PJSIP_TLS_TRANSPORT
+#define HAS_PJSIP_TRANSACTION
+#define HAS_PJSIP_UA_LAYER
+#define HAS_PJMEDIA_SDP
+#define HAS_PJMEDIA_SDP_NEGOTIATOR
+#define HAS_PJSIP_AUTH_CLIENT
+#define HAS_PJSIP_INV_SESSION
+#define HAS_PJSIP_REGC
+#define HAS_PJSIP_EVENT_FRAMEWORK
+#define HAS_PJSIP_CALL_TRANSFER
+#define HAS_PJSIP_PRESENCE
+#define HAS_PJSIP_IS_COMPOSING
+
+#define HAS_PJNATH_STUN
+#define HAS_PJNATH_ICE
+
+#define HAS_PJMEDIA
+#define HAS_PJMEDIA_SND_DEV
+#define HAS_PJMEDIA_EC
+#define HAS_PJMEDIA_SND_PORT
+#define HAS_PJMEDIA_RESAMPLE
+#define HAS_PJMEDIA_SILENCE_DET
+#define HAS_PJMEDIA_PLC
+#define HAS_PJMEDIA_CONFERENCE
+#define HAS_PJMEDIA_MASTER_PORT
+#define HAS_PJMEDIA_RTP
+#define HAS_PJMEDIA_RTCP
+#define HAS_PJMEDIA_JBUF
+#define HAS_PJMEDIA_STREAM
+#define HAS_PJMEDIA_TONEGEN
+#define HAS_PJMEDIA_UDP_TRANSPORT
+#define HAS_PJMEDIA_FILE_PLAYER
+#define HAS_PJMEDIA_FILE_CAPTURE
+#define HAS_PJMEDIA_MEM_PLAYER
+#define HAS_PJMEDIA_MEM_CAPTURE
+#define HAS_PJMEDIA_ICE
+
+#define HAS_PJMEDIA_G711_CODEC
+#define HAS_PJMEDIA_GSM_CODEC
+#define HAS_PJMEDIA_SPEEX_CODEC
+#define HAS_PJMEDIA_ILBC_CODEC
+#endif
+
+
+int dummy_function()
+{
+    pj_caching_pool cp;
+ 
+    sprintf(NULL, "%d", 0);
+    rand();
+    
+#ifdef HAS_PJLIB
+    pj_init();
+    pj_caching_pool_init(&cp, NULL, 0);
+    pj_array_erase(NULL, 0, 0, 0);
+    pj_create_unique_string(NULL, NULL);
+    pj_hash_create(NULL, 0);
+    pj_hash_get(NULL, NULL, 0, NULL);
+    pj_hash_set(NULL, NULL, NULL, 0, 0, NULL);
+    pj_ioqueue_create(NULL, 0, NULL);
+    pj_ioqueue_register_sock(NULL, NULL, 0, NULL, NULL, NULL);
+    pj_pool_alloc(NULL, 0);
+    pj_timer_heap_create(NULL, 0, NULL);
+#endif
+
+#ifdef HAS_PJLIB_STUN
+    pjstun_get_mapped_addr(&cp.factory, 0, NULL, NULL, 80, NULL, 80, NULL);
+#endif
+
+#ifdef HAS_PJLIB_GETOPT
+    pj_getopt_long(0, NULL, NULL, NULL, NULL);
+#endif
+    
+#ifdef HAS_PJLIB_XML
+    pj_xml_parse(NULL, NULL, 100);
+    pj_xml_print(NULL, NULL, 10, PJ_FALSE);
+    pj_xml_clone(NULL, NULL);
+    pj_xml_node_new(NULL, NULL);
+    pj_xml_attr_new(NULL, NULL, NULL);
+    pj_xml_add_node(NULL, NULL);
+    pj_xml_add_attr(NULL, NULL);
+    pj_xml_find_node(NULL, NULL);
+    pj_xml_find_next_node(NULL, NULL, NULL);
+    pj_xml_find_attr(NULL, NULL, NULL);
+    pj_xml_find(NULL, NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJLIB_SCANNER
+    pj_cis_buf_init(NULL);
+    pj_cis_init(NULL, NULL);
+    pj_cis_dup(NULL, NULL);
+    pj_cis_add_alpha(NULL);
+    pj_cis_add_str(NULL, NULL);
+
+    pj_scan_init(NULL, NULL, 0, 0, NULL);
+    pj_scan_fini(NULL);
+    pj_scan_peek(NULL, NULL, NULL);
+    pj_scan_peek_n(NULL, 0, NULL);
+    pj_scan_peek_until(NULL, NULL, NULL);
+    pj_scan_get(NULL, NULL, NULL);
+    pj_scan_get_unescape(NULL, NULL, NULL);
+    pj_scan_get_quote(NULL, 0, 0, NULL);
+    pj_scan_get_n(NULL, 0, NULL);
+    pj_scan_get_char(NULL);
+    pj_scan_get_until(NULL, NULL, NULL);
+    pj_scan_strcmp(NULL, NULL, 0);
+    pj_scan_stricmp(NULL, NULL, 0);
+    pj_scan_stricmp_alnum(NULL, NULL, 0);
+    pj_scan_get_newline(NULL);
+    pj_scan_restore_state(NULL, NULL);
+#endif
+
+#ifdef HAS_PJLIB_DNS
+    pj_dns_make_query(NULL, NULL, 0, 0, NULL);
+    pj_dns_parse_packet(NULL, NULL, 0, NULL);
+    pj_dns_packet_dup(NULL, NULL, 0, NULL);
+#endif
+
+#ifdef HAS_PJLIB_RESOLVER
+    pj_dns_resolver_create(NULL, NULL, 0, NULL, NULL, NULL);
+    pj_dns_resolver_set_ns(NULL, 0, NULL, NULL);
+    pj_dns_resolver_handle_events(NULL, NULL);
+    pj_dns_resolver_destroy(NULL, 0);
+    pj_dns_resolver_start_query(NULL, NULL, 0, 0, NULL, NULL, NULL);
+    pj_dns_resolver_cancel_query(NULL, 0);
+    pj_dns_resolver_add_entry(NULL, NULL, 0);
+#endif
+
+#ifdef HAS_PJLIB_SRV_RESOLVER
+    pj_dns_srv_resolve(NULL, NULL, 0, NULL, NULL, PJ_FALSE, NULL, NULL);
+#endif
+
+#ifdef HAS_PJLIB_CRC32
+    pj_crc32_init(NULL);
+    pj_crc32_update(NULL, NULL, 0);
+    pj_crc32_final(NULL);
+#endif
+
+#ifdef HAS_PJLIB_HMAC_MD5
+    pj_hmac_md5(NULL, 0, NULL, 0, NULL);
+#endif
+
+#ifdef HAS_PJLIB_HMAC_SHA1
+    pj_hmac_sha1(NULL, 0, NULL, 0, NULL);
+#endif
+
+#ifdef HAS_PJNATH_STUN
+    pj_stun_session_create(NULL, NULL, NULL, PJ_FALSE, NULL);
+    pj_stun_session_destroy(NULL);
+    pj_stun_session_set_credential(NULL, NULL);
+    pj_stun_session_create_req(NULL, 0, NULL, NULL);
+    pj_stun_session_create_ind(NULL, 0, NULL);
+    pj_stun_session_create_res(NULL, NULL, 0, NULL, NULL);
+    pj_stun_session_send_msg(NULL, PJ_FALSE, NULL, 0, NULL);
+#endif
+
+#ifdef HAS_PJNATH_ICE
+    pj_ice_strans_create(NULL, NULL, 0, NULL, NULL, NULL);
+    pj_ice_strans_set_stun_domain(NULL, NULL, NULL);
+    pj_ice_strans_create_comp(NULL, 0, 0, NULL);
+    pj_ice_strans_add_cand(NULL, 0, PJ_ICE_CAND_TYPE_HOST, 0, NULL, PJ_FALSE);
+    pj_ice_strans_init_ice(NULL, PJ_ICE_SESS_ROLE_CONTROLLED, NULL, NULL);
+    pj_ice_strans_start_ice(NULL, NULL, NULL, 0, NULL);
+    pj_ice_strans_stop_ice(NULL);
+    pj_ice_strans_sendto(NULL, 0, NULL, 0, NULL, 0);
+#endif
+
+#ifdef HAS_PJSIP_CORE_MSG_ELEM
+    /* Parameter container */
+    pjsip_param_find(NULL, NULL);
+    pjsip_param_print_on(NULL, NULL, 0, NULL, NULL, 0);
+
+    /* SIP URI */
+    pjsip_sip_uri_create(NULL, 0);
+    pjsip_name_addr_create(NULL);
+
+    /* TEL URI */
+    pjsip_tel_uri_create(NULL);
+
+    /* Message and headers */
+    pjsip_msg_create(NULL, PJSIP_REQUEST_MSG);
+    pjsip_msg_print(NULL, NULL, 0);
+    pjsip_accept_hdr_create(NULL);
+    pjsip_allow_hdr_create(NULL);
+    pjsip_cid_hdr_create(NULL);
+    pjsip_clen_hdr_create(NULL);
+    pjsip_cseq_hdr_create(NULL);
+    pjsip_contact_hdr_create(NULL);
+    pjsip_ctype_hdr_create(NULL);
+    pjsip_expires_hdr_create(NULL, 0);
+    pjsip_from_hdr_create(NULL);
+    pjsip_max_fwd_hdr_create(NULL, 0);
+    pjsip_min_expires_hdr_create(NULL, 0);
+    pjsip_rr_hdr_create(NULL);
+    pjsip_require_hdr_create(NULL);
+    pjsip_retry_after_hdr_create(NULL, 0);
+    pjsip_supported_hdr_create(NULL);
+    pjsip_unsupported_hdr_create(NULL);
+    pjsip_via_hdr_create(NULL);
+    pjsip_warning_hdr_create(NULL, 0, NULL, NULL);
+
+    pjsip_parse_uri(NULL, NULL, 0, 0);
+    pjsip_parse_msg(NULL, NULL, 0, NULL);
+    pjsip_parse_rdata(NULL, 0, NULL);
+    pjsip_find_msg(NULL, 0, 0, NULL);
+#endif
+
+#ifdef HAS_PJSIP_CORE
+    pjsip_endpt_create(NULL, NULL, NULL);
+
+    pjsip_tpmgr_create(NULL, NULL, NULL, NULL, NULL);
+    pjsip_tpmgr_destroy(NULL);
+    pjsip_transport_send(NULL, NULL, NULL, 0, NULL, NULL);
+
+
+#endif
+
+#ifdef HAS_PJSIP_CORE_MSG_UTIL
+    pjsip_endpt_create_request(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+			       -1, NULL, NULL);
+    pjsip_endpt_create_request_from_hdr(NULL, NULL, NULL, NULL, NULL, NULL,
+					NULL, -1, NULL, NULL);
+    pjsip_endpt_create_response(NULL, NULL, -1, NULL, NULL);
+    pjsip_endpt_create_ack(NULL, NULL, NULL, NULL);
+    pjsip_endpt_create_cancel(NULL, NULL, NULL);
+    pjsip_get_request_dest(NULL, NULL);
+    pjsip_endpt_send_request_stateless(NULL, NULL, NULL, NULL);
+    pjsip_get_response_addr(NULL, NULL, NULL);
+    pjsip_endpt_send_response(NULL, NULL, NULL, NULL, NULL);
+    pjsip_endpt_respond_stateless(NULL, NULL, -1, NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJSIP_UDP_TRANSPORT
+    pjsip_udp_transport_start(NULL, NULL, NULL, 1, NULL);
+#endif
+
+#ifdef HAS_PJSIP_TCP_TRANSPORT
+    pjsip_tcp_transport_start(NULL, NULL, 1, NULL);
+#endif
+
+#ifdef HAS_PJSIP_TLS_TRANSPORT
+    pjsip_tls_transport_start(NULL, NULL, NULL, NULL, 0, NULL);
+#endif
+
+#ifdef HAS_PJSIP_TRANSACTION
+    pjsip_tsx_layer_init_module(NULL);
+
+    pjsip_tsx_layer_destroy();
+    pjsip_tsx_create_uac(NULL, NULL, NULL);
+    pjsip_tsx_create_uas(NULL, NULL, NULL);
+    pjsip_tsx_recv_msg(NULL, NULL);
+    pjsip_tsx_send_msg(NULL, NULL);
+    pjsip_tsx_terminate(NULL, 200);
+
+    pjsip_endpt_send_request(NULL, NULL, -1, NULL, NULL);
+    pjsip_endpt_respond(NULL, NULL, NULL, -1, NULL, NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_SDP
+    pjmedia_sdp_parse(NULL, NULL, 1024, NULL);
+    pjmedia_sdp_print(NULL, NULL, 1024);
+    pjmedia_sdp_validate(NULL);
+    pjmedia_sdp_session_clone(NULL, NULL);
+    pjmedia_sdp_session_cmp(NULL, NULL, 0);
+    pjmedia_sdp_attr_to_rtpmap(NULL, NULL, NULL);
+    pjmedia_sdp_attr_get_fmtp(NULL, NULL);
+    pjmedia_sdp_attr_get_rtcp(NULL, NULL);
+    pjmedia_sdp_conn_clone(NULL, NULL);
+    pjmedia_sdp_media_clone(NULL, NULL);
+    pjmedia_sdp_media_find_attr(NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_SDP_NEGOTIATOR
+    pjmedia_sdp_neg_create_w_local_offer(NULL, NULL, NULL);
+    pjmedia_sdp_neg_create_w_remote_offer(NULL, NULL, NULL, NULL);
+    pjmedia_sdp_neg_get_state(NULL);
+    pjmedia_sdp_neg_negotiate(NULL, NULL, PJ_FALSE);
+#endif
+
+#ifdef HAS_PJSIP_UA_LAYER
+    pjsip_ua_init_module(NULL, NULL);
+    pjsip_ua_destroy();
+    pjsip_dlg_create_uac(NULL, NULL, NULL, NULL, NULL, NULL);
+    pjsip_dlg_create_uas(NULL, NULL, NULL, NULL);
+    pjsip_dlg_terminate(NULL);
+    pjsip_dlg_set_route_set(NULL, NULL);
+    pjsip_dlg_create_request(NULL, NULL, -1, NULL);
+    pjsip_dlg_send_request(NULL, NULL, -1, NULL);
+    pjsip_dlg_create_response(NULL, NULL, -1, NULL, NULL);
+    pjsip_dlg_modify_response(NULL, NULL, -1, NULL);
+    pjsip_dlg_send_response(NULL, NULL, NULL);
+    pjsip_dlg_respond(NULL, NULL, -1, NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJSIP_AUTH_CLIENT
+    pjsip_auth_clt_init(NULL, NULL, NULL, 0);
+    pjsip_auth_clt_clone(NULL, NULL, NULL);
+    pjsip_auth_clt_set_credentials(NULL, 0, NULL);
+    pjsip_auth_clt_init_req(NULL, NULL);
+    pjsip_auth_clt_reinit_req(NULL, NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJSIP_INV_SESSION
+    pjsip_inv_usage_init(NULL, NULL);
+    pjsip_inv_create_uac(NULL, NULL, 0, NULL);
+    pjsip_inv_verify_request(NULL, NULL, NULL, NULL, NULL, NULL);
+    pjsip_inv_create_uas(NULL, NULL, NULL, 0, NULL);
+    pjsip_inv_terminate(NULL, 200, PJ_FALSE);
+    pjsip_inv_invite(NULL, NULL);
+    pjsip_inv_initial_answer(NULL, NULL, 200, NULL, NULL, NULL);
+    pjsip_inv_answer(NULL, 200, NULL, NULL, NULL);
+    pjsip_inv_end_session(NULL, 200, NULL, NULL);
+    pjsip_inv_reinvite(NULL, NULL, NULL, NULL);
+    pjsip_inv_update(NULL, NULL, NULL, NULL);
+    pjsip_inv_send_msg(NULL, NULL);
+    pjsip_dlg_get_inv_session(NULL);
+    //pjsip_tsx_get_inv_session(NULL);
+    pjsip_inv_state_name(PJSIP_INV_STATE_NULL);
+#endif
+
+#ifdef HAS_PJSIP_REGC
+    //pjsip_regc_get_module();
+    pjsip_regc_create(NULL, NULL, NULL, NULL);
+    pjsip_regc_destroy(NULL);
+    pjsip_regc_get_info(NULL, NULL);
+    pjsip_regc_get_pool(NULL);
+    pjsip_regc_init(NULL, NULL, NULL, NULL, 0, NULL, 600);
+    pjsip_regc_set_credentials(NULL, 1, NULL);
+    pjsip_regc_set_route_set(NULL, NULL);
+    pjsip_regc_register(NULL, PJ_TRUE, NULL);
+    pjsip_regc_unregister(NULL, NULL);
+    pjsip_regc_update_contact(NULL, 10, NULL);
+    pjsip_regc_update_expires(NULL, 600);
+    pjsip_regc_send(NULL, NULL);
+#endif
+
+#ifdef HAS_PJSIP_EVENT_FRAMEWORK
+    pjsip_evsub_init_module(NULL);
+    pjsip_evsub_instance();
+    pjsip_evsub_register_pkg(NULL, NULL, 30, 10, NULL);
+    pjsip_evsub_create_uac(NULL, NULL, NULL, 10, NULL);
+    pjsip_evsub_create_uas(NULL, NULL, NULL, 10, NULL);
+    pjsip_evsub_terminate(NULL, PJ_FALSE);
+    pjsip_evsub_get_state(NULL);
+    pjsip_evsub_get_state_name(NULL);
+    pjsip_evsub_initiate(NULL, NULL, -1, NULL);
+    pjsip_evsub_accept(NULL, NULL, 200, NULL);
+    pjsip_evsub_notify(NULL, PJSIP_EVSUB_STATE_ACTIVE, NULL, NULL, NULL);
+    pjsip_evsub_current_notify(NULL, NULL);
+    pjsip_evsub_send_request(NULL, NULL);
+    pjsip_tsx_get_evsub(NULL);
+    pjsip_evsub_set_mod_data(NULL, 1, NULL);
+    pjsip_evsub_get_mod_data(NULL, 1);
+#endif
+
+#ifdef HAS_PJSIP_CALL_TRANSFER
+    pjsip_xfer_init_module(NULL);
+    pjsip_xfer_create_uac(NULL, NULL, NULL);
+    pjsip_xfer_create_uas(NULL, NULL, NULL, NULL);
+    pjsip_xfer_initiate(NULL, NULL, NULL);
+    pjsip_xfer_accept(NULL, NULL, 200, NULL);
+    pjsip_xfer_notify(NULL, PJSIP_EVSUB_STATE_ACTIVE, 200, NULL, NULL);
+    pjsip_xfer_current_notify(NULL, NULL);
+    pjsip_xfer_send_request(NULL, NULL);
+#endif
+
+#ifdef HAS_PJSIP_PRESENCE
+    pjsip_pres_init_module(NULL, NULL);
+    pjsip_pres_instance();
+    pjsip_pres_create_uac(NULL, NULL, 0, NULL);
+    pjsip_pres_create_uas(NULL, NULL, NULL, NULL);
+    pjsip_pres_terminate(NULL, PJ_FALSE);
+    pjsip_pres_initiate(NULL, 100, NULL);
+    pjsip_pres_accept(NULL, NULL, 200, NULL);
+    pjsip_pres_notify(NULL, PJSIP_EVSUB_STATE_ACTIVE, NULL, NULL, NULL);
+    pjsip_pres_current_notify(NULL, NULL);
+    pjsip_pres_send_request(NULL, NULL);
+    pjsip_pres_get_status(NULL, NULL);
+    pjsip_pres_set_status(NULL, NULL);
+#endif
+
+#ifdef HAS_PJSIP_IS_COMPOSING
+    pjsip_iscomposing_create_xml(NULL, PJ_TRUE, NULL, NULL, 0);
+    pjsip_iscomposing_create_body(NULL, PJ_TRUE, NULL, NULL, 0);
+    pjsip_iscomposing_parse(NULL, NULL, 0, NULL, NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA
+    pjmedia_endpt_create(NULL, NULL, 1, NULL);
+    pjmedia_endpt_destroy(NULL);
+    pjmedia_endpt_create_sdp(NULL, NULL, 1, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_EC
+    pjmedia_echo_create(NULL, 0, 0, 0, 0, 0, NULL);
+    pjmedia_echo_destroy(NULL);
+    pjmedia_echo_playback(NULL, NULL);
+    pjmedia_echo_capture(NULL, NULL, 0);
+    pjmedia_echo_cancel(NULL, NULL, NULL, 0, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_SND_DEV
+    pjmedia_snd_init(NULL);
+    pjmedia_snd_get_dev_count();
+    pjmedia_snd_get_dev_info(0);
+    pjmedia_snd_open(-1, -1, 8000, 1, 80, 16, NULL, NULL, NULL, NULL);
+    pjmedia_snd_open_rec(-1, 8000, 1, 160, 16, NULL, NULL, NULL);
+    pjmedia_snd_open_player(-1, 8000, 1, 160, 16, NULL, NULL, NULL);
+    pjmedia_snd_stream_start(NULL);
+    pjmedia_snd_stream_stop(NULL);
+    pjmedia_snd_stream_close(NULL);
+    pjmedia_snd_deinit();
+#endif
+
+#ifdef HAS_PJMEDIA_SND_PORT
+    pjmedia_snd_port_create(NULL, -1, -1, 8000, 1, 180, 16, 0, NULL);
+    pjmedia_snd_port_create_rec(NULL, -1, 8000, 1, 160, 16, 0, NULL);
+    pjmedia_snd_port_create_player(NULL, -1, 8000, 1, 160, 16, 0, NULL);
+    pjmedia_snd_port_destroy(NULL);
+    pjmedia_snd_port_get_snd_stream(NULL);
+    pjmedia_snd_port_connect(NULL, NULL);
+    pjmedia_snd_port_get_port(NULL);
+    pjmedia_snd_port_disconnect(NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_RESAMPLE
+    pjmedia_resample_create(NULL, PJ_TRUE, PJ_TRUE, 0, 0, 0, 0, NULL);
+    pjmedia_resample_run(NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_SILENCE_DET
+    pjmedia_silence_det_create(NULL, 8000, 80, NULL);
+    pjmedia_silence_det_detect(NULL, NULL, 0, NULL);
+    pjmedia_silence_det_apply(NULL, 0);
+#endif
+
+#ifdef HAS_PJMEDIA_PLC
+    pjmedia_plc_create(NULL, 8000, 80, 0, NULL);
+    pjmedia_plc_save(NULL, NULL);
+    pjmedia_plc_generate(NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_CONFERENCE
+    pjmedia_conf_create(NULL, 10, 8000, 1, 160, 16, 0, NULL);
+    pjmedia_conf_destroy(NULL);
+    pjmedia_conf_get_master_port(NULL);
+    pjmedia_conf_add_port(NULL, NULL, NULL, NULL, NULL);
+    pjmedia_conf_configure_port(NULL, 1, 0, 0);
+    pjmedia_conf_connect_port(NULL, 0, 0, 0);
+    pjmedia_conf_disconnect_port(NULL, 0, 0);
+    pjmedia_conf_remove_port(NULL, 0);
+    pjmedia_conf_enum_ports(NULL, NULL, NULL);
+    pjmedia_conf_get_port_info(NULL, 0, NULL);
+    pjmedia_conf_get_ports_info(NULL, NULL, NULL);
+    pjmedia_conf_get_signal_level(NULL, 0, NULL, NULL);
+    pjmedia_conf_adjust_rx_level(NULL, 0, 0);
+    pjmedia_conf_adjust_tx_level(NULL, 0, 0);
+#endif
+
+#ifdef HAS_PJMEDIA_MASTER_PORT
+    pjmedia_master_port_create(NULL, NULL, NULL, 0, NULL);
+    pjmedia_master_port_start(NULL);
+    pjmedia_master_port_stop(NULL);
+    pjmedia_master_port_set_uport(NULL, NULL);
+    pjmedia_master_port_get_uport(NULL);
+    pjmedia_master_port_set_dport(NULL, NULL);
+    pjmedia_master_port_get_dport(NULL);
+    pjmedia_master_port_destroy(NULL, PJ_FALSE);
+#endif
+
+#ifdef HAS_PJMEDIA_RTP
+    pjmedia_rtp_session_init(NULL, 0, 0);
+    pjmedia_rtp_encode_rtp(NULL, 0, 0, 0, 0, NULL, NULL);
+    pjmedia_rtp_decode_rtp(NULL, NULL, 0, NULL, NULL, NULL);
+    pjmedia_rtp_session_update(NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_RTCP
+    pjmedia_rtcp_init(NULL, NULL, 0, 0, 0);
+    pjmedia_rtcp_get_ntp_time(NULL, NULL);
+    pjmedia_rtcp_fini(NULL);
+    pjmedia_rtcp_rx_rtp(NULL, 0, 0, 0);
+    pjmedia_rtcp_tx_rtp(NULL, 0);
+    pjmedia_rtcp_rx_rtcp(NULL, NULL, 0);
+    pjmedia_rtcp_build_rtcp(NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_JBUF
+    pjmedia_jbuf_create(NULL, NULL, 0, 0, 0, NULL);
+    pjmedia_jbuf_set_fixed(NULL, 0);
+    pjmedia_jbuf_set_adaptive(NULL, 0, 0, 0);
+    pjmedia_jbuf_destroy(NULL);
+    pjmedia_jbuf_put_frame(NULL, NULL, 0, 0);
+    pjmedia_jbuf_get_frame(NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_STREAM
+    pjmedia_stream_create(NULL, NULL, NULL, NULL, NULL, NULL);
+    pjmedia_stream_destroy(NULL);
+    pjmedia_stream_get_port(NULL, NULL);
+    pjmedia_stream_get_transport(NULL);
+    pjmedia_stream_start(NULL);
+    pjmedia_stream_get_stat(NULL, NULL);
+    pjmedia_stream_pause(NULL, PJMEDIA_DIR_ENCODING);
+    pjmedia_stream_resume(NULL, PJMEDIA_DIR_ENCODING);
+    pjmedia_stream_dial_dtmf(NULL, NULL);
+    pjmedia_stream_check_dtmf(NULL);
+    pjmedia_stream_get_dtmf(NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_TONEGEN
+    pjmedia_tonegen_create(NULL, 0, 0, 0, 0, 0, NULL);
+    pjmedia_tonegen_is_busy(NULL);
+    pjmedia_tonegen_stop(NULL);
+    pjmedia_tonegen_play(NULL, 0, NULL, 0);
+    pjmedia_tonegen_play_digits(NULL, 0, NULL, 0);
+    pjmedia_tonegen_get_digit_map(NULL, NULL);
+    pjmedia_tonegen_set_digit_map(NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_UDP_TRANSPORT
+    pjmedia_transport_udp_create(NULL, NULL, 0, 0, NULL);
+    pjmedia_transport_udp_close(NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_FILE_PLAYER
+    pjmedia_wav_player_port_create(NULL, NULL, 0, 0, 0, NULL);
+    pjmedia_wav_player_port_set_pos(NULL, 0);
+    pjmedia_wav_player_port_get_pos(NULL);
+    pjmedia_wav_player_set_eof_cb(NULL, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_FILE_CAPTURE
+    pjmedia_wav_writer_port_create(NULL, NULL, 8000, 1, 80, 16, 0, 0, NULL);
+    pjmedia_wav_writer_port_get_pos(NULL);
+    pjmedia_wav_writer_port_set_cb(NULL, 0, NULL, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_MEM_PLAYER
+    pjmedia_mem_player_create(NULL, NULL, 1000, 8000, 1, 80, 16, 0, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_MEM_CAPTURE
+    pjmedia_mem_capture_create(NULL, NULL, 1000, 8000, 1, 80, 16, 0, NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_ICE
+    pjmedia_ice_create(NULL, NULL, 0, NULL, NULL);
+    pjmedia_ice_destroy(NULL);
+    pjmedia_ice_start_init(NULL, 0, NULL, NULL, NULL);
+    pjmedia_ice_init_ice(NULL, PJ_ICE_SESS_ROLE_CONTROLLED, NULL, NULL);
+    pjmedia_ice_modify_sdp(NULL, NULL, NULL);
+    pjmedia_ice_start_ice(NULL, NULL, NULL, 0);
+    pjmedia_ice_stop_ice(NULL);
+#endif
+
+#ifdef HAS_PJMEDIA_G711_CODEC
+    pjmedia_codec_g711_init(NULL);
+    pjmedia_codec_g711_deinit();
+#endif
+
+#ifdef HAS_PJMEDIA_GSM_CODEC
+    pjmedia_codec_gsm_init(NULL);
+    pjmedia_codec_gsm_deinit();
+#endif
+
+#ifdef HAS_PJMEDIA_SPEEX_CODEC
+    pjmedia_codec_speex_init(NULL, 0, 0, 0);
+    pjmedia_codec_speex_deinit();
+#endif
+
+#ifdef HAS_PJMEDIA_ILBC_CODEC
+    pjmedia_codec_ilbc_init(NULL, 0);
+    pjmedia_codec_ilbc_deinit();
+#endif
+
+    return 0;
+}
+
+
+int test_main()
+{
+    return dummy_function();
+}
+
+#if defined(PJ_RTEMS) && PJ_RTEMS!=0
+#  include "../../pjlib/src/pjlib-test/main_rtems.c"
+#else
+int main()
+{
+  return test_main();
+}
+#endif
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/httpdemo.c b/jni/libpjsip/sources/pjsip-apps/src/samples/httpdemo.c
new file mode 100644
index 0000000..6b2bf8e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/httpdemo.c
@@ -0,0 +1,183 @@
+/* $Id: httpdemo.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 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 
+ */
+
+/**
+ * \page page_httpdemo_c Samples: HTTP Client demo
+ *
+ * This file is pjsip-apps/src/samples/httpdemo.c
+ *
+ * \includelineno httpdemo.c
+ */
+
+#include <pjlib.h>
+#include <pjlib-util.h>
+#include <pjlib-util/http_client.h>
+#include <pjsip.h>
+#include <pjmedia.h>
+#include <pjnath.h>
+#include <pjsip_simple.h>
+
+static pj_timer_heap_t *timer_heap;
+static pj_ioqueue_t *ioqueue;
+static pj_pool_t *pool;
+static pj_http_req *http_req;
+static pj_pool_factory *mem;
+static FILE *f = NULL;
+
+//#define VERBOSE
+#define THIS_FILE	    "http_demo"
+
+static void on_response(pj_http_req *http_req, const pj_http_resp *resp)
+{
+    unsigned i;
+
+    PJ_UNUSED_ARG(http_req);
+    PJ_LOG(3,(THIS_FILE, "%.*s %d %.*s", (int)resp->version.slen, resp->version.ptr,
+				           resp->status_code,
+				           (int)resp->reason.slen, resp->reason.ptr));
+
+    for (i=0; i<resp->headers.count; ++i) {
+	const pj_http_header_elmt *h = &resp->headers.header[i];
+
+	if (!pj_stricmp2(&h->name, "Content-Length") ||
+	    !pj_stricmp2(&h->name, "Content-Type"))
+	{
+	    PJ_LOG(3,(THIS_FILE, "%.*s: %.*s",
+		      (int)h->name.slen, h->name.ptr,
+		      (int)h->value.slen, h->value.ptr));
+	}
+    }
+}
+
+static void on_send_data(pj_http_req *http_req, void **data, pj_size_t *size)
+{
+	PJ_UNUSED_ARG(http_req);
+	PJ_UNUSED_ARG(size);
+	PJ_UNUSED_ARG(data);
+}
+
+static void on_data_read(pj_http_req *hreq, void *data, pj_size_t size)
+{
+    PJ_UNUSED_ARG(hreq);
+
+    if (size > 0) {
+        fwrite(data, 1, size, f);
+        fflush(f);
+#ifdef VERBOSE
+        PJ_LOG(3, (THIS_FILE, "Data received: %d bytes", size));
+        printf("%.*s\n", (int)size, (char *)data);
+#endif
+    }
+}
+
+static void on_complete(pj_http_req *hreq, pj_status_t status,
+                        const pj_http_resp *resp)
+{
+    PJ_UNUSED_ARG(hreq);
+
+    if (status != PJ_SUCCESS) {
+        PJ_PERROR(1, (THIS_FILE, status, "HTTP request completed with error"));
+        return;
+    }
+    PJ_LOG(3, (THIS_FILE, "Data completed: %d bytes", resp->size));
+    if (resp->size > 0 && resp->data) {
+#ifdef VERBOSE
+        printf("%.*s\n", (int)resp->size, (char *)resp->data);
+#endif
+    }
+}
+
+pj_status_t getURL(const char *curl)
+{
+    pj_str_t url;
+    pj_http_req_callback hcb;
+    pj_status_t status;
+
+    pj_bzero(&hcb, sizeof(hcb));
+    hcb.on_complete = &on_complete;
+    hcb.on_data_read = &on_data_read;
+    hcb.on_send_data = &on_send_data;
+    hcb.on_response = &on_response;
+
+    /* Create pool, timer, and ioqueue */
+    pool = pj_pool_create(mem, NULL, 8192, 4096, NULL);
+    if (pj_timer_heap_create(pool, 16, &timer_heap))
+        return -31;
+    if (pj_ioqueue_create(pool, 16, &ioqueue))
+        return -32;
+
+    pj_strdup2(pool, &url, curl);
+
+    if ((status = pj_http_req_create(pool, &url, timer_heap, ioqueue, 
+                           NULL, &hcb, &http_req)) != PJ_SUCCESS)
+        return status;
+
+    if ((status = pj_http_req_start(http_req)) != PJ_SUCCESS)
+        return status;
+
+    while (pj_http_req_is_running(http_req)) {
+        pj_time_val delay = {0, 50};
+	pj_ioqueue_poll(ioqueue, &delay);
+	pj_timer_heap_poll(timer_heap, NULL);
+    }
+
+    pj_http_req_destroy(http_req);
+    pj_ioqueue_destroy(ioqueue);
+    pj_timer_heap_destroy(timer_heap);
+    pj_pool_release(pool);
+
+    return PJ_SUCCESS;
+}
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pj_status_t status;
+
+    if (argc < 2 || argc > 3) {
+	puts("Usage: httpdemo URL [output-filename]");
+	return 1;
+    }
+
+    pj_log_set_level(5);
+
+    pj_init();
+    pj_caching_pool_init(&cp, NULL, 0);
+    mem = &cp.factory;
+    pjlib_util_init();
+
+    if (argc > 2)
+	f = fopen(argv[2], "wb");
+    else
+	f = stdout;
+
+    status = getURL(argv[1]);
+    if (status != PJ_SUCCESS) {
+        PJ_PERROR(1, (THIS_FILE, status, "Error"));
+    }
+
+    if (f != stdout)
+	fclose(f);
+
+    pj_caching_pool_destroy(&cp);
+    pj_shutdown();
+    return 0;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/icedemo.c b/jni/libpjsip/sources/pjsip-apps/src/samples/icedemo.c
new file mode 100644
index 0000000..8dbba21
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/icedemo.c
@@ -0,0 +1,1272 @@
+/* $Id: icedemo.c 4624 2013-10-21 06:37:30Z ming $ */
+/* 
+ * Copyright (C) 2008-2011 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 <stdio.h>
+#include <stdlib.h>
+#include <pjlib.h>
+#include <pjlib-util.h>
+#include <pjnath.h>
+
+
+#define THIS_FILE   "icedemo.c"
+
+/* For this demo app, configure longer STUN keep-alive time
+ * so that it does't clutter the screen output.
+ */
+#define KA_INTERVAL 300
+
+
+/* This is our global variables */
+static struct app_t
+{
+    /* Command line options are stored here */
+    struct options
+    {
+	unsigned    comp_cnt;
+	pj_str_t    ns;
+	int	    max_host;
+	pj_bool_t   regular;
+	pj_str_t    stun_srv;
+	pj_str_t    turn_srv;
+	pj_bool_t   turn_tcp;
+	pj_str_t    turn_username;
+	pj_str_t    turn_password;
+	pj_bool_t   turn_fingerprint;
+	const char *log_file;
+    } opt;
+
+    /* Our global variables */
+    pj_caching_pool	 cp;
+    pj_pool_t		*pool;
+    pj_thread_t		*thread;
+    pj_bool_t		 thread_quit_flag;
+    pj_ice_strans_cfg	 ice_cfg;
+    pj_ice_strans	*icest;
+    FILE		*log_fhnd;
+
+    /* Variables to store parsed remote ICE info */
+    struct rem_info
+    {
+	char		 ufrag[80];
+	char		 pwd[80];
+	unsigned	 comp_cnt;
+	pj_sockaddr	 def_addr[PJ_ICE_MAX_COMP];
+	unsigned	 cand_cnt;
+	pj_ice_sess_cand cand[PJ_ICE_ST_MAX_CAND];
+    } rem;
+
+} icedemo;
+
+/* Utility to display error messages */
+static void icedemo_perror(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(1,(THIS_FILE, "%s: %s", title, errmsg));
+}
+
+/* Utility: display error message and exit application (usually
+ * because of fatal error.
+ */
+static void err_exit(const char *title, pj_status_t status)
+{
+    if (status != PJ_SUCCESS) {
+	icedemo_perror(title, status);
+    }
+    PJ_LOG(3,(THIS_FILE, "Shutting down.."));
+
+    if (icedemo.icest)
+	pj_ice_strans_destroy(icedemo.icest);
+    
+    pj_thread_sleep(500);
+
+    icedemo.thread_quit_flag = PJ_TRUE;
+    if (icedemo.thread) {
+	pj_thread_join(icedemo.thread);
+	pj_thread_destroy(icedemo.thread);
+    }
+
+    if (icedemo.ice_cfg.stun_cfg.ioqueue)
+	pj_ioqueue_destroy(icedemo.ice_cfg.stun_cfg.ioqueue);
+
+    if (icedemo.ice_cfg.stun_cfg.timer_heap)
+	pj_timer_heap_destroy(icedemo.ice_cfg.stun_cfg.timer_heap);
+
+    pj_caching_pool_destroy(&icedemo.cp);
+
+    pj_shutdown();
+
+    if (icedemo.log_fhnd) {
+	fclose(icedemo.log_fhnd);
+	icedemo.log_fhnd = NULL;
+    }
+
+    exit(status != PJ_SUCCESS);
+}
+
+#define CHECK(expr)	status=expr; \
+			if (status!=PJ_SUCCESS) { \
+			    err_exit(#expr, status); \
+			}
+
+/*
+ * This function checks for events from both timer and ioqueue (for
+ * network events). It is invoked by the worker thread.
+ */
+static pj_status_t handle_events(unsigned max_msec, unsigned *p_count)
+{
+    enum { MAX_NET_EVENTS = 1 };
+    pj_time_val max_timeout = {0, 0};
+    pj_time_val timeout = { 0, 0};
+    unsigned count = 0, net_event_count = 0;
+    int c;
+
+    max_timeout.msec = max_msec;
+
+    /* Poll the timer to run it and also to retrieve the earliest entry. */
+    timeout.sec = timeout.msec = 0;
+    c = pj_timer_heap_poll( icedemo.ice_cfg.stun_cfg.timer_heap, &timeout );
+    if (c > 0)
+	count += c;
+
+    /* timer_heap_poll should never ever returns negative value, or otherwise
+     * ioqueue_poll() will block forever!
+     */
+    pj_assert(timeout.sec >= 0 && timeout.msec >= 0);
+    if (timeout.msec >= 1000) timeout.msec = 999;
+
+    /* compare the value with the timeout to wait from timer, and use the 
+     * minimum value. 
+    */
+    if (PJ_TIME_VAL_GT(timeout, max_timeout))
+	timeout = max_timeout;
+
+    /* Poll ioqueue. 
+     * Repeat polling the ioqueue while we have immediate events, because
+     * timer heap may process more than one events, so if we only process
+     * one network events at a time (such as when IOCP backend is used),
+     * the ioqueue may have trouble keeping up with the request rate.
+     *
+     * For example, for each send() request, one network event will be
+     *   reported by ioqueue for the send() completion. If we don't poll
+     *   the ioqueue often enough, the send() completion will not be
+     *   reported in timely manner.
+     */
+    do {
+	c = pj_ioqueue_poll( icedemo.ice_cfg.stun_cfg.ioqueue, &timeout);
+	if (c < 0) {
+	    pj_status_t err = pj_get_netos_error();
+	    pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout));
+	    if (p_count)
+		*p_count = count;
+	    return err;
+	} else if (c == 0) {
+	    break;
+	} else {
+	    net_event_count += c;
+	    timeout.sec = timeout.msec = 0;
+	}
+    } while (c > 0 && net_event_count < MAX_NET_EVENTS);
+
+    count += net_event_count;
+    if (p_count)
+	*p_count = count;
+
+    return PJ_SUCCESS;
+
+}
+
+/*
+ * This is the worker thread that polls event in the background.
+ */
+static int icedemo_worker_thread(void *unused)
+{
+    PJ_UNUSED_ARG(unused);
+
+    while (!icedemo.thread_quit_flag) {
+	handle_events(500, NULL);
+    }
+
+    return 0;
+}
+
+/*
+ * This is the callback that is registered to the ICE stream transport to
+ * receive notification about incoming data. By "data" it means application
+ * data such as RTP/RTCP, and not packets that belong to ICE signaling (such
+ * as STUN connectivity checks or TURN signaling).
+ */
+static void cb_on_rx_data(pj_ice_strans *ice_st,
+			  unsigned comp_id, 
+			  void *pkt, pj_size_t size,
+			  const pj_sockaddr_t *src_addr,
+			  unsigned src_addr_len)
+{
+    char ipstr[PJ_INET6_ADDRSTRLEN+10];
+
+    PJ_UNUSED_ARG(ice_st);
+    PJ_UNUSED_ARG(src_addr_len);
+    PJ_UNUSED_ARG(pkt);
+
+    // Don't do this! It will ruin the packet buffer in case TCP is used!
+    //((char*)pkt)[size] = '\0';
+
+    PJ_LOG(3,(THIS_FILE, "Component %d: received %d bytes data from %s: \"%.*s\"",
+	      comp_id, size,
+	      pj_sockaddr_print(src_addr, ipstr, sizeof(ipstr), 3),
+	      (unsigned)size,
+	      (char*)pkt));
+}
+
+/*
+ * This is the callback that is registered to the ICE stream transport to
+ * receive notification about ICE state progression.
+ */
+static void cb_on_ice_complete(pj_ice_strans *ice_st, 
+			       pj_ice_strans_op op,
+			       pj_status_t status)
+{
+    const char *opname = 
+	(op==PJ_ICE_STRANS_OP_INIT? "initialization" :
+	    (op==PJ_ICE_STRANS_OP_NEGOTIATION ? "negotiation" : "unknown_op"));
+
+    if (status == PJ_SUCCESS) {
+	PJ_LOG(3,(THIS_FILE, "ICE %s successful", opname));
+    } else {
+	char errmsg[PJ_ERR_MSG_SIZE];
+
+	pj_strerror(status, errmsg, sizeof(errmsg));
+	PJ_LOG(1,(THIS_FILE, "ICE %s failed: %s", opname, errmsg));
+	pj_ice_strans_destroy(ice_st);
+	icedemo.icest = NULL;
+    }
+}
+
+/* log callback to write to file */
+static void log_func(int level, const char *data, int len)
+{
+    pj_log_write(level, data, len);
+    if (icedemo.log_fhnd) {
+	if (fwrite(data, len, 1, icedemo.log_fhnd) != 1)
+	    return;
+    }
+}
+
+/*
+ * This is the main application initialization function. It is called
+ * once (and only once) during application initialization sequence by 
+ * main().
+ */
+static pj_status_t icedemo_init(void)
+{
+    pj_status_t status;
+
+    if (icedemo.opt.log_file) {
+	icedemo.log_fhnd = fopen(icedemo.opt.log_file, "a");
+	pj_log_set_log_func(&log_func);
+    }
+
+    /* Initialize the libraries before anything else */
+    CHECK( pj_init() );
+    CHECK( pjlib_util_init() );
+    CHECK( pjnath_init() );
+
+    /* Must create pool factory, where memory allocations come from */
+    pj_caching_pool_init(&icedemo.cp, NULL, 0);
+
+    /* Init our ICE settings with null values */
+    pj_ice_strans_cfg_default(&icedemo.ice_cfg);
+
+    icedemo.ice_cfg.stun_cfg.pf = &icedemo.cp.factory;
+
+    /* Create application memory pool */
+    icedemo.pool = pj_pool_create(&icedemo.cp.factory, "icedemo", 
+				  512, 512, NULL);
+
+    /* Create timer heap for timer stuff */
+    CHECK( pj_timer_heap_create(icedemo.pool, 100, 
+				&icedemo.ice_cfg.stun_cfg.timer_heap) );
+
+    /* and create ioqueue for network I/O stuff */
+    CHECK( pj_ioqueue_create(icedemo.pool, 16, 
+			     &icedemo.ice_cfg.stun_cfg.ioqueue) );
+
+    /* something must poll the timer heap and ioqueue, 
+     * unless we're on Symbian where the timer heap and ioqueue run
+     * on themselves.
+     */
+    CHECK( pj_thread_create(icedemo.pool, "icedemo", &icedemo_worker_thread,
+			    NULL, 0, 0, &icedemo.thread) );
+
+    icedemo.ice_cfg.af = pj_AF_INET();
+
+    /* Create DNS resolver if nameserver is set */
+    if (icedemo.opt.ns.slen) {
+	CHECK( pj_dns_resolver_create(&icedemo.cp.factory, 
+				      "resolver", 
+				      0, 
+				      icedemo.ice_cfg.stun_cfg.timer_heap,
+				      icedemo.ice_cfg.stun_cfg.ioqueue, 
+				      &icedemo.ice_cfg.resolver) );
+
+	CHECK( pj_dns_resolver_set_ns(icedemo.ice_cfg.resolver, 1, 
+				      &icedemo.opt.ns, NULL) );
+    }
+
+    /* -= Start initializing ICE stream transport config =- */
+
+    /* Maximum number of host candidates */
+    if (icedemo.opt.max_host != -1)
+	icedemo.ice_cfg.stun.max_host_cands = icedemo.opt.max_host;
+
+    /* Nomination strategy */
+    if (icedemo.opt.regular)
+	icedemo.ice_cfg.opt.aggressive = PJ_FALSE;
+    else
+	icedemo.ice_cfg.opt.aggressive = PJ_TRUE;
+
+    /* Configure STUN/srflx candidate resolution */
+    if (icedemo.opt.stun_srv.slen) {
+	char *pos;
+
+	/* Command line option may contain port number */
+	if ((pos=pj_strchr(&icedemo.opt.stun_srv, ':')) != NULL) {
+	    icedemo.ice_cfg.stun.server.ptr = icedemo.opt.stun_srv.ptr;
+	    icedemo.ice_cfg.stun.server.slen = (pos - icedemo.opt.stun_srv.ptr);
+
+	    icedemo.ice_cfg.stun.port = (pj_uint16_t)atoi(pos+1);
+	} else {
+	    icedemo.ice_cfg.stun.server = icedemo.opt.stun_srv;
+	    icedemo.ice_cfg.stun.port = PJ_STUN_PORT;
+	}
+
+	/* For this demo app, configure longer STUN keep-alive time
+	 * so that it does't clutter the screen output.
+	 */
+	icedemo.ice_cfg.stun.cfg.ka_interval = KA_INTERVAL;
+    }
+
+    /* Configure TURN candidate */
+    if (icedemo.opt.turn_srv.slen) {
+	char *pos;
+
+	/* Command line option may contain port number */
+	if ((pos=pj_strchr(&icedemo.opt.turn_srv, ':')) != NULL) {
+	    icedemo.ice_cfg.turn.server.ptr = icedemo.opt.turn_srv.ptr;
+	    icedemo.ice_cfg.turn.server.slen = (pos - icedemo.opt.turn_srv.ptr);
+
+	    icedemo.ice_cfg.turn.port = (pj_uint16_t)atoi(pos+1);
+	} else {
+	    icedemo.ice_cfg.turn.server = icedemo.opt.turn_srv;
+	    icedemo.ice_cfg.turn.port = PJ_STUN_PORT;
+	}
+
+	/* TURN credential */
+	icedemo.ice_cfg.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
+	icedemo.ice_cfg.turn.auth_cred.data.static_cred.username = icedemo.opt.turn_username;
+	icedemo.ice_cfg.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
+	icedemo.ice_cfg.turn.auth_cred.data.static_cred.data = icedemo.opt.turn_password;
+
+	/* Connection type to TURN server */
+	if (icedemo.opt.turn_tcp)
+	    icedemo.ice_cfg.turn.conn_type = PJ_TURN_TP_TCP;
+	else
+	    icedemo.ice_cfg.turn.conn_type = PJ_TURN_TP_UDP;
+
+	/* For this demo app, configure longer keep-alive time
+	 * so that it does't clutter the screen output.
+	 */
+	icedemo.ice_cfg.turn.alloc_param.ka_interval = KA_INTERVAL;
+    }
+
+    /* -= That's it for now, initialization is complete =- */
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Create ICE stream transport instance, invoked from the menu.
+ */
+static void icedemo_create_instance(void)
+{
+    pj_ice_strans_cb icecb;
+    pj_status_t status;
+
+    if (icedemo.icest != NULL) {
+	puts("ICE instance already created, destroy it first");
+	return;
+    }
+
+    /* init the callback */
+    pj_bzero(&icecb, sizeof(icecb));
+    icecb.on_rx_data = cb_on_rx_data;
+    icecb.on_ice_complete = cb_on_ice_complete;
+
+    /* create the instance */
+    status = pj_ice_strans_create("icedemo",		    /* object name  */
+				&icedemo.ice_cfg,	    /* settings	    */
+				icedemo.opt.comp_cnt,	    /* comp_cnt	    */
+				NULL,			    /* user data    */
+				&icecb,			    /* callback	    */
+				&icedemo.icest)		    /* instance ptr */
+				;
+    if (status != PJ_SUCCESS)
+	icedemo_perror("error creating ice", status);
+    else
+	PJ_LOG(3,(THIS_FILE, "ICE instance successfully created"));
+}
+
+/* Utility to nullify parsed remote info */
+static void reset_rem_info(void)
+{
+    pj_bzero(&icedemo.rem, sizeof(icedemo.rem));
+}
+
+
+/*
+ * Destroy ICE stream transport instance, invoked from the menu.
+ */
+static void icedemo_destroy_instance(void)
+{
+    if (icedemo.icest == NULL) {
+	PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
+	return;
+    }
+
+    pj_ice_strans_destroy(icedemo.icest);
+    icedemo.icest = NULL;
+
+    reset_rem_info();
+
+    PJ_LOG(3,(THIS_FILE, "ICE instance destroyed"));
+}
+
+
+/*
+ * Create ICE session, invoked from the menu.
+ */
+static void icedemo_init_session(unsigned rolechar)
+{
+    pj_ice_sess_role role = (pj_tolower((pj_uint8_t)rolechar)=='o' ? 
+				PJ_ICE_SESS_ROLE_CONTROLLING : 
+				PJ_ICE_SESS_ROLE_CONTROLLED);
+    pj_status_t status;
+
+    if (icedemo.icest == NULL) {
+	PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
+	return;
+    }
+
+    if (pj_ice_strans_has_sess(icedemo.icest)) {
+	PJ_LOG(1,(THIS_FILE, "Error: Session already created"));
+	return;
+    }
+
+    status = pj_ice_strans_init_ice(icedemo.icest, role, NULL, NULL);
+    if (status != PJ_SUCCESS)
+	icedemo_perror("error creating session", status);
+    else
+	PJ_LOG(3,(THIS_FILE, "ICE session created"));
+
+    reset_rem_info();
+}
+
+
+/*
+ * Stop/destroy ICE session, invoked from the menu.
+ */
+static void icedemo_stop_session(void)
+{
+    pj_status_t status;
+
+    if (icedemo.icest == NULL) {
+	PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
+	return;
+    }
+
+    if (!pj_ice_strans_has_sess(icedemo.icest)) {
+	PJ_LOG(1,(THIS_FILE, "Error: No ICE session, initialize first"));
+	return;
+    }
+
+    status = pj_ice_strans_stop_ice(icedemo.icest);
+    if (status != PJ_SUCCESS)
+	icedemo_perror("error stopping session", status);
+    else
+	PJ_LOG(3,(THIS_FILE, "ICE session stopped"));
+
+    reset_rem_info();
+}
+
+#define PRINT(...)	    \
+	printed = pj_ansi_snprintf(p, maxlen - (p-buffer),  \
+				   __VA_ARGS__); \
+	if (printed <= 0 || printed >= (int)(maxlen - (p-buffer))) \
+	    return -PJ_ETOOSMALL; \
+	p += printed
+
+
+/* Utility to create a=candidate SDP attribute */
+static int print_cand(char buffer[], unsigned maxlen,
+		      const pj_ice_sess_cand *cand)
+{
+    char ipaddr[PJ_INET6_ADDRSTRLEN];
+    char *p = buffer;
+    int printed;
+
+    PRINT("a=candidate:%.*s %u UDP %u %s %u typ ",
+	  (int)cand->foundation.slen,
+	  cand->foundation.ptr,
+	  (unsigned)cand->comp_id,
+	  cand->prio,
+	  pj_sockaddr_print(&cand->addr, ipaddr, 
+			    sizeof(ipaddr), 0),
+	  (unsigned)pj_sockaddr_get_port(&cand->addr));
+
+    PRINT("%s\n",
+	  pj_ice_get_cand_type_name(cand->type));
+
+    if (p == buffer+maxlen)
+	return -PJ_ETOOSMALL;
+
+    *p = '\0';
+
+    return (int)(p-buffer);
+}
+
+/* 
+ * Encode ICE information in SDP.
+ */
+static int encode_session(char buffer[], unsigned maxlen)
+{
+    char *p = buffer;
+    unsigned comp;
+    int printed;
+    pj_str_t local_ufrag, local_pwd;
+    pj_status_t status;
+
+    /* Write "dummy" SDP v=, o=, s=, and t= lines */
+    PRINT("v=0\no=- 3414953978 3414953978 IN IP4 localhost\ns=ice\nt=0 0\n");
+
+    /* Get ufrag and pwd from current session */
+    pj_ice_strans_get_ufrag_pwd(icedemo.icest, &local_ufrag, &local_pwd,
+				NULL, NULL);
+
+    /* Write the a=ice-ufrag and a=ice-pwd attributes */
+    PRINT("a=ice-ufrag:%.*s\na=ice-pwd:%.*s\n",
+	   (int)local_ufrag.slen,
+	   local_ufrag.ptr,
+	   (int)local_pwd.slen,
+	   local_pwd.ptr);
+
+    /* Write each component */
+    for (comp=0; comp<icedemo.opt.comp_cnt; ++comp) {
+	unsigned j, cand_cnt;
+	pj_ice_sess_cand cand[PJ_ICE_ST_MAX_CAND];
+	char ipaddr[PJ_INET6_ADDRSTRLEN];
+
+	/* Get default candidate for the component */
+	status = pj_ice_strans_get_def_cand(icedemo.icest, comp+1, &cand[0]);
+	if (status != PJ_SUCCESS)
+	    return -status;
+
+	/* Write the default address */
+	if (comp==0) {
+	    /* For component 1, default address is in m= and c= lines */
+	    PRINT("m=audio %d RTP/AVP 0\n"
+		  "c=IN IP4 %s\n",
+		  (int)pj_sockaddr_get_port(&cand[0].addr),
+		  pj_sockaddr_print(&cand[0].addr, ipaddr,
+				    sizeof(ipaddr), 0));
+	} else if (comp==1) {
+	    /* For component 2, default address is in a=rtcp line */
+	    PRINT("a=rtcp:%d IN IP4 %s\n",
+		  (int)pj_sockaddr_get_port(&cand[0].addr),
+		  pj_sockaddr_print(&cand[0].addr, ipaddr,
+				    sizeof(ipaddr), 0));
+	} else {
+	    /* For other components, we'll just invent this.. */
+	    PRINT("a=Xice-defcand:%d IN IP4 %s\n",
+		  (int)pj_sockaddr_get_port(&cand[0].addr),
+		  pj_sockaddr_print(&cand[0].addr, ipaddr,
+				    sizeof(ipaddr), 0));
+	}
+
+	/* Enumerate all candidates for this component */
+	cand_cnt = PJ_ARRAY_SIZE(cand);
+	status = pj_ice_strans_enum_cands(icedemo.icest, comp+1,
+					  &cand_cnt, cand);
+	if (status != PJ_SUCCESS)
+	    return -status;
+
+	/* And encode the candidates as SDP */
+	for (j=0; j<cand_cnt; ++j) {
+	    printed = print_cand(p, maxlen - (unsigned)(p-buffer), &cand[j]);
+	    if (printed < 0)
+		return -PJ_ETOOSMALL;
+	    p += printed;
+	}
+    }
+
+    if (p == buffer+maxlen)
+	return -PJ_ETOOSMALL;
+
+    *p = '\0';
+    return (int)(p - buffer);
+}
+
+
+/*
+ * Show information contained in the ICE stream transport. This is
+ * invoked from the menu.
+ */
+static void icedemo_show_ice(void)
+{
+    static char buffer[1000];
+    int len;
+
+    if (icedemo.icest == NULL) {
+	PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
+	return;
+    }
+
+    puts("General info");
+    puts("---------------");
+    printf("Component count    : %d\n", icedemo.opt.comp_cnt);
+    printf("Status             : ");
+    if (pj_ice_strans_sess_is_complete(icedemo.icest))
+	puts("negotiation complete");
+    else if (pj_ice_strans_sess_is_running(icedemo.icest))
+	puts("negotiation is in progress");
+    else if (pj_ice_strans_has_sess(icedemo.icest))
+	puts("session ready");
+    else
+	puts("session not created");
+
+    if (!pj_ice_strans_has_sess(icedemo.icest)) {
+	puts("Create the session first to see more info");
+	return;
+    }
+
+    printf("Negotiated comp_cnt: %d\n", 
+	   pj_ice_strans_get_running_comp_cnt(icedemo.icest));
+    printf("Role               : %s\n",
+	   pj_ice_strans_get_role(icedemo.icest)==PJ_ICE_SESS_ROLE_CONTROLLED ?
+	   "controlled" : "controlling");
+
+    len = encode_session(buffer, sizeof(buffer));
+    if (len < 0)
+	err_exit("not enough buffer to show ICE status", -len);
+
+    puts("");
+    printf("Local SDP (paste this to remote host):\n"
+	   "--------------------------------------\n"
+	   "%s\n", buffer);
+
+
+    puts("");
+    puts("Remote info:\n"
+	 "----------------------");
+    if (icedemo.rem.cand_cnt==0) {
+	puts("No remote info yet");
+    } else {
+	unsigned i;
+
+	printf("Remote ufrag       : %s\n", icedemo.rem.ufrag);
+	printf("Remote password    : %s\n", icedemo.rem.pwd);
+	printf("Remote cand. cnt.  : %d\n", icedemo.rem.cand_cnt);
+
+	for (i=0; i<icedemo.rem.cand_cnt; ++i) {
+	    len = print_cand(buffer, sizeof(buffer), &icedemo.rem.cand[i]);
+	    if (len < 0)
+		err_exit("not enough buffer to show ICE status", -len);
+
+	    printf("  %s", buffer);
+	}
+    }
+}
+
+
+/*
+ * Input and parse SDP from the remote (containing remote's ICE information) 
+ * and save it to global variables.
+ */
+static void icedemo_input_remote(void)
+{
+    char linebuf[80];
+    unsigned media_cnt = 0;
+    unsigned comp0_port = 0;
+    char     comp0_addr[80];
+    pj_bool_t done = PJ_FALSE;
+
+    puts("Paste SDP from remote host, end with empty line");
+
+    reset_rem_info();
+
+    comp0_addr[0] = '\0';
+
+    while (!done) {
+	pj_size_t len;
+	char *line;
+
+	printf(">");
+	if (stdout) fflush(stdout);
+
+	if (fgets(linebuf, sizeof(linebuf), stdin)==NULL)
+	    break;
+
+	len = strlen(linebuf);
+	while (len && (linebuf[len-1] == '\r' || linebuf[len-1] == '\n'))
+	    linebuf[--len] = '\0';
+
+	line = linebuf;
+	while (len && pj_isspace(*line))
+	    ++line, --len;
+
+	if (len==0)
+	    break;
+
+	/* Ignore subsequent media descriptors */
+	if (media_cnt > 1)
+	    continue;
+
+	switch (line[0]) {
+	case 'm':
+	    {
+		int cnt;
+		char media[32], portstr[32];
+
+		++media_cnt;
+		if (media_cnt > 1) {
+		    puts("Media line ignored");
+		    break;
+		}
+
+		cnt = sscanf(line+2, "%s %s RTP/", media, portstr);
+		if (cnt != 2) {
+		    PJ_LOG(1,(THIS_FILE, "Error parsing media line"));
+		    goto on_error;
+		}
+
+		comp0_port = atoi(portstr);
+		
+	    }
+	    break;
+	case 'c':
+	    {
+		int cnt;
+		char c[32], net[32], ip[80];
+		
+		cnt = sscanf(line+2, "%s %s %s", c, net, ip);
+		if (cnt != 3) {
+		    PJ_LOG(1,(THIS_FILE, "Error parsing connection line"));
+		    goto on_error;
+		}
+
+		strcpy(comp0_addr, ip);
+	    }
+	    break;
+	case 'a':
+	    {
+		char *attr = strtok(line+2, ": \t\r\n");
+		if (strcmp(attr, "ice-ufrag")==0) {
+		    strcpy(icedemo.rem.ufrag, attr+strlen(attr)+1);
+		} else if (strcmp(attr, "ice-pwd")==0) {
+		    strcpy(icedemo.rem.pwd, attr+strlen(attr)+1);
+		} else if (strcmp(attr, "rtcp")==0) {
+		    char *val = attr+strlen(attr)+1;
+		    int af, cnt;
+		    int port;
+		    char net[32], ip[64];
+		    pj_str_t tmp_addr;
+		    pj_status_t status;
+
+		    cnt = sscanf(val, "%d IN %s %s", &port, net, ip);
+		    if (cnt != 3) {
+			PJ_LOG(1,(THIS_FILE, "Error parsing rtcp attribute"));
+			goto on_error;
+		    }
+
+		    if (strchr(ip, ':'))
+			af = pj_AF_INET6();
+		    else
+			af = pj_AF_INET();
+
+		    pj_sockaddr_init(af, &icedemo.rem.def_addr[1], NULL, 0);
+		    tmp_addr = pj_str(ip);
+		    status = pj_sockaddr_set_str_addr(af, &icedemo.rem.def_addr[1],
+						      &tmp_addr);
+		    if (status != PJ_SUCCESS) {
+			PJ_LOG(1,(THIS_FILE, "Invalid IP address"));
+			goto on_error;
+		    }
+		    pj_sockaddr_set_port(&icedemo.rem.def_addr[1], (pj_uint16_t)port);
+
+		} else if (strcmp(attr, "candidate")==0) {
+		    char *sdpcand = attr+strlen(attr)+1;
+		    int af, cnt;
+		    char foundation[32], transport[12], ipaddr[80], type[32];
+		    pj_str_t tmpaddr;
+		    int comp_id, prio, port;
+		    pj_ice_sess_cand *cand;
+		    pj_status_t status;
+
+		    cnt = sscanf(sdpcand, "%s %d %s %d %s %d typ %s",
+				 foundation,
+				 &comp_id,
+				 transport,
+				 &prio,
+				 ipaddr,
+				 &port,
+				 type);
+		    if (cnt != 7) {
+			PJ_LOG(1, (THIS_FILE, "error: Invalid ICE candidate line"));
+			goto on_error;
+		    }
+
+		    cand = &icedemo.rem.cand[icedemo.rem.cand_cnt];
+		    pj_bzero(cand, sizeof(*cand));
+		    
+		    if (strcmp(type, "host")==0)
+			cand->type = PJ_ICE_CAND_TYPE_HOST;
+		    else if (strcmp(type, "srflx")==0)
+			cand->type = PJ_ICE_CAND_TYPE_SRFLX;
+		    else if (strcmp(type, "relay")==0)
+			cand->type = PJ_ICE_CAND_TYPE_RELAYED;
+		    else {
+			PJ_LOG(1, (THIS_FILE, "Error: invalid candidate type '%s'", 
+				   type));
+			goto on_error;
+		    }
+
+		    cand->comp_id = (pj_uint8_t)comp_id;
+		    pj_strdup2(icedemo.pool, &cand->foundation, foundation);
+		    cand->prio = prio;
+		    
+		    if (strchr(ipaddr, ':'))
+			af = pj_AF_INET6();
+		    else
+			af = pj_AF_INET();
+
+		    tmpaddr = pj_str(ipaddr);
+		    pj_sockaddr_init(af, &cand->addr, NULL, 0);
+		    status = pj_sockaddr_set_str_addr(af, &cand->addr, &tmpaddr);
+		    if (status != PJ_SUCCESS) {
+			PJ_LOG(1,(THIS_FILE, "Error: invalid IP address '%s'",
+				  ipaddr));
+			goto on_error;
+		    }
+
+		    pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)port);
+
+		    ++icedemo.rem.cand_cnt;
+
+		    if (cand->comp_id > icedemo.rem.comp_cnt)
+			icedemo.rem.comp_cnt = cand->comp_id;
+		}
+	    }
+	    break;
+	}
+    }
+
+    if (icedemo.rem.cand_cnt==0 ||
+	icedemo.rem.ufrag[0]==0 ||
+	icedemo.rem.pwd[0]==0 ||
+	icedemo.rem.comp_cnt == 0)
+    {
+	PJ_LOG(1, (THIS_FILE, "Error: not enough info"));
+	goto on_error;
+    }
+
+    if (comp0_port==0 || comp0_addr[0]=='\0') {
+	PJ_LOG(1, (THIS_FILE, "Error: default address for component 0 not found"));
+	goto on_error;
+    } else {
+	int af;
+	pj_str_t tmp_addr;
+	pj_status_t status;
+
+	if (strchr(comp0_addr, ':'))
+	    af = pj_AF_INET6();
+	else
+	    af = pj_AF_INET();
+
+	pj_sockaddr_init(af, &icedemo.rem.def_addr[0], NULL, 0);
+	tmp_addr = pj_str(comp0_addr);
+	status = pj_sockaddr_set_str_addr(af, &icedemo.rem.def_addr[0],
+					  &tmp_addr);
+	if (status != PJ_SUCCESS) {
+	    PJ_LOG(1,(THIS_FILE, "Invalid IP address in c= line"));
+	    goto on_error;
+	}
+	pj_sockaddr_set_port(&icedemo.rem.def_addr[0], (pj_uint16_t)comp0_port);
+    }
+
+    PJ_LOG(3, (THIS_FILE, "Done, %d remote candidate(s) added", 
+	       icedemo.rem.cand_cnt));
+    return;
+
+on_error:
+    reset_rem_info();
+}
+
+
+/*
+ * Start ICE negotiation! This function is invoked from the menu.
+ */
+static void icedemo_start_nego(void)
+{
+    pj_str_t rufrag, rpwd;
+    pj_status_t status;
+
+    if (icedemo.icest == NULL) {
+	PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
+	return;
+    }
+
+    if (!pj_ice_strans_has_sess(icedemo.icest)) {
+	PJ_LOG(1,(THIS_FILE, "Error: No ICE session, initialize first"));
+	return;
+    }
+
+    if (icedemo.rem.cand_cnt == 0) {
+	PJ_LOG(1,(THIS_FILE, "Error: No remote info, input remote info first"));
+	return;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Starting ICE negotiation.."));
+
+    status = pj_ice_strans_start_ice(icedemo.icest, 
+				     pj_cstr(&rufrag, icedemo.rem.ufrag),
+				     pj_cstr(&rpwd, icedemo.rem.pwd),
+				     icedemo.rem.cand_cnt,
+				     icedemo.rem.cand);
+    if (status != PJ_SUCCESS)
+	icedemo_perror("Error starting ICE", status);
+    else
+	PJ_LOG(3,(THIS_FILE, "ICE negotiation started"));
+}
+
+
+/*
+ * Send application data to remote agent.
+ */
+static void icedemo_send_data(unsigned comp_id, const char *data)
+{
+    pj_status_t status;
+
+    if (icedemo.icest == NULL) {
+	PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
+	return;
+    }
+
+    if (!pj_ice_strans_has_sess(icedemo.icest)) {
+	PJ_LOG(1,(THIS_FILE, "Error: No ICE session, initialize first"));
+	return;
+    }
+
+    /*
+    if (!pj_ice_strans_sess_is_complete(icedemo.icest)) {
+	PJ_LOG(1,(THIS_FILE, "Error: ICE negotiation has not been started or is in progress"));
+	return;
+    }
+    */
+
+    if (comp_id<1||comp_id>pj_ice_strans_get_running_comp_cnt(icedemo.icest)) {
+	PJ_LOG(1,(THIS_FILE, "Error: invalid component ID"));
+	return;
+    }
+
+    status = pj_ice_strans_sendto(icedemo.icest, comp_id, data, strlen(data),
+				  &icedemo.rem.def_addr[comp_id-1],
+				  pj_sockaddr_get_len(&icedemo.rem.def_addr[comp_id-1]));
+    if (status != PJ_SUCCESS)
+	icedemo_perror("Error sending data", status);
+    else
+	PJ_LOG(3,(THIS_FILE, "Data sent"));
+}
+
+
+/*
+ * Display help for the menu.
+ */
+static void icedemo_help_menu(void)
+{
+    puts("");
+    puts("-= Help on using ICE and this icedemo program =-");
+    puts("");
+    puts("This application demonstrates how to use ICE in pjnath without having\n"
+	 "to use the SIP protocol. To use this application, you will need to run\n"
+	 "two instances of this application, to simulate two ICE agents.\n");
+
+    puts("Basic ICE flow:\n"
+	 " create instance [menu \"c\"]\n"
+	 " repeat these steps as wanted:\n"
+	 "   - init session as offerer or answerer [menu \"i\"]\n"
+	 "   - display our SDP [menu \"s\"]\n"
+	 "   - \"send\" our SDP from the \"show\" output above to remote, by\n"
+	 "     copy-pasting the SDP to the other icedemo application\n"
+	 "   - parse remote SDP, by pasting SDP generated by the other icedemo\n"
+	 "     instance [menu \"r\"]\n"
+	 "   - begin ICE negotiation in our end [menu \"b\"], and \n"
+	 "   - immediately begin ICE negotiation in the other icedemo instance\n"
+	 "   - ICE negotiation will run, and result will be printed to screen\n"
+	 "   - send application data to remote [menu \"x\"]\n"
+	 "   - end/stop ICE session [menu \"e\"]\n"
+	 " destroy instance [menu \"d\"]\n"
+	 "");
+
+    puts("");
+    puts("This concludes the help screen.");
+    puts("");
+}
+
+
+/*
+ * Display console menu
+ */
+static void icedemo_print_menu(void)
+{
+    puts("");
+    puts("+----------------------------------------------------------------------+");
+    puts("|                    M E N U                                           |");
+    puts("+---+------------------------------------------------------------------+");
+    puts("| c | create           Create the instance                             |");
+    puts("| d | destroy          Destroy the instance                            |");
+    puts("| i | init o|a         Initialize ICE session as offerer or answerer   |");
+    puts("| e | stop             End/stop ICE session                            |");
+    puts("| s | show             Display local ICE info                          |");
+    puts("| r | remote           Input remote ICE info                           |");
+    puts("| b | start            Begin ICE negotiation                           |");
+    puts("| x | send <compid> .. Send data to remote                             |");
+    puts("+---+------------------------------------------------------------------+");
+    puts("| h |  help            * Help! *                                       |");
+    puts("| q |  quit            Quit                                            |");
+    puts("+----------------------------------------------------------------------+");
+}
+
+
+/*
+ * Main console loop.
+ */
+static void icedemo_console(void)
+{
+    pj_bool_t app_quit = PJ_FALSE;
+
+    while (!app_quit) {
+	char input[80], *cmd;
+	const char *SEP = " \t\r\n";
+	pj_size_t len;
+
+	icedemo_print_menu();
+
+	printf("Input: ");
+	if (stdout) fflush(stdout);
+
+	pj_bzero(input, sizeof(input));
+	if (fgets(input, sizeof(input), stdin) == NULL)
+	    break;
+
+	len = strlen(input);
+	while (len && (input[len-1]=='\r' || input[len-1]=='\n'))
+	    input[--len] = '\0';
+
+	cmd = strtok(input, SEP);
+	if (!cmd)
+	    continue;
+
+	if (strcmp(cmd, "create")==0 || strcmp(cmd, "c")==0) {
+
+	    icedemo_create_instance();
+
+	} else if (strcmp(cmd, "destroy")==0 || strcmp(cmd, "d")==0) {
+
+	    icedemo_destroy_instance();
+
+	} else if (strcmp(cmd, "init")==0 || strcmp(cmd, "i")==0) {
+
+	    char *role = strtok(NULL, SEP);
+	    if (role)
+		icedemo_init_session(*role);
+	    else
+		puts("error: Role required");
+
+	} else if (strcmp(cmd, "stop")==0 || strcmp(cmd, "e")==0) {
+
+	    icedemo_stop_session();
+
+	} else if (strcmp(cmd, "show")==0 || strcmp(cmd, "s")==0) {
+
+	    icedemo_show_ice();
+
+	} else if (strcmp(cmd, "remote")==0 || strcmp(cmd, "r")==0) {
+
+	    icedemo_input_remote();
+
+	} else if (strcmp(cmd, "start")==0 || strcmp(cmd, "b")==0) {
+
+	    icedemo_start_nego();
+
+	} else if (strcmp(cmd, "send")==0 || strcmp(cmd, "x")==0) {
+
+	    char *comp = strtok(NULL, SEP);
+
+	    if (!comp) {
+		PJ_LOG(1,(THIS_FILE, "Error: component ID required"));
+	    } else {
+		char *data = comp + strlen(comp) + 1;
+		if (!data)
+		    data = "";
+		icedemo_send_data(atoi(comp), data);
+	    }
+
+	} else if (strcmp(cmd, "help")==0 || strcmp(cmd, "h")==0) {
+
+	    icedemo_help_menu();
+
+	} else if (strcmp(cmd, "quit")==0 || strcmp(cmd, "q")==0) {
+
+	    app_quit = PJ_TRUE;
+
+	} else {
+
+	    printf("Invalid command '%s'\n", cmd);
+
+	}
+    }
+}
+
+
+/*
+ * Display program usage.
+ */
+static void icedemo_usage()
+{
+    puts("Usage: icedemo [optons]");
+    printf("icedemo v%s by pjsip.org\n", pj_get_version());
+    puts("");
+    puts("General options:");
+    puts(" --comp-cnt, -c N          Component count (default=1)");
+    puts(" --nameserver, -n IP       Configure nameserver to activate DNS SRV");
+    puts("                           resolution");
+    puts(" --max-host, -H N          Set max number of host candidates to N");
+    puts(" --regular, -R             Use regular nomination (default aggressive)");
+    puts(" --log-file, -L FILE       Save output to log FILE");
+    puts(" --help, -h                Display this screen.");
+    puts("");
+    puts("STUN related options:");
+    puts(" --stun-srv, -s HOSTDOM    Enable srflx candidate by resolving to STUN server.");
+    puts("                           HOSTDOM may be a \"host_or_ip[:port]\" or a domain");
+    puts("                           name if DNS SRV resolution is used.");
+    puts("");
+    puts("TURN related options:");
+    puts(" --turn-srv, -t HOSTDOM    Enable relayed candidate by using this TURN server.");
+    puts("                           HOSTDOM may be a \"host_or_ip[:port]\" or a domain");
+    puts("                           name if DNS SRV resolution is used.");
+    puts(" --turn-tcp, -T            Use TCP to connect to TURN server");
+    puts(" --turn-username, -u UID   Set TURN username of the credential to UID");
+    puts(" --turn-password, -p PWD   Set password of the credential to WPWD");
+    puts(" --turn-fingerprint, -F    Use fingerprint for outgoing TURN requests");
+    puts("");
+}
+
+
+/*
+ * And here's the main()
+ */
+int main(int argc, char *argv[])
+{
+    struct pj_getopt_option long_options[] = {
+	{ "comp-cnt",           1, 0, 'c'},
+	{ "nameserver",		1, 0, 'n'},
+	{ "max-host",		1, 0, 'H'},
+	{ "help",		0, 0, 'h'},
+	{ "stun-srv",		1, 0, 's'},
+	{ "turn-srv",		1, 0, 't'},
+	{ "turn-tcp",		0, 0, 'T'},
+	{ "turn-username",	1, 0, 'u'},
+	{ "turn-password",	1, 0, 'p'},
+	{ "turn-fingerprint",	0, 0, 'F'},
+	{ "regular",		0, 0, 'R'},
+	{ "log-file",		1, 0, 'L'},
+    };
+    int c, opt_id;
+    pj_status_t status;
+
+    icedemo.opt.comp_cnt = 1;
+    icedemo.opt.max_host = -1;
+
+    while((c=pj_getopt_long(argc,argv, "c:n:s:t:u:p:H:L:hTFR", long_options, &opt_id))!=-1) {
+	switch (c) {
+	case 'c':
+	    icedemo.opt.comp_cnt = atoi(pj_optarg);
+	    if (icedemo.opt.comp_cnt < 1 || icedemo.opt.comp_cnt >= PJ_ICE_MAX_COMP) {
+		puts("Invalid component count value");
+		return 1;
+	    }
+	    break;
+	case 'n':
+	    icedemo.opt.ns = pj_str(pj_optarg);
+	    break;
+	case 'H':
+	    icedemo.opt.max_host = atoi(pj_optarg);
+	    break;
+	case 'h':
+	    icedemo_usage();
+	    return 0;
+	case 's':
+	    icedemo.opt.stun_srv = pj_str(pj_optarg);
+	    break;
+	case 't':
+	    icedemo.opt.turn_srv = pj_str(pj_optarg);
+	    break;
+	case 'T':
+	    icedemo.opt.turn_tcp = PJ_TRUE;
+	    break;
+	case 'u':
+	    icedemo.opt.turn_username = pj_str(pj_optarg);
+	    break;
+	case 'p':
+	    icedemo.opt.turn_password = pj_str(pj_optarg);
+	    break;
+	case 'F':
+	    icedemo.opt.turn_fingerprint = PJ_TRUE;
+	    break;
+	case 'R':
+	    icedemo.opt.regular = PJ_TRUE;
+	    break;
+	case 'L':
+	    icedemo.opt.log_file = pj_optarg;
+	    break;
+	default:
+	    printf("Argument \"%s\" is not valid. Use -h to see help",
+		   argv[pj_optind]);
+	    return 1;
+	}
+    }
+
+    status = icedemo_init();
+    if (status != PJ_SUCCESS)
+	return 1;
+
+    icedemo_console();
+
+    err_exit("Quitting..", PJ_SUCCESS);
+    return 0;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/invtester.c b/jni/libpjsip/sources/pjsip-apps/src/samples/invtester.c
new file mode 100644
index 0000000..a1eb413
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/invtester.c
@@ -0,0 +1,295 @@
+/* $Id: invtester.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/**
+ * invtester.c
+ *
+ * Send INVITE/re-INVITE without SDP.
+ */
+
+
+/* Include all headers. */
+#include <pjsip.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+#define THIS_FILE	"invtester.c"
+
+#define PORT		50060
+#define PORT_STR	":50060"
+#define SAME_BRANCH	0
+#define ACK_HAS_SDP	1
+
+static pjsip_endpoint *sip_endpt;
+static pj_bool_t       quit_flag;
+static pjsip_dialog   *dlg;
+
+
+/* Callback to handle incoming requests. */
+static void on_tsx_state(pjsip_transaction *tsx, pjsip_event *event);
+
+static pjsip_module mod_app =
+{
+    NULL, NULL,			    /* prev, next.		*/
+    { "mod-app", 7 },		    /* Name.			*/
+    -1,				    /* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
+    NULL,			    /* load()			*/
+    NULL,			    /* start()			*/
+    NULL,			    /* stop()			*/
+    NULL,			    /* unload()			*/
+    NULL,			    /* on_rx_request()		*/
+    NULL,			    /* on_rx_response()		*/
+    NULL,			    /* on_tx_request.		*/
+    NULL,			    /* on_tx_response()		*/
+    &on_tsx_state		    /* on_tsx_state()		*/
+};
+
+
+/* Worker thread */
+static int worker_thread(void *arg)
+{
+    PJ_UNUSED_ARG(arg);
+
+    while (!quit_flag) {
+	pj_time_val timeout = {0, 500};
+	pjsip_endpt_handle_events(sip_endpt, &timeout);
+    }
+
+    return 0;
+}
+
+/* Send request */
+static void send_request(const pjsip_method *method,
+			 int cseq,
+			 const pj_str_t *branch,
+			 pj_bool_t with_offer)
+{
+    pjsip_tx_data *tdata;
+    pj_str_t dummy_sdp_str = 
+    {
+	"v=0\r\n"
+	"o=- 3360842071 3360842071 IN IP4 192.168.0.68\r\n"
+	"s=pjmedia\r\n"
+	"c=IN IP4 192.168.0.68\r\n"
+	"t=0 0\r\n"
+	"m=audio 4000 RTP/AVP 0 101\r\n"
+	"a=rtcp:4001 IN IP4 192.168.0.68\r\n"
+	"a=rtpmap:0 PCMU/8000\r\n"
+	"a=sendrecv\r\n"
+	"a=rtpmap:101 telephone-event/8000\r\n"
+	"a=fmtp:101 0-15\r\n",
+	0
+    };
+    pj_status_t status;
+
+    status = pjsip_dlg_create_request(dlg, method, cseq, &tdata);
+    pj_assert(status == PJ_SUCCESS);
+
+    if (branch) {
+	pjsip_via_hdr *via;
+
+	via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
+	pj_strdup(tdata->pool, &via->branch_param, branch);
+    }
+
+    if (with_offer) {
+	pjsip_msg_body *body;
+	pj_str_t mime_application = { "application", 11};
+	pj_str_t mime_sdp = {"sdp", 3};
+
+
+	dummy_sdp_str.slen = pj_ansi_strlen(dummy_sdp_str.ptr);
+	body = pjsip_msg_body_create(tdata->pool, 
+				     &mime_application, &mime_sdp, 
+				     &dummy_sdp_str);
+	tdata->msg->body = body;
+    }
+
+    status = pjsip_dlg_send_request(dlg, tdata, -1, NULL);
+    pj_assert(status == PJ_SUCCESS);
+}
+
+/* Callback to handle incoming requests. */
+static void on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)
+{
+    if (tsx->role == PJSIP_ROLE_UAC) {
+	if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->state == PJSIP_TSX_STATE_TERMINATED) {
+#if SAME_BRANCH
+	    send_request(&pjsip_ack_method, tsx->cseq, &tsx->branch, ACK_HAS_SDP);
+#else
+	    send_request(&pjsip_ack_method, tsx->cseq, NULL, ACK_HAS_SDP);
+#endif
+	}
+
+    } else {
+	if (event->type == PJSIP_EVENT_RX_MSG && tsx->state == PJSIP_TSX_STATE_TRYING) {
+	    pjsip_tx_data *tdata;
+
+	    pjsip_dlg_create_response(dlg, event->body.tsx_state.src.rdata,
+				      200, NULL, &tdata);
+	    pjsip_dlg_send_response(dlg, tsx, tdata);
+	}
+    }
+}
+
+/* make call */
+void make_call(char *uri, pj_bool_t with_offer)
+{
+    pj_str_t local = pj_str("sip:localhost" PORT_STR);
+    pj_str_t remote = pj_str(uri);
+    pj_status_t status;
+
+    status = pjsip_dlg_create_uac(pjsip_ua_instance(),
+				  &local, &local, &remote, &remote, &dlg);
+    pj_assert(status == PJ_SUCCESS);
+
+    pjsip_dlg_inc_lock(dlg);
+
+    status = pjsip_dlg_add_usage(dlg, &mod_app, NULL);
+    pj_assert(status == PJ_SUCCESS);
+
+    pjsip_dlg_inc_session(dlg, &mod_app);
+
+    send_request(&pjsip_invite_method, -1, NULL, with_offer);
+
+    pjsip_dlg_dec_lock(dlg);
+}
+
+/* reinvite */
+void reinvite(pj_bool_t with_offer)
+{
+    send_request(&pjsip_invite_method, -1, NULL, with_offer);
+}
+
+/* hangup call */
+void hangup(void)
+{
+    send_request(&pjsip_bye_method, -1, NULL, PJ_FALSE);
+    pjsip_dlg_dec_session(dlg, &mod_app);
+}
+
+/*
+ * main()
+ *
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pj_thread_t *thread;
+    pj_pool_t *pool;
+    pj_status_t status;
+    
+    if (argc != 2) {
+	puts("Error: destination URL needed");
+	return 0;
+    }
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Then init PJLIB-UTIL: */
+    status = pjlib_util_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+
+    /* Create the endpoint: */
+    status = pjsip_endpt_create(&cp.factory, "sipstateless", 
+				&sip_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* 
+     * Add UDP transport, with hard-coded port 
+     */
+    {
+	pj_sockaddr_in addr;
+
+	addr.sin_family = pj_AF_INET();
+	addr.sin_addr.s_addr = 0;
+	addr.sin_port = pj_htons(PORT);
+
+	status = pjsip_udp_transport_start( sip_endpt, &addr, NULL, 1, NULL);
+	if (status != PJ_SUCCESS) {
+	    PJ_LOG(3,(THIS_FILE, 
+		      "Error starting UDP transport (port in use?)"));
+	    return 1;
+	}
+    }
+
+    status = pjsip_tsx_layer_init_module(sip_endpt);
+    pj_assert(status == PJ_SUCCESS);
+
+    status = pjsip_ua_init_module(sip_endpt, NULL);
+    pj_assert(status == PJ_SUCCESS);
+
+    /*
+     * Register our module to receive incoming requests.
+     */
+    status = pjsip_endpt_register_module( sip_endpt, &mod_app);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    pool = pjsip_endpt_create_pool(sip_endpt, "", 1000, 1000);
+
+    status = pj_thread_create(pool, "", &worker_thread, NULL, 0, 0, &thread);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    printf("Destination URL: %s\n", argv[1]);
+
+    for (;;) {
+	char line[10];
+
+	fgets(line, sizeof(line), stdin);
+
+	switch (line[0]) {
+	case 'm':
+	    make_call(argv[1], PJ_FALSE);
+	    break;
+	case 'M':
+	    make_call(argv[1], PJ_TRUE);
+	    break;
+	case 'r':
+	    reinvite(PJ_FALSE);
+	    break;
+	case 'R':
+	    reinvite(PJ_TRUE);
+	    break;
+	case 'h':
+	    hangup();
+	    break;
+	case 'q':
+	    goto on_quit;
+	}
+    }
+
+on_quit:
+    quit_flag = 1;
+    pj_thread_join(thread);
+
+    pjsip_endpt_destroy(sip_endpt);
+    pj_caching_pool_destroy(&cp);
+    pj_shutdown();
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/jbsim.c b/jni/libpjsip/sources/pjsip-apps/src/samples/jbsim.c
new file mode 100644
index 0000000..510f67c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/jbsim.c
@@ -0,0 +1,1141 @@
+/* $Id: jbsim.c 3664 2011-07-19 03:42:28Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 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 
+ */
+
+/* jbsim:
+
+    This program emulates various system and network impairment
+    conditions as well as application parameters and apply it to
+    an input WAV file. The output is another WAV file as well as
+    a detailed log file (in CSV format) for troubleshooting.
+ */
+
+
+/* Include PJMEDIA and PJLIB */
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+#include <pjlib.h>
+#include <pjlib-util.h>
+
+#define THIS_FILE   "jbsim.c"
+
+/* Timer resolution in ms (must be NONZERO!) */
+#define WALL_CLOCK_TICK	    1
+
+/* Defaults settings */
+#define CODEC		"PCMU"
+#define LOG_FILE	"jbsim.csv"
+#define WAV_REF		"../../tests/pjsua/wavs/input.8.wav"
+#define WAV_OUT		"jbsim.wav"
+#define DURATION	60
+#define DTX		PJ_TRUE
+#define PLC		PJ_TRUE
+#define MIN_LOST_BURST	0
+#define MAX_LOST_BURST	20
+#define LOSS_CORR	0
+#define LOSS_EXTRA	2
+#define SILENT		1
+
+/*
+   Test setup:
+
+   Input WAV --> TX Stream --> Loop transport --> RX Stream --> Out WAV
+ */
+
+/* Stream settings */
+struct stream_cfg
+{
+    const char	*name;		/* for logging purposes */
+    pjmedia_dir	 dir;		/* stream direction	*/
+    pj_str_t	 codec;		/* codec name		*/
+    unsigned	 ptime;		/* zero for default	*/
+    pj_bool_t	 dtx;		/* DTX enabled?		*/
+    pj_bool_t	 plc;		/* PLC enabled?		*/
+};
+
+/* Stream instance. We will instantiate two streams, TX and RX */
+struct stream
+{
+    pj_pool_t		*pool;
+    pjmedia_stream	*strm;
+    pjmedia_port	*port;
+
+    /*
+     * Running states: 
+     */
+    union {
+	/* TX stream state */
+	struct {
+	    pj_time_val	next_schedule;	/* Time to send next packet */
+	    unsigned	total_tx;	/* # of TX packets so far   */
+	    int		total_lost;	/* # of dropped pkts so far */
+	    unsigned	cur_lost_burst;	/* current # of lost bursts */
+	    unsigned	drop_prob;	/* drop probability value   */
+				        
+	} tx;
+
+	/* RX stream state */
+	struct {
+	    pj_time_val	next_schedule;	/* Time to fetch next pkt   */
+	} rx;
+    } state;
+};
+
+/* 
+ * Logging 
+ */
+
+/* Events names */
+#define EVENT_LOG	""
+#define EVENT_TX	"TX/PUT"
+#define EVENT_TX_DROP	"*** LOSS ***"
+#define EVENT_GET_PRE	"GET (pre)"
+#define EVENT_GET_POST	"GET (post)"
+
+
+/* Logging entry */
+struct log_entry
+{
+    pj_time_val			 wall_clock;	/* Wall clock time	    */
+    const char			*event;		/* Event name		    */
+    pjmedia_jb_state		*jb_state;	/* JB state, optional	    */
+    pjmedia_rtcp_stat		*stat;		/* Stream stat, optional    */
+    const char			*log;		/* Log message, optional    */
+};
+
+/* Test settings, taken from command line */
+struct test_cfg
+{
+    /* General options */
+    pj_bool_t	     silent;		/* Write little to stdout   */
+    const char	    *log_file;		/* The output log file	    */
+
+    /* Test settings */
+    pj_str_t	     codec;		/* Codec to be used	    */
+    unsigned	     duration_msec;	/* Test duration	    */
+
+    /* Transmitter setting */
+    const char	    *tx_wav_in;		/* Input/reference WAV	    */
+    unsigned	     tx_ptime;		/* TX stream ptime	    */
+    unsigned	     tx_min_jitter;	/* Minimum jitter in ms	    */
+    unsigned	     tx_max_jitter;	/* Max jitter in ms	    */
+    unsigned	     tx_dtx;		/* DTX enabled?		    */
+    unsigned	     tx_pct_avg_lost;	/* Average loss in percent  */
+    unsigned	     tx_min_lost_burst;	/* Min lost burst in #pkt   */
+    unsigned	     tx_max_lost_burst;	/* Max lost burst in #pkt   */
+    unsigned	     tx_pct_loss_corr;	/* Loss correlation in pct  */
+
+    /* Receiver setting */
+    const char	    *rx_wav_out;	/* Output WAV file	    */
+    unsigned	     rx_ptime;		/* RX stream ptime	    */
+    unsigned	     rx_snd_burst;	/* RX sound burst	    */
+    pj_bool_t	     rx_plc;		/* RX PLC enabled?	    */
+    int		     rx_jb_init;	/* if > 0 will enable prefetch (ms) */
+    int		     rx_jb_min_pre;	/* JB minimum prefetch (ms) */
+    int		     rx_jb_max_pre;	/* JB maximum prefetch (ms) */
+    int		     rx_jb_max;		/* JB maximum size (ms)	    */
+};
+
+/*
+ * Global var
+ */
+struct global_app
+{
+    pj_caching_pool	 cp;
+    pj_pool_t		*pool;
+    pj_int16_t		*framebuf;
+    pjmedia_endpt	*endpt;
+    pjmedia_transport	*loop;
+
+    pj_oshandle_t	 log_fd;
+
+    struct test_cfg	 cfg;
+
+    struct stream	*tx;
+    pjmedia_port	*tx_wav;
+
+    struct stream	*rx;
+    pjmedia_port	*rx_wav;
+
+    pj_time_val		 wall_clock;
+};
+
+static struct global_app g_app;
+
+
+#ifndef MAX
+#   define MAX(a,b)	(a<b ? b : a)
+#endif
+
+#ifndef MIN
+#   define MIN(a,b)	(a<b ? a : b)
+#endif
+
+/*****************************************************************************
+ * Logging
+ */
+static void write_log(struct log_entry *entry, pj_bool_t to_stdout)
+{
+    /* Format (CSV): */
+    const char *format = "TIME;EVENT;#RX packets;#packets lost;#JB prefetch;#JB size;#JBDISCARD;#JBEMPTY;Log Message";
+    static char log[2000];
+    enum { D = 20 };
+    char s_jbprefetch[D],
+	 s_jbsize[D],
+	 s_rxpkt[D],
+	 s_losspkt[D],
+	 s_jbdiscard[D],
+	 s_jbempty[D];
+    static pj_bool_t header_written;
+
+    if (!header_written) {
+	pj_ansi_snprintf(log, sizeof(log),
+			 "%s\n", format);
+	if (g_app.log_fd != NULL) {
+	    pj_ssize_t size = strlen(log);
+	    pj_file_write(g_app.log_fd, log, &size);
+	}
+	if (to_stdout && !g_app.cfg.silent)
+	    printf("%s", log);
+	header_written = PJ_TRUE;
+    }
+
+    if (entry->jb_state) {
+	sprintf(s_jbprefetch, "%d", entry->jb_state->prefetch);
+	sprintf(s_jbsize, "%d", entry->jb_state->size);
+	sprintf(s_jbdiscard, "%d", entry->jb_state->discard);
+	sprintf(s_jbempty, "%d", entry->jb_state->empty);
+    } else {
+	strcpy(s_jbprefetch, "");
+	strcpy(s_jbsize, "");
+	strcpy(s_jbdiscard, "");
+	strcpy(s_jbempty, "");
+    }
+
+    if (entry->stat) {
+	sprintf(s_rxpkt, "%d", entry->stat->rx.pkt);
+	sprintf(s_losspkt, "%d", entry->stat->rx.loss);
+    } else {
+	strcpy(s_rxpkt, "");
+	strcpy(s_losspkt, "");
+    }
+
+    if (entry->log == NULL)
+	entry->log = "";
+
+    pj_ansi_snprintf(log, sizeof(log),
+		     "'%d.%03d;"	    /* time */
+		     "%s;"	    /* event */
+		     "%s;"	    /* rxpkt */
+		     "%s;"	    /* jb prefetch */
+		     "%s;"	    /* jbsize */
+		     "%s;"	    /* losspkt */
+		     "%s;"	    /* jbdiscard */
+		     "%s;"	    /* jbempty */
+		     "%s\n"	    /* logmsg */,
+
+		     (int)entry->wall_clock.sec, (int)entry->wall_clock.msec, /* time */
+		     entry->event,
+		     s_rxpkt,
+		     s_losspkt,
+		     s_jbprefetch,
+		     s_jbsize,
+		     s_jbdiscard,
+		     s_jbempty,
+		     entry->log
+		     );
+    if (g_app.log_fd != NULL) {
+	pj_ssize_t size = strlen(log);
+	pj_file_write(g_app.log_fd, log, &size);
+    }
+
+    if (to_stdout && !g_app.cfg.silent)
+	printf("%s", log);
+}
+
+static void log_cb(int level, const char *data, int len)
+{
+    struct log_entry entry;
+
+    /* Write to stdout */
+    pj_log_write(level, data, len);
+    puts("");
+
+    /* Also add to CSV file */
+    pj_bzero(&entry, sizeof(entry));
+    entry.event = EVENT_LOG;
+    entry.log = data;
+    entry.wall_clock = g_app.wall_clock;
+    write_log(&entry, PJ_FALSE);
+}
+
+static void jbsim_perror(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(1,(THIS_FILE, "%s: %s", title, errmsg));
+}
+
+/*****************************************************************************
+ * stream
+ */
+
+static void stream_destroy(struct stream *stream)
+{
+    if (stream->strm)
+	pjmedia_stream_destroy(stream->strm);
+    if (stream->pool)
+	pj_pool_release(stream->pool);
+}
+
+static pj_status_t stream_init(const struct stream_cfg *cfg, struct stream **p_stream)
+{
+    pj_pool_t *pool = NULL;
+    struct stream *stream = NULL;
+    pjmedia_codec_mgr *cm;
+    unsigned count;
+    const pjmedia_codec_info *ci;
+    pjmedia_stream_info si;
+    pj_status_t status;
+
+    /* Create instance */
+    pool = pj_pool_create(&g_app.cp.factory, cfg->name, 512, 512, NULL);
+    stream = PJ_POOL_ZALLOC_T(pool, struct stream);
+    stream->pool = pool;
+    
+    /* Create stream info */
+    pj_bzero(&si, sizeof(si));
+    si.type = PJMEDIA_TYPE_AUDIO;
+    si.proto = PJMEDIA_TP_PROTO_RTP_AVP;
+    si.dir = cfg->dir;
+    pj_sockaddr_in_init(&si.rem_addr.ipv4, NULL, 4000);	/* dummy */
+    pj_sockaddr_in_init(&si.rem_rtcp.ipv4, NULL, 4001);	/* dummy */
+
+    /* Apply JB settings if this is RX direction */
+    if (cfg->dir == PJMEDIA_DIR_DECODING) {
+	si.jb_init = g_app.cfg.rx_jb_init;
+	si.jb_min_pre = g_app.cfg.rx_jb_min_pre;
+	si.jb_max_pre = g_app.cfg.rx_jb_max_pre;
+	si.jb_max = g_app.cfg.rx_jb_max;
+    }
+
+    /* Get the codec info and param */
+    cm = pjmedia_endpt_get_codec_mgr(g_app.endpt);
+    count = 1;
+    status = pjmedia_codec_mgr_find_codecs_by_id(cm, &cfg->codec, &count, &ci, NULL);
+    if (status != PJ_SUCCESS) {
+	jbsim_perror("Unable to find codec", status);
+	goto on_error;
+    }
+
+    pj_memcpy(&si.fmt, ci, sizeof(*ci));
+
+    si.param = PJ_POOL_ALLOC_T(pool, struct pjmedia_codec_param);
+    status = pjmedia_codec_mgr_get_default_param(cm, &si.fmt, si.param);
+    if (status != PJ_SUCCESS) {
+	jbsim_perror("Unable to get codec defaults", status);
+	goto on_error;
+    }
+
+    si.tx_pt = si.fmt.pt;
+
+    /* Apply ptime setting */
+    if (cfg->ptime) {
+	si.param->setting.frm_per_pkt = (pj_uint8_t)
+					((cfg->ptime + si.param->info.frm_ptime - 1) /
+					 si.param->info.frm_ptime);
+    }
+    /* Apply DTX setting */
+    si.param->setting.vad = cfg->dtx;
+
+    /* Apply PLC setting */
+    si.param->setting.plc = cfg->plc;
+
+    /* Create stream */
+    status = pjmedia_stream_create(g_app.endpt, pool, &si, g_app.loop, NULL, &stream->strm);
+    if (status != PJ_SUCCESS) {
+	jbsim_perror("Error creating stream", status);
+	goto on_error;
+    }
+
+    status = pjmedia_stream_get_port(stream->strm, &stream->port);
+    if (status != PJ_SUCCESS) {
+	jbsim_perror("Error retrieving stream", status);
+	goto on_error;
+    }
+
+    /* Start stream */
+    status = pjmedia_stream_start(stream->strm);
+    if (status != PJ_SUCCESS) {
+	jbsim_perror("Error starting stream", status);
+	goto on_error;
+    }
+
+    /* Done */
+    *p_stream = stream;
+    return PJ_SUCCESS;
+
+on_error:
+    if (stream) {
+	stream_destroy(stream);
+    } else {
+	if (pool)
+	    pj_pool_release(pool);
+    }
+    return status;
+}
+
+
+/*****************************************************************************
+ * The test session
+ */
+static void test_destroy(void)
+{
+    if (g_app.tx)
+	stream_destroy(g_app.tx);
+    if (g_app.tx_wav)
+	pjmedia_port_destroy(g_app.tx_wav);
+    if (g_app.rx)
+	stream_destroy(g_app.rx);
+    if (g_app.rx_wav)
+	pjmedia_port_destroy(g_app.rx_wav);
+    if (g_app.loop)
+	pjmedia_transport_close(g_app.loop);
+    if (g_app.endpt)
+	pjmedia_endpt_destroy( g_app.endpt );
+    if (g_app.log_fd) {
+	pj_log_set_log_func(&pj_log_write);
+	pj_log_set_decor(pj_log_get_decor() | PJ_LOG_HAS_NEWLINE);
+	pj_file_close(g_app.log_fd);
+	g_app.log_fd = NULL;
+    }
+    if (g_app.pool)
+	pj_pool_release(g_app.pool);
+    pj_caching_pool_destroy( &g_app.cp );
+    pj_shutdown();
+}
+
+
+static pj_status_t test_init(void)
+{
+    struct stream_cfg strm_cfg;
+    pj_status_t status;
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&g_app.cp, &pj_pool_factory_default_policy, 0);
+
+    /* Pool */
+    g_app.pool = pj_pool_create(&g_app.cp.factory, "g_app", 512, 512, NULL);
+
+    /* Log file */
+    if (g_app.cfg.log_file) {
+	status = pj_file_open(g_app.pool, g_app.cfg.log_file, 
+			      PJ_O_WRONLY,
+			      &g_app.log_fd);
+	if (status != PJ_SUCCESS) {
+	    jbsim_perror("Error writing output file", status);
+	    goto on_error;
+	}
+
+	pj_log_set_decor(PJ_LOG_HAS_SENDER | PJ_LOG_HAS_COLOR | PJ_LOG_HAS_LEVEL_TEXT);
+	pj_log_set_log_func(&log_cb);
+    }
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&g_app.cp.factory, NULL, 0, &g_app.endpt);
+    if (status != PJ_SUCCESS) {
+	jbsim_perror("Error creating media endpoint", status);
+	goto on_error;
+    }
+
+    /* Register codecs */
+    pjmedia_codec_register_audio_codecs(g_app.endpt, NULL);
+
+    /* Create the loop transport */
+    status = pjmedia_transport_loop_create(g_app.endpt, &g_app.loop);
+    if (status != PJ_SUCCESS) {
+	jbsim_perror("Error creating loop transport", status);
+	goto on_error;
+    }
+
+    /* Create transmitter stream */
+    pj_bzero(&strm_cfg, sizeof(strm_cfg));
+    strm_cfg.name = "tx";
+    strm_cfg.dir = PJMEDIA_DIR_ENCODING;
+    strm_cfg.codec = g_app.cfg.codec;
+    strm_cfg.ptime = g_app.cfg.tx_ptime;
+    strm_cfg.dtx = g_app.cfg.tx_dtx;
+    strm_cfg.plc = PJ_TRUE;
+    status = stream_init(&strm_cfg, &g_app.tx);
+    if (status != PJ_SUCCESS) 
+	goto on_error;
+
+    /* Create transmitter WAV */
+    status = pjmedia_wav_player_port_create(g_app.pool, 
+					    g_app.cfg.tx_wav_in,
+					    g_app.cfg.tx_ptime,
+					    0,
+					    0,
+					    &g_app.tx_wav);
+    if (status != PJ_SUCCESS) {
+	jbsim_perror("Error reading input WAV file", status);
+	goto on_error;
+    }
+
+    /* Make sure stream and WAV parameters match */
+    if (PJMEDIA_PIA_SRATE(&g_app.tx_wav->info) != PJMEDIA_PIA_SRATE(&g_app.tx->port->info) ||
+	PJMEDIA_PIA_CCNT(&g_app.tx_wav->info) != PJMEDIA_PIA_CCNT(&g_app.tx->port->info))
+    {
+	jbsim_perror("Error: Input WAV file has different clock rate "
+		     "or number of channels than the codec", PJ_SUCCESS);
+	goto on_error;
+    }
+
+
+    /* Create receiver */
+    pj_bzero(&strm_cfg, sizeof(strm_cfg));
+    strm_cfg.name = "rx";
+    strm_cfg.dir = PJMEDIA_DIR_DECODING;
+    strm_cfg.codec = g_app.cfg.codec;
+    strm_cfg.ptime = g_app.cfg.rx_ptime;
+    strm_cfg.dtx = PJ_TRUE;
+    strm_cfg.plc = g_app.cfg.rx_plc;
+    status = stream_init(&strm_cfg, &g_app.rx);
+    if (status != PJ_SUCCESS) 
+	goto on_error;
+
+    /* Create receiver WAV */
+    status = pjmedia_wav_writer_port_create(g_app.pool, 
+					    g_app.cfg.rx_wav_out,
+					    PJMEDIA_PIA_SRATE(&g_app.rx->port->info),
+					    PJMEDIA_PIA_CCNT(&g_app.rx->port->info),
+					    PJMEDIA_PIA_SPF(&g_app.rx->port->info),
+					    PJMEDIA_PIA_BITS(&g_app.rx->port->info),
+					    0,
+					    0,
+					    &g_app.rx_wav);
+    if (status != PJ_SUCCESS) {
+	jbsim_perror("Error creating output WAV file", status);
+	goto on_error;
+    }
+
+
+    /* Frame buffer */
+    g_app.framebuf = (pj_int16_t*)
+		     pj_pool_alloc(g_app.pool,
+				   MAX(PJMEDIA_PIA_SPF(&g_app.rx->port->info),
+				       PJMEDIA_PIA_SPF(&g_app.tx->port->info)) * sizeof(pj_int16_t));
+
+
+    /* Set the receiver in the loop transport */
+    pjmedia_transport_loop_disable_rx(g_app.loop, g_app.tx->strm, PJ_TRUE);
+
+    /* Done */
+    return PJ_SUCCESS;
+
+on_error:
+    test_destroy();
+    return status;
+}
+
+static void run_one_frame(pjmedia_port *src, pjmedia_port *dst,
+			  pj_bool_t *has_frame)
+{
+    pjmedia_frame frame;
+    pj_status_t status;
+
+    pj_bzero(&frame, sizeof(frame));
+    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+    frame.buf = g_app.framebuf;
+    frame.size = PJMEDIA_PIA_SPF(&dst->info) * 2;
+    
+    status = pjmedia_port_get_frame(src, &frame);
+    pj_assert(status == PJ_SUCCESS);
+
+    if (status!= PJ_SUCCESS || frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {
+	frame.buf = g_app.framebuf;
+	pjmedia_zero_samples(g_app.framebuf, PJMEDIA_PIA_SPF(&src->info));
+	frame.size = PJMEDIA_PIA_SPF(&src->info) * 2;
+	if (has_frame)
+	    *has_frame = PJ_FALSE;
+    } else {
+	if (has_frame)
+	    *has_frame = PJ_TRUE;
+    }
+
+
+    status = pjmedia_port_put_frame(dst, &frame);
+    pj_assert(status == PJ_SUCCESS);
+}
+
+
+/* This is the transmission "tick".
+ * This function is called periodically every "tick" milliseconds, and
+ * it will determine whether to transmit packet(s) (or to drop it).
+ */
+static void tx_tick(const pj_time_val *t)
+{
+    struct stream *strm = g_app.tx;
+    static char log_msg[120];
+    pjmedia_port *port = g_app.tx->port;
+    long pkt_interval; 
+
+    /* packet interval, without jitter */
+    pkt_interval = PJMEDIA_PIA_SPF(&port->info) * 1000 /
+		   PJMEDIA_PIA_SRATE(&port->info);
+
+    while (PJ_TIME_VAL_GTE(*t, strm->state.tx.next_schedule)) {
+	struct log_entry entry;
+	pj_bool_t drop_this_pkt = PJ_FALSE;
+	int jitter;
+
+	/* Init log entry */
+	pj_bzero(&entry, sizeof(entry));
+	entry.wall_clock = *t;
+
+	/* 
+	 * Determine whether to drop this packet 
+	 */
+	if (strm->state.tx.cur_lost_burst) {
+	    /* We are currently dropping packet */
+
+	    /* Make it comply to minimum lost burst */
+	    if (strm->state.tx.cur_lost_burst < g_app.cfg.tx_min_lost_burst) {
+		drop_this_pkt = PJ_TRUE;
+	    }
+
+	    /* Correlate the next packet loss */
+	    if (!drop_this_pkt && 
+		strm->state.tx.cur_lost_burst < g_app.cfg.tx_max_lost_burst &&
+		MAX(strm->state.tx.total_lost-LOSS_EXTRA,0) * 100 / MAX(strm->state.tx.total_tx,1) < g_app.cfg.tx_pct_avg_lost
+	       ) 
+	    {
+		strm->state.tx.drop_prob = ((g_app.cfg.tx_pct_loss_corr * strm->state.tx.drop_prob) +
+					     ((100-g_app.cfg.tx_pct_loss_corr) * (pj_rand()%100))
+					   ) / 100;
+		if (strm->state.tx.drop_prob >= 100)
+		    strm->state.tx.drop_prob = 99;
+
+		if (strm->state.tx.drop_prob >= 100 - g_app.cfg.tx_pct_avg_lost)
+		    drop_this_pkt = PJ_TRUE;
+	    }
+	}
+
+	/* If we're not dropping packet then use randomly distributed loss */
+	if (!drop_this_pkt &&
+	    MAX(strm->state.tx.total_lost-LOSS_EXTRA,0) * 100 / MAX(strm->state.tx.total_tx,1) < g_app.cfg.tx_pct_avg_lost)
+	{
+	    strm->state.tx.drop_prob = pj_rand() % 100;
+
+	    if (strm->state.tx.drop_prob >= 100 - g_app.cfg.tx_pct_avg_lost)
+		drop_this_pkt = PJ_TRUE;
+	}
+
+	if (drop_this_pkt) {
+	    /* Drop the frame */
+	    pjmedia_transport_simulate_lost(g_app.loop, PJMEDIA_DIR_ENCODING, 100);
+	    run_one_frame(g_app.tx_wav, g_app.tx->port, NULL);
+	    pjmedia_transport_simulate_lost(g_app.loop, PJMEDIA_DIR_ENCODING, 0);
+
+	    entry.event = EVENT_TX_DROP;
+	    entry.log = "** This packet was lost **";
+
+	    ++strm->state.tx.total_lost;
+	    ++strm->state.tx.cur_lost_burst;
+
+	} else {
+	    pjmedia_rtcp_stat stat;
+	    pjmedia_jb_state jstate;
+	    unsigned last_discard;
+
+	    pjmedia_stream_get_stat_jbuf(g_app.rx->strm, &jstate);
+	    last_discard = jstate.discard;
+
+	    run_one_frame(g_app.tx_wav, g_app.tx->port, NULL);
+
+	    pjmedia_stream_get_stat(g_app.rx->strm, &stat);
+	    pjmedia_stream_get_stat_jbuf(g_app.rx->strm, &jstate);
+
+	    entry.event = EVENT_TX;
+	    entry.jb_state = &jstate;
+	    entry.stat = &stat;
+	    entry.log = log_msg;
+
+	    if (jstate.discard > last_discard)
+		strcat(log_msg, "** Note: packet was discarded by jitter buffer **");
+
+	    strm->state.tx.cur_lost_burst = 0;
+	}
+
+	write_log(&entry, PJ_TRUE);
+
+	++strm->state.tx.total_tx;
+
+	/* Calculate next schedule */
+	strm->state.tx.next_schedule.sec = 0;
+	strm->state.tx.next_schedule.msec = (strm->state.tx.total_tx + 1) * pkt_interval;
+
+	/* Apply jitter */
+	if (g_app.cfg.tx_max_jitter || g_app.cfg.tx_min_jitter) {
+
+	    if (g_app.cfg.tx_max_jitter == g_app.cfg.tx_min_jitter) {
+		/* Fixed jitter */
+		switch (pj_rand() % 3) {
+		case 0:
+		    jitter = 0 - g_app.cfg.tx_min_jitter;
+		    break;
+		case 2:
+		    jitter = g_app.cfg.tx_min_jitter;
+		    break;
+		default:
+		    jitter = 0;
+		    break;
+		}
+	    } else {
+		int jitter_range;
+		jitter_range = (g_app.cfg.tx_max_jitter-g_app.cfg.tx_min_jitter)*2;
+		jitter = pj_rand() % jitter_range;
+		if (jitter < jitter_range/2) {
+		    jitter = 0 - g_app.cfg.tx_min_jitter - (jitter/2);
+		} else {
+		    jitter = g_app.cfg.tx_min_jitter + (jitter/2);
+		}
+	    }
+
+	} else {
+	    jitter = 0;
+	}
+
+	pj_time_val_normalize(&strm->state.tx.next_schedule);
+
+	sprintf(log_msg, "** Packet #%u tick is at %d.%03d, %d ms jitter applied **", 
+		strm->state.tx.total_tx+1,
+		(int)strm->state.tx.next_schedule.sec, (int)strm->state.tx.next_schedule.msec,
+		jitter);
+
+	strm->state.tx.next_schedule.msec += jitter;
+	pj_time_val_normalize(&strm->state.tx.next_schedule);
+
+    } /* while */
+}
+
+
+/* This is the RX "tick".
+ * This function is called periodically every "tick" milliseconds, and
+ * it will determine whether to call get_frame() from the RX stream.
+ */
+static void rx_tick(const pj_time_val *t)
+{
+    struct stream *strm = g_app.rx;
+    pjmedia_port *port = g_app.rx->port;
+    long pkt_interval;
+
+    pkt_interval = PJMEDIA_PIA_SPF(&port->info) * 1000 /
+		   PJMEDIA_PIA_SRATE(&port->info) *
+		   g_app.cfg.rx_snd_burst;
+
+    if (PJ_TIME_VAL_GTE(*t, strm->state.rx.next_schedule)) {
+	unsigned i;
+	for (i=0; i<g_app.cfg.rx_snd_burst; ++i) {
+	    struct log_entry entry;
+	    pjmedia_rtcp_stat stat;
+	    pjmedia_jb_state jstate;
+	    pj_bool_t has_frame;
+	    char msg[120];
+	    unsigned last_empty;
+
+	    pjmedia_stream_get_stat(g_app.rx->strm, &stat);
+	    pjmedia_stream_get_stat_jbuf(g_app.rx->strm, &jstate);
+	    last_empty = jstate.empty;
+
+	    /* Pre GET event */
+	    pj_bzero(&entry, sizeof(entry));
+	    entry.event = EVENT_GET_PRE;
+	    entry.wall_clock = *t;
+	    entry.stat = &stat;
+	    entry.jb_state = &jstate;
+
+	    write_log(&entry, PJ_TRUE);
+
+	    /* GET */
+	    run_one_frame(g_app.rx->port, g_app.rx_wav, &has_frame);
+
+	    /* Post GET event */
+	    pjmedia_stream_get_stat(g_app.rx->strm, &stat);
+	    pjmedia_stream_get_stat_jbuf(g_app.rx->strm, &jstate);
+
+	    pj_bzero(&entry, sizeof(entry));
+	    entry.event = EVENT_GET_POST;
+	    entry.wall_clock = *t;
+	    entry.stat = &stat;
+	    entry.jb_state = &jstate;
+
+	    msg[0] = '\0';
+	    entry.log = msg;
+
+	    if (jstate.empty > last_empty)
+		strcat(msg, "** JBUF was empty **");
+	    if (!has_frame)
+		strcat(msg, "** NULL frame was returned **");
+
+	    write_log(&entry, PJ_TRUE);
+
+	}
+
+
+	strm->state.rx.next_schedule.msec += pkt_interval;
+	pj_time_val_normalize(&strm->state.rx.next_schedule);
+    }
+	    
+}
+
+static void test_loop(long duration)
+{
+    g_app.wall_clock.sec = 0;
+    g_app.wall_clock.msec = 0;
+
+    while (PJ_TIME_VAL_MSEC(g_app.wall_clock) <= duration) {
+
+	/* Run TX tick */
+	tx_tick(&g_app.wall_clock);
+
+	/* Run RX tick */
+	rx_tick(&g_app.wall_clock);
+
+	/* Increment tick */
+	g_app.wall_clock.msec += WALL_CLOCK_TICK;
+	pj_time_val_normalize(&g_app.wall_clock);
+    }
+}
+
+
+/*****************************************************************************
+ * usage()
+ */
+enum {
+    OPT_CODEC	    = 'c',
+    OPT_INPUT	    = 'i',
+    OPT_OUTPUT	    = 'o',
+    OPT_DURATION    = 'd',
+    OPT_LOG_FILE    = 'l',
+    OPT_LOSS	    = 'x',
+    OPT_MIN_JITTER  = 'j',
+    OPT_MAX_JITTER  = 'J',
+    OPT_SND_BURST   = 'b',
+    OPT_TX_PTIME    = 't',
+    OPT_RX_PTIME    = 'r',
+    OPT_NO_VAD	    = 'U',
+    OPT_NO_PLC	    = 'p',
+    OPT_JB_PREFETCH = 'P', 
+    OPT_JB_MIN_PRE  = 'm',
+    OPT_JB_MAX_PRE  = 'M',
+    OPT_JB_MAX	    = 'X',
+    OPT_HELP	    = 'h',
+    OPT_MIN_LOST_BURST = 1,
+    OPT_MAX_LOST_BURST,
+    OPT_LOSS_CORR,
+};
+
+
+static void usage(void)
+{
+    printf("jbsim - System and network impairments simulator\n");
+    printf("Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)\n");
+    printf("\n");
+    printf("This program emulates various system and network impairment\n");
+    printf("conditions as well as application parameters and apply it to\n");
+    printf("an input WAV file. The output is another WAV file as well as\n");
+    printf("a detailed log file (in CSV format) for troubleshooting.\n");
+    printf("\n");
+    printf("Usage:\n");
+    printf(" jbsim [OPTIONS]\n");
+    printf("\n");
+    printf("General OPTIONS:\n");
+    printf("  --codec, -%c NAME       Set the audio codec\n", OPT_CODEC);
+    printf("                         Default: %s\n", CODEC);
+    printf("  --input, -%c FILE       Set WAV reference file to FILE\n", OPT_INPUT);
+    printf("                         Default: " WAV_REF "\n");
+    printf("  --output, -%c FILE      Set WAV output file to FILE\n", OPT_OUTPUT);
+    printf("                         Default: " WAV_OUT "\n");
+    printf("  --duration, -%c SEC     Set test duration to SEC seconds\n", OPT_DURATION);
+    printf("                         Default: %d\n", DURATION);
+    printf("  --log-file, -%c FILE    Save simulation log file to FILE\n", OPT_LOG_FILE);
+    printf("                         Note: FILE will be in CSV format with semicolon separator\n");
+    printf("                         Default: %s\n", LOG_FILE);
+    printf("  --help, -h             Display this screen\n");
+    printf("\n");
+    printf("Simulation OPTIONS:\n");
+    printf("  --loss, -%c PCT         Set packet average loss to PCT percent\n", OPT_LOSS);
+    printf("                         Default: 0\n");
+    printf("  --loss-corr PCT        Set the loss correlation to PCT percent. Default: 0\n");
+    printf("  --min-lost-burst N     Set minimum packet lost burst (default:%d)\n", MIN_LOST_BURST);
+    printf("  --max-lost-burst N     Set maximum packet lost burst (default:%d)\n", MAX_LOST_BURST);
+    printf("  --min-jitter, -%c MSEC  Set minimum network jitter to MSEC\n", OPT_MIN_JITTER);
+    printf("                         Default: 0\n");
+    printf("  --max-jitter, -%c MSEC  Set maximum network jitter to MSEC\n", OPT_MAX_JITTER);
+    printf("                         Default: 0\n");
+    printf("  --snd-burst, -%c VAL    Set RX sound burst value to VAL frames.\n", OPT_SND_BURST);
+    printf("                         Default: 1\n");
+    printf("  --tx-ptime, -%c MSEC    Set transmitter ptime to MSEC\n", OPT_TX_PTIME);
+    printf("                         Default: 0 (not set, use default)\n");
+    printf("  --rx-ptime, -%c MSEC    Set receiver ptime to MSEC\n", OPT_RX_PTIME);
+    printf("                         Default: 0 (not set, use default)\n");
+    printf("  --no-vad, -%c           Disable VAD/DTX in transmitter\n", OPT_NO_VAD);
+    printf("  --no-plc, -%c           Disable PLC in receiver\n", OPT_NO_PLC);
+    printf("  --jb-prefetch, -%c      Enable prefetch bufferring in jitter buffer\n", OPT_JB_PREFETCH);
+    printf("  --jb-min-pre, -%c MSEC  Jitter buffer minimum prefetch delay in msec\n", OPT_JB_MIN_PRE);
+    printf("  --jb-max-pre, -%c MSEC  Jitter buffer maximum prefetch delay in msec\n", OPT_JB_MAX_PRE);
+    printf("  --jb-max, -%c MSEC      Set maximum delay that can be accomodated by the\n", OPT_JB_MAX);
+    printf("                         jitter buffer msec.\n");
+}
+
+
+static int init_options(int argc, char *argv[])
+{
+    struct pj_getopt_option long_options[] = {
+	{ "codec",	    1, 0, OPT_CODEC },
+	{ "input",	    1, 0, OPT_INPUT },
+	{ "output",	    1, 0, OPT_OUTPUT },
+	{ "duration",	    1, 0, OPT_DURATION },
+	{ "log-file",	    1, 0, OPT_LOG_FILE},
+	{ "loss",	    1, 0, OPT_LOSS },
+	{ "min-lost-burst", 1, 0, OPT_MIN_LOST_BURST},
+	{ "max-lost-burst", 1, 0, OPT_MAX_LOST_BURST},
+	{ "loss-corr",	    1, 0, OPT_LOSS_CORR},
+	{ "min-jitter",	    1, 0, OPT_MIN_JITTER },
+	{ "max-jitter",	    1, 0, OPT_MAX_JITTER },
+	{ "snd-burst",	    1, 0, OPT_SND_BURST },
+	{ "tx-ptime",	    1, 0, OPT_TX_PTIME },
+	{ "rx-ptime",	    1, 0, OPT_RX_PTIME },
+	{ "no-vad",	    0, 0, OPT_NO_VAD },
+	{ "no-plc",	    0, 0, OPT_NO_PLC },
+	{ "jb-prefetch",    0, 0, OPT_JB_PREFETCH },
+	{ "jb-min-pre",     1, 0, OPT_JB_MIN_PRE },
+	{ "jb-max-pre",     1, 0, OPT_JB_MAX_PRE },
+	{ "jb-max",	    1, 0, OPT_JB_MAX },
+	{ "help",	    0, 0, OPT_HELP},
+	{ NULL, 0, 0, 0 },
+    };
+    int c;
+    int option_index;
+    char format[128];
+
+    /* Init default config */
+    g_app.cfg.codec = pj_str(CODEC);
+    g_app.cfg.duration_msec = DURATION * 1000;
+    g_app.cfg.silent = SILENT;
+    g_app.cfg.log_file = LOG_FILE;
+    g_app.cfg.tx_wav_in = WAV_REF;
+    g_app.cfg.tx_ptime = 0;
+    g_app.cfg.tx_min_jitter = 0;
+    g_app.cfg.tx_max_jitter = 0;
+    g_app.cfg.tx_dtx = DTX;
+    g_app.cfg.tx_pct_avg_lost = 0;
+    g_app.cfg.tx_min_lost_burst = MIN_LOST_BURST;
+    g_app.cfg.tx_max_lost_burst = MAX_LOST_BURST;
+    g_app.cfg.tx_pct_loss_corr = LOSS_CORR;
+
+    g_app.cfg.rx_wav_out = WAV_OUT;
+    g_app.cfg.rx_ptime = 0;
+    g_app.cfg.rx_plc = PLC;
+    g_app.cfg.rx_snd_burst = 1;
+    g_app.cfg.rx_jb_init = -1;
+    g_app.cfg.rx_jb_min_pre = -1;
+    g_app.cfg.rx_jb_max_pre = -1;
+    g_app.cfg.rx_jb_max = -1;
+
+    /* Build format */
+    format[0] = '\0';
+    for (c=0; c<PJ_ARRAY_SIZE(long_options)-1; ++c) {
+	if (long_options[c].has_arg) {
+	    char cmd[10];
+	    pj_ansi_snprintf(cmd, sizeof(cmd), "%c:", long_options[c].val);
+	    pj_ansi_strcat(format, cmd);
+	}
+    }
+    for (c=0; c<PJ_ARRAY_SIZE(long_options)-1; ++c) {
+	if (long_options[c].has_arg == 0) {
+	    char cmd[10];
+	    pj_ansi_snprintf(cmd, sizeof(cmd), "%c", long_options[c].val);
+	    pj_ansi_strcat(format, cmd);
+	}
+    }
+
+    /* Parse options */
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc,argv, format, 
+			    long_options, &option_index))!=-1) 
+    {
+	switch (c) {
+	case OPT_CODEC:
+	    g_app.cfg.codec = pj_str(pj_optarg);
+	    break;
+	case OPT_INPUT:
+	    g_app.cfg.tx_wav_in = pj_optarg;
+	    break;
+	case OPT_OUTPUT:
+	    g_app.cfg.rx_wav_out = pj_optarg;
+	    break;
+	case OPT_DURATION:
+	    g_app.cfg.duration_msec = atoi(pj_optarg) * 1000;
+	    break;
+	case OPT_LOG_FILE:
+	    g_app.cfg.log_file = pj_optarg;
+	    break;
+	case OPT_LOSS:
+	    g_app.cfg.tx_pct_avg_lost = atoi(pj_optarg);
+	    if (g_app.cfg.tx_pct_avg_lost > 100) {
+		puts("Error: Invalid loss value?");
+		return 1;
+	    }
+	    break;
+	case OPT_MIN_LOST_BURST:
+	    g_app.cfg.tx_min_lost_burst = atoi(pj_optarg);
+	    break;
+	case OPT_MAX_LOST_BURST:
+	    g_app.cfg.tx_max_lost_burst = atoi(pj_optarg);
+	    break;
+	case OPT_LOSS_CORR:
+	    g_app.cfg.tx_pct_loss_corr = atoi(pj_optarg);
+	    if (g_app.cfg.tx_pct_avg_lost > 100) {
+		puts("Error: Loss correlation is in percentage, value is not valid?");
+		return 1;
+	    }
+	    break;
+	case OPT_MIN_JITTER:
+	    g_app.cfg.tx_min_jitter = atoi(pj_optarg);
+	    break;
+	case OPT_MAX_JITTER:
+	    g_app.cfg.tx_max_jitter = atoi(pj_optarg);
+	    break;
+	case OPT_SND_BURST:
+	    g_app.cfg.rx_snd_burst = atoi(pj_optarg);
+	    break;
+	case OPT_TX_PTIME:
+	    g_app.cfg.tx_ptime = atoi(pj_optarg);
+	    break;
+	case OPT_RX_PTIME:
+	    g_app.cfg.rx_ptime = atoi(pj_optarg);
+	    break;
+	case OPT_NO_VAD:
+	    g_app.cfg.tx_dtx = PJ_FALSE;
+	    break;
+	case OPT_NO_PLC:
+	    g_app.cfg.rx_plc = PJ_FALSE;
+	    break;
+	case OPT_JB_PREFETCH:
+	    g_app.cfg.rx_jb_init = 1;
+	    break;
+	case OPT_JB_MIN_PRE:
+	    g_app.cfg.rx_jb_min_pre = atoi(pj_optarg);
+	    break;
+	case OPT_JB_MAX_PRE:
+	    g_app.cfg.rx_jb_max_pre = atoi(pj_optarg);
+	    break;
+	case OPT_JB_MAX:
+	    g_app.cfg.rx_jb_max = atoi(pj_optarg);
+	    break;
+	case OPT_HELP:
+	    usage();
+	    return 1;
+	default:
+	    usage();
+	    return 1;
+	}
+    }
+
+    /* Check for orphaned params */
+    if (pj_optind < argc) {
+	usage();
+	return 1;
+    }
+
+    /* Normalize options */
+    if (g_app.cfg.rx_jb_init < g_app.cfg.rx_jb_min_pre)
+	g_app.cfg.rx_jb_init = g_app.cfg.rx_jb_min_pre;
+    else if (g_app.cfg.rx_jb_init > g_app.cfg.rx_jb_max_pre)
+	g_app.cfg.rx_jb_init = g_app.cfg.rx_jb_max_pre;
+
+    if (g_app.cfg.tx_max_jitter < g_app.cfg.tx_min_jitter)
+	g_app.cfg.tx_max_jitter = g_app.cfg.tx_min_jitter;
+    return 0;
+}
+
+/*****************************************************************************
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_status_t status;
+
+    if (init_options(argc, argv) != 0)
+	return 1;
+
+
+    /* Init */
+    status = test_init();
+    if (status != PJ_SUCCESS)
+	return 1;
+
+    /* Print parameters */
+    PJ_LOG(3,(THIS_FILE, "Starting simulation. Parameters: "));
+    PJ_LOG(3,(THIS_FILE, "  Codec=%.*s, tx_ptime=%d, rx_ptime=%d",
+	      (int)g_app.cfg.codec.slen,
+	      g_app.cfg.codec.ptr,
+	      g_app.cfg.tx_ptime,
+	      g_app.cfg.rx_ptime));
+    PJ_LOG(3,(THIS_FILE, " Loss avg=%d%%, min_burst=%d, max_burst=%d",
+	      g_app.cfg.tx_pct_avg_lost,
+	      g_app.cfg.tx_min_lost_burst,
+	      g_app.cfg.tx_max_lost_burst));
+    PJ_LOG(3,(THIS_FILE, " TX jitter min=%dms, max=%dms",
+	      g_app.cfg.tx_min_jitter, 
+	      g_app.cfg.tx_max_jitter));
+    PJ_LOG(3,(THIS_FILE, " RX jb init:%dms, min_pre=%dms, max_pre=%dms, max=%dms",
+	      g_app.cfg.rx_jb_init,
+	      g_app.cfg.rx_jb_min_pre,
+	      g_app.cfg.rx_jb_max_pre,
+	      g_app.cfg.rx_jb_max));
+    PJ_LOG(3,(THIS_FILE, " RX sound burst:%d frames",
+	      g_app.cfg.rx_snd_burst));
+    PJ_LOG(3,(THIS_FILE, " DTX=%d, PLC=%d",
+	      g_app.cfg.tx_dtx, g_app.cfg.rx_plc));
+
+    /* Run test loop */
+    test_loop(g_app.cfg.duration_msec);
+
+    /* Print statistics */
+    PJ_LOG(3,(THIS_FILE, "Simulation done"));
+    PJ_LOG(3,(THIS_FILE, " TX packets=%u, dropped=%u/%5.1f%%",
+	      g_app.tx->state.tx.total_tx,
+	      g_app.tx->state.tx.total_lost,
+	      (float)(g_app.tx->state.tx.total_lost * 100.0 / g_app.tx->state.tx.total_tx)));
+
+    /* Done */
+    test_destroy();
+
+    return 0;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/latency.c b/jni/libpjsip/sources/pjsip-apps/src/samples/latency.c
new file mode 100644
index 0000000..fdade1f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/latency.c
@@ -0,0 +1,203 @@
+/* $Id: latency.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/* See http://trac.pjsip.org/repos/wiki/MeasuringSoundLatency on
+ * how to use this program.
+ */
+
+#include <pjmedia.h>
+#include <pjlib.h>
+
+#include <stdio.h>
+
+#define THIS_FILE   "lacency.c"
+
+
+/* Util to display the error message for the specified error code  */
+static int app_perror( const char *sender, const char *title, 
+		       pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    PJ_UNUSED_ARG(sender);
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+
+    printf("%s: %s [code=%d]\n", title, errmsg, status);
+    return 1;
+}
+
+/*
+ * Find out latency
+ */
+static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav)
+{
+    pjmedia_frame frm;
+    short *buf;
+    unsigned i, samples_per_frame;
+    pj_size_t read, len;
+    unsigned start_pos;
+    pj_status_t status;
+
+    unsigned lat_sum = 0,
+	     lat_cnt = 0,
+	     lat_min = 10000,
+	     lat_max = 0;
+
+    samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
+    frm.buf = pj_pool_alloc(pool, samples_per_frame * 2);
+    frm.size = samples_per_frame * 2;
+    len = pjmedia_wav_player_get_len(wav);
+    buf = pj_pool_alloc(pool, len + samples_per_frame);
+
+    read = 0;
+    while (read < len/2) {
+	status = pjmedia_port_get_frame(wav, &frm);
+	if (status != PJ_SUCCESS)
+	    break;
+
+	pjmedia_copy_samples(buf+read, (short*)frm.buf, samples_per_frame);
+	read += samples_per_frame;
+    }
+
+    if (read < 2 * PJMEDIA_PIA_SRATE(&wav->info)) {
+	puts("Error: too short");
+	return -1;
+    }
+
+    start_pos = 0;
+    while (start_pos < len/2 - PJMEDIA_PIA_SRATE(&wav->info)) {
+	int max_signal = 0;
+	unsigned max_signal_pos = start_pos;
+	unsigned max_echo_pos = 0;
+	unsigned pos;
+	unsigned lat;
+
+	/* Get the largest signal in the next 0.7s */
+	for (i=start_pos; i<start_pos + PJMEDIA_PIA_SRATE(&wav->info) * 700 / 1000; ++i) {
+	    if (abs(buf[i]) > max_signal) {
+		max_signal = abs(buf[i]);
+		max_signal_pos = i;
+	    }
+	}
+
+	/* Advance 10ms from max_signal_pos */
+	pos = max_signal_pos + 10 * PJMEDIA_PIA_SRATE(&wav->info) / 1000;
+
+	/* Get the largest signal in the next 500ms */
+	max_signal = 0;
+	max_echo_pos = pos;
+	for (i=pos; i<pos+PJMEDIA_PIA_SRATE(&wav->info)/2; ++i) {
+	    if (abs(buf[i]) > max_signal) {
+		max_signal = abs(buf[i]);
+		max_echo_pos = i;
+	    }
+	}
+
+	lat = (max_echo_pos - max_signal_pos) * 1000 / PJMEDIA_PIA_SRATE(&wav->info);
+	
+#if 0
+	printf("Latency = %u\n", lat);
+#endif
+
+	lat_sum += lat;
+	lat_cnt++;
+	if (lat < lat_min)
+	    lat_min = lat;
+	if (lat > lat_max)
+	    lat_max = lat;
+
+	/* Advance next loop */
+	start_pos += PJMEDIA_PIA_SRATE(&wav->info);
+    }
+
+    printf("Latency average = %u\n", lat_sum / lat_cnt);
+    printf("Latency minimum = %u\n", lat_min);
+    printf("Latency maximum = %u\n", lat_max);
+    printf("Number of data  = %u\n", lat_cnt);
+    return 0;
+}
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    enum { NSAMPLES = 160, COUNT=100 };
+    pj_caching_pool cp;
+    pj_pool_t *pool;
+    pjmedia_port *wav;
+    pj_status_t status;
+
+
+    /* Verify cmd line arguments. */
+    if (argc != 2) {
+	puts("Error: missing argument(s)");
+	puts("Usage: latency REV.WAV");
+	return 1;
+    }
+
+    pj_log_set_level(0);
+
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "wav",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    status = pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE, 
+				  &pjmedia_strerror);
+    pj_assert(status == PJ_SUCCESS);
+
+    /* Wav */
+    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
+					      argv[1],	/* file to play	    */
+					      0,	/* use default ptime*/
+					      0,	/* flags	    */
+					      0,	/* default buffer   */
+					      &wav	/* returned port    */
+					      );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, argv[1], status);
+	return 1;
+    }
+
+    status = calculate_latency(pool, wav);
+    if (status != PJ_SUCCESS)
+	return 1;
+
+    status = pjmedia_port_destroy( wav );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    pj_pool_release( pool );
+    pj_caching_pool_destroy( &cp );
+    pj_shutdown();
+
+    /* Done. */
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/level.c b/jni/libpjsip/sources/pjsip-apps/src/samples/level.c
new file mode 100644
index 0000000..59bbb96
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/level.c
@@ -0,0 +1,179 @@
+/* $Id: level.c 3664 2011-07-19 03:42:28Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+/**
+ * \page page_pjmedia_samples_level_c Samples: Reading from WAV File
+ *
+ * This is a very simple example to use the @ref PJMEDIA_FILE_PLAY, to
+ * directly read the samples from the file.
+ *
+ * This file is pjsip-apps/src/samples/level.c
+ *
+ * \includelineno level.c
+ */
+
+
+static const char *desc = 
+ " FILE:								    \n"
+ "  level.c								    \n"
+ "									    \n"
+ " PURPOSE:								    \n"
+ "  Read PCM WAV file and display the audio level the first 100 frames.     \n"
+ "  Each frame is assumed to have 160 samples.				    \n"
+ "									    \n"
+ " USAGE:								    \n"
+ "  level file.wav							    \n"
+ "									    \n"
+ "  The WAV file SHOULD have a 16bit mono samples.			    ";
+
+#include <pjmedia.h>
+#include <pjlib.h>
+
+#include <stdio.h>
+
+/* For logging purpose. */
+#define THIS_FILE   "level.c"
+
+
+/* Util to display the error message for the specified error code  */
+static int app_perror( const char *sender, const char *title, 
+		       pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    PJ_UNUSED_ARG(sender);
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+
+    printf("%s: %s [code=%d]\n", title, errmsg, status);
+    return 1;
+}
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    enum { NSAMPLES = 640, COUNT=100 };
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_port *file_port;
+    int i;
+    pj_status_t status;
+
+
+    /* Verify cmd line arguments. */
+    if (argc != 2) {
+	puts("");
+	puts(desc);
+	return 1;
+    }
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "wav",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    /* Create file media port from the WAV file */
+    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
+					      argv[1],	/* file to play	    */
+					      0,	/* use default ptime*/
+					      0,	/* flags	    */
+					      0,	/* default buffer   */
+					      &file_port/* returned port    */
+					      );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to use WAV file", status);
+	return 1;
+    }
+
+    if (PJMEDIA_PIA_SPF(&file_port->info) > NSAMPLES) {
+	app_perror(THIS_FILE, "WAV clock rate is too big", PJ_EINVAL);
+	return 1;
+    }
+
+    puts("Time\tPCMU\tLinear");
+    puts("------------------------");
+
+    for (i=0; i<COUNT; ++i) {
+	pj_int16_t framebuf[NSAMPLES];
+	pjmedia_frame frm;
+	pj_int32_t level32;
+	unsigned ms;
+	int level;
+
+	frm.buf = framebuf;
+	frm.size = sizeof(framebuf);
+	
+	pjmedia_port_get_frame(file_port, &frm);
+
+	level32 = pjmedia_calc_avg_signal(framebuf, 
+					  PJMEDIA_PIA_SPF(&file_port->info));
+	level = pjmedia_linear2ulaw(level32) ^ 0xFF;
+
+	ms = i * 1000 * PJMEDIA_PIA_SPF(&file_port->info) /
+		PJMEDIA_PIA_SRATE(&file_port->info);
+	printf("%03d.%03d\t%7d\t%7d\n", 
+	        ms/1000, ms%1000, level, level32);
+    }
+    puts("");
+    
+
+    /* Destroy file port */
+    status = pjmedia_port_destroy( file_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+
+    /* Done. */
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/main_rtems.c b/jni/libpjsip/sources/pjsip-apps/src/samples/main_rtems.c
new file mode 100644
index 0000000..d26605a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/main_rtems.c
@@ -0,0 +1,12 @@
+
+/* 
+ *  !! OIY OIY !!
+ *
+ *  The purpose of this file is only to get the executable linked. I haven't
+ *  actually tried to run this on RTEMS!!
+ *
+ */
+
+#include "../../pjlib/src/pjlib-test/main_rtems.c"
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/mix.c b/jni/libpjsip/sources/pjsip-apps/src/samples/mix.c
new file mode 100644
index 0000000..c8e224f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/mix.c
@@ -0,0 +1,237 @@
+/* $Id: mix.c 3664 2011-07-19 03:42:28Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+ /**
+ * \page page_pjmedia_samples_mix_c Samples: Mixing WAV files
+ *
+ * This file is pjsip-apps/src/samples/mix.c
+ *
+ * \includelineno mix.c
+ */
+
+#include <pjlib.h>
+#include <pjlib-util.h>
+#include <pjmedia.h>
+
+#define THIS_FILE   "mix.c"
+
+static const char *desc = 
+ " mix\n"
+ "\n"
+ " PURPOSE:\n"
+ "  Mix input WAV files and save it to output WAV. Input WAV can have\n"
+ "  different clock rate.\n"
+ "\n"
+ "\n"
+ " USAGE:\n"
+ "  mix [options] output.wav input1.wav [input2.wav] ...\n"
+ "\n"
+ " arguments:\n"
+ "    output.wav    Set the output WAV filename.\n"
+ "    input1.wav    Set the input WAV filename.\n"
+ "    input2.wav    Set the input WAV filename.\n"
+ "\n"
+ " options:\n"
+ "    -c N          Set clock rate to N Hz (default 16000)\n"
+ "    -f            Force write (overwrite output without warning\n"
+;
+
+#define MAX_WAV	    16
+#define PTIME	    20
+#define APPEND	    1000
+
+struct wav_input
+{
+    const char	    *fname;
+    pjmedia_port    *port;
+    unsigned	     slot;
+};
+
+static int err_ret(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(3,(THIS_FILE, "%s error: %s", title, errmsg));
+    return 1;
+}
+
+static void usage(void)
+{
+    puts(desc);
+}
+
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pj_pool_t *pool;
+    pjmedia_endpt *med_ept;
+    unsigned clock_rate = 16000;
+    int c, force=0;
+    const char *out_fname;
+    pjmedia_conf *conf;
+    pjmedia_port *wavout;
+    struct wav_input wav_input[MAX_WAV];
+    pj_size_t longest = 0, processed;
+    unsigned i, input_cnt = 0;
+    pj_status_t status;
+
+#define CHECK(op)   do { \
+			status = op; \
+			if (status != PJ_SUCCESS) \
+			    return err_ret(#op, status); \
+		    } while (0)
+
+
+    /* Parse arguments */
+    while ((c=pj_getopt(argc, argv, "c:f")) != -1) {
+	switch (c) {
+	case 'c':
+	    clock_rate = atoi(pj_optarg);
+	    if (clock_rate < 1000) {
+		puts("Error: invalid clock rate");
+		usage();
+		return -1;
+	    }
+	    break;
+	case 'f':
+	    force = 1;
+	    break;
+	}
+    }
+
+    /* Get output WAV name */
+    if (pj_optind == argc) {
+	puts("Error: no WAV output is specified");
+	usage();
+	return 1;
+    }
+
+    out_fname = argv[pj_optind++];
+    if (force==0 && pj_file_exists(out_fname)) {
+	char in[8];
+
+	printf("File %s exists, overwrite? [Y/N] ", out_fname);
+	fflush(stdout);
+	if (fgets(in, sizeof(in), stdin) == NULL)
+	    return 1;
+	if (pj_tolower(in[0]) != 'y')
+	    return 1;
+    }
+
+    /* Scan input file names */
+    for (input_cnt=0 ; pj_optind<argc && input_cnt<MAX_WAV; 
+	 ++pj_optind, ++input_cnt) 
+    {
+	if (!pj_file_exists(argv[pj_optind])) {
+	    printf("Error: input file %s doesn't exist\n",
+		   argv[pj_optind]);
+	    return 1;
+	}
+	wav_input[input_cnt].fname = argv[pj_optind];
+	wav_input[input_cnt].port = NULL;
+	wav_input[input_cnt].slot = 0;
+    }
+
+    if (input_cnt == 0) {
+	puts("Error: no input WAV is specified");
+	return 0;
+    }
+
+    /* Initialialize */
+    CHECK( pj_init() );
+    CHECK( pjlib_util_init() );
+    pj_caching_pool_init(&cp, NULL, 0);
+    CHECK( pjmedia_endpt_create(&cp.factory, NULL, 1, &med_ept) );
+
+    pool = pj_pool_create(&cp.factory, "mix", 1000, 1000, NULL);
+
+    /* Create the bridge */
+    CHECK( pjmedia_conf_create(pool, MAX_WAV+4, clock_rate, 1, 
+			       clock_rate * PTIME / 1000, 16, 
+			       PJMEDIA_CONF_NO_DEVICE, &conf) );
+
+    /* Create the WAV output */
+    CHECK( pjmedia_wav_writer_port_create(pool, out_fname, clock_rate, 1,
+					  clock_rate * PTIME / 1000,
+					  16, 0, 0, &wavout) );
+
+    /* Create and register each WAV input to the bridge */
+    for (i=0; i<input_cnt; ++i) {
+	pj_ssize_t len;
+
+	CHECK( pjmedia_wav_player_port_create(pool, wav_input[i].fname, 20,
+					      PJMEDIA_FILE_NO_LOOP, 0, 
+					      &wav_input[i].port) );
+	len = pjmedia_wav_player_get_len(wav_input[i].port);
+	len = (pj_ssize_t)(len * 1.0 * clock_rate / 
+			   PJMEDIA_PIA_SRATE(&wav_input[i].port->info));
+	if (len > (pj_ssize_t)longest)
+	    longest = len;
+
+	CHECK( pjmedia_conf_add_port(conf, pool, wav_input[i].port,
+				     NULL, &wav_input[i].slot));
+
+	CHECK( pjmedia_conf_connect_port(conf, wav_input[i].slot, 0, 0) );
+    }
+
+    /* Loop reading frame from the bridge and write it to WAV */
+    processed = 0;
+    while (processed < longest + clock_rate * APPEND * 2 / 1000) {
+	pj_int16_t framebuf[PTIME * 48000 / 1000];
+	pjmedia_port *cp = pjmedia_conf_get_master_port(conf);
+	pjmedia_frame frame;
+
+	frame.buf = framebuf;
+	frame.size = PJMEDIA_PIA_SPF(&cp->info) * 2;
+	pj_assert(frame.size <= sizeof(framebuf));
+	
+	CHECK( pjmedia_port_get_frame(cp, &frame) );
+
+	if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {
+	    pj_bzero(frame.buf, frame.size);
+	    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+	}
+
+	CHECK( pjmedia_port_put_frame(wavout, &frame));
+
+	processed += frame.size;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Done. Output duration: %d.%03d",
+	      (processed >> 2)/clock_rate,
+	      ((processed >> 2)*1000/clock_rate) % 1000));
+
+    /* Shutdown everything */
+    CHECK( pjmedia_port_destroy(wavout) );
+    for (i=0; i<input_cnt; ++i) {
+	CHECK( pjmedia_conf_remove_port(conf, wav_input[i].slot) );
+	CHECK( pjmedia_port_destroy(wav_input[i].port) );
+    }
+
+    CHECK(pjmedia_conf_destroy(conf));
+    CHECK(pjmedia_endpt_destroy(med_ept));
+
+    pj_pool_release(pool);
+    pj_caching_pool_destroy(&cp);
+    pj_shutdown();
+
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/pcaputil.c b/jni/libpjsip/sources/pjsip-apps/src/samples/pcaputil.c
new file mode 100644
index 0000000..3eb1603
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/pcaputil.c
@@ -0,0 +1,540 @@
+/* $Id: pcaputil.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 <pjlib.h>
+#include <pjlib-util.h>
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+
+static const char *USAGE =
+"pcaputil [options] INPUT OUTPUT\n"
+"\n"
+"  Convert captured RTP packets in PCAP file to WAV file or play it\n"
+"  to audio device.\n"
+"\n"
+"  INPUT  is the PCAP file name/path.\n"
+"  OUTPUT is the WAV file name/path to store the output, or set to \"-\",\n"
+"         to play the output to audio device. The program will decode\n"
+"         the RTP contents using codec that is available in PJMEDIA,\n"
+"         and optionally decrypt the content using the SRTP crypto and\n"
+"         keys below.\n"
+"\n"
+"Options to filter packets from PCAP file:\n"
+"(you can always select the relevant packets from Wireshark of course!)\n"
+"  --src-ip=IP            Only include packets from this source address\n"
+"  --dst-ip=IP            Only include packets destined to this address\n"
+"  --src-port=port        Only include packets from this source port number\n"
+"  --dst-port=port        Only include packets destined to this port number\n"
+"\n"
+"Options for RTP packet processing:\n"
+""
+"  --codec=codec_id	  The codec ID formatted \"name/clock-rate/channel-count\"\n"
+"                         must be specified for codec with dynamic PT,\n"
+"                         e.g: \"Speex/8000\"\n"
+"  --srtp-crypto=TAG, -c  Set crypto to be used to decrypt SRTP packets. Valid\n"
+"                         tags are: \n"
+"                           AES_CM_128_HMAC_SHA1_80 \n"
+"                           AES_CM_128_HMAC_SHA1_32\n"
+"  --srtp-key=KEY, -k     Set the base64 key to decrypt SRTP packets.\n"
+"\n"
+"Options for playing to audio device:\n"
+""
+"  --play-dev-id=dev_id   Audio device ID for playback.\n"
+"\n"
+"  Example:\n"
+"    pcaputil file.pcap output.wav\n"
+"    pcaputil -c AES_CM_128_HMAC_SHA1_80 \\\n"
+"             -k VLDONbsbGl2Puqy+0PV7w/uGfpSPKFevDpxGsxN3 \\\n"
+"             file.pcap output.wav\n"
+"\n"
+;
+
+static struct app
+{
+    pj_caching_pool	 cp;
+    pj_pool_t		*pool;
+    pjmedia_endpt	*mept;
+    pj_pcap_file	*pcap;
+    pjmedia_port	*wav;
+    pjmedia_codec	*codec;
+    pjmedia_aud_stream  *aud_strm;
+    unsigned		 pt;
+    pjmedia_transport	*srtp;
+    pjmedia_rtp_session	 rtp_sess;
+    pj_bool_t		 rtp_sess_init;
+} app;
+
+
+static void cleanup()
+{
+    if (app.srtp) pjmedia_transport_close(app.srtp);
+    if (app.wav) {
+        pj_ssize_t pos = pjmedia_wav_writer_port_get_pos(app.wav);
+        if (pos >= 0) {
+            unsigned msec;
+            msec = (unsigned)pos / 2 * 1000 / PJMEDIA_PIA_SRATE(&app.wav->info);
+            printf("Written: %dm:%02ds.%03d\n",
+                    msec / 1000 / 60,
+                    (msec / 1000) % 60,
+                    msec % 1000);
+        }
+	pjmedia_port_destroy(app.wav);
+    }
+    if (app.pcap) pj_pcap_close(app.pcap);
+    if (app.codec) {
+	pjmedia_codec_mgr *cmgr;
+	pjmedia_codec_close(app.codec);
+	cmgr = pjmedia_endpt_get_codec_mgr(app.mept);
+	pjmedia_codec_mgr_dealloc_codec(cmgr, app.codec);
+    }
+    if (app.aud_strm) {
+	pjmedia_aud_stream_stop(app.aud_strm);
+	pjmedia_aud_stream_destroy(app.aud_strm);
+    }
+    if (app.mept) pjmedia_endpt_destroy(app.mept);
+    if (app.pool) pj_pool_release(app.pool);
+    pj_caching_pool_destroy(&app.cp);
+    pj_shutdown();
+}
+
+static void err_exit(const char *title, pj_status_t status)
+{
+    if (status != PJ_SUCCESS) {
+	char errmsg[PJ_ERR_MSG_SIZE];
+	pj_strerror(status, errmsg, sizeof(errmsg));
+	printf("Error: %s: %s\n", title, errmsg);
+    } else {
+	printf("Error: %s\n", title);
+    }
+    cleanup();
+    exit(1);
+}
+
+#define T(op)	    do { \
+			status = op; \
+			if (status != PJ_SUCCESS) \
+    			    err_exit(#op, status); \
+		    } while (0)
+
+
+static void read_rtp(pj_uint8_t *buf, pj_size_t bufsize,
+		     pjmedia_rtp_hdr **rtp,
+		     pj_uint8_t **payload,
+		     unsigned *payload_size,
+		     pj_bool_t check_pt)
+{
+    pj_status_t status;
+
+    /* Init RTP session */
+    if (!app.rtp_sess_init) {
+	T(pjmedia_rtp_session_init(&app.rtp_sess, 0, 0));
+	app.rtp_sess_init = PJ_TRUE;
+    }
+
+    /* Loop reading until we have a good RTP packet */
+    for (;;) {
+	pj_size_t sz = bufsize;
+	const pjmedia_rtp_hdr *r;
+	const void *p;
+	pjmedia_rtp_status seq_st;
+
+	status = pj_pcap_read_udp(app.pcap, NULL, buf, &sz);
+	if (status != PJ_SUCCESS)
+	    err_exit("Error reading PCAP file", status);
+
+	/* Decode RTP packet to make sure that this is an RTP packet.
+	 * We will decode it again to get the payload after we do
+	 * SRTP decoding
+	 */
+	status = pjmedia_rtp_decode_rtp(&app.rtp_sess, buf, (int)sz, &r, 
+					&p, payload_size);
+	if (status != PJ_SUCCESS) {
+	    char errmsg[PJ_ERR_MSG_SIZE];
+	    pj_strerror(status, errmsg, sizeof(errmsg));
+	    printf("Not RTP packet, skipping packet: %s\n", errmsg);
+	    continue;
+	}
+
+	/* Decrypt SRTP */
+#if PJMEDIA_HAS_SRTP
+	if (app.srtp) {
+	    int len = (int)sz;
+	    status = pjmedia_transport_srtp_decrypt_pkt(app.srtp, PJ_TRUE, 
+						        buf, &len);
+	    if (status != PJ_SUCCESS) {
+		char errmsg[PJ_ERR_MSG_SIZE];
+		pj_strerror(status, errmsg, sizeof(errmsg));
+		printf("SRTP packet decryption failed, skipping packet: %s\n", 
+			errmsg);
+		continue;
+	    }
+	    sz = len;
+
+	    /* Decode RTP packet again */
+	    status = pjmedia_rtp_decode_rtp(&app.rtp_sess, buf, (int)sz, &r,
+					    &p, payload_size);
+	    if (status != PJ_SUCCESS) {
+		char errmsg[PJ_ERR_MSG_SIZE];
+		pj_strerror(status, errmsg, sizeof(errmsg));
+		printf("Not RTP packet, skipping packet: %s\n", errmsg);
+		continue;
+	    }
+	}
+#endif
+
+	/* Update RTP session */
+	pjmedia_rtp_session_update2(&app.rtp_sess, r, &seq_st, PJ_FALSE);
+
+	/* Skip out-of-order packet */
+	if (seq_st.diff == 0) {
+	    printf("Skipping out of order packet\n");
+	    continue;
+	}
+
+	/* Skip if payload type is different */
+	if (check_pt && r->pt != app.pt) {
+	    printf("Skipping RTP packet with bad payload type\n");
+	    continue;
+	}
+
+	/* Skip bad packet */
+	if (seq_st.status.flag.bad) {
+	    printf("Skipping bad RTP\n");
+	    continue;
+	}
+
+
+	*rtp = (pjmedia_rtp_hdr*)r;
+	*payload = (pj_uint8_t*)p;
+
+	/* We have good packet */
+	break;
+    }
+}
+
+pjmedia_frame play_frm;
+static pj_bool_t play_frm_copied, play_frm_ready;
+
+static pj_status_t wait_play(pjmedia_frame *f)
+{
+    play_frm_copied = PJ_FALSE;
+    play_frm = *f;
+    play_frm_ready = PJ_TRUE;
+    while (!play_frm_copied) {
+	pj_thread_sleep(1);
+    }
+    play_frm_ready = PJ_FALSE;
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t play_cb(void *user_data, pjmedia_frame *f)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    if (!play_frm_ready) {
+	PJ_LOG(3, ("play_cb()", "Warning! Play frame not ready")); 
+	return PJ_SUCCESS;
+    }
+
+    pj_memcpy(f->buf, play_frm.buf, play_frm.size);
+    f->size = play_frm.size;
+
+    play_frm_copied = PJ_TRUE;
+    return PJ_SUCCESS;
+}
+
+static void pcap2wav(const pj_str_t *codec,
+		     const pj_str_t *wav_filename,
+		     pjmedia_aud_dev_index dev_id,
+		     const pj_str_t *srtp_crypto,
+		     const pj_str_t *srtp_key)
+{
+    const pj_str_t WAV = {".wav", 4};
+    struct pkt
+    {
+	pj_uint8_t	 buffer[320];
+	pjmedia_rtp_hdr	*rtp;
+	pj_uint8_t	*payload;
+	unsigned	 payload_len;
+    } pkt0;
+    pjmedia_codec_mgr *cmgr;
+    const pjmedia_codec_info *ci;
+    pjmedia_codec_param param;
+    unsigned samples_per_frame;
+    pj_status_t status;
+
+    /* Initialize all codecs */
+    T( pjmedia_codec_register_audio_codecs(app.mept, NULL) );
+
+    /* Create SRTP transport is needed */
+#if PJMEDIA_HAS_SRTP
+    if (srtp_crypto->slen) {
+	pjmedia_srtp_crypto crypto;
+
+	pj_bzero(&crypto, sizeof(crypto));
+	crypto.key = *srtp_key;
+	crypto.name = *srtp_crypto;
+	T( pjmedia_transport_srtp_create(app.mept, NULL, NULL, &app.srtp) );
+	T( pjmedia_transport_srtp_start(app.srtp, &crypto, &crypto) );
+    }
+#else
+    PJ_UNUSED_ARG(srtp_crypto);
+    PJ_UNUSED_ARG(srtp_key);
+#endif
+
+    /* Read first packet */
+    read_rtp(pkt0.buffer, sizeof(pkt0.buffer), &pkt0.rtp, 
+	     &pkt0.payload, &pkt0.payload_len, PJ_FALSE);
+
+    cmgr = pjmedia_endpt_get_codec_mgr(app.mept);
+
+    /* Get codec info and param for the specified payload type */
+    app.pt = pkt0.rtp->pt;
+    if (app.pt >=0 && app.pt < 96) {
+	T( pjmedia_codec_mgr_get_codec_info(cmgr, pkt0.rtp->pt, &ci) );
+    } else {
+	unsigned cnt = 2;
+	const pjmedia_codec_info *info[2];
+	T( pjmedia_codec_mgr_find_codecs_by_id(cmgr, codec, &cnt, 
+					       info, NULL) );
+	if (cnt != 1)
+	    err_exit("Codec ID must be specified and unique!", 0);
+
+	ci = info[0];
+    }
+    T( pjmedia_codec_mgr_get_default_param(cmgr, ci, &param) );
+
+    /* Alloc and init codec */
+    T( pjmedia_codec_mgr_alloc_codec(cmgr, ci, &app.codec) );
+    T( pjmedia_codec_init(app.codec, app.pool) );
+    T( pjmedia_codec_open(app.codec, &param) );
+
+    /* Init audio device or WAV file */
+    samples_per_frame = ci->clock_rate * param.info.frm_ptime / 1000;
+    if (pj_strcmp2(wav_filename, "-") == 0) {
+	pjmedia_aud_param aud_param;
+
+	/* Open audio device */
+	T( pjmedia_aud_dev_default_param(dev_id, &aud_param) );
+	aud_param.dir = PJMEDIA_DIR_PLAYBACK;
+	aud_param.channel_count = ci->channel_cnt;
+	aud_param.clock_rate = ci->clock_rate;
+	aud_param.samples_per_frame = samples_per_frame;
+	T( pjmedia_aud_stream_create(&aud_param, NULL, &play_cb, 
+				     NULL, &app.aud_strm) );
+	T( pjmedia_aud_stream_start(app.aud_strm) );
+    } else if (pj_stristr(wav_filename, &WAV)) {
+	/* Open WAV file */
+	T( pjmedia_wav_writer_port_create(app.pool, wav_filename->ptr,
+					  ci->clock_rate, ci->channel_cnt,
+					  samples_per_frame,
+					  param.info.pcm_bits_per_sample, 0, 0,
+					  &app.wav) );
+    } else {
+	err_exit("invalid output file", PJ_EINVAL);
+    }
+
+    /* Loop reading PCAP and writing WAV file */
+    for (;;) {
+	struct pkt pkt1;
+	pj_timestamp ts;
+	pjmedia_frame frames[16], pcm_frame;
+	short pcm[320];
+	unsigned i, frame_cnt;
+	long samples_cnt, ts_gap;
+
+	pj_assert(sizeof(pcm) >= samples_per_frame);
+
+	/* Parse first packet */
+	ts.u64 = 0;
+	frame_cnt = PJ_ARRAY_SIZE(frames);
+	T( pjmedia_codec_parse(app.codec, pkt0.payload, pkt0.payload_len, 
+				&ts, &frame_cnt, frames) );
+
+	/* Decode and write to WAV file */
+	samples_cnt = 0;
+	for (i=0; i<frame_cnt; ++i) {
+	    pjmedia_frame pcm_frame;
+
+	    pcm_frame.buf = pcm;
+	    pcm_frame.size = samples_per_frame * 2;
+
+	    T( pjmedia_codec_decode(app.codec, &frames[i], 
+				    (unsigned)pcm_frame.size, &pcm_frame) );
+	    if (app.wav) {
+		T( pjmedia_port_put_frame(app.wav, &pcm_frame) );
+	    }
+	    if (app.aud_strm) {
+		T( wait_play(&pcm_frame) );
+	    }
+	    samples_cnt += samples_per_frame;
+	}
+
+	/* Read next packet */
+	read_rtp(pkt1.buffer, sizeof(pkt1.buffer), &pkt1.rtp,
+		 &pkt1.payload, &pkt1.payload_len, PJ_TRUE);
+
+	/* Fill in the gap (if any) between pkt0 and pkt1 */
+	ts_gap = pj_ntohl(pkt1.rtp->ts) - pj_ntohl(pkt0.rtp->ts) -
+		 samples_cnt;
+	while (ts_gap >= (long)samples_per_frame) {
+
+	    pcm_frame.buf = pcm;
+	    pcm_frame.size = samples_per_frame * 2;
+
+	    if (app.codec->op->recover) {
+		T( pjmedia_codec_recover(app.codec, (unsigned)pcm_frame.size, 
+					 &pcm_frame) );
+	    } else {
+		pj_bzero(pcm_frame.buf, pcm_frame.size);
+	    }
+
+	    if (app.wav) {
+		T( pjmedia_port_put_frame(app.wav, &pcm_frame) );
+	    }
+	    if (app.aud_strm) {
+		T( wait_play(&pcm_frame) );
+	    }
+	    ts_gap -= samples_per_frame;
+	}
+	
+	/* Next */
+	pkt0 = pkt1;
+	pkt0.rtp = (pjmedia_rtp_hdr*)pkt0.buffer;
+	pkt0.payload = pkt0.buffer + (pkt1.payload - pkt1.buffer);
+    }
+}
+
+
+int main(int argc, char *argv[])
+{
+    pj_str_t input, output, srtp_crypto, srtp_key, codec;
+    pjmedia_aud_dev_index dev_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
+    pj_pcap_filter filter;
+    pj_status_t status;
+
+    enum { 
+	OPT_SRC_IP = 1, OPT_DST_IP, OPT_SRC_PORT, OPT_DST_PORT,
+	OPT_CODEC, OPT_PLAY_DEV_ID
+    };
+    struct pj_getopt_option long_options[] = {
+	{ "srtp-crypto",    1, 0, 'c' },
+	{ "srtp-key",	    1, 0, 'k' },
+	{ "src-ip",	    1, 0, OPT_SRC_IP },
+	{ "dst-ip",	    1, 0, OPT_DST_IP },
+	{ "src-port",	    1, 0, OPT_SRC_PORT },
+	{ "dst-port",	    1, 0, OPT_DST_PORT },
+	{ "codec",	    1, 0, OPT_CODEC },
+	{ "play-dev-id",    1, 0, OPT_PLAY_DEV_ID },
+	{ NULL, 0, 0, 0}
+    };
+    int c;
+    int option_index;
+    char key_bin[32];
+
+    srtp_crypto.slen = srtp_key.slen = 0;
+    codec.slen = 0;
+
+    pj_pcap_filter_default(&filter);
+    filter.link = PJ_PCAP_LINK_TYPE_ETH;
+    filter.proto = PJ_PCAP_PROTO_TYPE_UDP;
+
+    /* Parse arguments */
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc,argv, "c:k:", long_options, &option_index))!=-1) {
+	switch (c) {
+	case 'c':
+	    srtp_crypto = pj_str(pj_optarg);
+	    break;
+	case 'k':
+	    {
+		int key_len = sizeof(key_bin);
+		srtp_key = pj_str(pj_optarg);
+		if (pj_base64_decode(&srtp_key, (pj_uint8_t*)key_bin, &key_len)) {
+		    puts("Error: invalid key");
+		    return 1;
+		}
+		srtp_key.ptr = key_bin;
+		srtp_key.slen = key_len;
+	    }
+	    break;
+	case OPT_SRC_IP:
+	    {
+		pj_str_t t = pj_str(pj_optarg);
+		pj_in_addr a = pj_inet_addr(&t);
+		filter.ip_src = a.s_addr;
+	    }
+	    break;
+	case OPT_DST_IP:
+	    {
+		pj_str_t t = pj_str(pj_optarg);
+		pj_in_addr a = pj_inet_addr(&t);
+		filter.ip_dst = a.s_addr;
+	    }
+	    break;
+	case OPT_SRC_PORT:
+	    filter.src_port = pj_htons((pj_uint16_t)atoi(pj_optarg));
+	    break;
+	case OPT_DST_PORT:
+	    filter.dst_port = pj_htons((pj_uint16_t)atoi(pj_optarg));
+	    break;
+	case OPT_CODEC:
+	    codec = pj_str(pj_optarg);
+	    break;
+	case OPT_PLAY_DEV_ID:
+	    dev_id = atoi(pj_optarg);
+	    break;
+	default:
+	    puts("Error: invalid option");
+	    return 1;
+	}
+    }
+
+    if (pj_optind != argc - 2) {
+	puts(USAGE);
+	return 1;
+    }
+
+    if (!(srtp_crypto.slen) != !(srtp_key.slen)) {
+	puts("Error: both SRTP crypto and key must be specified");
+	puts(USAGE);
+	return 1;
+    }
+
+    input = pj_str(argv[pj_optind]);
+    output = pj_str(argv[pj_optind+1]);
+    
+    T( pj_init() );
+
+    pj_caching_pool_init(&app.cp, NULL, 0);
+    app.pool = pj_pool_create(&app.cp.factory, "pcaputil", 1000, 1000, NULL);
+
+    T( pjlib_util_init() );
+    T( pjmedia_endpt_create(&app.cp.factory, NULL, 0, &app.mept) );
+
+    T( pj_pcap_open(app.pool, input.ptr, &app.pcap) );
+    T( pj_pcap_set_filter(app.pcap, &filter) );
+
+    pcap2wav(&codec, &output, dev_id, &srtp_crypto, &srtp_key);
+
+    cleanup();
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/pjsip-perf.c b/jni/libpjsip/sources/pjsip-apps/src/samples/pjsip-perf.c
new file mode 100644
index 0000000..51023d6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/pjsip-perf.c
@@ -0,0 +1,1855 @@
+/* $Id: pjsip-perf.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+/**
+ * \page page_pjsip_perf_c Samples: SIP Performance Benchmark
+ *
+ * <b>pjsip-perf</b> is a complete program to measure the
+ * performance of PJSIP or other SIP endpoints. It consists of two
+ * parts:
+ *  - the server, to respond incoming requests, and
+ *  - the client, who actively submits requests and measure the
+ *     performance of the server.
+ *
+ * Both server and client part can run simultaneously, to measure the
+ * performance when both endpoints are co-located in a single program.
+ * 
+ * The server accepts both INVITE and non-INVITE requests.
+ * The server exports several different types of URL, which would
+ * control how the request would be handled by the server:
+ *  - URL with "0" as the user part will be handled statelessly.
+ *    It should not be used with INVITE method.
+ *  - URL with "1" as the user part will be handled statefully.
+ *    If the request is an INVITE request, INVITE transaction will
+ *    be created and 200/OK response will be sent, along with a valid
+ *    SDP body. However, the SDP is just a static text body, and
+ *    is not a proper SDP generated by PJMEDIA.
+ *  - URL with "2" as the user part is only meaningful for INVITE
+ *    requests, as it would be handled <b>call-statefully</b> by the
+ *    server. For this URL, the server also would generate SDP dynamically
+ *    and perform a proper SDP negotiation for the incoming call.
+ *    Also for every call, server will limit the call duration to
+ *    10 seconds, on which the call will be terminated if the client
+ *    doesn't hangup the call.
+ *    
+ *
+ *
+ * This file is pjsip-apps/src/samples/pjsip-perf.c
+ *
+ * \includelineno pjsip-perf.c
+ */
+
+/* Include all headers. */
+#include <pjsip.h>
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+#include <pjsip_ua.h>
+#include <pjsip_simple.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+#include <stdio.h>
+
+#if (defined(PJ_WIN32) && PJ_WIN32!=0) || (defined(PJ_WIN64) && PJ_WIN64!=0)
+#  include <windows.h>
+#endif
+
+#define THIS_FILE	    "pjsip-perf.c"
+#define DEFAULT_COUNT	    (pjsip_cfg()->tsx.max_count/2>10000?10000:pjsip_cfg()->tsx.max_count/2)
+#define JOB_WINDOW	    1000
+#define TERMINATE_TSX(x,c)
+
+
+#ifndef CACHING_POOL_SIZE
+#   define CACHING_POOL_SIZE   (256*1024*1024)
+#endif
+
+
+/* Static message body for INVITE, when stateful processing is
+ * invoked (instead of call-stateful, where SDP is generated
+ * dynamically.
+ */
+static pj_str_t dummy_sdp_str = 
+{
+    "v=0\r\n"
+    "o=- 3360842071 3360842071 IN IP4 192.168.0.68\r\n"
+    "s=pjmedia\r\n"
+    "c=IN IP4 192.168.0.68\r\n"
+    "t=0 0\r\n"
+    "m=audio 4000 RTP/AVP 0 8 3 103 102 101\r\n"
+    "a=rtcp:4001 IN IP4 192.168.0.68\r\n"
+    "a=rtpmap:103 speex/16000\r\n"
+    "a=rtpmap:102 speex/8000\r\n"
+    "a=rtpmap:3 GSM/8000\r\n"
+    "a=rtpmap:0 PCMU/8000\r\n"
+    "a=rtpmap:8 PCMA/8000\r\n"
+    "a=sendrecv\r\n"
+    "a=rtpmap:101 telephone-event/8000\r\n"
+    "a=fmtp:101 0-15\r\n",
+    0
+};
+
+static pj_str_t mime_application = { "application", 11};
+static pj_str_t mime_sdp = {"sdp", 3};
+
+
+struct srv_state
+{
+    unsigned	    stateless_cnt;
+    unsigned	    stateful_cnt;
+    unsigned	    call_cnt;
+};
+
+
+struct app
+{
+    pj_caching_pool	 cp;
+    pj_pool_t		*pool;
+    pj_bool_t		 use_tcp;
+    pj_str_t		 local_addr;
+    int			 local_port;
+    pjsip_endpoint	*sip_endpt;
+    pjmedia_endpt	*med_endpt;
+    pj_str_t		 local_uri;
+    pj_str_t		 local_contact;
+    unsigned		 skinfo_cnt;
+    pjmedia_sock_info	 skinfo[8];
+
+    pj_bool_t		 thread_quit;
+    unsigned		 thread_count;
+    pj_thread_t		*thread[16];
+
+    pj_bool_t		 real_sdp;
+    pjmedia_sdp_session *dummy_sdp;
+
+    int			 log_level;
+
+    struct {
+	pjsip_method	     method;
+	pj_str_t	     dst_uri;
+	pj_bool_t	     stateless;
+	unsigned	     timeout;
+	unsigned	     job_count,
+			     job_submitted, 
+			     job_finished,
+			     job_window;
+	unsigned	     stat_max_window;
+	pj_time_val	     first_request;
+	pj_time_val	     requests_sent;
+	pj_time_val	     last_completion;
+	unsigned	     total_responses;
+	unsigned	     response_codes[800];
+    } client;
+
+    struct {
+	pj_bool_t send_trying;
+	pj_bool_t send_ringing;
+	unsigned delay;
+	struct srv_state prev_state;
+	struct srv_state cur_state;
+    } server;
+
+
+} app;
+
+struct call
+{
+    pjsip_inv_session	*inv;
+    pj_timer_entry	 ans_timer;
+};
+
+
+static void app_perror(const char *sender, const char *title, 
+		       pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(1,(sender, "%s: %s [code=%d]", title, errmsg, status));
+}
+
+
+/**************************************************************************
+ * STATELESS SERVER
+ */
+static pj_bool_t mod_stateless_on_rx_request(pjsip_rx_data *rdata);
+
+/* Module to handle incoming requests statelessly.
+ */
+static pjsip_module mod_stateless_server =
+{
+    NULL, NULL,			    /* prev, next.		*/
+    { "mod-stateless-server", 20 }, /* Name.			*/
+    -1,				    /* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
+    NULL,			    /* load()			*/
+    NULL,			    /* start()			*/
+    NULL,			    /* stop()			*/
+    NULL,			    /* unload()			*/
+    &mod_stateless_on_rx_request,   /* on_rx_request()		*/
+    NULL,			    /* on_rx_response()		*/
+    NULL,			    /* on_tx_request.		*/
+    NULL,			    /* on_tx_response()		*/
+    NULL,			    /* on_tsx_state()		*/
+};
+
+
+static pj_bool_t mod_stateless_on_rx_request(pjsip_rx_data *rdata)
+{
+    const pj_str_t stateless_user = { "0", 1 };
+    pjsip_uri *uri;
+    pjsip_sip_uri *sip_uri;
+
+    uri = pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri);
+
+    /* Only want to receive SIP/SIPS scheme */
+    if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))
+	return PJ_FALSE;
+
+    sip_uri = (pjsip_sip_uri*) uri;
+
+    /* Check for matching user part */
+    if (pj_strcmp(&sip_uri->user, &stateless_user)!=0)
+	return PJ_FALSE;
+
+    /*
+     * Yes, this is for us.
+     */
+
+    /* Ignore ACK request */
+    if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD)
+	return PJ_TRUE;
+
+    /*
+     * Respond statelessly with 200/OK.
+     */
+    pjsip_endpt_respond_stateless(app.sip_endpt, rdata, 200, NULL,
+				  NULL, NULL);
+    app.server.cur_state.stateless_cnt++;
+    return PJ_TRUE;
+}
+
+
+/**************************************************************************
+ * STATEFUL SERVER
+ */
+static pj_bool_t mod_stateful_on_rx_request(pjsip_rx_data *rdata);
+
+/* Module to handle incoming requests statefully.
+ */
+static pjsip_module mod_stateful_server =
+{
+    NULL, NULL,			    /* prev, next.		*/
+    { "mod-stateful-server", 19 },  /* Name.			*/
+    -1,				    /* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
+    NULL,			    /* load()			*/
+    NULL,			    /* start()			*/
+    NULL,			    /* stop()			*/
+    NULL,			    /* unload()			*/
+    &mod_stateful_on_rx_request,   /* on_rx_request()		*/
+    NULL,			    /* on_rx_response()		*/
+    NULL,			    /* on_tx_request.		*/
+    NULL,			    /* on_tx_response()		*/
+    NULL,			    /* on_tsx_state()		*/
+};
+
+
+static pj_bool_t mod_stateful_on_rx_request(pjsip_rx_data *rdata)
+{
+    const pj_str_t stateful_user = { "1", 1 };
+    pjsip_uri *uri;
+    pjsip_sip_uri *sip_uri;
+
+    uri = pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri);
+
+    /* Only want to receive SIP/SIPS scheme */
+    if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))
+	return PJ_FALSE;
+
+    sip_uri = (pjsip_sip_uri*) uri;
+
+    /* Check for matching user part */
+    if (pj_strcmp(&sip_uri->user, &stateful_user)!=0)
+	return PJ_FALSE;
+
+    /*
+     * Yes, this is for us.
+     * Respond statefully with 200/OK.
+     */
+    switch (rdata->msg_info.msg->line.req.method.id) {
+    case PJSIP_INVITE_METHOD:
+	{
+	    pjsip_msg_body *body;
+
+	    if (dummy_sdp_str.slen == 0)
+		dummy_sdp_str.slen = pj_ansi_strlen(dummy_sdp_str.ptr);
+
+	    body = pjsip_msg_body_create(rdata->tp_info.pool, 
+					 &mime_application, &mime_sdp, 
+					 &dummy_sdp_str);
+	    pjsip_endpt_respond(app.sip_endpt, &mod_stateful_server, rdata,
+				200, NULL, NULL, body, NULL);
+	}
+	break;
+    case PJSIP_ACK_METHOD:
+	return PJ_TRUE;
+    default:
+	pjsip_endpt_respond(app.sip_endpt, &mod_stateful_server, rdata,
+			    200, NULL, NULL, NULL, NULL);
+	break;
+    }
+
+    app.server.cur_state.stateful_cnt++;
+    return PJ_TRUE;
+}
+
+
+/**************************************************************************
+ * CALL SERVER
+ */
+static pj_bool_t mod_call_on_rx_request(pjsip_rx_data *rdata);
+
+/* Module to handle incoming requests callly.
+ */
+static pjsip_module mod_call_server =
+{
+    NULL, NULL,			    /* prev, next.		*/
+    { "mod-call-server", 15 },	    /* Name.			*/
+    -1,				    /* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
+    NULL,			    /* load()			*/
+    NULL,			    /* start()			*/
+    NULL,			    /* stop()			*/
+    NULL,			    /* unload()			*/
+    &mod_call_on_rx_request,	    /* on_rx_request()		*/
+    NULL,			    /* on_rx_response()		*/
+    NULL,			    /* on_tx_request.		*/
+    NULL,			    /* on_tx_response()		*/
+    NULL,			    /* on_tsx_state()		*/
+};
+
+
+static pj_status_t send_response(pjsip_inv_session *inv, 
+				 pjsip_rx_data *rdata,
+				 int code,
+				 pj_bool_t *has_initial)
+{
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+    if (*has_initial) {
+	status = pjsip_inv_answer(inv, code, NULL, NULL, &tdata);
+    } else {
+	status = pjsip_inv_initial_answer(inv, rdata, code, 
+					  NULL, NULL, &tdata);
+    }
+
+    if (status != PJ_SUCCESS) {
+	if (*has_initial) {
+	    status = pjsip_inv_answer(inv, PJSIP_SC_NOT_ACCEPTABLE, 
+				      NULL, NULL, &tdata);
+	} else {
+	    status = pjsip_inv_initial_answer(inv, rdata, 
+					      PJSIP_SC_NOT_ACCEPTABLE,
+					      NULL, NULL, &tdata);
+	}
+
+	if (status == PJ_SUCCESS) {
+	    *has_initial = PJ_TRUE;
+	    pjsip_inv_send_msg(inv, tdata); 
+	} else {
+	    pjsip_inv_terminate(inv, 500, PJ_FALSE);
+	    return -1;
+	}
+    } else {
+	*has_initial = PJ_TRUE;
+
+	status = pjsip_inv_send_msg(inv, tdata); 
+	if (status != PJ_SUCCESS) {
+	    pjsip_tx_data_dec_ref(tdata);
+	    return status;
+	}
+    }
+
+    return status;
+}
+
+static void answer_timer_cb(pj_timer_heap_t *h, pj_timer_entry *entry)
+{
+    struct call *call = entry->user_data;
+    pj_bool_t has_initial = PJ_TRUE;
+
+    PJ_UNUSED_ARG(h);
+
+    entry->id = 0;
+    send_response(call->inv, NULL, 200, &has_initial);
+}
+
+static pj_bool_t mod_call_on_rx_request(pjsip_rx_data *rdata)
+{
+    const pj_str_t call_user = { "2", 1 };
+    pjsip_uri *uri;
+    pjsip_sip_uri *sip_uri;
+    struct call *call;
+    pjsip_dialog *dlg;
+    pjmedia_sdp_session *sdp;
+    pjsip_tx_data *tdata;
+    pj_bool_t has_initial = PJ_FALSE;
+    pj_status_t status;
+
+    uri = pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri);
+
+    /* Only want to receive SIP/SIPS scheme */
+    if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))
+	return PJ_FALSE;
+
+    sip_uri = (pjsip_sip_uri*) uri;
+
+    /* Only want to handle INVITE requests. */
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) {
+	return PJ_FALSE;
+    }
+
+
+    /* Check for matching user part. Incoming requests will be handled 
+     * call-statefully if:
+     *	- user part is "2", or
+     *  - user part is not "0" nor "1" and method is INVITE.
+     */
+    if (pj_strcmp(&sip_uri->user, &call_user) == 0 ||
+	sip_uri->user.slen != 1 ||
+	(*sip_uri->user.ptr != '0' && *sip_uri->user.ptr != '1'))
+    {
+	/* Match */
+
+    } else {
+	return PJ_FALSE;
+    }
+
+
+    /* Verify that we can handle the request. */
+    if (app.real_sdp) {
+	unsigned options = 0;
+	status = pjsip_inv_verify_request(rdata, &options, NULL, NULL,
+					  app.sip_endpt, &tdata);
+	if (status != PJ_SUCCESS) {
+
+	    /*
+	     * No we can't handle the incoming INVITE request.
+	     */
+
+	    if (tdata) {
+		pjsip_response_addr res_addr;
+
+		pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
+		pjsip_endpt_send_response(app.sip_endpt, &res_addr, tdata, 
+					  NULL, NULL);
+
+	    } else {
+
+		/* Respond with 500 (Internal Server Error) */
+		pjsip_endpt_respond_stateless(app.sip_endpt, rdata, 500, NULL,
+					      NULL, NULL);
+	    }
+
+	    return PJ_TRUE;
+	} 
+    }
+
+    /* Create UAS dialog */
+    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
+				   &app.local_contact, &dlg);
+    if (status != PJ_SUCCESS) {
+	const pj_str_t reason = pj_str("Unable to create dialog");
+	pjsip_endpt_respond_stateless( app.sip_endpt, rdata, 
+				       500, &reason,
+				       NULL, NULL);
+	return PJ_TRUE;
+    }
+
+    /* Alloc call structure. */
+    call = pj_pool_zalloc(dlg->pool, sizeof(struct call));
+
+    /* Create SDP from PJMEDIA */
+    if (app.real_sdp) {
+	status = pjmedia_endpt_create_sdp(app.med_endpt, rdata->tp_info.pool, 
+					  app.skinfo_cnt, app.skinfo, 
+					  &sdp);
+    } else {
+	sdp = app.dummy_sdp;
+    }
+
+    /* Create UAS invite session */
+    status = pjsip_inv_create_uas( dlg, rdata, sdp, 0, &call->inv);
+    if (status != PJ_SUCCESS) {
+	pjsip_dlg_create_response(dlg, rdata, 500, NULL, &tdata);
+	pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
+	return PJ_TRUE;
+    }
+    
+    /* Send 100/Trying if needed */
+    if (app.server.send_trying) {
+	status = send_response(call->inv, rdata, 100, &has_initial);
+	if (status != PJ_SUCCESS)
+	    return PJ_TRUE;
+    }
+
+    /* Send 180/Ringing if needed */
+    if (app.server.send_ringing) {
+	status = send_response(call->inv, rdata, 180, &has_initial);
+	if (status != PJ_SUCCESS)
+	    return PJ_TRUE;
+    }
+
+    /* Simulate call processing delay */
+    if (app.server.delay) {
+	pj_time_val delay;
+
+	call->ans_timer.id = 1;
+	call->ans_timer.user_data = call;
+	call->ans_timer.cb = &answer_timer_cb;
+	
+	delay.sec = 0;
+	delay.msec = app.server.delay;
+	pj_time_val_normalize(&delay);
+
+	pjsip_endpt_schedule_timer(app.sip_endpt, &call->ans_timer, &delay);
+
+    } else {
+	/* Send the 200 response immediately . */  
+	status = send_response(call->inv, rdata, 200, &has_initial);
+	PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, return PJ_TRUE);
+    }
+
+    /* Done */
+    app.server.cur_state.call_cnt++;
+
+    return PJ_TRUE;
+}
+
+
+
+/**************************************************************************
+ * Default handler when incoming request is not handled by any other
+ * modules.
+ */
+static pj_bool_t mod_responder_on_rx_request(pjsip_rx_data *rdata);
+
+/* Module to handle incoming requests statelessly.
+ */
+static pjsip_module mod_responder =
+{
+    NULL, NULL,			    /* prev, next.		*/
+    { "mod-responder", 13 },	    /* Name.			*/
+    -1,				    /* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION+1, /* Priority		*/
+    NULL,			    /* load()			*/
+    NULL,			    /* start()			*/
+    NULL,			    /* stop()			*/
+    NULL,			    /* unload()			*/
+    &mod_responder_on_rx_request,   /* on_rx_request()		*/
+    NULL,			    /* on_rx_response()		*/
+    NULL,			    /* on_tx_request.		*/
+    NULL,			    /* on_tx_response()		*/
+    NULL,			    /* on_tsx_state()		*/
+};
+
+
+static pj_bool_t mod_responder_on_rx_request(pjsip_rx_data *rdata)
+{
+    const pj_str_t reason = pj_str("Not expecting request at this URI");
+
+    /*
+     * Respond any requests (except ACK!) with 500.
+     */
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
+	pjsip_endpt_respond_stateless(app.sip_endpt, rdata, 500, &reason,
+				      NULL, NULL);
+    }
+
+    return PJ_TRUE;
+}
+
+
+
+/*****************************************************************************
+ * Below is a simple module to log all incoming and outgoing SIP messages
+ */
+
+
+/* Notification on incoming messages */
+static pj_bool_t logger_on_rx_msg(pjsip_rx_data *rdata)
+{
+    PJ_LOG(3,(THIS_FILE, "RX %d bytes %s from %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 rdata->msg_info.len,
+			 pjsip_rx_data_get_info(rdata),
+			 rdata->tp_info.transport->type_name,
+			 rdata->pkt_info.src_name,
+			 rdata->pkt_info.src_port,
+			 (int)rdata->msg_info.len,
+			 rdata->msg_info.msg_buf));
+    
+    /* Always return false, otherwise messages will not get processed! */
+    return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logger_on_tx_msg(pjsip_tx_data *tdata)
+{
+    
+    /* Important note:
+     *	tp_info field is only valid after outgoing messages has passed
+     *	transport layer. So don't try to access tp_info when the module
+     *	has lower priority than transport layer.
+     */
+
+    PJ_LOG(3,(THIS_FILE, "TX %d bytes %s to %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 (tdata->buf.cur - tdata->buf.start),
+			 pjsip_tx_data_get_info(tdata),
+			 tdata->tp_info.transport->type_name,
+			 tdata->tp_info.dst_name,
+			 tdata->tp_info.dst_port,
+			 (int)(tdata->buf.cur - tdata->buf.start),
+			 tdata->buf.start));
+
+    /* Always return success, otherwise message will not get sent! */
+    return PJ_SUCCESS;
+}
+
+/* The module instance. */
+static pjsip_module msg_logger = 
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-siprtp-log", 14 },		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &logger_on_rx_msg,			/* on_rx_request()	*/
+    &logger_on_rx_msg,			/* on_rx_response()	*/
+    &logger_on_tx_msg,			/* on_tx_request.	*/
+    &logger_on_tx_msg,			/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
+
+
+/**************************************************************************
+ * Test Client.
+ */
+
+static pj_bool_t mod_test_on_rx_response(pjsip_rx_data *rdata);
+
+static void call_on_media_update( pjsip_inv_session *inv,
+				  pj_status_t status);
+static void call_on_state_changed( pjsip_inv_session *inv, 
+				   pjsip_event *e);
+static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e);
+
+
+/* Module to handle incoming requests callly.
+ */
+static pjsip_module mod_test =
+{
+    NULL, NULL,			    /* prev, next.		*/
+    { "mod-test", 8 },		    /* Name.			*/
+    -1,				    /* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
+    NULL,			    /* load()			*/
+    NULL,			    /* start()			*/
+    NULL,			    /* stop()			*/
+    NULL,			    /* unload()			*/
+    NULL,			    /* on_rx_request()		*/
+    &mod_test_on_rx_response,	    /* on_rx_response()		*/
+    NULL,			    /* on_tx_request.		*/
+    NULL,			    /* on_tx_response()		*/
+    NULL,			    /* on_tsx_state()		*/
+};
+
+
+static void report_completion(int status_code)
+{
+    app.client.job_finished++;
+    if (status_code >= 200 && status_code < 800)
+	app.client.response_codes[status_code]++;
+    app.client.total_responses++;
+    pj_gettimeofday(&app.client.last_completion);
+}
+
+
+/* Handler when response is received. */
+static pj_bool_t mod_test_on_rx_response(pjsip_rx_data *rdata)
+{
+    if (pjsip_rdata_get_tsx(rdata) == NULL) {
+	report_completion(rdata->msg_info.msg->line.status.code);
+    }
+
+    return PJ_TRUE;
+}
+
+
+/*
+ * Create app
+ */
+static pj_status_t create_app(void)
+{
+    pj_status_t status;
+
+    status = pj_init();
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error initializing pjlib", status);
+	return status;
+    }
+
+    /* init PJLIB-UTIL: */
+    status = pjlib_util_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&app.cp, &pj_pool_factory_default_policy, 
+			 CACHING_POOL_SIZE);
+
+    /* Create application pool for misc. */
+    app.pool = pj_pool_create(&app.cp.factory, "app", 1000, 1000, NULL);
+
+    /* Create the endpoint: */
+    status = pjsip_endpt_create(&app.cp.factory, pj_gethostname()->ptr, 
+				&app.sip_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    return status;
+}
+
+
+/*
+ * Init SIP stack
+ */
+static pj_status_t init_sip()
+{
+    pj_status_t status = -1;
+
+    /* Add UDP/TCP transport. */
+    {
+	pj_sockaddr_in addr;
+	pjsip_host_port addrname;
+	const char *transport_type = NULL;
+
+	pj_bzero(&addr, sizeof(addr));
+	addr.sin_family = pj_AF_INET();
+	addr.sin_addr.s_addr = 0;
+	addr.sin_port = pj_htons((pj_uint16_t)app.local_port);
+
+	if (app.local_addr.slen) {
+	    addrname.host = app.local_addr;
+	    addrname.port = 5060;
+	} 
+	if (app.local_port != 0)
+	    addrname.port = app.local_port;
+
+	if (0) {
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP!=0
+	} else if (app.use_tcp) {
+	    pj_sockaddr_in local_addr;
+	    pjsip_tpfactory *tpfactory;
+	    
+	    transport_type = "tcp";
+	    pj_sockaddr_in_init(&local_addr, 0, (pj_uint16_t)app.local_port);
+	    status = pjsip_tcp_transport_start(app.sip_endpt, &local_addr,
+					       app.thread_count, &tpfactory);
+	    if (status == PJ_SUCCESS) {
+		app.local_addr = tpfactory->addr_name.host;
+		app.local_port = tpfactory->addr_name.port;
+	    }
+#endif
+	} else {
+	    pjsip_transport *tp;
+
+	    transport_type = "udp";
+	    status = pjsip_udp_transport_start(app.sip_endpt, &addr, 
+					       (app.local_addr.slen ? &addrname:NULL),
+					       app.thread_count, &tp);
+	    if (status == PJ_SUCCESS) {
+		app.local_addr = tp->local_name.host;
+		app.local_port = tp->local_name.port;
+	    }
+
+	}
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to start transport", status);
+	    return status;
+	}
+
+	app.local_uri.ptr = pj_pool_alloc(app.pool, 128);
+	app.local_uri.slen = pj_ansi_sprintf(app.local_uri.ptr, 
+				    	     "<sip:pjsip-perf@%.*s:%d;transport=%s>",
+					     (int)app.local_addr.slen,
+					     app.local_addr.ptr,
+					     app.local_port,
+					     transport_type);
+
+	app.local_contact = app.local_uri;
+    }
+
+    /* 
+     * Init transaction layer.
+     * This will create/initialize transaction hash tables etc.
+     */
+    status = pjsip_tsx_layer_init_module(app.sip_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /*  Initialize UA layer. */
+    status = pjsip_ua_init_module( app.sip_endpt, NULL );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Initialize 100rel support */
+    status = pjsip_100rel_init_module(app.sip_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /*  Init invite session module. */
+    {
+	pjsip_inv_callback inv_cb;
+
+	/* Init the callback for INVITE session: */
+	pj_bzero(&inv_cb, sizeof(inv_cb));
+	inv_cb.on_state_changed = &call_on_state_changed;
+	inv_cb.on_new_session = &call_on_forked;
+	inv_cb.on_media_update = &call_on_media_update;
+
+	/* Initialize invite session module:  */
+	status = pjsip_inv_usage_init(app.sip_endpt, &inv_cb);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    }
+
+    /* Register our module to receive incoming requests. */
+    status = pjsip_endpt_register_module( app.sip_endpt, &mod_test);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Register stateless server module */
+    status = pjsip_endpt_register_module( app.sip_endpt, &mod_stateless_server);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Register default responder module */
+    status = pjsip_endpt_register_module( app.sip_endpt, &mod_responder);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Register stateless server module */
+    status = pjsip_endpt_register_module( app.sip_endpt, &mod_stateful_server);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Register call server module */
+    status = pjsip_endpt_register_module( app.sip_endpt, &mod_call_server);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Done */
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Destroy SIP
+ */
+static void destroy_app()
+{
+    unsigned i;
+
+    app.thread_quit = 1;
+    for (i=0; i<app.thread_count; ++i) {
+	if (app.thread[i]) {
+	    pj_thread_join(app.thread[i]);
+	    pj_thread_destroy(app.thread[i]);
+	    app.thread[i] = NULL;
+	}
+    }
+
+    if (app.sip_endpt) {
+	pjsip_endpt_destroy(app.sip_endpt);
+	app.sip_endpt = NULL;
+    }
+
+    if (app.pool) {
+	pj_pool_release(app.pool);
+	app.pool = NULL;
+	PJ_LOG(3,(THIS_FILE, "Peak memory size: %uMB",
+			     app.cp.peak_used_size / 1000000));
+	pj_caching_pool_destroy(&app.cp);
+    }
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+}
+
+
+/*
+ * Init media stack.
+ */
+static pj_status_t init_media()
+{
+    unsigned	i;
+    pj_uint16_t	rtp_port;
+    pj_status_t	status;
+
+
+    /* Initialize media endpoint so that at least error subsystem is properly
+     * initialized.
+     */
+    status = pjmedia_endpt_create(&app.cp.factory, 
+				  pjsip_endpt_get_ioqueue(app.sip_endpt), 0, 
+				  &app.med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Must register all codecs to be supported */
+    pjmedia_codec_register_audio_codecs(app.med_endpt, NULL);
+
+    /* Init dummy socket addresses */
+    app.skinfo_cnt = 0;
+    for (i=0, rtp_port=4000; i<PJ_ARRAY_SIZE(app.skinfo); ++i, rtp_port+=2) {
+	pjmedia_sock_info *skinfo;
+
+	skinfo = &app.skinfo[i];
+	
+	pj_sockaddr_in_init(&skinfo->rtp_addr_name.ipv4, &app.local_addr,
+			    (pj_uint16_t)rtp_port);
+	pj_sockaddr_in_init(&skinfo->rtp_addr_name.ipv4, &app.local_addr,
+			    (pj_uint16_t)(rtp_port+1));
+	app.skinfo_cnt++;
+    }
+
+    /* Generate dummy SDP */
+    dummy_sdp_str.slen = pj_ansi_strlen(dummy_sdp_str.ptr);
+    status = pjmedia_sdp_parse(app.pool, dummy_sdp_str.ptr, dummy_sdp_str.slen, 
+			       &app.dummy_sdp);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error parsing dummy SDP", status);
+	return status;
+    }
+
+
+    /* Done */
+    return PJ_SUCCESS;
+}
+
+
+/* This is notification from the call about media negotiation
+ * status. This is called for client calls only.
+ */
+static void call_on_media_update( pjsip_inv_session *inv,
+				  pj_status_t status)
+{
+    if (status != PJ_SUCCESS) {
+	pjsip_tx_data *tdata;
+	pj_status_t status;
+
+	status = pjsip_inv_end_session(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE, 
+				       NULL, &tdata);
+	if (status == PJ_SUCCESS && tdata)
+	    status = pjsip_inv_send_msg(inv, tdata);
+    }
+}
+
+
+/* This is notification from the call when the call state has changed.
+ * This is called for client calls only.
+ */
+static void call_on_state_changed( pjsip_inv_session *inv, 
+				   pjsip_event *e)
+{
+    PJ_UNUSED_ARG(e);
+
+    /* Bail out if the session has been counted before */
+    if (inv->mod_data[mod_test.id] != NULL)
+	return;
+
+    /* Bail out if this is not an outgoing call */
+    if (inv->role != PJSIP_UAC_ROLE)
+	return;
+
+    if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
+	pjsip_tx_data *tdata;
+	pj_status_t status;
+
+	//report_completion(200);
+	//inv->mod_data[mod_test.id] = (void*)1;
+
+	status = pjsip_inv_end_session(inv, PJSIP_SC_OK, NULL, &tdata);
+	if (status == PJ_SUCCESS && tdata)
+	    status = pjsip_inv_send_msg(inv, tdata);
+
+    } else if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
+	report_completion(inv->cause);
+	inv->mod_data[mod_test.id] = (void*)(pj_ssize_t)1;
+    }
+}
+
+
+/* Not implemented for now */
+static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e)
+{
+    /* Do nothing */
+    PJ_UNUSED_ARG(inv);
+    PJ_UNUSED_ARG(e);
+}
+
+
+/*
+ * Make outgoing call.
+ */
+static pj_status_t make_call(const pj_str_t *dst_uri)
+{
+    struct call *call;
+    pjsip_dialog *dlg;
+    pjmedia_sdp_session *sdp;
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+
+    /* Create UAC dialog */
+    status = pjsip_dlg_create_uac( pjsip_ua_instance(), 
+				   &app.local_uri,	/* local URI	    */
+				   &app.local_contact,	/* local Contact    */
+				   dst_uri,		/* remote URI	    */
+				   dst_uri,		/* remote target    */
+				   &dlg);		/* dialog	    */
+    if (status != PJ_SUCCESS) {
+	return status;
+    }
+
+    /* Create call */
+    call = pj_pool_zalloc(dlg->pool, sizeof(struct call));
+
+    /* Create SDP */
+    if (app.real_sdp) {
+	status = pjmedia_endpt_create_sdp(app.med_endpt, dlg->pool, 1, 
+					  app.skinfo, &sdp);
+	if (status != PJ_SUCCESS) {
+	    pjsip_dlg_terminate(dlg);
+	    return status;
+	}
+    } else
+	sdp = app.dummy_sdp;
+
+    /* Create the INVITE session. */
+    status = pjsip_inv_create_uac( dlg, sdp, 0, &call->inv);
+    if (status != PJ_SUCCESS) {
+	pjsip_dlg_terminate(dlg);
+	return status;
+    }
+
+
+    /* Create initial INVITE request.
+     * This INVITE request will contain a perfectly good request and 
+     * an SDP body as well.
+     */
+    status = pjsip_inv_invite(call->inv, &tdata);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Send initial INVITE request. 
+     * From now on, the invite session's state will be reported to us
+     * via the invite session callbacks.
+     */
+    status = pjsip_inv_send_msg(call->inv, tdata);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Verify that valid SIP url is given.
+ */
+static pj_status_t verify_sip_url(const char *c_url)
+{
+    pjsip_uri *p;
+    pj_pool_t *pool;
+    char *url;
+    pj_size_t len = (c_url ? pj_ansi_strlen(c_url) : 0);
+
+    if (!len) return -1;
+
+    pool = pj_pool_create(&app.cp.factory, "check%p", 1024, 0, NULL);
+    if (!pool) return PJ_ENOMEM;
+
+    url = pj_pool_alloc(pool, len+1);
+    pj_ansi_strcpy(url, c_url);
+    url[len] = '\0';
+
+    p = pjsip_parse_uri(pool, url, len, 0);
+    if (!p || pj_stricmp2(pjsip_uri_get_scheme(p), "sip") != 0)
+	p = NULL;
+
+    pj_pool_release(pool);
+    return p ? 0 : -1;
+}
+
+
+static void usage(void)
+{
+    printf(
+	"Usage:\n"
+	"   pjsip-perf [OPTIONS]        -- to start as server\n"
+	"   pjsip-perf [OPTIONS] URL    -- to call server (possibly itself)\n"
+	"\n"
+	"where:\n"
+	"   URL                     The SIP URL to be contacted.\n"
+	"\n"
+	"Client options:\n"
+	"   --method=METHOD, -m     Set test method (set to INVITE for call benchmark)\n"
+        "                           [default: OPTIONS]\n"
+	"   --count=N, -n           Set total number of requests to initiate\n"
+	"                           [default=%d]\n"
+	"   --stateless, -s         Set to operate in stateless mode\n"
+	"                           [default: stateful]\n"
+	"   --timeout=SEC, -t       Set client timeout [default=60 sec]\n"
+	"   --window=COUNT, -w      Set maximum outstanding job [default: %d]\n"
+	"\n"
+	"SDP options (client and server):\n"
+	"   --real-sdp              Generate real SDP from pjmedia, and also perform\n"
+	"                           proper SDP negotiation [default: dummy]\n"
+	"\n"
+	"Client and Server options:\n"
+	"   --local-port=PORT, -p   Set local port [default: 5060]\n"
+	"   --use-tcp, -T           Use TCP instead of UDP. Note that when started as\n"
+	"                           client, you must add ;transport=tcp parameter to URL\n"
+	"                           [default: no]\n"
+	"   --thread-count=N        Set number of worker threads [default=1]\n"
+	"   --trying                Send 100/Trying response (server, default no)\n"
+	"   --ringing               Send 180/Ringing response (server, default no)\n"
+	"   --delay=MS, -d          Delay answering call by MS (server, default no)\n"
+	"\n"
+	"Misc options:\n"
+	"   --help, -h              Display this screen\n"
+	"   --verbose, -v           Verbose logging (put more than once for even more)\n"
+	"\n"
+	"When started as server, pjsip-perf can be contacted on the following URIs:\n"
+	"   - sip:0@server-addr     To handle requests statelessly.\n"
+	"   - sip:1@server-addr     To handle requests statefully.\n"
+	"   - sip:2@server-addr     To handle INVITE call.\n",
+	DEFAULT_COUNT, JOB_WINDOW);
+}
+
+
+static int my_atoi(const char *s)
+{
+    pj_str_t ss = pj_str((char*)s);
+    return pj_strtoul(&ss);
+}
+
+
+static pj_status_t init_options(int argc, char *argv[])
+{
+    enum { OPT_THREAD_COUNT = 1, OPT_REAL_SDP, OPT_TRYING, OPT_RINGING };
+    struct pj_getopt_option long_options[] = {
+	{ "local-port",	    1, 0, 'p' },
+	{ "count",	    1, 0, 'c' },
+	{ "thread-count",   1, 0, OPT_THREAD_COUNT },
+	{ "method",	    1, 0, 'm' },
+	{ "help",	    0, 0, 'h' },
+	{ "stateless",	    0, 0, 's' },
+	{ "timeout",	    1, 0, 't' },
+	{ "real-sdp",	    0, 0, OPT_REAL_SDP },
+	{ "verbose",        0, 0, 'v' },
+	{ "use-tcp",	    0, 0, 'T' },
+	{ "window",	    1, 0, 'w' },
+	{ "delay",	    1, 0, 'd' },
+	{ "trying",	    0, 0, OPT_TRYING},
+	{ "ringing",	    0, 0, OPT_RINGING},
+	{ NULL, 0, 0, 0 },
+    };
+    int c;
+    int option_index;
+
+    /* Init default application configs */
+    app.local_port = 5060;
+    app.thread_count = 1;
+    app.client.job_count = DEFAULT_COUNT;
+    app.client.method = *pjsip_get_options_method();
+    app.client.job_window = c = JOB_WINDOW;
+    app.client.timeout = 60;
+    app.log_level = 3;
+
+
+    /* Parse options */
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc,argv, "p:c:m:t:w:d:hsv", 
+			    long_options, &option_index))!=-1) 
+    {
+	switch (c) {
+	case 'p':
+	    app.local_port = my_atoi(pj_optarg);
+	    if (app.local_port < 0 || app.local_port > 65535) {
+		PJ_LOG(3,(THIS_FILE, "Invalid --local-port %s", pj_optarg));
+		return -1;
+	    }
+	    break;
+
+	case 'c':
+	    app.client.job_count = my_atoi(pj_optarg);
+	    if (app.client.job_count < 0) {
+		PJ_LOG(3,(THIS_FILE, "Invalid --local-port %s", pj_optarg));
+		return -1;
+	    }
+	    if (app.client.job_count > pjsip_cfg()->tsx.max_count)
+		PJ_LOG(3,(THIS_FILE, 
+			  "Warning: --count value (%d) exceeds maximum "
+			  "transaction count (%d)", app.client.job_count,
+			  pjsip_cfg()->tsx.max_count));
+	    break;
+
+	case OPT_THREAD_COUNT:
+	    app.thread_count = my_atoi(pj_optarg);
+	    if (app.thread_count < 1 || app.thread_count > 16) {
+		PJ_LOG(3,(THIS_FILE, "Invalid --thread-count %s", pj_optarg));
+		return -1;
+	    }
+	    break;
+
+	case 'm':
+	    {
+		pj_str_t temp = pj_str((char*)pj_optarg);
+		pjsip_method_init_np(&app.client.method, &temp);
+	    }
+	    break;
+
+	case 'h':
+	    usage();
+	    return -1;
+
+	case 's':
+	    app.client.stateless = PJ_TRUE;
+	    break;
+
+	case OPT_REAL_SDP:
+	    app.real_sdp = 1;
+	    break;
+
+	case 'v':
+	    app.log_level++;
+	    break;
+
+	case 't':
+	    app.client.timeout = my_atoi(pj_optarg);
+	    if (app.client.timeout < 0 || app.client.timeout > 600) {
+		PJ_LOG(3,(THIS_FILE, "Invalid --timeout %s", pj_optarg));
+		return -1;
+	    }
+	    break;
+
+	case 'w':
+	    app.client.job_window = my_atoi(pj_optarg);
+	    if (app.client.job_window <= 0) {
+		PJ_LOG(3,(THIS_FILE, "Invalid --window %s", pj_optarg));
+		return -1;
+	    }
+	    break;
+
+	case 'T':
+	    app.use_tcp = PJ_TRUE;
+	    break;
+
+	case 'd':
+	    app.server.delay = my_atoi(pj_optarg);
+	    if (app.server.delay > 3600) {
+		PJ_LOG(3,(THIS_FILE, "I think --delay %s is too long", 
+			  pj_optarg));
+		return -1;
+	    }
+	    break;
+
+	case OPT_TRYING:
+	    app.server.send_trying = 1;
+	    break;
+
+	case OPT_RINGING:
+	    app.server.send_ringing = 1;
+	    break;
+
+	default:
+	    PJ_LOG(1,(THIS_FILE, 
+		      "Invalid argument. Use --help to see help"));
+	    return -1;
+	}
+    }
+
+    if (pj_optind != argc) {
+
+	if (verify_sip_url(argv[pj_optind]) != PJ_SUCCESS) {
+	    PJ_LOG(1,(THIS_FILE, "Invalid SIP URI %s", argv[pj_optind]));
+	    return -1;
+	}
+	app.client.dst_uri = pj_str(argv[pj_optind]);
+	
+	pj_optind++;
+
+    }
+
+    if (pj_optind != argc) {
+	PJ_LOG(1,(THIS_FILE, "Error: unknown options %s", argv[pj_optind]));
+	return -1;
+    }
+
+    return 0;
+}
+
+
+/* Send one stateless request */
+static pj_status_t submit_stateless_job(void)
+{
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+    status = pjsip_endpt_create_request(app.sip_endpt, &app.client.method, 
+					&app.client.dst_uri, &app.local_uri,
+					&app.client.dst_uri, &app.local_contact,
+					NULL, -1, NULL, &tdata);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error creating request", status);
+	report_completion(701);
+	return status;
+    }
+
+    status = pjsip_endpt_send_request_stateless(app.sip_endpt, tdata, NULL,
+						NULL);
+    if (status != PJ_SUCCESS) {
+	pjsip_tx_data_dec_ref(tdata);
+	app_perror(THIS_FILE, "Error sending stateless request", status);
+	report_completion(701);
+	return status;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/* This callback is called when client transaction state has changed */
+static void tsx_completion_cb(void *token, pjsip_event *event)
+{
+    pjsip_transaction *tsx;
+
+    PJ_UNUSED_ARG(token);
+
+    if (event->type != PJSIP_EVENT_TSX_STATE)
+	return;
+
+    tsx = event->body.tsx_state.tsx;
+
+    if (tsx->mod_data[mod_test.id] != NULL) {
+	/* This transaction has been calculated before */
+	return;
+    }
+
+    if (tsx->state==PJSIP_TSX_STATE_TERMINATED) {
+	report_completion(tsx->status_code);
+	tsx->mod_data[mod_test.id] = (void*)(pj_ssize_t)1;
+    }
+    else if (tsx->method.id == PJSIP_INVITE_METHOD &&
+	     tsx->state == PJSIP_TSX_STATE_CONFIRMED) {
+
+	report_completion(tsx->status_code);
+	tsx->mod_data[mod_test.id] = (void*)(pj_ssize_t)1;
+	
+    } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
+
+	report_completion(tsx->status_code);
+	tsx->mod_data[mod_test.id] = (void*)(pj_ssize_t)1;
+
+	TERMINATE_TSX(tsx, tsx->status_code);
+    }
+}
+
+
+/* Send one stateful request */
+static pj_status_t submit_job(void)
+{
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+    status = pjsip_endpt_create_request(app.sip_endpt, &app.client.method, 
+					&app.client.dst_uri, &app.local_uri,
+					&app.client.dst_uri, &app.local_contact,
+					NULL, -1, NULL, &tdata);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error creating request", status);
+	report_completion(701);
+	return status;
+    }
+
+    status = pjsip_endpt_send_request(app.sip_endpt, tdata, -1, NULL, 
+				      &tsx_completion_cb);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error sending stateful request", status);
+	//should have been reported by tsx_completion_cb().
+	//report_completion(701);
+	//No longer necessary (r777)
+	//pjsip_tx_data_dec_ref(tdata);
+    }
+    return status;
+}
+
+
+/* Client worker thread */
+static int client_thread(void *arg)
+{
+    pj_time_val end_time, last_report, now;
+    unsigned thread_index = (unsigned)(long)(pj_ssize_t)arg;
+    unsigned cycle = 0, last_cycle = 0;
+
+    pj_thread_sleep(100);
+
+    pj_gettimeofday(&end_time);
+    end_time.sec += app.client.timeout;
+
+    pj_gettimeofday(&last_report);
+
+    if (app.client.first_request.sec == 0) {
+	pj_gettimeofday(&app.client.first_request);
+    }
+
+    /* Submit all jobs */
+    while (app.client.job_submitted < app.client.job_count && !app.thread_quit){
+	pj_time_val timeout = { 0, 1 };
+	unsigned i;
+	int outstanding;
+	pj_status_t status;
+
+	/* Calculate current outstanding job */
+	outstanding = app.client.job_submitted - app.client.job_finished;
+
+	/* Update stats on max outstanding jobs */
+	if (outstanding > (int)app.client.stat_max_window)
+	    app.client.stat_max_window = outstanding;
+
+	/* Wait if there are more pending jobs than allowed in the
+	 * window. But spawn a new job anyway if no events are happening
+	 * after we wait for some time.
+	 */
+	for (i=0; outstanding > (int)app.client.job_window && i<1000; ++i) {
+	    pj_time_val wait = { 0, 500 };
+	    unsigned count = 0;
+
+	    pjsip_endpt_handle_events2(app.sip_endpt, &wait, &count);
+	    outstanding = app.client.job_submitted - app.client.job_finished;
+
+	    if (count == 0)
+		break;
+
+	    ++cycle;
+	}
+
+
+	/* Submit one job */
+	if (app.client.method.id == PJSIP_INVITE_METHOD) {
+	    status = make_call(&app.client.dst_uri);
+	} else if (app.client.stateless) {
+	    status = submit_stateless_job();
+	} else {
+	    status = submit_job();
+	}
+
+	++app.client.job_submitted;
+	++cycle;
+
+	/* Handle event */
+	pjsip_endpt_handle_events2(app.sip_endpt, &timeout, NULL);
+
+	/* Check for time out, also print report */
+	if (cycle - last_cycle >= 500) {
+	    pj_gettimeofday(&now);
+	    if (PJ_TIME_VAL_GTE(now, end_time)) {
+		break;
+	    }
+	    last_cycle = cycle;
+
+	    
+	    if (thread_index == 0 && now.sec-last_report.sec >= 2) {
+		printf("\r%d jobs started, %d completed...   ",
+		       app.client.job_submitted, app.client.job_finished);
+		fflush(stdout);
+		last_report = now;
+	    }
+	}
+    }
+
+    if (app.client.requests_sent.sec == 0) {
+	pj_gettimeofday(&app.client.requests_sent);
+    }
+
+
+    if (thread_index == 0) {
+	printf("\r%d jobs started, %d completed%s\n",
+	       app.client.job_submitted, app.client.job_finished,
+	       (app.client.job_submitted!=app.client.job_finished ? 
+		", waiting..." : ".") );
+	fflush(stdout);
+    }
+
+    /* Wait until all jobs completes, or timed out */
+    pj_gettimeofday(&now);
+    while (PJ_TIME_VAL_LT(now, end_time) && 
+	   app.client.job_finished < app.client.job_count && 
+	   !app.thread_quit) 
+    {
+	pj_time_val timeout = { 0, 1 };
+	unsigned i;
+
+	for (i=0; i<1000; ++i) {
+	    unsigned count;
+	    count = 0;
+	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, &count);
+	    if (count == 0)
+		break;
+	}
+
+	pj_gettimeofday(&now);
+    }
+
+    /* Wait couple of seconds to let jobs completes (e.g. ACKs to be sent)  */
+    pj_gettimeofday(&now);
+    end_time = now;
+    end_time.sec += 2;
+    while (PJ_TIME_VAL_LT(now, end_time)) 
+    {
+	pj_time_val timeout = { 0, 1 };
+	unsigned i;
+
+	for (i=0; i<1000; ++i) {
+	    unsigned count;
+	    count = 0;
+	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, &count);
+	    if (count == 0)
+		break;
+	}
+
+	pj_gettimeofday(&now);
+    }
+
+    return 0;
+}
+
+
+static const char *good_number(char *buf, pj_int32_t val)
+{
+    if (val < 1000) {
+	pj_ansi_sprintf(buf, "%d", val);
+    } else if (val < 1000000) {
+	pj_ansi_sprintf(buf, "%d.%dK", 
+			val / 1000,
+			(val % 1000) / 100);
+    } else {
+	pj_ansi_sprintf(buf, "%d.%02dM", 
+			val / 1000000,
+			(val % 1000000) / 10000);
+    }
+
+    return buf;
+}
+
+
+static int server_thread(void *arg)
+{
+    pj_time_val timeout = { 0, 1 };
+    unsigned thread_index = (unsigned)(long)(pj_ssize_t)arg;
+    pj_time_val last_report, next_report;
+
+    pj_gettimeofday(&last_report);
+    next_report = last_report;
+    next_report.sec++;
+
+    while (!app.thread_quit) {
+	pj_time_val now;
+	unsigned i;
+
+	for (i=0; i<100; ++i) {
+	    unsigned count = 0;
+	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, &count);
+	    if (count == 0)
+		break;
+	}
+
+	if (thread_index == 0) {
+	    pj_gettimeofday(&now);
+
+	    if (PJ_TIME_VAL_GTE(now, next_report)) {
+		pj_time_val tmp;
+		unsigned msec;
+		unsigned stateless, stateful, call;
+		char str_stateless[32], str_stateful[32], str_call[32];
+
+		tmp = now;
+		PJ_TIME_VAL_SUB(tmp, last_report);
+		msec = PJ_TIME_VAL_MSEC(tmp);
+
+		last_report = now;
+		next_report = last_report;
+		next_report.sec++;
+
+		stateless = app.server.cur_state.stateless_cnt - app.server.prev_state.stateless_cnt;
+		stateful = app.server.cur_state.stateful_cnt - app.server.prev_state.stateful_cnt;
+		call = app.server.cur_state.call_cnt - app.server.prev_state.call_cnt;
+
+		good_number(str_stateless, app.server.cur_state.stateless_cnt);
+		good_number(str_stateful, app.server.cur_state.stateful_cnt);
+		good_number(str_call, app.server.cur_state.call_cnt);
+
+		printf("Total(rate): stateless:%s (%d/s), statefull:%s (%d/s), call:%s (%d/s)       \r",
+		       str_stateless, stateless*1000/msec,
+		       str_stateful, stateful*1000/msec,
+		       str_call, call*1000/msec);
+		fflush(stdout);
+
+		app.server.prev_state = app.server.cur_state;
+	    }
+	}
+    }
+
+    return 0;
+}
+
+static void write_report(const char *msg)
+{
+    puts(msg);
+
+#if (defined(PJ_WIN32) && PJ_WIN32!=0) || (defined(PJ_WIN64) && PJ_WIN64!=0)
+    OutputDebugString(msg);
+    OutputDebugString("\n");
+#endif
+}
+
+
+int main(int argc, char *argv[])
+{
+    static char report[1024];
+
+    printf("PJSIP Performance Measurement Tool v%s\n"
+           "(c)2006 pjsip.org\n\n",
+	   PJ_VERSION);
+
+    if (create_app() != 0)
+	return 1;
+
+    if (init_options(argc, argv) != 0)
+	return 1;
+
+    if (init_sip() != 0)
+	return 1;
+
+    if (init_media() != 0)
+	return 1;
+
+    pj_log_set_level(app.log_level);
+
+    if (app.log_level > 4) {
+	pjsip_endpt_register_module(app.sip_endpt, &msg_logger);
+    }
+
+
+    /* Misc infos */
+    if (app.client.dst_uri.slen != 0) {
+	if (app.client.method.id == PJSIP_INVITE_METHOD) {
+	    if (app.client.stateless) {
+		PJ_LOG(3,(THIS_FILE, 
+			  "Info: --stateless option makes no sense for INVITE,"
+			  " ignored."));
+	    }
+	}
+
+    }
+
+
+
+    if (app.client.dst_uri.slen) {
+	/* Client mode */
+	pj_status_t status;
+	char test_type[64];
+	unsigned msec_req, msec_res;
+	unsigned i;
+
+	/* Get the job name */
+	if (app.client.method.id == PJSIP_INVITE_METHOD) {
+	    pj_ansi_strcpy(test_type, "INVITE calls");
+	} else if (app.client.stateless) {
+	    pj_ansi_sprintf(test_type, "stateless %.*s requests",
+			    (int)app.client.method.name.slen,
+			    app.client.method.name.ptr);
+	} else {
+	    pj_ansi_sprintf(test_type, "stateful %.*s requests",
+			    (int)app.client.method.name.slen,
+			    app.client.method.name.ptr);
+	}
+	
+
+	printf("Sending %d %s to '%.*s' with %d maximum outstanding jobs, please wait..\n", 
+		  app.client.job_count, test_type,
+		  (int)app.client.dst_uri.slen, app.client.dst_uri.ptr,
+		  app.client.job_window);
+
+	for (i=0; i<app.thread_count; ++i) {
+	    status = pj_thread_create(app.pool, NULL, &client_thread, 
+				      (void*)(pj_ssize_t)i, 0, 0, 
+				      &app.thread[i]);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to create thread", status);
+		return 1;
+	    }
+	}
+
+	for (i=0; i<app.thread_count; ++i) {
+	    pj_thread_join(app.thread[i]);
+	    app.thread[i] = NULL;
+	}
+
+	if (app.client.last_completion.sec) {
+	    pj_time_val duration;
+	    duration = app.client.last_completion;
+	    PJ_TIME_VAL_SUB(duration, app.client.first_request);
+	    msec_res = PJ_TIME_VAL_MSEC(duration);
+	} else {
+	    msec_res = app.client.timeout * 1000;
+	}
+
+	if (msec_res == 0) msec_res = 1;
+
+	if (app.client.requests_sent.sec) {
+	    pj_time_val duration;
+	    duration = app.client.requests_sent;
+	    PJ_TIME_VAL_SUB(duration, app.client.first_request);
+	    msec_req = PJ_TIME_VAL_MSEC(duration);
+	} else {
+	    msec_req = app.client.timeout * 1000;
+	}
+
+	if (msec_req == 0) msec_req = 1;
+
+	if (app.client.job_submitted < app.client.job_count)
+	    puts("\ntimed-out!\n");
+	else
+	    puts("\ndone.\n");
+
+	pj_ansi_snprintf(
+	    report, sizeof(report),
+	    "Total %d %s sent in %d ms at rate of %d/sec\n"
+	    "Total %d responses receieved in %d ms at rate of %d/sec:",
+	    app.client.job_submitted, test_type, msec_req, 
+	    app.client.job_submitted * 1000 / msec_req,
+	    app.client.total_responses, msec_res,
+	    app.client.total_responses*1000/msec_res);
+	write_report(report);
+
+	/* Print detailed response code received */
+	pj_ansi_sprintf(report, "\nDetailed responses received:");
+	write_report(report);
+
+	for (i=0; i<PJ_ARRAY_SIZE(app.client.response_codes); ++i) {
+	    const pj_str_t *reason;
+
+	    if (app.client.response_codes[i] == 0)
+		continue;
+
+	    reason = pjsip_get_status_text(i);
+	    pj_ansi_snprintf( report, sizeof(report),
+			      " - %d responses:  %7d     (%.*s)",
+			      i, app.client.response_codes[i],
+			      (int)reason->slen, reason->ptr);
+	    write_report(report);
+	}
+
+	/* Total responses and rate */
+	pj_ansi_snprintf( report, sizeof(report),
+	    "                    ------\n"
+	    " TOTAL responses:  %7d (rate=%d/sec)\n",
+	    app.client.total_responses, 
+	    app.client.total_responses*1000/msec_res);
+
+	write_report(report);
+
+	pj_ansi_sprintf(report, "Maximum outstanding job: %d", 
+			app.client.stat_max_window);
+	write_report(report);
+
+
+    } else {
+	/* Server mode */
+	char s[10], *unused;
+	pj_status_t status;
+	unsigned i;
+
+	puts("pjsip-perf started in server-mode");
+
+	printf("Receiving requests on the following URIs:\n"
+	       "  sip:0@%.*s:%d%s    for stateless handling\n"
+	       "  sip:1@%.*s:%d%s    for stateful handling\n"
+	       "  sip:2@%.*s:%d%s    for call handling\n",
+	       (int)app.local_addr.slen,
+	       app.local_addr.ptr,
+	       app.local_port,
+	       (app.use_tcp ? ";transport=tcp" : ""),
+	       (int)app.local_addr.slen,
+	       app.local_addr.ptr,
+	       app.local_port,
+	       (app.use_tcp ? ";transport=tcp" : ""),
+	       (int)app.local_addr.slen,
+	       app.local_addr.ptr,
+	       app.local_port,
+	       (app.use_tcp ? ";transport=tcp" : ""));
+	printf("INVITE with non-matching user part will be handled call-statefully\n");
+
+	for (i=0; i<app.thread_count; ++i) {
+	    status = pj_thread_create(app.pool, NULL, &server_thread, 
+				      (void*)(pj_ssize_t)i, 0, 0, 
+				      &app.thread[i]);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to create thread", status);
+		return 1;
+	    }
+	}
+
+	puts("\nPress <ENTER> to quit\n");
+	fflush(stdout);
+	unused = fgets(s, sizeof(s), stdin);
+	PJ_UNUSED_ARG(unused);
+
+	app.thread_quit = PJ_TRUE;
+	for (i=0; i<app.thread_count; ++i) {
+	    pj_thread_join(app.thread[i]);
+	    app.thread[i] = NULL;
+	}
+
+	puts("");
+    }
+
+
+    destroy_app();
+
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/pjsua2_demo.cpp b/jni/libpjsip/sources/pjsip-apps/src/samples/pjsua2_demo.cpp
new file mode 100644
index 0000000..26bb8ad
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/pjsua2_demo.cpp
@@ -0,0 +1,323 @@
+/* $Id: pjsua2_demo.cpp 4708 2014-01-21 10:59:25Z nanang $ */
+/*
+ * Copyright (C) 2008-2013 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.hpp>
+#include <iostream>
+#include <memory>
+#include <pj/file_access.h>
+
+using namespace pj;
+
+class MyAccount;
+
+class MyCall : public Call
+{
+private:
+    MyAccount *myAcc;
+
+public:
+    MyCall(Account &acc, int call_id = PJSUA_INVALID_ID)
+    : Call(acc, call_id)
+    {
+        myAcc = (MyAccount *)&acc;
+    }
+    
+    virtual void onCallState(OnCallStateParam &prm);
+};
+
+class MyAccount : public Account
+{
+public:
+    std::vector<Call *> calls;
+    
+public:
+    MyAccount()
+    {}
+
+    ~MyAccount()
+    {
+        std::cout << "*** Account is being deleted: No of calls="
+                  << calls.size() << std::endl;
+    }
+    
+    void removeCall(Call *call)
+    {
+        for (std::vector<Call *>::iterator it = calls.begin();
+             it != calls.end(); ++it)
+        {
+            if (*it == call) {
+                calls.erase(it);
+                break;
+            }
+        }
+    }
+
+    virtual void onRegState(OnRegStateParam &prm)
+    {
+	AccountInfo ai = getInfo();
+	std::cout << (ai.regIsActive? "*** Register: code=" : "*** Unregister: code=")
+		  << prm.code << std::endl;
+    }
+    
+    virtual void onIncomingCall(OnIncomingCallParam &iprm)
+    {
+        Call *call = new MyCall(*this, iprm.callId);
+        CallInfo ci = call->getInfo();
+        CallOpParam prm;
+        
+        std::cout << "*** Incoming Call: " <<  ci.remoteUri << " ["
+                  << ci.stateText << "]" << std::endl;
+        
+        calls.push_back(call);
+        prm.statusCode = (pjsip_status_code)200;
+        call->answer(prm);
+    }
+};
+
+void MyCall::onCallState(OnCallStateParam &prm)
+{
+    PJ_UNUSED_ARG(prm);
+
+    CallInfo ci = getInfo();
+    std::cout << "*** Call: " <<  ci.remoteUri << " [" << ci.stateText
+              << "]" << std::endl;
+    
+    if (ci.state == PJSIP_INV_STATE_DISCONNECTED) {
+        myAcc->removeCall(this);
+        /* Delete the call */
+        delete this;
+    }
+}
+
+static void mainProg1() throw(Error)
+{
+    Endpoint ep;
+
+    // Create library
+    ep.libCreate();
+
+    // Init library
+    EpConfig ep_cfg;
+    ep_cfg.logConfig.level = 4;
+    ep.libInit( ep_cfg );
+
+    // Transport
+    TransportConfig tcfg;
+    tcfg.port = 5060;
+    ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg);
+
+    // Start library
+    ep.libStart();
+    std::cout << "*** PJSUA2 STARTED ***" << std::endl;
+
+    // Add account
+    AccountConfig acc_cfg;
+    acc_cfg.idUri = "sip:test1@pjsip.org";
+    acc_cfg.regConfig.registrarUri = "sip:pjsip.org";
+    acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*",
+                                                        "test1", 0, "test1") );
+    std::auto_ptr<MyAccount> acc(new MyAccount);
+    acc->create(acc_cfg);
+    
+    pj_thread_sleep(2000);
+    
+    // Make outgoing call
+    Call *call = new MyCall(*acc);
+    acc->calls.push_back(call);
+    CallOpParam prm(true);
+    prm.opt.audioCount = 1;
+    prm.opt.videoCount = 0;
+    call->makeCall("sip:test1@pjsip.org", prm);
+    
+    // Hangup all calls
+    pj_thread_sleep(8000);
+    ep.hangupAllCalls();
+    pj_thread_sleep(4000);
+    
+    // Destroy library
+    std::cout << "*** PJSUA2 SHUTTING DOWN ***" << std::endl;
+}
+
+void mainProg2() throw(Error)
+{
+    Endpoint ep;
+
+    // Create library
+    ep.libCreate();
+
+    string json_str;
+
+    {
+	EpConfig epCfg;
+	JsonDocument jDoc;
+
+	epCfg.uaConfig.maxCalls = 61;
+	epCfg.uaConfig.userAgent = "Just JSON Test";
+	epCfg.uaConfig.stunServer.push_back("stun1.pjsip.org");
+	epCfg.uaConfig.stunServer.push_back("stun2.pjsip.org");
+	epCfg.logConfig.filename = "THE.LOG";
+
+	jDoc.writeObject(epCfg);
+	json_str = jDoc.saveString();
+	std::cout << json_str << std::endl << std::endl;
+    }
+
+    {
+	EpConfig epCfg;
+	JsonDocument rDoc;
+	string output;
+
+	rDoc.loadString(json_str);
+	rDoc.readObject(epCfg);
+
+	JsonDocument wDoc;
+
+	wDoc.writeObject(epCfg);
+	json_str = wDoc.saveString();
+	std::cout << json_str << std::endl << std::endl;
+
+	wDoc.saveFile("jsontest.js");
+    }
+
+    {
+	EpConfig epCfg;
+	JsonDocument rDoc;
+
+	rDoc.loadFile("jsontest.js");
+	rDoc.readObject(epCfg);
+	pj_file_delete("jsontest.js");
+    }
+
+    ep.libDestroy();
+}
+
+
+void mainProg3() throw(Error)
+{
+    Endpoint ep;
+
+    // Create library
+    ep.libCreate();
+
+    // Init library
+    EpConfig ep_cfg;
+    ep.libInit( ep_cfg );
+
+    // Start library
+    ep.libStart();
+    std::cout << "*** PJSUA2 STARTED ***" << std::endl;
+
+    // Create player and recorder
+    {
+	AudioMediaPlayer amp;
+	amp.createPlayer("../../tests/pjsua/wavs/input.16.wav");
+
+	AudioMediaRecorder amr;
+	amr.createRecorder("recorder_test_output.wav");
+
+	amp.startTransmit(ep.audDevManager().getPlaybackDevMedia());
+	amp.startTransmit(amr);
+
+	pj_thread_sleep(5000);
+    }
+
+    ep.libDestroy();
+}
+
+
+void mainProg() throw(Error)
+{
+    Endpoint ep;
+
+    // Create library
+    ep.libCreate();
+
+    string json_str;
+
+    {
+	JsonDocument jdoc;
+	AccountConfig accCfg;
+
+	accCfg.idUri = "\"Just Test\" <sip:test@pjsip.org>";
+	accCfg.regConfig.registrarUri = "sip:pjsip.org";
+	SipHeader h;
+	h.hName = "X-Header";
+	h.hValue = "User header";
+	accCfg.regConfig.headers.push_back(h);
+
+	accCfg.sipConfig.proxies.push_back("<sip:sip.pjsip.org;transport=tcp>");
+	accCfg.sipConfig.proxies.push_back("<sip:sip.pjsip.org;transport=tls>");
+
+	accCfg.mediaConfig.transportConfig.tlsConfig.ciphers.push_back(1);
+	accCfg.mediaConfig.transportConfig.tlsConfig.ciphers.push_back(2);
+	accCfg.mediaConfig.transportConfig.tlsConfig.ciphers.push_back(3);
+
+	AuthCredInfo aci;
+	aci.scheme = "digest";
+	aci.username = "test";
+	aci.data = "passwd";
+	aci.realm = "*";
+	accCfg.sipConfig.authCreds.push_back(aci);
+
+	jdoc.writeObject(accCfg);
+	json_str = jdoc.saveString();
+	std::cout << "Original:" << std::endl;
+	std::cout << json_str << std::endl << std::endl;
+    }
+
+    {
+	JsonDocument rdoc;
+
+	rdoc.loadString(json_str);
+	AccountConfig accCfg;
+	rdoc.readObject(accCfg);
+
+	JsonDocument wdoc;
+	wdoc.writeObject(accCfg);
+	json_str = wdoc.saveString();
+
+	std::cout << "Parsed:" << std::endl;
+	std::cout << json_str << std::endl << std::endl;
+    }
+
+    ep.libDestroy();
+}
+
+int main()
+{
+    int ret = 0;
+
+    /* Test endpoint instantiation and destruction without libCreate(),
+     * libInit() etc.
+     */
+    {
+	Endpoint ep;
+    }
+
+    try {
+	mainProg3();
+	std::cout << "Success" << std::endl;
+    } catch (Error & err) {
+	std::cout << "Exception: " << err.info() << std::endl;
+	ret = 1;
+    }
+
+    return ret;
+}
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/playfile.c b/jni/libpjsip/sources/pjsip-apps/src/samples/playfile.c
new file mode 100644
index 0000000..778b3e5
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/playfile.c
@@ -0,0 +1,217 @@
+/* $Id: playfile.c 3664 2011-07-19 03:42:28Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 <pjmedia.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+
+/**
+ * \page page_pjmedia_samples_playfile_c Samples: Playing WAV File to Sound Device
+ *
+ * This is a very simple example to use the @ref PJMEDIA_FILE_PLAY and
+ * @ref PJMED_SND_PORT. In this example, we open both the file and sound
+ * device, and connect the two of them, and voila! Sound will be playing
+ * the contents of the file.
+ *
+ * @see page_pjmedia_samples_recfile_c
+ *
+ * This file is pjsip-apps/src/samples/playfile.c
+ *
+ * \includelineno playfile.c
+ */
+
+
+/*
+ * playfile.c
+ *
+ * PURPOSE:
+ *  Play a WAV file to sound player device.
+ *
+ * USAGE:
+ *  playfile FILE.WAV
+ *
+ *  The WAV file could have mono or stereo channels with arbitrary
+ *  sampling rate, but MUST contain uncompressed (i.e. 16bit) PCM.
+ *
+ */
+
+
+/* For logging purpose. */
+#define THIS_FILE   "playfile.c"
+
+
+static const char *desc = 
+" FILE		    						    \n"
+"		    						    \n"
+"  playfile.c	    						    \n"
+"		    						    \n"
+" PURPOSE	    						    \n"
+"		    						    \n"
+"  Demonstrate how to play a WAV file.				    \n"
+"		    						    \n"
+" USAGE		    						    \n"
+"		    						    \n"
+"  playfile FILE.WAV						    \n"
+"		    						    \n"
+"  The WAV file could have mono or stereo channels with arbitrary   \n"
+"  sampling rate, but MUST contain uncompressed (i.e. 16bit) PCM.   \n";
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_port *file_port;
+    pjmedia_snd_port *snd_port;
+    char tmp[10];
+    pj_status_t status;
+
+
+    if (argc != 2) {
+    	puts("Error: filename required");
+	puts(desc);
+	return 1;
+    }
+
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "wav",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    /* Create file media port from the WAV file */
+    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
+					      argv[1],	/* file to play	    */
+					      20,	/* ptime.	    */
+					      0,	/* flags	    */
+					      0,	/* default buffer   */
+					      &file_port/* returned port    */
+					      );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to use WAV file", status);
+	return 1;
+    }
+
+    /* Create sound player port. */
+    status = pjmedia_snd_port_create_player( 
+		 pool,				    /* pool		    */
+		 -1,				    /* use default dev.	    */
+		 PJMEDIA_PIA_SRATE(&file_port->info),/* clock rate.	    */
+		 PJMEDIA_PIA_CCNT(&file_port->info),/* # of channels.	    */
+		 PJMEDIA_PIA_SPF(&file_port->info), /* samples per frame.   */
+		 PJMEDIA_PIA_BITS(&file_port->info),/* bits per sample.	    */
+		 0,				    /* options		    */
+		 &snd_port			    /* returned port	    */
+		 );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to open sound device", status);
+	return 1;
+    }
+
+    /* Connect file port to the sound player.
+     * Stream playing will commence immediately.
+     */
+    status = pjmedia_snd_port_connect( snd_port, file_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+
+    /* 
+     * File should be playing and looping now, using sound device's thread. 
+     */
+
+
+    /* Sleep to allow log messages to flush */
+    pj_thread_sleep(100);
+
+
+    printf("Playing %s..\n", argv[1]);
+    puts("");
+    puts("Press <ENTER> to stop playing and quit");
+
+    if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
+	puts("EOF while reading stdin, will quit now..");
+    }
+
+    
+    /* Start deinitialization: */
+
+    /* Disconnect sound port from file port */
+    status = pjmedia_snd_port_disconnect(snd_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Without this sleep, Windows/DirectSound will repeteadly
+     * play the last frame during destroy.
+     */
+    pj_thread_sleep(100);
+
+    /* Destroy sound device */
+    status = pjmedia_snd_port_destroy( snd_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Destroy file port */
+    status = pjmedia_port_destroy( file_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+
+    /* Done. */
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/playsine.c b/jni/libpjsip/sources/pjsip-apps/src/samples/playsine.c
new file mode 100644
index 0000000..03d8946
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/playsine.c
@@ -0,0 +1,318 @@
+/* $Id: playsine.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+/**
+ * \page page_pjmedia_samples_playsine_c Samples: Using Custom Ports (Sine Wave Generator)
+ *
+ * This example demonstrate how to create a custom media port (in this case, a
+ * sine wave generator) and connect it to the sound device.
+ *
+ * This file is pjsip-apps/src/samples/playsine.c
+ *
+ * \includelineno playsine.c
+ */
+
+/*
+ * playsine.c
+ *
+ * PURPOSE:
+ *  Demonstrate how to create and use custom media port which
+ *  simply feed a sine wav to the sound player.
+ *
+ * USAGE:
+ *  playsine [nchannel]
+ *
+ * where:
+ *  nchannel is 1 for mono (this is the default) or 2 for stereo.
+ */
+
+#include <pjmedia.h>
+#include <pjlib.h>
+
+#include <stdlib.h>	/* atoi() */
+#include <stdio.h>
+#include <math.h>	/* sin()  */
+
+/* For logging purpose. */
+#define THIS_FILE   "playsine.c"
+
+
+/* Util to display the error message for the specified error code  */
+static int app_perror( const char *sender, const char *title, 
+		       pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    PJ_UNUSED_ARG(sender);
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+
+    printf("%s: %s [code=%d]\n", title, errmsg, status);
+    return 1;
+}
+
+
+/* Struct attached to sine generator */
+typedef struct
+{
+    pj_int16_t	*samples;	/* Sine samples.    */
+} port_data;
+
+
+/* This callback is called to feed more samples */
+static pj_status_t sine_get_frame( pjmedia_port *port, 
+				   pjmedia_frame *frame)
+{
+    port_data *sine = port->port_data.pdata;
+    pj_int16_t *samples = frame->buf;
+    unsigned i, left, right;
+    pj_size_t count;
+
+    /* Get number of samples */
+    count = frame->size / 2 / PJMEDIA_PIA_CCNT(&port->info);
+
+    left = 0;
+    right = 0;
+
+    for (i=0; i<count; ++i) {
+	*samples++ = sine->samples[left];
+	++left;
+
+	if (PJMEDIA_PIA_CCNT(&port->info) == 2) {
+	    *samples++ = sine->samples[right];
+	    right += 2; /* higher pitch so we can distinguish left and right. */
+	    if (right >= count)
+		right = 0;
+	}
+    }
+
+    /* Must set frame->type correctly, otherwise the sound device
+     * will refuse to play.
+     */
+    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+
+    return PJ_SUCCESS;
+}
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+/*
+ * Create a media port to generate sine wave samples.
+ */
+static pj_status_t create_sine_port(pj_pool_t *pool,
+				    unsigned sampling_rate,
+				    unsigned channel_count,
+				    pjmedia_port **p_port)
+{
+    pjmedia_port *port;
+    unsigned i;
+    unsigned count;
+    pj_str_t name;
+    port_data *sine;
+
+    PJ_ASSERT_RETURN(pool && channel_count > 0 && channel_count <= 2, 
+		     PJ_EINVAL);
+
+    port = pj_pool_zalloc(pool, sizeof(pjmedia_port));
+    PJ_ASSERT_RETURN(port != NULL, PJ_ENOMEM);
+
+    /* Fill in port info. */
+    name = pj_str("sine generator");
+    pjmedia_port_info_init(&port->info, &name,
+                           PJMEDIA_SIG_CLASS_PORT_AUD('s', 'i'),
+			   sampling_rate,
+			   channel_count,
+			   16, sampling_rate * 20 / 1000 * channel_count);
+    
+    /* Set the function to feed frame */
+    port->get_frame = &sine_get_frame;
+
+    /* Create sine port data */
+    port->port_data.pdata = sine = pj_pool_zalloc(pool, sizeof(port_data));
+
+    /* Create samples */
+    count = PJMEDIA_PIA_SPF(&port->info) / channel_count;
+    sine->samples = pj_pool_alloc(pool, count * sizeof(pj_int16_t));
+    PJ_ASSERT_RETURN(sine->samples != NULL, PJ_ENOMEM);
+
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<count; i++ )
+    {
+        sine->samples[i] = (pj_int16_t) (10000.0 * 
+		sin(((double)i/(double)count) * M_PI * 8.) );
+    }
+
+    *p_port = port;
+
+    return PJ_SUCCESS;
+}
+
+
+/* Show usage */
+static void usage(void)
+{
+    puts("");
+    puts("Usage: playsine [nchannel]");
+    puts("");
+    puts("where");
+    puts(" nchannel is number of audio channels (1 for mono, or 2 for stereo).");
+    puts(" Default is 1 (mono).");
+    puts("");
+}
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_port *sine_port;
+    pjmedia_snd_port *snd_port;
+    char tmp[10];
+    int channel_count = 1;
+    pj_status_t status;
+
+    if (argc == 2) {
+	channel_count = atoi(argv[1]);
+	if (channel_count < 1 || channel_count > 2) {
+	    puts("Error: invalid arguments");
+	    usage();
+	    return 1;
+	}
+    }
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for our sine generator */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "wav",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    /* Create a media port to generate sine wave samples. */
+    status = create_sine_port( pool,	    /* memory pool	    */
+			       11025,	    /* sampling rate	    */
+			       channel_count,/* # of channels	    */
+			       &sine_port   /* returned port	    */
+		             );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to create sine port", status);
+	return 1;
+    }
+
+    /* Create sound player port. */
+    status = pjmedia_snd_port_create_player( 
+		 pool,				    /* pool		    */
+		 -1,				    /* use default dev.	    */
+		 PJMEDIA_PIA_SRATE(&sine_port->info),/* clock rate.	    */
+		 PJMEDIA_PIA_CCNT(&sine_port->info),/* # of channels.	    */
+		 PJMEDIA_PIA_SPF(&sine_port->info), /* samples per frame.   */
+		 PJMEDIA_PIA_BITS(&sine_port->info),/* bits per sample.	    */
+		 0,				    /* options		    */
+		 &snd_port			    /* returned port	    */
+		 );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to open sound device", status);
+	return 1;
+    }
+
+    /* Connect sine generator port to the sound player 
+     * Stream playing will commence immediately.
+     */
+    status = pjmedia_snd_port_connect( snd_port, sine_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+
+    /* 
+     * Audio should be playing in a loop now, using sound device's thread. 
+     */
+
+
+    /* Sleep to allow log messages to flush */
+    pj_thread_sleep(100);
+
+
+    puts("Playing sine wave..");
+    puts("");
+    puts("Press <ENTER> to stop playing and quit");
+
+    if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
+	puts("EOF while reading stdin, will quit now..");
+    }
+
+    
+    /* Start deinitialization: */
+
+    /* Disconnect sound port from file port */
+    status = pjmedia_snd_port_disconnect(snd_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Without this sleep, Windows/DirectSound will repeteadly
+     * play the last frame during destroy.
+     */
+    pj_thread_sleep(100);
+
+    /* Destroy sound device */
+    status = pjmedia_snd_port_destroy( snd_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Destroy sine generator */
+    status = pjmedia_port_destroy( sine_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+
+    /* Done. */
+    return 0;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/proxy.h b/jni/libpjsip/sources/pjsip-apps/src/samples/proxy.h
new file mode 100644
index 0000000..257fd1f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/proxy.h
@@ -0,0 +1,587 @@
+/* $Id: proxy.h 4370 2013-02-26 05:30:00Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 <pjsip.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+
+/* Options */
+static struct global_struct
+{
+    pj_caching_pool	 cp;
+    pjsip_endpoint	*endpt;
+    int			 port;
+    pj_pool_t		*pool;
+
+    pj_thread_t		*thread;
+    pj_bool_t		 quit_flag;
+
+    pj_bool_t		 record_route;
+
+    unsigned		 name_cnt;
+    pjsip_host_port	 name[16];
+} global;
+
+
+
+static void app_perror(const char *msg, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(1,(THIS_FILE, "%s: %s", msg, errmsg));
+}
+
+
+static void usage(void)
+{
+    puts("Options:\n"
+	 "\n"
+	 " -p, --port N       Set local listener port to N\n"
+	 " -R, --rr           Perform record routing\n"
+	 " -L, --log-level N  Set log level to N (default: 4)\n"
+	 " -h, --help         Show this help screen\n"
+	 );
+}
+
+
+static pj_status_t init_options(int argc, char *argv[])
+{
+    struct pj_getopt_option long_opt[] = {
+	{ "port",	1, 0, 'p'},
+	{ "rr",		0, 0, 'R'},
+	{ "log-level",	1, 0, 'L'},
+	{ "help",	0, 0, 'h'},
+	{ NULL,		0, 0, 0}
+    };
+    int c;
+    int opt_ind;
+
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc, argv, "p:L:Rh", long_opt, &opt_ind))!=-1) {
+	switch (c) {
+	case 'p':
+	    global.port = atoi(pj_optarg);
+	    printf("Port is set to %d\n", global.port);
+	    break;
+	
+	case 'R':
+	    global.record_route = PJ_TRUE;
+	    printf("Using record route mode\n");
+	    break;
+
+	case 'L':
+	    pj_log_set_level(atoi(pj_optarg));
+	    break;
+
+	case 'h':
+	    usage();
+	    return -1;
+
+	default:
+	    puts("Unknown option. Run with --help for help.");
+	    return -1;
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * This is a very simple PJSIP module, whose sole purpose is to display
+ * incoming and outgoing messages to log. This module will have priority
+ * higher than transport layer, which means:
+ *
+ *  - incoming messages will come to this module first before reaching
+ *    transaction layer.
+ *
+ *  - outgoing messages will come to this module last, after the message
+ *    has been 'printed' to contiguous buffer by transport layer and
+ *    appropriate transport instance has been decided for this message.
+ *
+ */
+
+/* Notification on incoming messages */
+static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
+{
+    PJ_LOG(5,(THIS_FILE, "RX %d bytes %s from %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 rdata->msg_info.len,
+			 pjsip_rx_data_get_info(rdata),
+			 rdata->tp_info.transport->type_name,
+			 rdata->pkt_info.src_name,
+			 rdata->pkt_info.src_port,
+			 (int)rdata->msg_info.len,
+			 rdata->msg_info.msg_buf));
+    
+    /* Always return false, otherwise messages will not get processed! */
+    return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
+{
+    
+    /* Important note:
+     *	tp_info field is only valid after outgoing messages has passed
+     *	transport layer. So don't try to access tp_info when the module
+     *	has lower priority than transport layer.
+     */
+
+    PJ_LOG(5,(THIS_FILE, "TX %d bytes %s to %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 (tdata->buf.cur - tdata->buf.start),
+			 pjsip_tx_data_get_info(tdata),
+			 tdata->tp_info.transport->type_name,
+			 tdata->tp_info.dst_name,
+			 tdata->tp_info.dst_port,
+			 (int)(tdata->buf.cur - tdata->buf.start),
+			 tdata->buf.start));
+
+    /* Always return success, otherwise message will not get sent! */
+    return PJ_SUCCESS;
+}
+
+/* The module instance. */
+static pjsip_module mod_msg_logger = 
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-msg-logger", 14 },		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &logging_on_rx_msg,			/* on_rx_request()	*/
+    &logging_on_rx_msg,			/* on_rx_response()	*/
+    &logging_on_tx_msg,			/* on_tx_request.	*/
+    &logging_on_tx_msg,			/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
+
+static pj_status_t init_stack(void)
+{
+    pj_status_t status;
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Then init PJLIB-UTIL: */
+    status = pjlib_util_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&global.cp, &pj_pool_factory_default_policy, 0);
+
+    /* Create the endpoint: */
+    status = pjsip_endpt_create(&global.cp.factory, NULL, &global.endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Init transaction layer for stateful proxy only */
+#if STATEFUL
+    status = pjsip_tsx_layer_init_module(global.endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+#endif
+
+    /* Create listening transport */
+    {
+	pj_sockaddr_in addr;
+
+	addr.sin_family = pj_AF_INET();
+	addr.sin_addr.s_addr = 0;
+	addr.sin_port = pj_htons((pj_uint16_t)global.port);
+
+	status = pjsip_udp_transport_start( global.endpt, &addr, 
+					    NULL, 1, NULL);
+	if (status != PJ_SUCCESS)
+	    return status;
+    }
+
+    /* Create pool for the application */
+    global.pool = pj_pool_create(&global.cp.factory, "proxyapp", 
+				 4000, 4000, NULL);
+
+    /* Register the logger module */
+    pjsip_endpt_register_module(global.endpt, &mod_msg_logger);
+
+    return PJ_SUCCESS;
+}
+
+
+static pj_status_t init_proxy(void)
+{
+    pj_sockaddr pri_addr;
+    pj_sockaddr addr_list[16];
+    unsigned addr_cnt = PJ_ARRAY_SIZE(addr_list);
+    unsigned i;
+
+    /* List all names matching local endpoint.
+     * Note that PJLIB version 0.6 and newer has a function to
+     * enumerate local IP interface (pj_enum_ip_interface()), so
+     * by using it would be possible to list all IP interfaces in
+     * this host.
+     */
+
+    /* The first address is important since this would be the one
+     * to be added in Record-Route.
+     */
+    if (pj_gethostip(pj_AF_INET(), &pri_addr)==PJ_SUCCESS) {
+	pj_strdup2(global.pool, &global.name[global.name_cnt].host,
+		   pj_inet_ntoa(pri_addr.ipv4.sin_addr));
+	global.name[global.name_cnt].port = global.port;
+	global.name_cnt++;
+    }
+
+    /* Get the rest of IP interfaces */
+    if (pj_enum_ip_interface(pj_AF_INET(), &addr_cnt, addr_list) == PJ_SUCCESS) {
+	for (i=0; i<addr_cnt; ++i) {
+
+	    if (addr_list[i].ipv4.sin_addr.s_addr == pri_addr.ipv4.sin_addr.s_addr)
+		continue;
+
+	    pj_strdup2(global.pool, &global.name[global.name_cnt].host,
+		       pj_inet_ntoa(addr_list[i].ipv4.sin_addr));
+	    global.name[global.name_cnt].port = global.port;
+	    global.name_cnt++;
+	}
+    }
+
+    /* Add loopback address. */
+#if PJ_IP_HELPER_IGNORE_LOOPBACK_IF
+    global.name[global.name_cnt].host = pj_str("127.0.0.1");
+    global.name[global.name_cnt].port = global.port;
+    global.name_cnt++;
+#endif
+
+    global.name[global.name_cnt].host = *pj_gethostname();
+    global.name[global.name_cnt].port = global.port;
+    global.name_cnt++;
+
+    global.name[global.name_cnt].host = pj_str("localhost");
+    global.name[global.name_cnt].port = global.port;
+    global.name_cnt++;
+
+    PJ_LOG(3,(THIS_FILE, "Proxy started, listening on port %d", global.port));
+    PJ_LOG(3,(THIS_FILE, "Local host aliases:"));
+    for (i=0; i<global.name_cnt; ++i) {
+	PJ_LOG(3,(THIS_FILE, " %.*s:%d", 
+		  (int)global.name[i].host.slen,
+		  global.name[i].host.ptr,
+		  global.name[i].port));
+    }
+
+    if (global.record_route) {
+	PJ_LOG(3,(THIS_FILE, "Using Record-Route mode"));
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+#if PJ_HAS_THREADS
+static int worker_thread(void *p)
+{
+    pj_time_val delay = {0, 10};
+
+    PJ_UNUSED_ARG(p);
+
+    while (!global.quit_flag) {
+	pjsip_endpt_handle_events(global.endpt, &delay);
+    }
+
+    return 0;
+}
+#endif
+
+
+/* Utility to determine if URI is local to this host. */
+static pj_bool_t is_uri_local(const pjsip_sip_uri *uri)
+{
+    unsigned i;
+    for (i=0; i<global.name_cnt; ++i) {
+	if ((uri->port == global.name[i].port ||
+	     (uri->port==0 && global.name[i].port==5060)) &&
+	    pj_stricmp(&uri->host, &global.name[i].host)==0)
+	{
+	    /* Match */
+	    return PJ_TRUE;
+	}
+    }
+
+    /* Doesn't match */
+    return PJ_FALSE;
+}
+
+
+/* Proxy utility to verify incoming requests.
+ * Return non-zero if verification failed.
+ */
+static pj_status_t proxy_verify_request(pjsip_rx_data *rdata)
+{
+    const pj_str_t STR_PROXY_REQUIRE = {"Proxy-Require", 13};
+
+    /* RFC 3261 Section 16.3 Request Validation */
+
+    /* Before an element can proxy a request, it MUST verify the message's
+     * validity.  A valid message must pass the following checks:
+     * 
+     * 1. Reasonable Syntax
+     * 2. URI scheme
+     * 3. Max-Forwards
+     * 4. (Optional) Loop Detection
+     * 5. Proxy-Require
+     * 6. Proxy-Authorization
+     */
+
+    /* 1. Reasonable Syntax.
+     * This would have been checked by transport layer.
+     */
+
+    /* 2. URI scheme.
+     * We only want to support "sip:"/"sips:" URI scheme for this simple proxy.
+     */
+    if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.msg->line.req.uri) &&
+	!PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri))
+    {
+	pjsip_endpt_respond_stateless(global.endpt, rdata, 
+				      PJSIP_SC_UNSUPPORTED_URI_SCHEME, NULL,
+				      NULL, NULL);
+	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_UNSUPPORTED_URI_SCHEME);
+    }
+
+    /* 3. Max-Forwards.
+     * Send error if Max-Forwards is 1 or lower.
+     */
+    if (rdata->msg_info.max_fwd && rdata->msg_info.max_fwd->ivalue <= 1) {
+	pjsip_endpt_respond_stateless(global.endpt, rdata, 
+				      PJSIP_SC_TOO_MANY_HOPS, NULL,
+				      NULL, NULL);
+	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_TOO_MANY_HOPS);
+    }
+
+    /* 4. (Optional) Loop Detection.
+     * Nah, we don't do that with this simple proxy.
+     */
+
+    /* 5. Proxy-Require */
+    if (pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_PROXY_REQUIRE, 
+				   NULL) != NULL) 
+    {
+	pjsip_endpt_respond_stateless(global.endpt, rdata, 
+				      PJSIP_SC_BAD_EXTENSION, NULL,
+				      NULL, NULL);
+	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_EXTENSION);
+    }
+
+    /* 6. Proxy-Authorization.
+     * Nah, we don't require any authorization with this sample.
+     */
+
+    return PJ_SUCCESS;
+}
+
+
+/* Process route information in the reqeust */
+static pj_status_t proxy_process_routing(pjsip_tx_data *tdata)
+{
+    pjsip_sip_uri *target;
+    pjsip_route_hdr *hroute;
+
+    /* RFC 3261 Section 16.4 Route Information Preprocessing */
+
+    target = (pjsip_sip_uri*) tdata->msg->line.req.uri;
+
+    /* The proxy MUST inspect the Request-URI of the request.  If the
+     * Request-URI of the request contains a value this proxy previously
+     * placed into a Record-Route header field (see Section 16.6 item 4),
+     * the proxy MUST replace the Request-URI in the request with the last
+     * value from the Route header field, and remove that value from the
+     * Route header field.  The proxy MUST then proceed as if it received
+     * this modified request.
+     */
+    if (is_uri_local(target)) {
+	pjsip_route_hdr *r;
+	pjsip_sip_uri *uri;
+
+	/* Find the first Route header */
+	r = hroute = (pjsip_route_hdr*)
+		     pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
+	if (r == NULL) {
+	    /* No Route header. This request is destined for this proxy. */
+	    return PJ_SUCCESS;
+	}
+
+	/* Find the last Route header */
+	while ( (r=(pjsip_route_hdr*)pjsip_msg_find_hdr(tdata->msg, 
+						        PJSIP_H_ROUTE, 
+							r->next)) != NULL )
+	{
+	    hroute = r;
+	}
+
+	/* If the last Route header doesn't have ";lr" parameter, then
+	 * this is a strict-routed request indeed, and we follow the steps
+	 * in processing strict-route requests above.
+	 *
+	 * But if it does contain ";lr" parameter, skip the strict-route
+	 * processing.
+	 */
+	uri = (pjsip_sip_uri*)
+	      pjsip_uri_get_uri(&hroute->name_addr);
+	if (uri->lr_param == 0) {
+	    /* Yes this is strict route, so:
+	     * - replace req URI with the URI in Route header,
+	     * - remove the Route header,
+	     * - proceed as if it received this modified request. 
+	    */
+	    tdata->msg->line.req.uri = hroute->name_addr.uri;
+	    target = (pjsip_sip_uri*) tdata->msg->line.req.uri;
+	    pj_list_erase(hroute);
+	}
+    }
+
+    /* If the Request-URI contains a maddr parameter, the proxy MUST check
+     * to see if its value is in the set of addresses or domains the proxy
+     * is configured to be responsible for.  If the Request-URI has a maddr
+     * parameter with a value the proxy is responsible for, and the request
+     * was received using the port and transport indicated (explicitly or by
+     * default) in the Request-URI, the proxy MUST strip the maddr and any
+     * non-default port or transport parameter and continue processing as if
+     * those values had not been present in the request.
+     */
+    if (target->maddr_param.slen != 0) {
+	pjsip_sip_uri maddr_uri;
+
+	maddr_uri.host = target->maddr_param;
+	maddr_uri.port = global.port;
+
+	if (is_uri_local(&maddr_uri)) {
+	    target->maddr_param.slen = 0;
+	    target->port = 0;
+	    target->transport_param.slen = 0;
+	}
+    }
+
+    /* If the first value in the Route header field indicates this proxy,
+     * the proxy MUST remove that value from the request.
+     */
+    hroute = (pjsip_route_hdr*) 
+	      pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
+    if (hroute && is_uri_local((pjsip_sip_uri*)hroute->name_addr.uri)) {
+	pj_list_erase(hroute);
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/* Postprocess the request before forwarding it */
+static void proxy_postprocess(pjsip_tx_data *tdata)
+{
+    /* Optionally record-route */
+    if (global.record_route) {
+	char uribuf[128];
+	pj_str_t uri;
+	const pj_str_t H_RR = { "Record-Route", 12 };
+	pjsip_generic_string_hdr *rr;
+
+	pj_ansi_snprintf(uribuf, sizeof(uribuf), "<sip:%.*s:%d;lr>",
+			 (int)global.name[0].host.slen,
+			 global.name[0].host.ptr,
+			 global.name[0].port);
+	uri = pj_str(uribuf);
+	rr = pjsip_generic_string_hdr_create(tdata->pool,
+					     &H_RR, &uri);
+	pjsip_msg_insert_first_hdr(tdata->msg, (pjsip_hdr*)rr);
+    }
+}
+
+
+/* Calculate new target for the request */
+static pj_status_t proxy_calculate_target(pjsip_rx_data *rdata,
+					  pjsip_tx_data *tdata)
+{
+    pjsip_sip_uri *target;
+
+    /* RFC 3261 Section 16.5 Determining Request Targets */
+
+    target = (pjsip_sip_uri*) tdata->msg->line.req.uri;
+
+    /* If the Request-URI of the request contains an maddr parameter, the
+     * Request-URI MUST be placed into the target set as the only target
+     * URI, and the proxy MUST proceed to Section 16.6.
+     */
+    if (target->maddr_param.slen) {
+	proxy_postprocess(tdata);
+	return PJ_SUCCESS;
+    }
+
+
+    /* If the domain of the Request-URI indicates a domain this element is
+     * not responsible for, the Request-URI MUST be placed into the target
+     * set as the only target, and the element MUST proceed to the task of
+     * Request Forwarding (Section 16.6).
+     */
+    if (!is_uri_local(target)) {
+	proxy_postprocess(tdata);
+	return PJ_SUCCESS;
+    }
+
+    /* If the target set for the request has not been predetermined as
+     * described above, this implies that the element is responsible for the
+     * domain in the Request-URI, and the element MAY use whatever mechanism
+     * it desires to determine where to send the request. 
+     */
+
+    /* We're not interested to receive request destined to us, so
+     * respond with 404/Not Found (only if request is not ACK!).
+     */
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
+	pjsip_endpt_respond_stateless(global.endpt, rdata,
+				      PJSIP_SC_NOT_FOUND, NULL,
+				      NULL, NULL);
+    }
+
+    /* Delete the request since we're not forwarding it */
+    pjsip_tx_data_dec_ref(tdata);
+
+    return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_FOUND);
+}
+
+
+/* Destroy stack */
+static void destroy_stack(void)
+{
+    pjsip_endpt_destroy(global.endpt);
+    pj_pool_release(global.pool);
+    pj_caching_pool_destroy(&global.cp);
+
+    pj_shutdown();
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/recfile.c b/jni/libpjsip/sources/pjsip-apps/src/samples/recfile.c
new file mode 100644
index 0000000..fedd5c6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/recfile.c
@@ -0,0 +1,202 @@
+/* $Id: recfile.c 3664 2011-07-19 03:42:28Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/**
+ * \page page_pjmedia_samples_recfile_c Samples: Capturing Audio to WAV File
+ *
+ * In this example, we capture audio from the sound device and save it to
+ * WAVE file.
+ *
+ * @see page_pjmedia_samples_playfile_c
+ *
+ * This file is pjsip-apps/src/samples/recfile.c
+ *
+ * \includelineno recfile.c
+ */
+
+#include <pjmedia.h>
+#include <pjlib.h>
+
+#include <stdio.h>
+
+/* For logging purpose. */
+#define THIS_FILE   "recfile.c"
+
+
+/* Configs */
+#define CLOCK_RATE	    44100
+#define NCHANNELS	    2
+#define SAMPLES_PER_FRAME   (NCHANNELS * (CLOCK_RATE * 10 / 1000))
+#define BITS_PER_SAMPLE	    16
+
+
+static const char *desc = 
+ " FILE					    \n"
+ "  recfile.c				    \n"
+ "					    \n"
+ " PURPOSE:				    \n"
+ "  Record microphone to WAVE file.	    \n"
+ "					    \n"
+ " USAGE:				    \n"
+ "  recfile FILE.WAV			    \n"
+ "";
+
+
+/* Util to display the error message for the specified error code  */
+static int app_perror( const char *sender, const char *title, 
+		       pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    PJ_UNUSED_ARG(sender);
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+
+    printf("%s: %s [code=%d]\n", title, errmsg, status);
+    return 1;
+}
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_port *file_port;
+    pjmedia_snd_port *snd_port;
+    char tmp[10];
+    pj_status_t status;
+
+
+    /* Verify cmd line arguments. */
+    if (argc != 2) {
+	puts("");
+	puts(desc);
+	return 0;
+    }
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "app",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    /* Create WAVE file writer port. */
+    status = pjmedia_wav_writer_port_create(  pool, argv[1],
+					      CLOCK_RATE,
+					      NCHANNELS,
+					      SAMPLES_PER_FRAME,
+					      BITS_PER_SAMPLE,
+					      0, 0, 
+					      &file_port);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to open WAV file for writing", status);
+	return 1;
+    }
+
+    /* Create sound player port. */
+    status = pjmedia_snd_port_create_rec( 
+		 pool,				    /* pool		    */
+		 -1,				    /* use default dev.	    */
+		 PJMEDIA_PIA_SRATE(&file_port->info),/* clock rate.	    */
+		 PJMEDIA_PIA_CCNT(&file_port->info),/* # of channels.	    */
+		 PJMEDIA_PIA_SPF(&file_port->info), /* samples per frame.   */
+		 PJMEDIA_PIA_BITS(&file_port->info),/* bits per sample.	    */
+		 0,				    /* options		    */
+		 &snd_port			    /* returned port	    */
+		 );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to open sound device", status);
+	return 1;
+    }
+
+    /* Connect file port to the sound player.
+     * Stream playing will commence immediately.
+     */
+    status = pjmedia_snd_port_connect( snd_port, file_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+
+    /* 
+     * Recording should be started now. 
+     */
+
+
+    /* Sleep to allow log messages to flush */
+    pj_thread_sleep(10);
+
+
+    printf("Recodring %s..\n", argv[1]);
+    puts("");
+    puts("Press <ENTER> to stop recording and quit");
+
+    if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
+	puts("EOF while reading stdin, will quit now..");
+    }
+
+    
+    /* Start deinitialization: */
+
+    /* Destroy sound device */
+    status = pjmedia_snd_port_destroy( snd_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Destroy file port */
+    status = pjmedia_port_destroy( file_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+
+    /* Done. */
+    return 0;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/resampleplay.c b/jni/libpjsip/sources/pjsip-apps/src/samples/resampleplay.c
new file mode 100644
index 0000000..c73b2e3
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/resampleplay.c
@@ -0,0 +1,232 @@
+/* $Id: resampleplay.c 3664 2011-07-19 03:42:28Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/**
+ * \page page_pjmedia_samples_resampleplay_c Samples: Using Resample Port
+ *
+ * This example demonstrates how to use @ref PJMEDIA_RESAMPLE_PORT to
+ * change the sampling rate of the media streams.
+ *
+ * This file is pjsip-apps/src/samples/resampleplay.c
+ *
+ * \includelineno resampleplay.c
+ */
+
+#include <pjmedia.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+/* For logging purpose. */
+#define THIS_FILE   "resampleplay.c"
+
+
+static const char *desc = 
+" FILE		    						    \n"
+"		    						    \n"
+"  resampleplay.c	    					    \n"
+"		    						    \n"
+" PURPOSE	    						    \n"
+"		    						    \n"
+"  Demonstrate how use resample port to play a WAV file to sound    \n"
+"  device using different sampling rate.			    \n"
+"		    						    \n"
+" USAGE		    						    \n"
+"		    						    \n"
+"  resampleplay [options] FILE.WAV				    \n"
+"		    						    \n"
+" where options:						    \n"
+SND_USAGE
+"		    						    \n"
+"  The WAV file could have mono or stereo channels with arbitrary   \n"
+"  sampling rate, but MUST contain uncompressed (i.e. 16bit) PCM.   \n";
+
+
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_port *file_port;
+    pjmedia_port *resample_port;
+    pjmedia_snd_port *snd_port;
+    char tmp[10];
+    pj_status_t status;
+
+    int dev_id = -1;
+    int sampling_rate = CLOCK_RATE;
+    int channel_count = NCHANNELS;
+    int samples_per_frame = NSAMPLES;
+    int bits_per_sample = NBITS;
+    //int ptime;
+    //int down_samples;
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Get options */
+    if (get_snd_options(THIS_FILE, argc, argv, &dev_id, &sampling_rate,
+			&channel_count, &samples_per_frame, &bits_per_sample))
+    {
+	puts("");
+	puts(desc);
+	return 1;
+    }
+
+    if (!argv[pj_optind]) {
+	puts("Error: no file is specified");
+	puts(desc);
+	return 1;
+    }
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "app",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    /* Create the file port. */
+    status = pjmedia_wav_player_port_create( pool, argv[pj_optind], 0, 0,
+					     0, &file_port);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to open file", status);
+	return 1;
+    }
+
+    /* File must have same number of channels. */
+    if (PJMEDIA_PIA_CCNT(&file_port->info) != (unsigned)channel_count) {
+	PJ_LOG(3,(THIS_FILE, "Error: file has different number of channels. "
+			     "Perhaps you'd need -c option?"));
+	pjmedia_port_destroy(file_port);
+	return 1;
+    }
+
+    /* Calculate number of samples per frame to be taken from file port */
+    //ptime = samples_per_frame * 1000 / sampling_rate;
+
+    /* Create the resample port. */
+    status = pjmedia_resample_port_create( pool, file_port,
+					   sampling_rate, 0,
+					   &resample_port);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to create resample port", status);
+	return 1;
+    }
+
+    /* Create sound player port. */
+    status = pjmedia_snd_port_create( 
+		 pool,			/* pool			    */
+		 dev_id,		/* device		    */
+		 dev_id,		/* device		    */
+		 sampling_rate,		/* clock rate.		    */
+		 channel_count,		/* # of channels.	    */
+		 samples_per_frame,	/* samples per frame.	    */
+		 bits_per_sample,	/* bits per sample.	    */
+		 0,			/* options		    */
+		 &snd_port		/* returned port	    */
+		 );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to open sound device", status);
+	return 1;
+    }
+
+    /* Connect resample port to sound device */
+    status = pjmedia_snd_port_connect( snd_port, resample_port);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error connecting sound ports", status);
+	return 1;
+    }
+
+
+    /* Dump memory usage */
+    dump_pool_usage(THIS_FILE, &cp);
+
+    /* 
+     * File should be playing and looping now, using sound device's thread. 
+     */
+
+
+    /* Sleep to allow log messages to flush */
+    pj_thread_sleep(100);
+
+
+    printf("Playing %s at sampling rate %d (original file sampling rate=%d)\n",
+	   argv[pj_optind], sampling_rate,
+	   PJMEDIA_PIA_SRATE(&file_port->info));
+    puts("");
+    puts("Press <ENTER> to stop playing and quit");
+
+    if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
+	puts("EOF while reading stdin, will quit now..");
+    }
+    
+    /* Start deinitialization: */
+
+
+    /* Destroy sound device */
+    status = pjmedia_snd_port_destroy( snd_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Destroy resample port. 
+     * This will destroy all downstream ports (e.g. the file port)
+     */
+    status = pjmedia_port_destroy( resample_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+
+    /* Done. */
+    return 0;
+
+}
+
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/simple_pjsua.c b/jni/libpjsip/sources/pjsip-apps/src/samples/simple_pjsua.c
new file mode 100644
index 0000000..7716f7f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/simple_pjsua.c
@@ -0,0 +1,201 @@
+/* $Id: simple_pjsua.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/**
+ * simple_pjsua.c
+ *
+ * This is a very simple but fully featured SIP user agent, with the 
+ * following capabilities:
+ *  - SIP registration
+ *  - Making and receiving call
+ *  - Audio/media to sound device.
+ *
+ * Usage:
+ *  - To make outgoing call, start simple_pjsua with the URL of remote
+ *    destination to contact.
+ *    E.g.:
+ *	 simpleua sip:user@remote
+ *
+ *  - Incoming calls will automatically be answered with 200.
+ *
+ * This program will quit once it has completed a single call.
+ */
+
+#include <pjsua-lib/pjsua.h>
+
+#define THIS_FILE	"APP"
+
+#define SIP_DOMAIN	"example.com"
+#define SIP_USER	"alice"
+#define SIP_PASSWD	"secret"
+
+
+/* Callback called by the library upon receiving incoming call */
+static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
+			     pjsip_rx_data *rdata)
+{
+    pjsua_call_info ci;
+
+    PJ_UNUSED_ARG(acc_id);
+    PJ_UNUSED_ARG(rdata);
+
+    pjsua_call_get_info(call_id, &ci);
+
+    PJ_LOG(3,(THIS_FILE, "Incoming call from %.*s!!",
+			 (int)ci.remote_info.slen,
+			 ci.remote_info.ptr));
+
+    /* Automatically answer incoming calls with 200/OK */
+    pjsua_call_answer(call_id, 200, NULL, NULL);
+}
+
+/* Callback called by the library when call's state has changed */
+static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
+{
+    pjsua_call_info ci;
+
+    PJ_UNUSED_ARG(e);
+
+    pjsua_call_get_info(call_id, &ci);
+    PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,
+			 (int)ci.state_text.slen,
+			 ci.state_text.ptr));
+}
+
+/* Callback called by the library when call's media state has changed */
+static void on_call_media_state(pjsua_call_id call_id)
+{
+    pjsua_call_info ci;
+
+    pjsua_call_get_info(call_id, &ci);
+
+    if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
+	// When media is active, connect call to sound device.
+	pjsua_conf_connect(ci.conf_slot, 0);
+	pjsua_conf_connect(0, ci.conf_slot);
+    }
+}
+
+/* Display error and exit application */
+static void error_exit(const char *title, pj_status_t status)
+{
+    pjsua_perror(THIS_FILE, title, status);
+    pjsua_destroy();
+    exit(1);
+}
+
+/*
+ * main()
+ *
+ * argv[1] may contain URL to call.
+ */
+int main(int argc, char *argv[])
+{
+    pjsua_acc_id acc_id;
+    pj_status_t status;
+
+    /* Create pjsua first! */
+    status = pjsua_create();
+    if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()", status);
+
+    /* If argument is specified, it's got to be a valid SIP URL */
+    if (argc > 1) {
+	status = pjsua_verify_url(argv[1]);
+	if (status != PJ_SUCCESS) error_exit("Invalid URL in argv", status);
+    }
+
+    /* Init pjsua */
+    {
+	pjsua_config cfg;
+	pjsua_logging_config log_cfg;
+
+	pjsua_config_default(&cfg);
+	cfg.cb.on_incoming_call = &on_incoming_call;
+	cfg.cb.on_call_media_state = &on_call_media_state;
+	cfg.cb.on_call_state = &on_call_state;
+
+	pjsua_logging_config_default(&log_cfg);
+	log_cfg.console_level = 4;
+
+	status = pjsua_init(&cfg, &log_cfg, NULL);
+	if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status);
+    }
+
+    /* Add UDP transport. */
+    {
+	pjsua_transport_config cfg;
+
+	pjsua_transport_config_default(&cfg);
+	cfg.port = 5060;
+	status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
+	if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
+    }
+
+    /* Initialization is done, now start pjsua */
+    status = pjsua_start();
+    if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);
+
+    /* Register to SIP server by creating SIP account. */
+    {
+	pjsua_acc_config cfg;
+
+	pjsua_acc_config_default(&cfg);
+	cfg.id = pj_str("sip:" SIP_USER "@" SIP_DOMAIN);
+	cfg.reg_uri = pj_str("sip:" SIP_DOMAIN);
+	cfg.cred_count = 1;
+	cfg.cred_info[0].realm = pj_str(SIP_DOMAIN);
+	cfg.cred_info[0].scheme = pj_str("digest");
+	cfg.cred_info[0].username = pj_str(SIP_USER);
+	cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
+	cfg.cred_info[0].data = pj_str(SIP_PASSWD);
+
+	status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
+	if (status != PJ_SUCCESS) error_exit("Error adding account", status);
+    }
+
+    /* If URL is specified, make call to the URL. */
+    if (argc > 1) {
+	pj_str_t uri = pj_str(argv[1]);
+	status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL);
+	if (status != PJ_SUCCESS) error_exit("Error making call", status);
+    }
+
+    /* Wait until user press "q" to quit. */
+    for (;;) {
+	char option[10];
+
+	puts("Press 'h' to hangup all calls, 'q' to quit");
+	if (fgets(option, sizeof(option), stdin) == NULL) {
+	    puts("EOF while reading stdin, will quit now..");
+	    break;
+	}
+
+	if (option[0] == 'q')
+	    break;
+
+	if (option[0] == 'h')
+	    pjsua_call_hangup_all();
+    }
+
+    /* Destroy pjsua */
+    pjsua_destroy();
+
+    return 0;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/simpleua.c b/jni/libpjsip/sources/pjsip-apps/src/samples/simpleua.c
new file mode 100644
index 0000000..2906323
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/simpleua.c
@@ -0,0 +1,1030 @@
+/* $Id: simpleua.c 4051 2012-04-13 08:16:30Z ming $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+/**
+ * simpleua.c
+ *
+ * This is a very simple SIP user agent complete with media. The user
+ * agent should do a proper SDP negotiation and start RTP media once
+ * SDP negotiation has completed.
+ *
+ * This program does not register to SIP server.
+ *
+ * Capabilities to be demonstrated here:
+ *  - Basic call
+ *  - Should support IPv6 (not tested)
+ *  - UDP transport at port 5060 (hard coded)
+ *  - RTP socket at port 4000 (hard coded)
+ *  - proper SDP negotiation
+ *  - PCMA/PCMU codec only.
+ *  - Audio/media to sound device.
+ *
+ *
+ * Usage:
+ *  - To make outgoing call, start simpleua with the URL of remote
+ *    destination to contact.
+ *    E.g.:
+ *	 simpleua sip:user@remote
+ *
+ *  - Incoming calls will automatically be answered with 180, then 200.
+ *
+ * This program does not disconnect call.
+ *
+ * This program will quit once it has completed a single call.
+ */
+
+/* Include all headers. */
+#include <pjsip.h>
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+#include <pjsip_ua.h>
+#include <pjsip_simple.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+/* For logging purpose. */
+#define THIS_FILE   "simpleua.c"
+
+#include "util.h"
+
+
+/* Settings */
+#define AF		pj_AF_INET() /* Change to pj_AF_INET6() for IPv6.
+				      * PJ_HAS_IPV6 must be enabled and
+				      * your system must support IPv6.  */
+#if 0
+#define SIP_PORT	5080	     /* Listening SIP port		*/
+#define RTP_PORT	5000	     /* RTP port			*/
+#else
+#define SIP_PORT	5060	     /* Listening SIP port		*/
+#define RTP_PORT	4000	     /* RTP port			*/
+#endif
+
+#define MAX_MEDIA_CNT	2	     /* Media count, set to 1 for audio
+				      * only or 2 for audio and video	*/
+
+/*
+ * Static variables.
+ */
+
+static pj_bool_t	     g_complete;    /* Quit flag.		*/
+static pjsip_endpoint	    *g_endpt;	    /* SIP endpoint.		*/
+static pj_caching_pool	     cp;	    /* Global pool factory.	*/
+
+static pjmedia_endpt	    *g_med_endpt;   /* Media endpoint.		*/
+
+static pjmedia_transport_info g_med_tpinfo[MAX_MEDIA_CNT]; 
+					    /* Socket info for media	*/
+static pjmedia_transport    *g_med_transport[MAX_MEDIA_CNT];
+					    /* Media stream transport	*/
+static pjmedia_sock_info     g_sock_info[MAX_MEDIA_CNT];  
+					    /* Socket info array	*/
+
+/* Call variables: */
+static pjsip_inv_session    *g_inv;	    /* Current invite session.	*/
+static pjmedia_stream       *g_med_stream;  /* Call's audio stream.	*/
+static pjmedia_snd_port	    *g_snd_port;    /* Sound device.		*/
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+static pjmedia_vid_stream   *g_med_vstream; /* Call's video stream.	*/
+static pjmedia_vid_port	    *g_vid_capturer;/* Call's video capturer.	*/
+static pjmedia_vid_port	    *g_vid_renderer;/* Call's video renderer.	*/
+#endif	/* PJMEDIA_HAS_VIDEO */
+
+/*
+ * Prototypes:
+ */
+
+/* Callback to be called when SDP negotiation is done in the call: */
+static void call_on_media_update( pjsip_inv_session *inv,
+				  pj_status_t status);
+
+/* Callback to be called when invite session's state has changed: */
+static void call_on_state_changed( pjsip_inv_session *inv, 
+				   pjsip_event *e);
+
+/* Callback to be called when dialog has forked: */
+static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e);
+
+/* Callback to be called to handle incoming requests outside dialogs: */
+static pj_bool_t on_rx_request( pjsip_rx_data *rdata );
+
+
+
+
+/* This is a PJSIP module to be registered by application to handle
+ * incoming requests outside any dialogs/transactions. The main purpose
+ * here is to handle incoming INVITE request message, where we will
+ * create a dialog and INVITE session for it.
+ */
+static pjsip_module mod_simpleua =
+{
+    NULL, NULL,			    /* prev, next.		*/
+    { "mod-simpleua", 12 },	    /* Name.			*/
+    -1,				    /* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
+    NULL,			    /* load()			*/
+    NULL,			    /* start()			*/
+    NULL,			    /* stop()			*/
+    NULL,			    /* unload()			*/
+    &on_rx_request,		    /* on_rx_request()		*/
+    NULL,			    /* on_rx_response()		*/
+    NULL,			    /* on_tx_request.		*/
+    NULL,			    /* on_tx_response()		*/
+    NULL,			    /* on_tsx_state()		*/
+};
+
+
+/* Notification on incoming messages */
+static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
+{
+    PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 rdata->msg_info.len,
+			 pjsip_rx_data_get_info(rdata),
+			 rdata->tp_info.transport->type_name,
+			 rdata->pkt_info.src_name,
+			 rdata->pkt_info.src_port,
+			 (int)rdata->msg_info.len,
+			 rdata->msg_info.msg_buf));
+    
+    /* Always return false, otherwise messages will not get processed! */
+    return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
+{
+    
+    /* Important note:
+     *	tp_info field is only valid after outgoing messages has passed
+     *	transport layer. So don't try to access tp_info when the module
+     *	has lower priority than transport layer.
+     */
+
+    PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 (tdata->buf.cur - tdata->buf.start),
+			 pjsip_tx_data_get_info(tdata),
+			 tdata->tp_info.transport->type_name,
+			 tdata->tp_info.dst_name,
+			 tdata->tp_info.dst_port,
+			 (int)(tdata->buf.cur - tdata->buf.start),
+			 tdata->buf.start));
+
+    /* Always return success, otherwise message will not get sent! */
+    return PJ_SUCCESS;
+}
+
+/* The module instance. */
+static pjsip_module msg_logger = 
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-msg-log", 13 },		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &logging_on_rx_msg,			/* on_rx_request()	*/
+    &logging_on_rx_msg,			/* on_rx_response()	*/
+    &logging_on_tx_msg,			/* on_tx_request.	*/
+    &logging_on_tx_msg,			/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
+
+/*
+ * main()
+ *
+ * If called with argument, treat argument as SIP URL to be called.
+ * Otherwise wait for incoming calls.
+ */
+int main(int argc, char *argv[])
+{
+    pj_pool_t *pool = NULL;
+    pj_status_t status;
+    unsigned i;
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    pj_log_set_level(5);
+
+    /* Then init PJLIB-UTIL: */
+    status = pjlib_util_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+
+    /* Create global endpoint: */
+    {
+	const pj_str_t *hostname;
+	const char *endpt_name;
+
+	/* Endpoint MUST be assigned a globally unique name.
+	 * The name will be used as the hostname in Warning header.
+	 */
+
+	/* For this implementation, we'll use hostname for simplicity */
+	hostname = pj_gethostname();
+	endpt_name = hostname->ptr;
+
+	/* Create the endpoint: */
+
+	status = pjsip_endpt_create(&cp.factory, endpt_name, 
+				    &g_endpt);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    }
+
+
+    /* 
+     * Add UDP transport, with hard-coded port 
+     * Alternatively, application can use pjsip_udp_transport_attach() to
+     * start UDP transport, if it already has an UDP socket (e.g. after it
+     * resolves the address with STUN).
+     */
+    {
+	pj_sockaddr addr;
+
+	pj_sockaddr_init(AF, &addr, NULL, (pj_uint16_t)SIP_PORT);
+	
+	if (AF == pj_AF_INET()) {
+	    status = pjsip_udp_transport_start( g_endpt, &addr.ipv4, NULL, 
+						1, NULL);
+	} else if (AF == pj_AF_INET6()) {
+	    status = pjsip_udp_transport_start6(g_endpt, &addr.ipv6, NULL,
+						1, NULL);
+	} else {
+	    status = PJ_EAFNOTSUP;
+	}
+
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to start UDP transport", status);
+	    return 1;
+	}
+    }
+
+
+    /* 
+     * Init transaction layer.
+     * This will create/initialize transaction hash tables etc.
+     */
+    status = pjsip_tsx_layer_init_module(g_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* 
+     * Initialize UA layer module.
+     * This will create/initialize dialog hash tables etc.
+     */
+    status = pjsip_ua_init_module( g_endpt, NULL );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* 
+     * Init invite session module.
+     * The invite session module initialization takes additional argument,
+     * i.e. a structure containing callbacks to be called on specific
+     * occurence of events.
+     *
+     * The on_state_changed and on_new_session callbacks are mandatory.
+     * Application must supply the callback function.
+     *
+     * We use on_media_update() callback in this application to start
+     * media transmission.
+     */
+    {
+	pjsip_inv_callback inv_cb;
+
+	/* Init the callback for INVITE session: */
+	pj_bzero(&inv_cb, sizeof(inv_cb));
+	inv_cb.on_state_changed = &call_on_state_changed;
+	inv_cb.on_new_session = &call_on_forked;
+	inv_cb.on_media_update = &call_on_media_update;
+
+	/* Initialize invite session module:  */
+	status = pjsip_inv_usage_init(g_endpt, &inv_cb);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    }
+
+    /* Initialize 100rel support */
+    status = pjsip_100rel_init_module(g_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /*
+     * Register our module to receive incoming requests.
+     */
+    status = pjsip_endpt_register_module( g_endpt, &mod_simpleua);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /*
+     * Register message logger module.
+     */
+    status = pjsip_endpt_register_module( g_endpt, &msg_logger);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+#if PJ_HAS_THREADS
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &g_med_endpt);
+#else
+    status = pjmedia_endpt_create(&cp.factory, 
+				  pjsip_endpt_get_ioqueue(g_endpt), 
+				  0, &g_med_endpt);
+#endif
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* 
+     * Add PCMA/PCMU codec to the media endpoint. 
+     */
+#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
+    status = pjmedia_codec_g711_init(g_med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+#endif
+
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+    /* Init video subsystem */
+    pool = pjmedia_endpt_create_pool(g_med_endpt, "Video subsystem", 512, 512);
+    status = pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    status = pjmedia_converter_mgr_create(pool, NULL);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    status = pjmedia_vid_codec_mgr_create(pool, NULL);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    status = pjmedia_vid_dev_subsys_init(&cp.factory);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+#  if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC!=0
+    /* Init ffmpeg video codecs */
+    status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+#  endif  /* PJMEDIA_HAS_FFMPEG_VID_CODEC */
+
+#endif	/* PJMEDIA_HAS_VIDEO */
+    
+    /* 
+     * Create media transport used to send/receive RTP/RTCP socket.
+     * One media transport is needed for each call. Application may
+     * opt to re-use the same media transport for subsequent calls.
+     */
+    for (i = 0; i < PJ_ARRAY_SIZE(g_med_transport); ++i) {
+	status = pjmedia_transport_udp_create3(g_med_endpt, AF, NULL, NULL, 
+					       RTP_PORT + i*2, 0, 
+					       &g_med_transport[i]);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to create media transport", status);
+	    return 1;
+	}
+
+	/* 
+	 * Get socket info (address, port) of the media transport. We will
+	 * need this info to create SDP (i.e. the address and port info in
+	 * the SDP).
+	 */
+	pjmedia_transport_info_init(&g_med_tpinfo[i]);
+	pjmedia_transport_get_info(g_med_transport[i], &g_med_tpinfo[i]);
+
+	pj_memcpy(&g_sock_info[i], &g_med_tpinfo[i].sock_info,
+		  sizeof(pjmedia_sock_info));
+    }
+
+    /*
+     * If URL is specified, then make call immediately.
+     */
+    if (argc > 1) {
+	pj_sockaddr hostaddr;
+	char hostip[PJ_INET6_ADDRSTRLEN+2];
+	char temp[80];
+	pj_str_t dst_uri = pj_str(argv[1]);
+	pj_str_t local_uri;
+	pjsip_dialog *dlg;
+	pjmedia_sdp_session *local_sdp;
+	pjsip_tx_data *tdata;
+
+	if (pj_gethostip(AF, &hostaddr) != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to retrieve local host IP", status);
+	    return 1;
+	}
+	pj_sockaddr_print(&hostaddr, hostip, sizeof(hostip), 2);
+
+	pj_ansi_sprintf(temp, "<sip:simpleuac@%s:%d>", 
+			hostip, SIP_PORT);
+	local_uri = pj_str(temp);
+
+	/* Create UAC dialog */
+	status = pjsip_dlg_create_uac( pjsip_ua_instance(), 
+				       &local_uri,  /* local URI */
+				       &local_uri,  /* local Contact */
+				       &dst_uri,    /* remote URI */
+				       &dst_uri,    /* remote target */
+				       &dlg);	    /* dialog */
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to create UAC dialog", status);
+	    return 1;
+	}
+
+	/* If we expect the outgoing INVITE to be challenged, then we should
+	 * put the credentials in the dialog here, with something like this:
+	 *
+	    {
+		pjsip_cred_info	cred[1];
+
+		cred[0].realm	  = pj_str("sip.server.realm");
+		cred[0].scheme    = pj_str("digest");
+		cred[0].username  = pj_str("theuser");
+		cred[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
+		cred[0].data      = pj_str("thepassword");
+
+		pjsip_auth_clt_set_credentials( &dlg->auth_sess, 1, cred);
+	    }
+	 *
+	 */
+
+
+	/* Get the SDP body to be put in the outgoing INVITE, by asking
+	 * media endpoint to create one for us.
+	 */
+	status = pjmedia_endpt_create_sdp( g_med_endpt,	    /* the media endpt	*/
+					   dlg->pool,	    /* pool.		*/
+					   MAX_MEDIA_CNT,   /* # of streams	*/
+					   g_sock_info,     /* RTP sock info	*/
+					   &local_sdp);	    /* the SDP result	*/
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+
+	/* Create the INVITE session, and pass the SDP returned earlier
+	 * as the session's initial capability.
+	 */
+	status = pjsip_inv_create_uac( dlg, local_sdp, 0, &g_inv);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+	/* If we want the initial INVITE to travel to specific SIP proxies,
+	 * then we should put the initial dialog's route set here. The final
+	 * route set will be updated once a dialog has been established.
+	 * To set the dialog's initial route set, we do it with something
+	 * like this:
+	 *
+	    {
+		pjsip_route_hdr route_set;
+		pjsip_route_hdr *route;
+		const pj_str_t hname = { "Route", 5 };
+		char *uri = "sip:proxy.server;lr";
+
+		pj_list_init(&route_set);
+
+		route = pjsip_parse_hdr( dlg->pool, &hname, 
+					 uri, strlen(uri),
+					 NULL);
+		PJ_ASSERT_RETURN(route != NULL, 1);
+		pj_list_push_back(&route_set, route);
+
+		pjsip_dlg_set_route_set(dlg, &route_set);
+	    }
+	 *
+	 * Note that Route URI SHOULD have an ";lr" parameter!
+	 */
+
+	/* Create initial INVITE request.
+	 * This INVITE request will contain a perfectly good request and 
+	 * an SDP body as well.
+	 */
+	status = pjsip_inv_invite(g_inv, &tdata);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+
+	/* Send initial INVITE request. 
+	 * From now on, the invite session's state will be reported to us
+	 * via the invite session callbacks.
+	 */
+	status = pjsip_inv_send_msg(g_inv, tdata);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    } else {
+
+	/* No URL to make call to */
+
+	PJ_LOG(3,(THIS_FILE, "Ready to accept incoming calls..."));
+    }
+
+
+    /* Loop until one call is completed */
+    for (;!g_complete;) {
+	pj_time_val timeout = {0, 10};
+	pjsip_endpt_handle_events(g_endpt, &timeout);
+    }
+
+    /* On exit, dump current memory usage: */
+    dump_pool_usage(THIS_FILE, &cp);
+
+    /* Destroy audio ports. Destroy the audio port first
+     * before the stream since the audio port has threads
+     * that get/put frames to the stream.
+     */
+    if (g_snd_port)
+	pjmedia_snd_port_destroy(g_snd_port);
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+    /* Destroy video ports */
+    if (g_vid_capturer)
+	pjmedia_vid_port_destroy(g_vid_capturer);
+    if (g_vid_renderer)
+	pjmedia_vid_port_destroy(g_vid_renderer);
+#endif
+
+    /* Destroy streams */
+    if (g_med_stream)
+	pjmedia_stream_destroy(g_med_stream);
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+    if (g_med_vstream)
+	pjmedia_vid_stream_destroy(g_med_vstream);
+
+    /* Deinit ffmpeg codec */
+#   if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC!=0
+    pjmedia_codec_ffmpeg_vid_deinit();
+#   endif
+
+#endif
+
+    /* Destroy media transports */
+    for (i = 0; i < MAX_MEDIA_CNT; ++i) {
+	if (g_med_transport[i])
+	    pjmedia_transport_close(g_med_transport[i]);
+    }
+
+    /* Deinit pjmedia endpoint */
+    if (g_med_endpt)
+	pjmedia_endpt_destroy(g_med_endpt);
+
+    /* Deinit pjsip endpoint */
+    if (g_endpt)
+	pjsip_endpt_destroy(g_endpt);
+
+    /* Release pool */
+    if (pool)
+	pj_pool_release(pool);
+
+    return 0;
+}
+
+
+
+/*
+ * Callback when INVITE session state has changed.
+ * This callback is registered when the invite session module is initialized.
+ * We mostly want to know when the invite session has been disconnected,
+ * so that we can quit the application.
+ */
+static void call_on_state_changed( pjsip_inv_session *inv, 
+				   pjsip_event *e)
+{
+    PJ_UNUSED_ARG(e);
+
+    if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
+
+	PJ_LOG(3,(THIS_FILE, "Call DISCONNECTED [reason=%d (%s)]", 
+		  inv->cause,
+		  pjsip_get_status_text(inv->cause)->ptr));
+
+	PJ_LOG(3,(THIS_FILE, "One call completed, application quitting..."));
+	g_complete = 1;
+
+    } else {
+
+	PJ_LOG(3,(THIS_FILE, "Call state changed to %s", 
+		  pjsip_inv_state_name(inv->state)));
+
+    }
+}
+
+
+/* This callback is called when dialog has forked. */
+static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e)
+{
+    /* To be done... */
+    PJ_UNUSED_ARG(inv);
+    PJ_UNUSED_ARG(e);
+}
+
+
+/*
+ * Callback when incoming requests outside any transactions and any
+ * dialogs are received. We're only interested to hande incoming INVITE
+ * request, and we'll reject any other requests with 500 response.
+ */
+static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
+{
+    pj_sockaddr hostaddr;
+    char temp[80], hostip[PJ_INET6_ADDRSTRLEN];
+    pj_str_t local_uri;
+    pjsip_dialog *dlg;
+    pjmedia_sdp_session *local_sdp;
+    pjsip_tx_data *tdata;
+    unsigned options = 0;
+    pj_status_t status;
+
+
+    /* 
+     * Respond (statelessly) any non-INVITE requests with 500 
+     */
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) {
+
+	if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
+	    pj_str_t reason = pj_str("Simple UA unable to handle "
+				     "this request");
+
+	    pjsip_endpt_respond_stateless( g_endpt, rdata, 
+					   500, &reason,
+					   NULL, NULL);
+	}
+	return PJ_TRUE;
+    }
+
+
+    /*
+     * Reject INVITE if we already have an INVITE session in progress.
+     */
+    if (g_inv) {
+
+	pj_str_t reason = pj_str("Another call is in progress");
+
+	pjsip_endpt_respond_stateless( g_endpt, rdata, 
+				       500, &reason,
+				       NULL, NULL);
+	return PJ_TRUE;
+
+    }
+
+    /* Verify that we can handle the request. */
+    status = pjsip_inv_verify_request(rdata, &options, NULL, NULL,
+				      g_endpt, NULL);
+    if (status != PJ_SUCCESS) {
+
+	pj_str_t reason = pj_str("Sorry Simple UA can not handle this INVITE");
+
+	pjsip_endpt_respond_stateless( g_endpt, rdata, 
+				       500, &reason,
+				       NULL, NULL);
+	return PJ_TRUE;
+    } 
+
+    /*
+     * Generate Contact URI
+     */
+    if (pj_gethostip(AF, &hostaddr) != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to retrieve local host IP", status);
+	return PJ_TRUE;
+    }
+    pj_sockaddr_print(&hostaddr, hostip, sizeof(hostip), 2);
+
+    pj_ansi_sprintf(temp, "<sip:simpleuas@%s:%d>", 
+		    hostip, SIP_PORT);
+    local_uri = pj_str(temp);
+
+    /*
+     * Create UAS dialog.
+     */
+    status = pjsip_dlg_create_uas( pjsip_ua_instance(), 
+				   rdata,
+				   &local_uri, /* contact */
+				   &dlg);
+    if (status != PJ_SUCCESS) {
+	pjsip_endpt_respond_stateless(g_endpt, rdata, 500, NULL,
+				      NULL, NULL);
+	return PJ_TRUE;
+    }
+
+    /* 
+     * Get media capability from media endpoint: 
+     */
+
+    status = pjmedia_endpt_create_sdp( g_med_endpt, rdata->tp_info.pool,
+				       MAX_MEDIA_CNT, g_sock_info, &local_sdp);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
+
+
+    /* 
+     * Create invite session, and pass both the UAS dialog and the SDP
+     * capability to the session.
+     */
+    status = pjsip_inv_create_uas( dlg, rdata, local_sdp, 0, &g_inv);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
+
+
+    /*
+     * Initially send 180 response.
+     *
+     * The very first response to an INVITE must be created with
+     * pjsip_inv_initial_answer(). Subsequent responses to the same
+     * transaction MUST use pjsip_inv_answer().
+     */
+    status = pjsip_inv_initial_answer(g_inv, rdata, 
+				      180, 
+				      NULL, NULL, &tdata);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
+
+
+    /* Send the 180 response. */  
+    status = pjsip_inv_send_msg(g_inv, tdata); 
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
+
+
+    /*
+     * Now create 200 response.
+     */
+    status = pjsip_inv_answer( g_inv, 
+			       200, NULL,	/* st_code and st_text */
+			       NULL,		/* SDP already specified */
+			       &tdata);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
+
+    /*
+     * Send the 200 response.
+     */
+    status = pjsip_inv_send_msg(g_inv, tdata);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
+
+
+    /* Done. 
+     * When the call is disconnected, it will be reported via the callback.
+     */
+
+    return PJ_TRUE;
+}
+
+ 
+
+/*
+ * Callback when SDP negotiation has completed.
+ * We are interested with this callback because we want to start media
+ * as soon as SDP negotiation is completed.
+ */
+static void call_on_media_update( pjsip_inv_session *inv,
+				  pj_status_t status)
+{
+    pjmedia_stream_info stream_info;
+    const pjmedia_sdp_session *local_sdp;
+    const pjmedia_sdp_session *remote_sdp;
+    pjmedia_port *media_port;
+
+    if (status != PJ_SUCCESS) {
+
+	app_perror(THIS_FILE, "SDP negotiation has failed", status);
+
+	/* Here we should disconnect call if we're not in the middle 
+	 * of initializing an UAS dialog and if this is not a re-INVITE.
+	 */
+	return;
+    }
+
+    /* Get local and remote SDP.
+     * We need both SDPs to create a media session.
+     */
+    status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp);
+
+    status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
+
+
+    /* Create stream info based on the media audio SDP. */
+    status = pjmedia_stream_info_from_sdp(&stream_info, inv->dlg->pool,
+					  g_med_endpt,
+					  local_sdp, remote_sdp, 0);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE,"Unable to create audio stream info",status);
+	return;
+    }
+
+    /* If required, we can also change some settings in the stream info,
+     * (such as jitter buffer settings, codec settings, etc) before we
+     * create the stream.
+     */
+
+    /* Create new audio media stream, passing the stream info, and also the
+     * media socket that we created earlier.
+     */
+    status = pjmedia_stream_create(g_med_endpt, inv->dlg->pool, &stream_info,
+				   g_med_transport[0], NULL, &g_med_stream);
+    if (status != PJ_SUCCESS) {
+	app_perror( THIS_FILE, "Unable to create audio stream", status);
+	return;
+    }
+
+    /* Start the audio stream */
+    status = pjmedia_stream_start(g_med_stream);
+    if (status != PJ_SUCCESS) {
+	app_perror( THIS_FILE, "Unable to start audio stream", status);
+	return;
+    }
+
+    /* Get the media port interface of the audio stream. 
+     * Media port interface is basicly a struct containing get_frame() and
+     * put_frame() function. With this media port interface, we can attach
+     * the port interface to conference bridge, or directly to a sound
+     * player/recorder device.
+     */
+    pjmedia_stream_get_port(g_med_stream, &media_port);
+
+    /* Create sound port */
+    pjmedia_snd_port_create(inv->pool,
+                            PJMEDIA_AUD_DEFAULT_CAPTURE_DEV,
+                            PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV,
+                            PJMEDIA_PIA_SRATE(&media_port->info),/* clock rate	    */
+                            PJMEDIA_PIA_CCNT(&media_port->info),/* channel count    */
+                            PJMEDIA_PIA_SPF(&media_port->info), /* samples per frame*/
+                            PJMEDIA_PIA_BITS(&media_port->info),/* bits per sample  */
+                            0,
+                            &g_snd_port);
+
+    if (status != PJ_SUCCESS) {
+	app_perror( THIS_FILE, "Unable to create sound port", status);
+	PJ_LOG(3,(THIS_FILE, "%d %d %d %d",
+		    PJMEDIA_PIA_SRATE(&media_port->info),/* clock rate	    */
+		    PJMEDIA_PIA_CCNT(&media_port->info),/* channel count    */
+		    PJMEDIA_PIA_SPF(&media_port->info), /* samples per frame*/
+		    PJMEDIA_PIA_BITS(&media_port->info) /* bits per sample  */
+	    ));
+	return;
+    }
+
+    status = pjmedia_snd_port_connect(g_snd_port, media_port);
+
+
+    /* Get the media port interface of the second stream in the session,
+     * which is video stream. With this media port interface, we can attach
+     * the port directly to a renderer/capture video device.
+     */
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+    if (local_sdp->media_count > 1) {
+	pjmedia_vid_stream_info vstream_info;
+	pjmedia_vid_port_param vport_param;
+
+	pjmedia_vid_port_param_default(&vport_param);
+
+	/* Create stream info based on the media video SDP. */
+	status = pjmedia_vid_stream_info_from_sdp(&vstream_info,
+						  inv->dlg->pool, g_med_endpt,
+						  local_sdp, remote_sdp, 1);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE,"Unable to create video stream info",status);
+	    return;
+	}
+
+	/* If required, we can also change some settings in the stream info,
+	 * (such as jitter buffer settings, codec settings, etc) before we
+	 * create the video stream.
+	 */
+
+	/* Create new video media stream, passing the stream info, and also the
+	 * media socket that we created earlier.
+	 */
+	status = pjmedia_vid_stream_create(g_med_endpt, NULL, &vstream_info,
+	                                   g_med_transport[1], NULL,
+	                                   &g_med_vstream);
+	if (status != PJ_SUCCESS) {
+	    app_perror( THIS_FILE, "Unable to create video stream", status);
+	    return;
+	}
+
+	/* Start the video stream */
+	status = pjmedia_vid_stream_start(g_med_vstream);
+	if (status != PJ_SUCCESS) {
+	    app_perror( THIS_FILE, "Unable to start video stream", status);
+	    return;
+	}
+
+	if (vstream_info.dir & PJMEDIA_DIR_DECODING) {
+	    status = pjmedia_vid_dev_default_param(
+				inv->pool, PJMEDIA_VID_DEFAULT_RENDER_DEV,
+				&vport_param.vidparam);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to get default param of video "
+			   "renderer device", status);
+		return;
+	    }
+
+	    /* Get video stream port for decoding direction */
+	    pjmedia_vid_stream_get_port(g_med_vstream, PJMEDIA_DIR_DECODING,
+					&media_port);
+
+	    /* Set format */
+	    pjmedia_format_copy(&vport_param.vidparam.fmt,
+				&media_port->info.fmt);
+	    vport_param.vidparam.dir = PJMEDIA_DIR_RENDER;
+	    vport_param.active = PJ_TRUE;
+
+	    /* Create renderer */
+	    status = pjmedia_vid_port_create(inv->pool, &vport_param, 
+					     &g_vid_renderer);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to create video renderer device",
+			   status);
+		return;
+	    }
+
+	    /* Connect renderer to media_port */
+	    status = pjmedia_vid_port_connect(g_vid_renderer, media_port, 
+					      PJ_FALSE);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to connect renderer to stream",
+			   status);
+		return;
+	    }
+	}
+
+	/* Create capturer */
+	if (vstream_info.dir & PJMEDIA_DIR_ENCODING) {
+	    status = pjmedia_vid_dev_default_param(
+				inv->pool, PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
+				&vport_param.vidparam);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to get default param of video "
+			   "capture device", status);
+		return;
+	    }
+
+	    /* Get video stream port for decoding direction */
+	    pjmedia_vid_stream_get_port(g_med_vstream, PJMEDIA_DIR_ENCODING,
+					&media_port);
+
+	    /* Get capturer format from stream info */
+	    pjmedia_format_copy(&vport_param.vidparam.fmt, 
+	                        &media_port->info.fmt);
+	    vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+	    vport_param.active = PJ_TRUE;
+
+	    /* Create capturer */
+	    status = pjmedia_vid_port_create(inv->pool, &vport_param, 
+					     &g_vid_capturer);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to create video capture device",
+			   status);
+		return;
+	    }
+
+	    /* Connect capturer to media_port */
+	    status = pjmedia_vid_port_connect(g_vid_capturer, media_port, 
+					      PJ_FALSE);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to connect capturer to stream",
+			   status);
+		return;
+	    }
+	}
+
+	/* Start streaming */
+	if (g_vid_renderer) {
+	    status = pjmedia_vid_port_start(g_vid_renderer);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to start video renderer",
+			   status);
+		return;
+	    }
+	}
+	if (g_vid_capturer) {
+	    status = pjmedia_vid_port_start(g_vid_capturer);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to start video capturer",
+			   status);
+		return;
+	    }
+	}
+    }
+#endif	/* PJMEDIA_HAS_VIDEO */
+
+    /* Done with media. */
+}
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/sipecho.c b/jni/libpjsip/sources/pjsip-apps/src/samples/sipecho.c
new file mode 100644
index 0000000..dce4534
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/sipecho.c
@@ -0,0 +1,689 @@
+/* $Id: sipecho.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+/**
+ * sipecho.c
+ *
+ * - Accepts incoming calls and echoes back SDP and any media.
+ * - Specify URI in cmdline argument to make call
+ * - Accepts registration too!
+ */
+
+/* Include all headers. */
+#include <pjsip.h>
+#include <pjmedia/sdp.h>
+#include <pjsip_ua.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+/* For logging purpose. */
+#define THIS_FILE   "sipecho.c"
+
+#include "util.h"
+
+
+/* Settings */
+#define MAX_CALLS	8
+
+typedef struct call_t
+{
+    pjsip_inv_session	*inv;
+} call_t;
+
+static struct app_t
+{
+    pj_caching_pool	 cp;
+    pj_pool_t		*pool;
+
+    pjsip_endpoint	*sip_endpt;
+    //pjmedia_endpt	*med_endpt;
+
+    call_t		 call[MAX_CALLS];
+
+    pj_bool_t		 quit;
+    pj_thread_t		*worker_thread;
+
+    pj_bool_t		 enable_msg_logging;
+} app;
+
+/*
+ * Prototypes:
+ */
+
+static void call_on_media_update(pjsip_inv_session *inv, pj_status_t status);
+static void call_on_state_changed(pjsip_inv_session *inv, pjsip_event *e);
+static void call_on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
+static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e);
+static pj_bool_t on_rx_request( pjsip_rx_data *rdata );
+
+/* Globals */
+static int sip_af;
+static int sip_port = 5060;
+static pj_bool_t sip_tcp;
+
+/* This is a PJSIP module to be registered by application to handle
+ * incoming requests outside any dialogs/transactions. The main purpose
+ * here is to handle incoming INVITE request message, where we will
+ * create a dialog and INVITE session for it.
+ */
+static pjsip_module mod_sipecho =
+{
+    NULL, NULL,			    /* prev, next.		*/
+    { "mod-sipecho", 11 },	    /* Name.			*/
+    -1,				    /* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
+    NULL,			    /* load()			*/
+    NULL,			    /* start()			*/
+    NULL,			    /* stop()			*/
+    NULL,			    /* unload()			*/
+    &on_rx_request,		    /* on_rx_request()		*/
+    NULL,			    /* on_rx_response()		*/
+    NULL,			    /* on_tx_request.		*/
+    NULL,			    /* on_tx_response()		*/
+    NULL,			    /* on_tsx_state()		*/
+};
+
+/* Notification on incoming messages */
+static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
+{
+    if (!app.enable_msg_logging)
+	return PJ_FALSE;
+
+    PJ_LOG(3,(THIS_FILE, "RX %d bytes %s from %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 rdata->msg_info.len,
+			 pjsip_rx_data_get_info(rdata),
+			 rdata->tp_info.transport->type_name,
+			 rdata->pkt_info.src_name,
+			 rdata->pkt_info.src_port,
+			 (int)rdata->msg_info.len,
+			 rdata->msg_info.msg_buf));
+    return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
+{
+    if (!app.enable_msg_logging)
+	return PJ_SUCCESS;
+
+    PJ_LOG(3,(THIS_FILE, "TX %d bytes %s to %s %s:%d:\n"
+			 "%.*s\n"
+			 "--end msg--",
+			 (tdata->buf.cur - tdata->buf.start),
+			 pjsip_tx_data_get_info(tdata),
+			 tdata->tp_info.transport->type_name,
+			 tdata->tp_info.dst_name,
+			 tdata->tp_info.dst_port,
+			 (int)(tdata->buf.cur - tdata->buf.start),
+			 tdata->buf.start));
+    return PJ_SUCCESS;
+}
+
+/* The module instance. */
+static pjsip_module msg_logger =
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-msg-log", 13 },		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &logging_on_rx_msg,			/* on_rx_request()	*/
+    &logging_on_rx_msg,			/* on_rx_response()	*/
+    &logging_on_tx_msg,			/* on_tx_request.	*/
+    &logging_on_tx_msg,			/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
+static int worker_proc(void *arg)
+{
+    PJ_UNUSED_ARG(arg);
+
+    while (!app.quit) {
+	pj_time_val interval = { 0, 20 };
+	pjsip_endpt_handle_events(app.sip_endpt, &interval);
+    }
+
+    return 0;
+}
+
+static void hangup_all(void)
+{
+    unsigned i;
+    for (i=0; i<MAX_CALLS; ++i) {
+    	call_t *call = &app.call[i];
+
+    	if (call->inv && call->inv->state <= PJSIP_INV_STATE_CONFIRMED) {
+    	    pj_status_t status;
+    	    pjsip_tx_data *tdata;
+
+    	    status = pjsip_inv_end_session(call->inv, PJSIP_SC_BUSY_HERE, NULL, &tdata);
+    	    if (status==PJ_SUCCESS && tdata)
+    		pjsip_inv_send_msg(call->inv, tdata);
+    	}
+    }
+}
+
+static void destroy_stack(void)
+{
+    enum { WAIT_CLEAR = 5000, WAIT_INTERVAL = 500 };
+    unsigned i;
+
+    PJ_LOG(3,(THIS_FILE, "Shutting down.."));
+
+    /* Wait until all clear */
+    hangup_all();
+    for (i=0; i<WAIT_CLEAR/WAIT_INTERVAL; ++i) {
+	unsigned j;
+
+	for (j=0; j<MAX_CALLS; ++j) {
+	    call_t *call = &app.call[j];
+	    if (call->inv && call->inv->state <= PJSIP_INV_STATE_CONFIRMED)
+		break;
+	}
+
+	if (j==MAX_CALLS)
+	    return;
+
+	pj_thread_sleep(WAIT_INTERVAL);
+    }
+
+    app.quit = PJ_TRUE;
+    if (app.worker_thread) {
+	pj_thread_join(app.worker_thread);
+	app.worker_thread = NULL;
+    }
+
+    //if (app.med_endpt)
+	//pjmedia_endpt_destroy(app.med_endpt);
+
+    if (app.sip_endpt)
+	pjsip_endpt_destroy(app.sip_endpt);
+
+    if (app.pool)
+	pj_pool_release(app.pool);
+
+    dump_pool_usage(THIS_FILE, &app.cp);
+    pj_caching_pool_destroy(&app.cp);
+}
+
+#define CHECK_STATUS()	do { if (status != PJ_SUCCESS) return status; } while (0)
+
+static pj_status_t init_stack()
+{
+    pj_sockaddr addr;
+    pjsip_inv_callback inv_cb;
+    pj_status_t status;
+
+    pj_log_set_level(3);
+
+    status = pjlib_util_init();
+    CHECK_STATUS();
+
+    pj_caching_pool_init(&app.cp, NULL, 0);
+    app.pool = pj_pool_create( &app.cp.factory, "sipecho", 512, 512, 0);
+
+    status = pjsip_endpt_create(&app.cp.factory, NULL, &app.sip_endpt);
+    CHECK_STATUS();
+
+    pj_log_set_level(4);
+    pj_sockaddr_init((pj_uint16_t)sip_af, &addr, NULL, (pj_uint16_t)sip_port);
+    if (sip_af == pj_AF_INET()) {
+	if (sip_tcp) {
+	    status = pjsip_tcp_transport_start( app.sip_endpt, &addr.ipv4, 1,
+						NULL);
+	} else {
+	    status = pjsip_udp_transport_start( app.sip_endpt, &addr.ipv4,
+	                                        NULL, 1, NULL);
+	}
+    } else if (sip_af == pj_AF_INET6()) {
+	    status = pjsip_udp_transport_start6(app.sip_endpt, &addr.ipv6,
+	                                        NULL, 1, NULL);
+    } else {
+	status = PJ_EAFNOTSUP;
+    }
+
+    pj_log_set_level(3);
+    CHECK_STATUS();
+
+    status = pjsip_tsx_layer_init_module(app.sip_endpt) ||
+	     pjsip_ua_init_module( app.sip_endpt, NULL );
+    CHECK_STATUS();
+
+    pj_bzero(&inv_cb, sizeof(inv_cb));
+    inv_cb.on_state_changed = &call_on_state_changed;
+    inv_cb.on_new_session = &call_on_forked;
+    inv_cb.on_media_update = &call_on_media_update;
+    inv_cb.on_rx_offer = &call_on_rx_offer;
+
+    status = pjsip_inv_usage_init(app.sip_endpt, &inv_cb) ||
+	     pjsip_100rel_init_module(app.sip_endpt) ||
+	     pjsip_endpt_register_module( app.sip_endpt, &mod_sipecho) ||
+	     pjsip_endpt_register_module( app.sip_endpt, &msg_logger) ||
+	     //pjmedia_endpt_create(&app.cp.factory,
+		//		  pjsip_endpt_get_ioqueue(app.sip_endpt),
+		//		  0, &app.med_endpt) ||
+             pj_thread_create(app.pool, "sipecho", &worker_proc, NULL, 0, 0,
+                              &app.worker_thread);
+    CHECK_STATUS();
+
+    return PJ_SUCCESS;
+}
+
+static void destroy_call(call_t *call)
+{
+    call->inv = NULL;
+}
+
+static pjmedia_sdp_attr * find_remove_sdp_attrs(unsigned *cnt,
+                                                pjmedia_sdp_attr *attr[],
+                                                unsigned cnt_attr_to_remove,
+                                                const char* attr_to_remove[])
+{
+    pjmedia_sdp_attr *found_attr = NULL;
+    int i;
+
+    for (i=0; i<(int)*cnt; ++i) {
+	unsigned j;
+	for (j=0; j<cnt_attr_to_remove; ++j) {
+	    if (pj_strcmp2(&attr[i]->name, attr_to_remove[j])==0) {
+		if (!found_attr) found_attr = attr[i];
+		pj_array_erase(attr, sizeof(attr[0]), *cnt, i);
+		--(*cnt);
+		--i;
+		break;
+	    }
+	}
+    }
+
+    return found_attr;
+}
+
+static pjmedia_sdp_session *create_answer(int call_num, pj_pool_t *pool,
+                                          const pjmedia_sdp_session *offer)
+{
+    const char* dir_attrs[] = { "sendrecv", "sendonly", "recvonly", "inactive" };
+    const char *ice_attrs[] = {"ice-pwd", "ice-ufrag", "candidate"};
+    pjmedia_sdp_session *answer = pjmedia_sdp_session_clone(pool, offer);
+    pjmedia_sdp_attr *sess_dir_attr = NULL;
+    unsigned mi;
+
+    PJ_LOG(3,(THIS_FILE, "Call %d: creating answer:", call_num));
+
+    answer->name = pj_str("sipecho");
+    sess_dir_attr = find_remove_sdp_attrs(&answer->attr_count, answer->attr,
+                                          PJ_ARRAY_SIZE(dir_attrs),
+                                          dir_attrs);
+
+    for (mi=0; mi<answer->media_count; ++mi) {
+	pjmedia_sdp_media *m = answer->media[mi];
+	pjmedia_sdp_attr *m_dir_attr;
+	pjmedia_sdp_attr *dir_attr;
+	const char *our_dir = NULL;
+	pjmedia_sdp_conn *c;
+
+	/* Match direction */
+	m_dir_attr = find_remove_sdp_attrs(&m->attr_count, m->attr,
+	                                   PJ_ARRAY_SIZE(dir_attrs),
+	                                   dir_attrs);
+	dir_attr = m_dir_attr ? m_dir_attr : sess_dir_attr;
+
+	if (dir_attr) {
+	    if (pj_strcmp2(&dir_attr->name, "sendonly")==0)
+		our_dir = "recvonly";
+	    else if (pj_strcmp2(&dir_attr->name, "inactive")==0)
+		our_dir = "inactive";
+	    else if (pj_strcmp2(&dir_attr->name, "recvonly")==0)
+		our_dir = "inactive";
+
+	    if (our_dir) {
+		dir_attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
+		dir_attr->name = pj_str((char*)our_dir);
+		m->attr[m->attr_count++] = dir_attr;
+	    }
+	}
+
+	/* Remove ICE attributes */
+	find_remove_sdp_attrs(&m->attr_count, m->attr, PJ_ARRAY_SIZE(ice_attrs), ice_attrs);
+
+	/* Done */
+	c = m->conn ? m->conn : answer->conn;
+	PJ_LOG(3,(THIS_FILE, "  Media %d, %.*s: %s <--> %.*s:%d",
+		  mi, (int)m->desc.media.slen, m->desc.media.ptr,
+		  (our_dir ? our_dir : "sendrecv"),
+		  (int)c->addr.slen, c->addr.ptr, m->desc.port));
+    }
+
+    return answer;
+}
+
+static void call_on_state_changed( pjsip_inv_session *inv, 
+				   pjsip_event *e)
+{
+    call_t *call = (call_t*)inv->mod_data[mod_sipecho.id];
+    if (!call)
+	return;
+
+    PJ_UNUSED_ARG(e);
+    if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
+	PJ_LOG(3,(THIS_FILE, "Call %d: DISCONNECTED [reason=%d (%s)]",
+		  call - app.call, inv->cause,
+		  pjsip_get_status_text(inv->cause)->ptr));
+	destroy_call(call);
+    } else {
+	PJ_LOG(3,(THIS_FILE, "Call %d: state changed to %s",
+		  call - app.call, pjsip_inv_state_name(inv->state)));
+    }
+}
+
+static void call_on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer)
+{
+    call_t *call = (call_t*) inv->mod_data[mod_sipecho.id];
+    pjsip_inv_set_sdp_answer(inv, create_answer((int)(call - app.call), 
+			     inv->pool_prov, offer));
+}
+
+static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e)
+{
+    PJ_UNUSED_ARG(inv);
+    PJ_UNUSED_ARG(e);
+}
+
+static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
+{
+    pj_sockaddr hostaddr;
+    char temp[80], hostip[PJ_INET6_ADDRSTRLEN];
+    pj_str_t local_uri;
+    pjsip_dialog *dlg;
+    pjsip_rdata_sdp_info *sdp_info;
+    pjmedia_sdp_session *answer = NULL;
+    pjsip_tx_data *tdata = NULL;
+    call_t *call = NULL;
+    unsigned i;
+    pj_status_t status;
+
+    PJ_LOG(3,(THIS_FILE, "RX %.*s from %s",
+	      (int)rdata->msg_info.msg->line.req.method.name.slen,
+	      rdata->msg_info.msg->line.req.method.name.ptr,
+	      rdata->pkt_info.src_name));
+
+    if (rdata->msg_info.msg->line.req.method.id == PJSIP_REGISTER_METHOD) {
+	/* Let me be a registrar! */
+	pjsip_hdr hdr_list, *h;
+	pjsip_msg *msg;
+	int expires = -1;
+
+	pj_list_init(&hdr_list);
+	msg = rdata->msg_info.msg;
+	h = (pjsip_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);
+	if (h) {
+	    expires = ((pjsip_expires_hdr*)h)->ivalue;
+	    pj_list_push_back(&hdr_list, pjsip_hdr_clone(rdata->tp_info.pool, h));
+	    PJ_LOG(3,(THIS_FILE, " Expires=%d", expires));
+	}
+	if (expires != 0) {
+	    h = (pjsip_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);
+	    if (h)
+		pj_list_push_back(&hdr_list, pjsip_hdr_clone(rdata->tp_info.pool, h));
+	}
+
+	pjsip_endpt_respond(app.sip_endpt, &mod_sipecho, rdata, 200, NULL,
+	                    &hdr_list, NULL, NULL);
+	return PJ_TRUE;
+    }
+
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) {
+	if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
+	    pj_str_t reason = pj_str("Go away");
+	    pjsip_endpt_respond_stateless( app.sip_endpt, rdata,
+					   400, &reason,
+					   NULL, NULL);
+	}
+	return PJ_TRUE;
+    }
+
+    sdp_info = pjsip_rdata_get_sdp_info(rdata);
+    if (!sdp_info || !sdp_info->sdp) {
+	pj_str_t reason = pj_str("Require valid offer");
+	pjsip_endpt_respond_stateless( app.sip_endpt, rdata,
+				       400, &reason,
+				       NULL, NULL);
+    }
+
+    for (i=0; i<MAX_CALLS; ++i) {
+	if (app.call[i].inv == NULL) {
+	    call = &app.call[i];
+	    break;
+	}
+    }
+
+    if (i==MAX_CALLS) {
+	pj_str_t reason = pj_str("We're full");
+	pjsip_endpt_respond_stateless( app.sip_endpt, rdata,
+				       PJSIP_SC_BUSY_HERE, &reason,
+				       NULL, NULL);
+	return PJ_TRUE;
+    }
+
+    /* Generate Contact URI */
+    status = pj_gethostip(sip_af, &hostaddr);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to retrieve local host IP", status);
+	return PJ_TRUE;
+    }
+    pj_sockaddr_print(&hostaddr, hostip, sizeof(hostip), 2);
+    pj_ansi_sprintf(temp, "<sip:sipecho@%s:%d>", hostip, sip_port);
+    local_uri = pj_str(temp);
+
+    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
+				   &local_uri, &dlg);
+
+    if (status == PJ_SUCCESS)
+	answer = create_answer((int)(call-app.call), dlg->pool, sdp_info->sdp);
+    if (status == PJ_SUCCESS)
+    	status = pjsip_inv_create_uas( dlg, rdata, answer, 0, &call->inv);
+    if (status == PJ_SUCCESS)
+    	status = pjsip_inv_initial_answer(call->inv, rdata, 100,
+				          NULL, NULL, &tdata);
+    if (status == PJ_SUCCESS)
+    	status = pjsip_inv_send_msg(call->inv, tdata);
+
+    if (status == PJ_SUCCESS)
+    	status = pjsip_inv_answer(call->inv, 180, NULL,
+    	                          NULL, &tdata);
+    if (status == PJ_SUCCESS)
+    	status = pjsip_inv_send_msg(call->inv, tdata);
+
+    if (status == PJ_SUCCESS)
+    	status = pjsip_inv_answer(call->inv, 200, NULL,
+    	                          NULL, &tdata);
+    if (status == PJ_SUCCESS)
+    	status = pjsip_inv_send_msg(call->inv, tdata);
+
+    if (status != PJ_SUCCESS) {
+	pjsip_endpt_respond_stateless( app.sip_endpt, rdata,
+				       500, NULL, NULL, NULL);
+	destroy_call(call);
+    } else {
+	call->inv->mod_data[mod_sipecho.id] = call;
+    }
+
+    return PJ_TRUE;
+}
+
+static void call_on_media_update( pjsip_inv_session *inv,
+				  pj_status_t status)
+{
+    PJ_UNUSED_ARG(inv);
+    PJ_UNUSED_ARG(status);
+}
+
+
+static void usage()
+{
+    printf("\nUsage: sipecho OPTIONS\n");
+    printf("\n");
+    printf("where OPTIONS:\n");
+    printf("  --local-port, -p PORT        Bind to port PORT.\n");
+    printf("  --tcp, -t                    Listen to TCP instead.\n");
+    printf("  --ipv6, -6                   Use IPv6 instead.\n");
+    printf("  --help, -h                   Show this help page.\n");
+}
+
+/* main()
+ *
+ * If called with argument, treat argument as SIP URL to be called.
+ * Otherwise wait for incoming calls.
+ */
+int main(int argc, char *argv[])
+{
+    struct pj_getopt_option long_options[] = {
+        { "local-port",	1, 0, 'p' },
+        { "tcp",	0, 0, 't' },
+        { "ipv6",	0, 0, '6' },
+        { "help", 	0, 0, 'h' }
+    };
+    int c, option_index;
+
+    pj_log_set_level(5);
+
+    pj_init();
+
+    sip_af = pj_AF_INET();
+
+    pj_optind = 0;
+    while ((c = pj_getopt_long(argc, argv, "p:t6h", long_options,
+                               &option_index)) != -1)
+    {
+	switch (c) {
+	case 'p':
+	    sip_port = atoi(pj_optarg);
+	    break;
+	case 't':
+	    sip_tcp = PJ_TRUE;
+	    break;
+	case 'h':
+	    usage();
+	    return 0;
+	case '6':
+	    sip_af = pj_AF_INET6();
+	    break;
+	default:
+	    PJ_LOG(1,(THIS_FILE,
+		      "Argument \"%s\" is not valid. Use --help to see help",
+		      argv[pj_optind-1]));
+	    return -1;
+	}
+    }
+
+    if (init_stack())
+	goto on_error;
+
+    /* If URL is specified, then make call immediately. */
+    if (pj_optind != argc) {
+	pj_sockaddr hostaddr;
+	char hostip[PJ_INET6_ADDRSTRLEN+2];
+	char temp[80];
+	call_t *call;
+	pj_str_t dst_uri = pj_str(argv[pj_optind]);
+	pj_str_t local_uri;
+	pjsip_dialog *dlg;
+	pj_status_t status;
+	pjsip_tx_data *tdata;
+
+	if (pj_gethostip(sip_af, &hostaddr) != PJ_SUCCESS) {
+	    PJ_LOG(1,(THIS_FILE, "Unable to retrieve local host IP"));
+	    goto on_error;
+	}
+	pj_sockaddr_print(&hostaddr, hostip, sizeof(hostip), 2);
+
+	pj_ansi_sprintf(temp, "<sip:sipecho@%s:%d>",
+			hostip, sip_port);
+	local_uri = pj_str(temp);
+
+	call = &app.call[0];
+
+	status = pjsip_dlg_create_uac( pjsip_ua_instance(),
+				       &local_uri,  /* local URI */
+				       &local_uri,  /* local Contact */
+				       &dst_uri,    /* remote URI */
+				       &dst_uri,    /* remote target */
+				       &dlg);	    /* dialog */
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to create UAC dialog", status);
+	    return 1;
+	}
+
+	status = pjsip_inv_create_uac( dlg, NULL, 0, &call->inv);
+	if (status != PJ_SUCCESS) goto on_error;
+
+	call->inv->mod_data[mod_sipecho.id] = call;
+
+	status = pjsip_inv_invite(call->inv, &tdata);
+	if (status != PJ_SUCCESS) goto on_error;
+
+	status = pjsip_inv_send_msg(call->inv, tdata);
+	if (status != PJ_SUCCESS) goto on_error;
+
+	puts("Press ENTER to quit...");
+    } else {
+	puts("Ready for incoming calls. Press ENTER to quit...");
+    }
+
+    for (;;) {
+	char s[10];
+
+	printf("\nMenu:\n"
+	       "  h    Hangup all calls\n"
+	       "  l    %s message logging\n"
+	       "  q    Quit\n",
+	       (app.enable_msg_logging? "Disable" : "Enable"));
+
+	if (fgets(s, sizeof(s), stdin) == NULL)
+	    continue;
+
+	if (s[0]=='q')
+	    break;
+	switch (s[0]) {
+	case 'l':
+	    app.enable_msg_logging = !app.enable_msg_logging;
+	    break;
+	case 'h':
+	    hangup_all();
+	    break;
+	}
+    }
+
+    destroy_stack();
+
+    puts("Bye bye..");
+    return 0;
+
+on_error:
+    puts("An error has occurred. run a debugger..");
+    return 1;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/siprtp.c b/jni/libpjsip/sources/pjsip-apps/src/samples/siprtp.c
new file mode 100644
index 0000000..b60473e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/siprtp.c
@@ -0,0 +1,2189 @@
+/* $Id: siprtp.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+
+
+
+/* Usage */
+static const char *USAGE = 
+" PURPOSE:								    \n"
+"   This program establishes SIP INVITE session and media, and calculate    \n"
+"   the media quality (packet lost, jitter, rtt, etc.). Unlike normal	    \n"
+"   pjmedia applications, this program bypasses all pjmedia stream	    \n"
+"   framework and transmit encoded RTP packets manually using own thread.   \n"
+"\n"
+" USAGE:\n"
+"   siprtp [options]        => to start in server mode\n"
+"   siprtp [options] URL    => to start in client mode\n"
+"\n"
+" Program options:\n"
+"   --count=N,        -c    Set number of calls to create (default:1) \n"
+"   --gap=N           -g    Set call gapping to N msec (default:0)\n"
+"   --duration=SEC,   -d    Set maximum call duration (default:unlimited) \n"
+"   --auto-quit,      -q    Quit when calls have been completed (default:no)\n"
+"   --call-report     -R    Display report on call termination (default:yes)\n"
+"\n"
+" Address and ports options:\n"
+"   --local-port=PORT,-p    Set local SIP port (default: 5060)\n"
+"   --rtp-port=PORT,  -r    Set start of RTP port (default: 4000)\n"
+"   --ip-addr=IP,     -i    Set local IP address to use (otherwise it will\n"
+"                           try to determine local IP address from hostname)\n"
+"\n"
+" Logging Options:\n"
+"   --log-level=N,    -l    Set log verbosity level (default=5)\n"
+"   --app-log-level=N       Set app screen log verbosity (default=3)\n"
+"   --log-file=FILE         Write log to file FILE\n"
+"   --report-file=FILE      Write report to file FILE\n"
+"\n"
+/* Don't support this anymore, because codec is properly examined in
+   pjmedia_session_info_from_sdp() function.
+
+" Codec Options:\n"
+"   --a-pt=PT               Set audio payload type to PT (default=0)\n"
+"   --a-name=NAME           Set audio codec name to NAME (default=pcmu)\n"
+"   --a-clock=RATE          Set audio codec rate to RATE Hz (default=8000Hz)\n"
+"   --a-bitrate=BPS         Set audio codec bitrate to BPS (default=64000bps)\n"
+"   --a-ptime=MS            Set audio frame time to MS msec (default=20ms)\n"
+*/
+;
+
+
+/* Include all headers. */
+#include <pjsip.h>
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+#include <pjsip_ua.h>
+#include <pjsip_simple.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+#include <stdlib.h>
+
+/* Uncomment these to disable threads.
+ * NOTE:
+ *   when threading is disabled, siprtp won't transmit any
+ *   RTP packets.
+ */
+/*
+#undef PJ_HAS_THREADS
+#define PJ_HAS_THREADS 0
+*/
+
+
+#if PJ_HAS_HIGH_RES_TIMER==0
+#   error "High resolution timer is needed for this sample"
+#endif
+
+#define THIS_FILE	"siprtp.c"
+#define MAX_CALLS	1024
+#define RTP_START_PORT	4000
+
+
+/* Codec descriptor: */
+struct codec
+{
+    unsigned	pt;
+    char*	name;
+    unsigned	clock_rate;
+    unsigned	bit_rate;
+    unsigned	ptime;
+    char*	description;
+};
+
+
+/* A bidirectional media stream created when the call is active. */
+struct media_stream
+{
+    /* Static: */
+    unsigned		 call_index;	    /* Call owner.		*/
+    unsigned		 media_index;	    /* Media index in call.	*/
+    pjmedia_transport   *transport;	    /* To send/recv RTP/RTCP	*/
+
+    /* Active? */
+    pj_bool_t		 active;	    /* Non-zero if is in call.	*/
+
+    /* Current stream info: */
+    pjmedia_stream_info	 si;		    /* Current stream info.	*/
+
+    /* More info: */
+    unsigned		 clock_rate;	    /* clock rate		*/
+    unsigned		 samples_per_frame; /* samples per frame	*/
+    unsigned		 bytes_per_frame;   /* frame size.		*/
+
+    /* RTP session: */
+    pjmedia_rtp_session	 out_sess;	    /* outgoing RTP session	*/
+    pjmedia_rtp_session	 in_sess;	    /* incoming RTP session	*/
+
+    /* RTCP stats: */
+    pjmedia_rtcp_session rtcp;		    /* incoming RTCP session.	*/
+
+    /* Thread: */
+    pj_bool_t		 thread_quit_flag;  /* Stop media thread.	*/
+    pj_thread_t		*thread;	    /* Media thread.		*/
+};
+
+
+/* This is a call structure that is created when the application starts
+ * and only destroyed when the application quits.
+ */
+struct call
+{
+    unsigned		 index;
+    pjsip_inv_session	*inv;
+    unsigned		 media_count;
+    struct media_stream	 media[1];
+    pj_time_val		 start_time;
+    pj_time_val		 response_time;
+    pj_time_val		 connect_time;
+
+    pj_timer_entry	 d_timer;	    /**< Disconnect timer.	*/
+};
+
+
+/* Application's global variables */
+static struct app
+{
+    unsigned		 max_calls;
+    unsigned		 call_gap;
+    pj_bool_t		 call_report;
+    unsigned		 uac_calls;
+    unsigned		 duration;
+    pj_bool_t		 auto_quit;
+    unsigned		 thread_count;
+    int			 sip_port;
+    int			 rtp_start_port;
+    pj_str_t		 local_addr;
+    pj_str_t		 local_uri;
+    pj_str_t		 local_contact;
+    
+    int			 app_log_level;
+    int			 log_level;
+    char		*log_filename;
+    char		*report_filename;
+
+    struct codec	 audio_codec;
+
+    pj_str_t		 uri_to_call;
+
+    pj_caching_pool	 cp;
+    pj_pool_t		*pool;
+
+    pjsip_endpoint	*sip_endpt;
+    pj_bool_t		 thread_quit;
+    pj_thread_t		*sip_thread[1];
+
+    pjmedia_endpt	*med_endpt;
+    struct call		 call[MAX_CALLS];
+} app;
+
+
+
+/*
+ * Prototypes:
+ */
+
+/* Callback to be called when SDP negotiation is done in the call: */
+static void call_on_media_update( pjsip_inv_session *inv,
+				  pj_status_t status);
+
+/* Callback to be called when invite session's state has changed: */
+static void call_on_state_changed( pjsip_inv_session *inv, 
+				   pjsip_event *e);
+
+/* Callback to be called when dialog has forked: */
+static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e);
+
+/* Callback to be called to handle incoming requests outside dialogs: */
+static pj_bool_t on_rx_request( pjsip_rx_data *rdata );
+
+/* Worker thread prototype */
+static int sip_worker_thread(void *arg);
+
+/* Create SDP for call */
+static pj_status_t create_sdp( pj_pool_t *pool,
+			       struct call *call,
+			       pjmedia_sdp_session **p_sdp);
+
+/* Hangup call */
+static void hangup_call(unsigned index);
+
+/* Destroy the call's media */
+static void destroy_call_media(unsigned call_index);
+
+/* Destroy media. */
+static void destroy_media();
+
+/* This callback is called by media transport on receipt of RTP packet. */
+static void on_rx_rtp(void *user_data, void *pkt, pj_ssize_t size);
+
+/* This callback is called by media transport on receipt of RTCP packet. */
+static void on_rx_rtcp(void *user_data, void *pkt, pj_ssize_t size);
+
+/* Display error */
+static void app_perror(const char *sender, const char *title, 
+		       pj_status_t status);
+
+/* Print call */
+static void print_call(int call_index);
+
+
+/* This is a PJSIP module to be registered by application to handle
+ * incoming requests outside any dialogs/transactions. The main purpose
+ * here is to handle incoming INVITE request message, where we will
+ * create a dialog and INVITE session for it.
+ */
+static pjsip_module mod_siprtp =
+{
+    NULL, NULL,			    /* prev, next.		*/
+    { "mod-siprtpapp", 13 },	    /* Name.			*/
+    -1,				    /* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
+    NULL,			    /* load()			*/
+    NULL,			    /* start()			*/
+    NULL,			    /* stop()			*/
+    NULL,			    /* unload()			*/
+    &on_rx_request,		    /* on_rx_request()		*/
+    NULL,			    /* on_rx_response()		*/
+    NULL,			    /* on_tx_request.		*/
+    NULL,			    /* on_tx_response()		*/
+    NULL,			    /* on_tsx_state()		*/
+};
+
+
+/* Codec constants */
+struct codec audio_codecs[] = 
+{
+    { 0,  "PCMU", 8000, 64000, 20, "G.711 ULaw" },
+    { 3,  "GSM",  8000, 13200, 20, "GSM" },
+    { 4,  "G723", 8000, 6400,  30, "G.723.1" },
+    { 8,  "PCMA", 8000, 64000, 20, "G.711 ALaw" },
+    { 18, "G729", 8000, 8000,  20, "G.729" },
+};
+
+
+/*
+ * Init SIP stack
+ */
+static pj_status_t init_sip()
+{
+    unsigned i;
+    pj_status_t status;
+
+    /* init PJLIB-UTIL: */
+    status = pjlib_util_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&app.cp, &pj_pool_factory_default_policy, 0);
+
+    /* Create application pool for misc. */
+    app.pool = pj_pool_create(&app.cp.factory, "app", 1000, 1000, NULL);
+
+    /* Create the endpoint: */
+    status = pjsip_endpt_create(&app.cp.factory, pj_gethostname()->ptr, 
+				&app.sip_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Add UDP transport. */
+    {
+	pj_sockaddr_in addr;
+	pjsip_host_port addrname;
+	pjsip_transport *tp;
+
+	pj_bzero(&addr, sizeof(addr));
+	addr.sin_family = pj_AF_INET();
+	addr.sin_addr.s_addr = 0;
+	addr.sin_port = pj_htons((pj_uint16_t)app.sip_port);
+
+	if (app.local_addr.slen) {
+
+	    addrname.host = app.local_addr;
+	    addrname.port = app.sip_port;
+
+	    status = pj_sockaddr_in_init(&addr, &app.local_addr, 
+					 (pj_uint16_t)app.sip_port);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to resolve IP interface", status);
+		return status;
+	    }
+	}
+
+	status = pjsip_udp_transport_start( app.sip_endpt, &addr, 
+					    (app.local_addr.slen ? &addrname:NULL),
+					    1, &tp);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to start UDP transport", status);
+	    return status;
+	}
+
+	PJ_LOG(3,(THIS_FILE, "SIP UDP listening on %.*s:%d",
+		  (int)tp->local_name.host.slen, tp->local_name.host.ptr,
+		  tp->local_name.port));
+    }
+
+    /* 
+     * Init transaction layer.
+     * This will create/initialize transaction hash tables etc.
+     */
+    status = pjsip_tsx_layer_init_module(app.sip_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /*  Initialize UA layer. */
+    status = pjsip_ua_init_module( app.sip_endpt, NULL );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Initialize 100rel support */
+    status = pjsip_100rel_init_module(app.sip_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /*  Init invite session module. */
+    {
+	pjsip_inv_callback inv_cb;
+
+	/* Init the callback for INVITE session: */
+	pj_bzero(&inv_cb, sizeof(inv_cb));
+	inv_cb.on_state_changed = &call_on_state_changed;
+	inv_cb.on_new_session = &call_on_forked;
+	inv_cb.on_media_update = &call_on_media_update;
+
+	/* Initialize invite session module:  */
+	status = pjsip_inv_usage_init(app.sip_endpt, &inv_cb);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    }
+
+    /* Register our module to receive incoming requests. */
+    status = pjsip_endpt_register_module( app.sip_endpt, &mod_siprtp);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /* Init calls */
+    for (i=0; i<app.max_calls; ++i)
+	app.call[i].index = i;
+
+    /* Done */
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Destroy SIP
+ */
+static void destroy_sip()
+{
+    unsigned i;
+
+    app.thread_quit = 1;
+    for (i=0; i<app.thread_count; ++i) {
+	if (app.sip_thread[i]) {
+	    pj_thread_join(app.sip_thread[i]);
+	    pj_thread_destroy(app.sip_thread[i]);
+	    app.sip_thread[i] = NULL;
+	}
+    }
+
+    if (app.sip_endpt) {
+	pjsip_endpt_destroy(app.sip_endpt);
+	app.sip_endpt = NULL;
+    }
+
+}
+
+
+/*
+ * Init media stack.
+ */
+static pj_status_t init_media()
+{
+    unsigned	i, count;
+    pj_uint16_t	rtp_port;
+    pj_status_t	status;
+
+
+    /* Initialize media endpoint so that at least error subsystem is properly
+     * initialized.
+     */
+#if PJ_HAS_THREADS
+    status = pjmedia_endpt_create(&app.cp.factory, NULL, 1, &app.med_endpt);
+#else
+    status = pjmedia_endpt_create(&app.cp.factory, 
+				  pjsip_endpt_get_ioqueue(app.sip_endpt),
+				  0, &app.med_endpt);
+#endif
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Must register codecs to be supported */
+#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
+    pjmedia_codec_g711_init(app.med_endpt);
+#endif
+
+    /* RTP port counter */
+    rtp_port = (pj_uint16_t)(app.rtp_start_port & 0xFFFE);
+
+    /* Init media transport for all calls. */
+    for (i=0, count=0; i<app.max_calls; ++i, ++count) {
+
+	unsigned j;
+
+	/* Create transport for each media in the call */
+	for (j=0; j<PJ_ARRAY_SIZE(app.call[0].media); ++j) {
+	    /* Repeat binding media socket to next port when fails to bind
+	     * to current port number.
+	     */
+	    int retry;
+
+	    app.call[i].media[j].call_index = i;
+	    app.call[i].media[j].media_index = j;
+
+	    status = -1;
+	    for (retry=0; retry<100; ++retry,rtp_port+=2)  {
+		struct media_stream *m = &app.call[i].media[j];
+		
+		status = pjmedia_transport_udp_create2(app.med_endpt, 
+						       "siprtp",
+						       &app.local_addr,
+						       rtp_port, 0, 
+						       &m->transport);
+		if (status == PJ_SUCCESS) {
+		    rtp_port += 2;
+		    break;
+		}
+	    }
+	}
+
+	if (status != PJ_SUCCESS)
+	    goto on_error;
+    }
+
+    /* Done */
+    return PJ_SUCCESS;
+
+on_error:
+    destroy_media();
+    return status;
+}
+
+
+/*
+ * Destroy media.
+ */
+static void destroy_media()
+{
+    unsigned i;
+
+    for (i=0; i<app.max_calls; ++i) {
+	unsigned j;
+	for (j=0; j<PJ_ARRAY_SIZE(app.call[0].media); ++j) {
+	    struct media_stream *m = &app.call[i].media[j];
+
+	    if (m->transport) {
+		pjmedia_transport_close(m->transport);
+		m->transport = NULL;
+	    }
+	}
+    }
+
+    if (app.med_endpt) {
+	pjmedia_endpt_destroy(app.med_endpt);
+	app.med_endpt = NULL;
+    }
+}
+
+
+/*
+ * Make outgoing call.
+ */
+static pj_status_t make_call(const pj_str_t *dst_uri)
+{
+    unsigned i;
+    struct call *call;
+    pjsip_dialog *dlg;
+    pjmedia_sdp_session *sdp;
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+
+    /* Find unused call slot */
+    for (i=0; i<app.max_calls; ++i) {
+	if (app.call[i].inv == NULL)
+	    break;
+    }
+
+    if (i == app.max_calls)
+	return PJ_ETOOMANY;
+
+    call = &app.call[i];
+
+    /* Create UAC dialog */
+    status = pjsip_dlg_create_uac( pjsip_ua_instance(), 
+				   &app.local_uri,	/* local URI	    */
+				   &app.local_contact,	/* local Contact    */
+				   dst_uri,		/* remote URI	    */
+				   dst_uri,		/* remote target    */
+				   &dlg);		/* dialog	    */
+    if (status != PJ_SUCCESS) {
+	++app.uac_calls;
+	return status;
+    }
+
+    /* Create SDP */
+    create_sdp( dlg->pool, call, &sdp);
+
+    /* Create the INVITE session. */
+    status = pjsip_inv_create_uac( dlg, sdp, 0, &call->inv);
+    if (status != PJ_SUCCESS) {
+	pjsip_dlg_terminate(dlg);
+	++app.uac_calls;
+	return status;
+    }
+
+
+    /* Attach call data to invite session */
+    call->inv->mod_data[mod_siprtp.id] = call;
+
+    /* Mark start of call */
+    pj_gettimeofday(&call->start_time);
+
+
+    /* Create initial INVITE request.
+     * This INVITE request will contain a perfectly good request and 
+     * an SDP body as well.
+     */
+    status = pjsip_inv_invite(call->inv, &tdata);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    /* Send initial INVITE request. 
+     * From now on, the invite session's state will be reported to us
+     * via the invite session callbacks.
+     */
+    status = pjsip_inv_send_msg(call->inv, tdata);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Receive incoming call
+ */
+static void process_incoming_call(pjsip_rx_data *rdata)
+{
+    unsigned i, options;
+    struct call *call;
+    pjsip_dialog *dlg;
+    pjmedia_sdp_session *sdp;
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+    /* Find free call slot */
+    for (i=0; i<app.max_calls; ++i) {
+	if (app.call[i].inv == NULL)
+	    break;
+    }
+
+    if (i == app.max_calls) {
+	const pj_str_t reason = pj_str("Too many calls");
+	pjsip_endpt_respond_stateless( app.sip_endpt, rdata, 
+				       500, &reason,
+				       NULL, NULL);
+	return;
+    }
+
+    call = &app.call[i];
+
+    /* Verify that we can handle the request. */
+    options = 0;
+    status = pjsip_inv_verify_request(rdata, &options, NULL, NULL,
+  				   app.sip_endpt, &tdata);
+    if (status != PJ_SUCCESS) {
+	/*
+	 * No we can't handle the incoming INVITE request.
+	 */
+	if (tdata) {
+	    pjsip_response_addr res_addr;
+	    
+	    pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
+	    pjsip_endpt_send_response(app.sip_endpt, &res_addr, tdata,
+		NULL, NULL);
+	    
+	} else {
+	    
+	    /* Respond with 500 (Internal Server Error) */
+	    pjsip_endpt_respond_stateless(app.sip_endpt, rdata, 500, NULL,
+		NULL, NULL);
+	}
+	
+	return;
+    }
+
+    /* Create UAS dialog */
+    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
+				   &app.local_contact, &dlg);
+    if (status != PJ_SUCCESS) {
+	const pj_str_t reason = pj_str("Unable to create dialog");
+	pjsip_endpt_respond_stateless( app.sip_endpt, rdata, 
+				       500, &reason,
+				       NULL, NULL);
+	return;
+    }
+
+    /* Create SDP */
+    create_sdp( dlg->pool, call, &sdp);
+
+    /* Create UAS invite session */
+    status = pjsip_inv_create_uas( dlg, rdata, sdp, 0, &call->inv);
+    if (status != PJ_SUCCESS) {
+	pjsip_dlg_create_response(dlg, rdata, 500, NULL, &tdata);
+	pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
+	return;
+    }
+    
+
+    /* Attach call data to invite session */
+    call->inv->mod_data[mod_siprtp.id] = call;
+
+    /* Mark start of call */
+    pj_gettimeofday(&call->start_time);
+
+
+
+    /* Create 200 response .*/
+    status = pjsip_inv_initial_answer(call->inv, rdata, 200, 
+				      NULL, NULL, &tdata);
+    if (status != PJ_SUCCESS) {
+	status = pjsip_inv_initial_answer(call->inv, rdata, 
+					  PJSIP_SC_NOT_ACCEPTABLE,
+					  NULL, NULL, &tdata);
+	if (status == PJ_SUCCESS)
+	    pjsip_inv_send_msg(call->inv, tdata); 
+	else
+	    pjsip_inv_terminate(call->inv, 500, PJ_FALSE);
+	return;
+    }
+
+
+    /* Send the 200 response. */  
+    status = pjsip_inv_send_msg(call->inv, tdata); 
+    PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, return);
+
+
+    /* Done */
+}
+
+
+/* Callback to be called when dialog has forked: */
+static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e)
+{
+    PJ_UNUSED_ARG(inv);
+    PJ_UNUSED_ARG(e);
+
+    PJ_TODO( HANDLE_FORKING );
+}
+
+
+/* Callback to be called to handle incoming requests outside dialogs: */
+static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
+{
+    /* Ignore strandled ACKs (must not send respone */
+    if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD)
+	return PJ_FALSE;
+
+    /* Respond (statelessly) any non-INVITE requests with 500  */
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) {
+	pj_str_t reason = pj_str("Unsupported Operation");
+	pjsip_endpt_respond_stateless( app.sip_endpt, rdata, 
+				       500, &reason,
+				       NULL, NULL);
+	return PJ_TRUE;
+    }
+
+    /* Handle incoming INVITE */
+    process_incoming_call(rdata);
+
+    /* Done */
+    return PJ_TRUE;
+}
+
+
+/* Callback timer to disconnect call (limiting call duration) */
+static void timer_disconnect_call( pj_timer_heap_t *timer_heap,
+				   struct pj_timer_entry *entry)
+{
+    struct call *call = entry->user_data;
+
+    PJ_UNUSED_ARG(timer_heap);
+
+    entry->id = 0;
+    hangup_call(call->index);
+}
+
+
+/* Callback to be called when invite session's state has changed: */
+static void call_on_state_changed( pjsip_inv_session *inv, 
+				   pjsip_event *e)
+{
+    struct call *call = inv->mod_data[mod_siprtp.id];
+
+    PJ_UNUSED_ARG(e);
+
+    if (!call)
+	return;
+
+    if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
+	
+	pj_time_val null_time = {0, 0};
+
+	if (call->d_timer.id != 0) {
+	    pjsip_endpt_cancel_timer(app.sip_endpt, &call->d_timer);
+	    call->d_timer.id = 0;
+	}
+
+	PJ_LOG(3,(THIS_FILE, "Call #%d disconnected. Reason=%d (%.*s)",
+		  call->index,
+		  inv->cause,
+		  (int)inv->cause_text.slen,
+		  inv->cause_text.ptr));
+
+	if (app.call_report) {
+	    PJ_LOG(3,(THIS_FILE, "Call #%d statistics:", call->index));
+	    print_call(call->index);
+	}
+
+
+	call->inv = NULL;
+	inv->mod_data[mod_siprtp.id] = NULL;
+
+	destroy_call_media(call->index);
+
+	call->start_time = null_time;
+	call->response_time = null_time;
+	call->connect_time = null_time;
+
+	++app.uac_calls;
+
+    } else if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
+
+	pj_time_val t;
+
+	pj_gettimeofday(&call->connect_time);
+	if (call->response_time.sec == 0)
+	    call->response_time = call->connect_time;
+
+	t = call->connect_time;
+	PJ_TIME_VAL_SUB(t, call->start_time);
+
+	PJ_LOG(3,(THIS_FILE, "Call #%d connected in %d ms", call->index,
+		  PJ_TIME_VAL_MSEC(t)));
+
+	if (app.duration != 0) {
+	    call->d_timer.id = 1;
+	    call->d_timer.user_data = call;
+	    call->d_timer.cb = &timer_disconnect_call;
+
+	    t.sec = app.duration;
+	    t.msec = 0;
+
+	    pjsip_endpt_schedule_timer(app.sip_endpt, &call->d_timer, &t);
+	}
+
+    } else if (	inv->state == PJSIP_INV_STATE_EARLY ||
+		inv->state == PJSIP_INV_STATE_CONNECTING) {
+
+	if (call->response_time.sec == 0)
+	    pj_gettimeofday(&call->response_time);
+
+    }
+}
+
+
+/* Utility */
+static void app_perror(const char *sender, const char *title, 
+		       pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(3,(sender, "%s: %s [status=%d]", title, errmsg, status));
+}
+
+
+/* Worker thread for SIP */
+static int sip_worker_thread(void *arg)
+{
+    PJ_UNUSED_ARG(arg);
+
+    while (!app.thread_quit) {
+	pj_time_val timeout = {0, 10};
+	pjsip_endpt_handle_events(app.sip_endpt, &timeout);
+    }
+
+    return 0;
+}
+
+
+/* Init application options */
+static pj_status_t init_options(int argc, char *argv[])
+{
+    static char ip_addr[32];
+    static char local_uri[64];
+
+    enum { OPT_START,
+	   OPT_APP_LOG_LEVEL, OPT_LOG_FILE, 
+	   OPT_A_PT, OPT_A_NAME, OPT_A_CLOCK, OPT_A_BITRATE, OPT_A_PTIME,
+	   OPT_REPORT_FILE };
+
+    struct pj_getopt_option long_options[] = {
+	{ "count",	    1, 0, 'c' },
+	{ "gap",            1, 0, 'g' },
+	{ "call-report",    0, 0, 'R' },
+	{ "duration",	    1, 0, 'd' },
+	{ "auto-quit",	    0, 0, 'q' },
+	{ "local-port",	    1, 0, 'p' },
+	{ "rtp-port",	    1, 0, 'r' },
+	{ "ip-addr",	    1, 0, 'i' },
+
+	{ "log-level",	    1, 0, 'l' },
+	{ "app-log-level",  1, 0, OPT_APP_LOG_LEVEL },
+	{ "log-file",	    1, 0, OPT_LOG_FILE },
+
+	{ "report-file",    1, 0, OPT_REPORT_FILE },
+
+	/* Don't support this anymore, see comments in USAGE above.
+	{ "a-pt",	    1, 0, OPT_A_PT },
+	{ "a-name",	    1, 0, OPT_A_NAME },
+	{ "a-clock",	    1, 0, OPT_A_CLOCK },
+	{ "a-bitrate",	    1, 0, OPT_A_BITRATE },
+	{ "a-ptime",	    1, 0, OPT_A_PTIME },
+	*/
+
+	{ NULL, 0, 0, 0 },
+    };
+    int c;
+    int option_index;
+
+    /* Get local IP address for the default IP address */
+    {
+	const pj_str_t *hostname;
+	pj_sockaddr_in tmp_addr;
+	char *addr;
+
+	hostname = pj_gethostname();
+	pj_sockaddr_in_init(&tmp_addr, hostname, 0);
+	addr = pj_inet_ntoa(tmp_addr.sin_addr);
+	pj_ansi_strcpy(ip_addr, addr);
+    }
+
+    /* Init defaults */
+    app.max_calls = 1;
+    app.thread_count = 1;
+    app.sip_port = 5060;
+    app.rtp_start_port = RTP_START_PORT;
+    app.local_addr = pj_str(ip_addr);
+    app.log_level = 5;
+    app.app_log_level = 3;
+    app.log_filename = NULL;
+
+    /* Default codecs: */
+    app.audio_codec = audio_codecs[0];
+
+    /* Parse options */
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc,argv, "c:d:p:r:i:l:g:qR", 
+			    long_options, &option_index))!=-1) 
+    {
+	switch (c) {
+	case 'c':
+	    app.max_calls = atoi(pj_optarg);
+	    if (app.max_calls < 0 || app.max_calls > MAX_CALLS) {
+		PJ_LOG(3,(THIS_FILE, "Invalid max calls value %s", pj_optarg));
+		return 1;
+	    }
+	    break;
+	case 'g':
+	    app.call_gap = atoi(pj_optarg);
+	    break;
+	case 'R':
+	    app.call_report = PJ_TRUE;
+	    break;
+	case 'd':
+	    app.duration = atoi(pj_optarg);
+	    break;
+	case 'q':
+	    app.auto_quit = 1;
+	    break;
+
+	case 'p':
+	    app.sip_port = atoi(pj_optarg);
+	    break;
+	case 'r':
+	    app.rtp_start_port = atoi(pj_optarg);
+	    break;
+	case 'i':
+	    app.local_addr = pj_str(pj_optarg);
+	    break;
+
+	case 'l':
+	    app.log_level = atoi(pj_optarg);
+	    break;
+	case OPT_APP_LOG_LEVEL:
+	    app.app_log_level = atoi(pj_optarg);
+	    break;
+	case OPT_LOG_FILE:
+	    app.log_filename = pj_optarg;
+	    break;
+
+	case OPT_A_PT:
+	    app.audio_codec.pt = atoi(pj_optarg);
+	    break;
+	case OPT_A_NAME:
+	    app.audio_codec.name = pj_optarg;
+	    break;
+	case OPT_A_CLOCK:
+	    app.audio_codec.clock_rate = atoi(pj_optarg);
+	    break;
+	case OPT_A_BITRATE:
+	    app.audio_codec.bit_rate = atoi(pj_optarg);
+	    break;
+	case OPT_A_PTIME:
+	    app.audio_codec.ptime = atoi(pj_optarg);
+	    break;
+	case OPT_REPORT_FILE:
+	    app.report_filename = pj_optarg;
+	    break;
+
+	default:
+	    puts(USAGE);
+	    return 1;
+	}
+    }
+
+    /* Check if URL is specified */
+    if (pj_optind < argc)
+	app.uri_to_call = pj_str(argv[pj_optind]);
+
+    /* Build local URI and contact */
+    pj_ansi_sprintf( local_uri, "sip:%s:%d", app.local_addr.ptr, app.sip_port);
+    app.local_uri = pj_str(local_uri);
+    app.local_contact = app.local_uri;
+
+
+    return PJ_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * MEDIA STUFFS
+ */
+
+/*
+ * Create SDP session for a call.
+ */
+static pj_status_t create_sdp( pj_pool_t *pool,
+			       struct call *call,
+			       pjmedia_sdp_session **p_sdp)
+{
+    pj_time_val tv;
+    pjmedia_sdp_session *sdp;
+    pjmedia_sdp_media *m;
+    pjmedia_sdp_attr *attr;
+    pjmedia_transport_info tpinfo;
+    struct media_stream *audio = &call->media[0];
+
+    PJ_ASSERT_RETURN(pool && p_sdp, PJ_EINVAL);
+
+
+    /* Get transport info */
+    pjmedia_transport_info_init(&tpinfo);
+    pjmedia_transport_get_info(audio->transport, &tpinfo);
+
+    /* Create and initialize basic SDP session */
+    sdp = pj_pool_zalloc (pool, sizeof(pjmedia_sdp_session));
+
+    pj_gettimeofday(&tv);
+    sdp->origin.user = pj_str("pjsip-siprtp");
+    sdp->origin.version = sdp->origin.id = tv.sec + 2208988800UL;
+    sdp->origin.net_type = pj_str("IN");
+    sdp->origin.addr_type = pj_str("IP4");
+    sdp->origin.addr = *pj_gethostname();
+    sdp->name = pj_str("pjsip");
+
+    /* Since we only support one media stream at present, put the
+     * SDP connection line in the session level.
+     */
+    sdp->conn = pj_pool_zalloc (pool, sizeof(pjmedia_sdp_conn));
+    sdp->conn->net_type = pj_str("IN");
+    sdp->conn->addr_type = pj_str("IP4");
+    sdp->conn->addr = app.local_addr;
+
+
+    /* SDP time and attributes. */
+    sdp->time.start = sdp->time.stop = 0;
+    sdp->attr_count = 0;
+
+    /* Create media stream 0: */
+
+    sdp->media_count = 1;
+    m = pj_pool_zalloc (pool, sizeof(pjmedia_sdp_media));
+    sdp->media[0] = m;
+
+    /* Standard media info: */
+    m->desc.media = pj_str("audio");
+    m->desc.port = pj_ntohs(tpinfo.sock_info.rtp_addr_name.ipv4.sin_port);
+    m->desc.port_count = 1;
+    m->desc.transport = pj_str("RTP/AVP");
+
+    /* Add format and rtpmap for each codec. */
+    m->desc.fmt_count = 1;
+    m->attr_count = 0;
+
+    {
+	pjmedia_sdp_rtpmap rtpmap;
+	pjmedia_sdp_attr *attr;
+	char ptstr[10];
+
+	sprintf(ptstr, "%d", app.audio_codec.pt);
+	pj_strdup2(pool, &m->desc.fmt[0], ptstr);
+	rtpmap.pt = m->desc.fmt[0];
+	rtpmap.clock_rate = app.audio_codec.clock_rate;
+	rtpmap.enc_name = pj_str(app.audio_codec.name);
+	rtpmap.param.slen = 0;
+
+	pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
+	m->attr[m->attr_count++] = attr;
+    }
+
+    /* Add sendrecv attribute. */
+    attr = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_attr));
+    attr->name = pj_str("sendrecv");
+    m->attr[m->attr_count++] = attr;
+
+#if 1
+    /*
+     * Add support telephony event
+     */
+    m->desc.fmt[m->desc.fmt_count++] = pj_str("121");
+    /* Add rtpmap. */
+    attr = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_attr));
+    attr->name = pj_str("rtpmap");
+    attr->value = pj_str("121 telephone-event/8000");
+    m->attr[m->attr_count++] = attr;
+    /* Add fmtp */
+    attr = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_attr));
+    attr->name = pj_str("fmtp");
+    attr->value = pj_str("121 0-15");
+    m->attr[m->attr_count++] = attr;
+#endif
+
+    /* Done */
+    *p_sdp = sdp;
+
+    return PJ_SUCCESS;
+}
+
+
+#if (defined(PJ_WIN32) && PJ_WIN32 != 0) || (defined(PJ_WIN64) && PJ_WIN64 != 0)
+#include <windows.h>
+static void boost_priority(void)
+{
+    SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
+    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+}
+
+#elif defined(PJ_LINUX) && PJ_LINUX != 0
+#include <pthread.h>
+static void boost_priority(void)
+{
+#define POLICY	SCHED_FIFO
+    struct sched_param tp;
+    int max_prio;
+    int policy;
+    int rc;
+
+    if (sched_get_priority_min(POLICY) < sched_get_priority_max(POLICY))
+	max_prio = sched_get_priority_max(POLICY)-1;
+    else
+	max_prio = sched_get_priority_max(POLICY)+1;
+
+    /*
+     * Adjust process scheduling algorithm and priority
+     */
+    rc = sched_getparam(0, &tp);
+    if (rc != 0) {
+	app_perror( THIS_FILE, "sched_getparam error",
+		    PJ_RETURN_OS_ERROR(rc));
+	return;
+    }
+    tp.__sched_priority = max_prio;
+
+    rc = sched_setscheduler(0, POLICY, &tp);
+    if (rc != 0) {
+	app_perror( THIS_FILE, "sched_setscheduler error",
+		    PJ_RETURN_OS_ERROR(rc));
+    }
+
+    PJ_LOG(4, (THIS_FILE, "New process policy=%d, priority=%d",
+	      policy, tp.__sched_priority));
+
+    /*
+     * Adjust thread scheduling algorithm and priority
+     */
+    rc = pthread_getschedparam(pthread_self(), &policy, &tp);
+    if (rc != 0) {
+	app_perror( THIS_FILE, "pthread_getschedparam error",
+		    PJ_RETURN_OS_ERROR(rc));
+	return;
+    }
+
+    PJ_LOG(4, (THIS_FILE, "Old thread policy=%d, priority=%d",
+	      policy, tp.__sched_priority));
+
+    policy = POLICY;
+    tp.__sched_priority = max_prio;
+
+    rc = pthread_setschedparam(pthread_self(), policy, &tp);
+    if (rc != 0) {
+	app_perror( THIS_FILE, "pthread_setschedparam error",
+		    PJ_RETURN_OS_ERROR(rc));
+	return;
+    }
+
+    PJ_LOG(4, (THIS_FILE, "New thread policy=%d, priority=%d",
+	      policy, tp.__sched_priority));
+}
+
+#else
+#  define boost_priority()
+#endif
+
+
+/*
+ * This callback is called by media transport on receipt of RTP packet.
+ */
+static void on_rx_rtp(void *user_data, void *pkt, pj_ssize_t size)
+{
+    struct media_stream *strm;
+    pj_status_t status;
+    const pjmedia_rtp_hdr *hdr;
+    const void *payload;
+    unsigned payload_len;
+
+    strm = user_data;
+
+    /* Discard packet if media is inactive */
+    if (!strm->active)
+	return;
+
+    /* Check for errors */
+    if (size < 0) {
+	app_perror(THIS_FILE, "RTP recv() error", (pj_status_t)-size);
+	return;
+    }
+
+    /* Decode RTP packet. */
+    status = pjmedia_rtp_decode_rtp(&strm->in_sess, 
+				    pkt, (int)size, 
+				    &hdr, &payload, &payload_len);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "RTP decode error", status);
+	return;
+    }
+
+    //PJ_LOG(4,(THIS_FILE, "Rx seq=%d", pj_ntohs(hdr->seq)));
+
+    /* Update the RTCP session. */
+    pjmedia_rtcp_rx_rtp(&strm->rtcp, pj_ntohs(hdr->seq),
+			pj_ntohl(hdr->ts), payload_len);
+
+    /* Update RTP session */
+    pjmedia_rtp_session_update(&strm->in_sess, hdr, NULL);
+
+}
+
+/*
+ * This callback is called by media transport on receipt of RTCP packet.
+ */
+static void on_rx_rtcp(void *user_data, void *pkt, pj_ssize_t size)
+{
+    struct media_stream *strm;
+
+    strm = user_data;
+
+    /* Discard packet if media is inactive */
+    if (!strm->active)
+	return;
+
+    /* Check for errors */
+    if (size < 0) {
+	app_perror(THIS_FILE, "Error receiving RTCP packet",(pj_status_t)-size);
+	return;
+    }
+
+    /* Update RTCP session */
+    pjmedia_rtcp_rx_rtcp(&strm->rtcp, pkt, size);
+}
+
+
+/* 
+ * Media thread 
+ *
+ * This is the thread to send and receive both RTP and RTCP packets.
+ */
+static int media_thread(void *arg)
+{
+    enum { RTCP_INTERVAL = 5000, RTCP_RAND = 2000 };
+    struct media_stream *strm = arg;
+    char packet[1500];
+    unsigned msec_interval;
+    pj_timestamp freq, next_rtp, next_rtcp;
+
+
+    /* Boost thread priority if necessary */
+    boost_priority();
+
+    /* Let things settle */
+    pj_thread_sleep(100);
+
+    msec_interval = strm->samples_per_frame * 1000 / strm->clock_rate;
+    pj_get_timestamp_freq(&freq);
+
+    pj_get_timestamp(&next_rtp);
+    next_rtp.u64 += (freq.u64 * msec_interval / 1000);
+
+    next_rtcp = next_rtp;
+    next_rtcp.u64 += (freq.u64 * (RTCP_INTERVAL+(pj_rand()%RTCP_RAND)) / 1000);
+
+
+    while (!strm->thread_quit_flag) {
+	pj_timestamp now, lesser;
+	pj_time_val timeout;
+	pj_bool_t send_rtp, send_rtcp;
+
+	send_rtp = send_rtcp = PJ_FALSE;
+
+	/* Determine how long to sleep */
+	if (next_rtp.u64 < next_rtcp.u64) {
+	    lesser = next_rtp;
+	    send_rtp = PJ_TRUE;
+	} else {
+	    lesser = next_rtcp;
+	    send_rtcp = PJ_TRUE;
+	}
+
+	pj_get_timestamp(&now);
+	if (lesser.u64 <= now.u64) {
+	    timeout.sec = timeout.msec = 0;
+	    //printf("immediate "); fflush(stdout);
+	} else {
+	    pj_uint64_t tick_delay;
+	    tick_delay = lesser.u64 - now.u64;
+	    timeout.sec = 0;
+	    timeout.msec = (pj_uint32_t)(tick_delay * 1000 / freq.u64);
+	    pj_time_val_normalize(&timeout);
+
+	    //printf("%d:%03d ", timeout.sec, timeout.msec); fflush(stdout);
+	}
+
+	/* Wait for next interval */
+	//if (timeout.sec!=0 && timeout.msec!=0) {
+	    pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout));
+	    if (strm->thread_quit_flag)
+		break;
+	//}
+
+	pj_get_timestamp(&now);
+
+	if (send_rtp || next_rtp.u64 <= now.u64) {
+	    /*
+	     * Time to send RTP packet.
+	     */
+	    pj_status_t status;
+	    const void *p_hdr;
+	    const pjmedia_rtp_hdr *hdr;
+	    pj_ssize_t size;
+	    int hdrlen;
+
+	    /* Format RTP header */
+	    status = pjmedia_rtp_encode_rtp( &strm->out_sess, strm->si.tx_pt,
+					     0, /* marker bit */
+					     strm->bytes_per_frame, 
+					     strm->samples_per_frame,
+					     &p_hdr, &hdrlen);
+	    if (status == PJ_SUCCESS) {
+
+		//PJ_LOG(4,(THIS_FILE, "\t\tTx seq=%d", pj_ntohs(hdr->seq)));
+		
+		hdr = (const pjmedia_rtp_hdr*) p_hdr;
+
+		/* Copy RTP header to packet */
+		pj_memcpy(packet, hdr, hdrlen);
+
+		/* Zero the payload */
+		pj_bzero(packet+hdrlen, strm->bytes_per_frame);
+
+		/* Send RTP packet */
+		size = hdrlen + strm->bytes_per_frame;
+		status = pjmedia_transport_send_rtp(strm->transport, 
+						    packet, size);
+		if (status != PJ_SUCCESS)
+		    app_perror(THIS_FILE, "Error sending RTP packet", status);
+
+	    } else {
+		pj_assert(!"RTP encode() error");
+	    }
+
+	    /* Update RTCP SR */
+	    pjmedia_rtcp_tx_rtp( &strm->rtcp, (pj_uint16_t)strm->bytes_per_frame);
+
+	    /* Schedule next send */
+	    next_rtp.u64 += (msec_interval * freq.u64 / 1000);
+	}
+
+
+	if (send_rtcp || next_rtcp.u64 <= now.u64) {
+	    /*
+	     * Time to send RTCP packet.
+	     */
+	    void *rtcp_pkt;
+	    int rtcp_len;
+	    pj_ssize_t size;
+	    pj_status_t status;
+
+	    /* Build RTCP packet */
+	    pjmedia_rtcp_build_rtcp(&strm->rtcp, &rtcp_pkt, &rtcp_len);
+
+    
+	    /* Send packet */
+	    size = rtcp_len;
+	    status = pjmedia_transport_send_rtcp(strm->transport,
+						 rtcp_pkt, size);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Error sending RTCP packet", status);
+	    }
+	    
+	    /* Schedule next send */
+    	    next_rtcp.u64 += (freq.u64 * (RTCP_INTERVAL+(pj_rand()%RTCP_RAND)) /
+			      1000);
+	}
+    }
+
+    return 0;
+}
+
+
+/* Callback to be called when SDP negotiation is done in the call: */
+static void call_on_media_update( pjsip_inv_session *inv,
+				  pj_status_t status)
+{
+    struct call *call;
+    pj_pool_t *pool;
+    struct media_stream *audio;
+    const pjmedia_sdp_session *local_sdp, *remote_sdp;
+    struct codec *codec_desc = NULL;
+    unsigned i;
+
+    call = inv->mod_data[mod_siprtp.id];
+    pool = inv->dlg->pool;
+    audio = &call->media[0];
+
+    /* If this is a mid-call media update, then destroy existing media */
+    if (audio->thread != NULL)
+	destroy_call_media(call->index);
+
+
+    /* Do nothing if media negotiation has failed */
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "SDP negotiation failed", status);
+	return;
+    }
+
+    
+    /* Capture stream definition from the SDP */
+    pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp);
+    pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
+
+    status = pjmedia_stream_info_from_sdp(&audio->si, inv->pool, app.med_endpt,
+					  local_sdp, remote_sdp, 0);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error creating stream info from SDP", status);
+	return;
+    }
+
+    /* Get the remainder of codec information from codec descriptor */
+    if (audio->si.fmt.pt == app.audio_codec.pt)
+	codec_desc = &app.audio_codec;
+    else {
+	/* Find the codec description in codec array */
+	for (i=0; i<PJ_ARRAY_SIZE(audio_codecs); ++i) {
+	    if (audio_codecs[i].pt == audio->si.fmt.pt) {
+		codec_desc = &audio_codecs[i];
+		break;
+	    }
+	}
+
+	if (codec_desc == NULL) {
+	    PJ_LOG(3, (THIS_FILE, "Error: Invalid codec payload type"));
+	    return;
+	}
+    }
+
+    audio->clock_rate = audio->si.fmt.clock_rate;
+    audio->samples_per_frame = audio->clock_rate * codec_desc->ptime / 1000;
+    audio->bytes_per_frame = codec_desc->bit_rate * codec_desc->ptime / 1000 / 8;
+
+
+    pjmedia_rtp_session_init(&audio->out_sess, audio->si.tx_pt, 
+			     pj_rand());
+    pjmedia_rtp_session_init(&audio->in_sess, audio->si.fmt.pt, 0);
+    pjmedia_rtcp_init(&audio->rtcp, "rtcp", audio->clock_rate, 
+		      audio->samples_per_frame, 0);
+
+
+    /* Attach media to transport */
+    status = pjmedia_transport_attach(audio->transport, audio, 
+				      &audio->si.rem_addr, 
+				      &audio->si.rem_rtcp, 
+				      sizeof(pj_sockaddr_in),
+				      &on_rx_rtp,
+				      &on_rx_rtcp);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error on pjmedia_transport_attach()", status);
+	return;
+    }
+
+    /* Start media thread. */
+    audio->thread_quit_flag = 0;
+#if PJ_HAS_THREADS
+    status = pj_thread_create( inv->pool, "media", &media_thread, audio,
+			       0, 0, &audio->thread);
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error creating media thread", status);
+	return;
+    }
+#endif
+
+    /* Set the media as active */
+    audio->active = PJ_TRUE;
+}
+
+
+
+/* Destroy call's media */
+static void destroy_call_media(unsigned call_index)
+{
+    struct media_stream *audio = &app.call[call_index].media[0];
+
+    if (audio) {
+	audio->active = PJ_FALSE;
+
+	if (audio->thread) {
+	    audio->thread_quit_flag = 1;
+	    pj_thread_join(audio->thread);
+	    pj_thread_destroy(audio->thread);
+	    audio->thread = NULL;
+	    audio->thread_quit_flag = 0;
+	}
+
+	pjmedia_transport_detach(audio->transport, audio);
+    }
+}
+
+ 
+/*****************************************************************************
+ * USER INTERFACE STUFFS
+ */
+
+static void call_get_duration(int call_index, pj_time_val *dur)
+{
+    struct call *call = &app.call[call_index];
+    pjsip_inv_session *inv;
+
+    dur->sec = dur->msec = 0;
+
+    if (!call)
+	return;
+
+    inv = call->inv;
+    if (!inv)
+	return;
+
+    if (inv->state >= PJSIP_INV_STATE_CONFIRMED && call->connect_time.sec) {
+
+	pj_gettimeofday(dur);
+	PJ_TIME_VAL_SUB((*dur), call->connect_time);
+    }
+}
+
+
+static const char *good_number(char *buf, pj_int32_t val)
+{
+    if (val < 1000) {
+	pj_ansi_sprintf(buf, "%d", val);
+    } else if (val < 1000000) {
+	pj_ansi_sprintf(buf, "%d.%02dK", 
+			val / 1000,
+			(val % 1000) / 100);
+    } else {
+	pj_ansi_sprintf(buf, "%d.%02dM", 
+			val / 1000000,
+			(val % 1000000) / 10000);
+    }
+
+    return buf;
+}
+
+
+
+static void print_avg_stat(void)
+{
+#define MIN_(var,val)	   if ((int)val < (int)var) var = val
+#define MAX_(var,val)	   if ((int)val > (int)var) var = val
+#define AVG_(var,val)	   var = ( ((var * count) + val) / (count+1) )
+#define BIGVAL		    0x7FFFFFFFL
+    struct stat_entry
+    {
+	int min, avg, max;
+    };
+
+    struct stat_entry call_dur, call_pdd;
+    pjmedia_rtcp_stat min_stat, avg_stat, max_stat;
+
+    char srx_min[16], srx_avg[16], srx_max[16];
+    char brx_min[16], brx_avg[16], brx_max[16];
+    char stx_min[16], stx_avg[16], stx_max[16];
+    char btx_min[16], btx_avg[16], btx_max[16];
+
+
+    unsigned i, count;
+
+    pj_bzero(&call_dur, sizeof(call_dur)); 
+    call_dur.min = BIGVAL;
+
+    pj_bzero(&call_pdd, sizeof(call_pdd)); 
+    call_pdd.min = BIGVAL;
+
+    pj_bzero(&min_stat, sizeof(min_stat));
+    min_stat.rx.pkt = min_stat.tx.pkt = BIGVAL;
+    min_stat.rx.bytes = min_stat.tx.bytes = BIGVAL;
+    min_stat.rx.loss = min_stat.tx.loss = BIGVAL;
+    min_stat.rx.dup = min_stat.tx.dup = BIGVAL;
+    min_stat.rx.reorder = min_stat.tx.reorder = BIGVAL;
+    min_stat.rx.jitter.min = min_stat.tx.jitter.min = BIGVAL;
+    min_stat.rtt.min = BIGVAL;
+
+    pj_bzero(&avg_stat, sizeof(avg_stat));
+    pj_bzero(&max_stat, sizeof(max_stat));
+
+
+    for (i=0, count=0; i<app.max_calls; ++i) {
+
+	struct call *call = &app.call[i];
+	struct media_stream *audio = &call->media[0];
+	pj_time_val dur;
+	unsigned msec_dur;
+
+	if (call->inv == NULL || 
+	    call->inv->state < PJSIP_INV_STATE_CONFIRMED ||
+	    call->connect_time.sec == 0) 
+	{
+	    continue;
+	}
+
+	/* Duration */
+	call_get_duration(i, &dur);
+	msec_dur = PJ_TIME_VAL_MSEC(dur);
+
+	MIN_(call_dur.min, msec_dur);
+	MAX_(call_dur.max, msec_dur);
+	AVG_(call_dur.avg, msec_dur);
+
+	/* Connect delay */
+	if (call->connect_time.sec) {
+	    pj_time_val t = call->connect_time;
+	    PJ_TIME_VAL_SUB(t, call->start_time);
+	    msec_dur = PJ_TIME_VAL_MSEC(t);
+	} else {
+	    msec_dur = 10;
+	}
+
+	MIN_(call_pdd.min, msec_dur);
+	MAX_(call_pdd.max, msec_dur);
+	AVG_(call_pdd.avg, msec_dur);
+
+	/* RX Statistisc: */
+
+	/* Packets */
+	MIN_(min_stat.rx.pkt, audio->rtcp.stat.rx.pkt);
+	MAX_(max_stat.rx.pkt, audio->rtcp.stat.rx.pkt);
+	AVG_(avg_stat.rx.pkt, audio->rtcp.stat.rx.pkt);
+
+	/* Bytes */
+	MIN_(min_stat.rx.bytes, audio->rtcp.stat.rx.bytes);
+	MAX_(max_stat.rx.bytes, audio->rtcp.stat.rx.bytes);
+	AVG_(avg_stat.rx.bytes, audio->rtcp.stat.rx.bytes);
+
+
+	/* Packet loss */
+	MIN_(min_stat.rx.loss, audio->rtcp.stat.rx.loss);
+	MAX_(max_stat.rx.loss, audio->rtcp.stat.rx.loss);
+	AVG_(avg_stat.rx.loss, audio->rtcp.stat.rx.loss);
+
+	/* Packet dup */
+	MIN_(min_stat.rx.dup, audio->rtcp.stat.rx.dup);
+	MAX_(max_stat.rx.dup, audio->rtcp.stat.rx.dup);
+	AVG_(avg_stat.rx.dup, audio->rtcp.stat.rx.dup);
+
+	/* Packet reorder */
+	MIN_(min_stat.rx.reorder, audio->rtcp.stat.rx.reorder);
+	MAX_(max_stat.rx.reorder, audio->rtcp.stat.rx.reorder);
+	AVG_(avg_stat.rx.reorder, audio->rtcp.stat.rx.reorder);
+
+	/* Jitter  */
+	MIN_(min_stat.rx.jitter.min, audio->rtcp.stat.rx.jitter.min);
+	MAX_(max_stat.rx.jitter.max, audio->rtcp.stat.rx.jitter.max);
+	AVG_(avg_stat.rx.jitter.mean, audio->rtcp.stat.rx.jitter.mean);
+
+
+	/* TX Statistisc: */
+
+	/* Packets */
+	MIN_(min_stat.tx.pkt, audio->rtcp.stat.tx.pkt);
+	MAX_(max_stat.tx.pkt, audio->rtcp.stat.tx.pkt);
+	AVG_(avg_stat.tx.pkt, audio->rtcp.stat.tx.pkt);
+
+	/* Bytes */
+	MIN_(min_stat.tx.bytes, audio->rtcp.stat.tx.bytes);
+	MAX_(max_stat.tx.bytes, audio->rtcp.stat.tx.bytes);
+	AVG_(avg_stat.tx.bytes, audio->rtcp.stat.tx.bytes);
+
+	/* Packet loss */
+	MIN_(min_stat.tx.loss, audio->rtcp.stat.tx.loss);
+	MAX_(max_stat.tx.loss, audio->rtcp.stat.tx.loss);
+	AVG_(avg_stat.tx.loss, audio->rtcp.stat.tx.loss);
+
+	/* Packet dup */
+	MIN_(min_stat.tx.dup, audio->rtcp.stat.tx.dup);
+	MAX_(max_stat.tx.dup, audio->rtcp.stat.tx.dup);
+	AVG_(avg_stat.tx.dup, audio->rtcp.stat.tx.dup);
+
+	/* Packet reorder */
+	MIN_(min_stat.tx.reorder, audio->rtcp.stat.tx.reorder);
+	MAX_(max_stat.tx.reorder, audio->rtcp.stat.tx.reorder);
+	AVG_(avg_stat.tx.reorder, audio->rtcp.stat.tx.reorder);
+
+	/* Jitter  */
+	MIN_(min_stat.tx.jitter.min, audio->rtcp.stat.tx.jitter.min);
+	MAX_(max_stat.tx.jitter.max, audio->rtcp.stat.tx.jitter.max);
+	AVG_(avg_stat.tx.jitter.mean, audio->rtcp.stat.tx.jitter.mean);
+
+
+	/* RTT */
+	MIN_(min_stat.rtt.min, audio->rtcp.stat.rtt.min);
+	MAX_(max_stat.rtt.max, audio->rtcp.stat.rtt.max);
+	AVG_(avg_stat.rtt.mean, audio->rtcp.stat.rtt.mean);
+
+	++count;
+    }
+
+    if (count == 0) {
+	puts("No active calls");
+	return;
+    }
+
+    printf("Total %d call(s) active.\n"
+	   "                    Average Statistics\n"
+	   "                    min     avg     max \n"
+	   "                -----------------------\n"
+	   " call duration: %7d %7d %7d %s\n"
+	   " connect delay: %7d %7d %7d %s\n"
+	   " RX stat:\n"
+	   "       packets: %7s %7s %7s %s\n"
+	   "       payload: %7s %7s %7s %s\n"
+	   "          loss: %7d %7d %7d %s\n"
+	   "  percent loss: %7.3f %7.3f %7.3f %s\n"
+	   "           dup: %7d %7d %7d %s\n"
+	   "       reorder: %7d %7d %7d %s\n"
+	   "        jitter: %7.3f %7.3f %7.3f %s\n"
+	   " TX stat:\n"
+	   "       packets: %7s %7s %7s %s\n"
+	   "       payload: %7s %7s %7s %s\n"
+	   "          loss: %7d %7d %7d %s\n"
+	   "  percent loss: %7.3f %7.3f %7.3f %s\n"
+	   "           dup: %7d %7d %7d %s\n"
+	   "       reorder: %7d %7d %7d %s\n"
+	   "        jitter: %7.3f %7.3f %7.3f %s\n"
+	   " RTT          : %7.3f %7.3f %7.3f %s\n"
+	   ,
+	   count,
+	   call_dur.min/1000, call_dur.avg/1000, call_dur.max/1000, 
+	   "seconds",
+
+	   call_pdd.min, call_pdd.avg, call_pdd.max, 
+	   "ms",
+
+	   /* rx */
+
+	   good_number(srx_min, min_stat.rx.pkt),
+	   good_number(srx_avg, avg_stat.rx.pkt),
+	   good_number(srx_max, max_stat.rx.pkt),
+	   "packets",
+
+	   good_number(brx_min, min_stat.rx.bytes),
+	   good_number(brx_avg, avg_stat.rx.bytes),
+	   good_number(brx_max, max_stat.rx.bytes),
+	   "bytes",
+
+	   min_stat.rx.loss, avg_stat.rx.loss, max_stat.rx.loss,
+	   "packets",
+	   
+	   min_stat.rx.loss*100.0/(min_stat.rx.pkt+min_stat.rx.loss),
+	   avg_stat.rx.loss*100.0/(avg_stat.rx.pkt+avg_stat.rx.loss),
+	   max_stat.rx.loss*100.0/(max_stat.rx.pkt+max_stat.rx.loss),
+	   "%",
+
+
+	   min_stat.rx.dup, avg_stat.rx.dup, max_stat.rx.dup,
+	   "packets",
+
+	   min_stat.rx.reorder, avg_stat.rx.reorder, max_stat.rx.reorder,
+	   "packets",
+
+	   min_stat.rx.jitter.min/1000.0, 
+	   avg_stat.rx.jitter.mean/1000.0, 
+	   max_stat.rx.jitter.max/1000.0,
+	   "ms",
+	
+	   /* tx */
+
+	   good_number(stx_min, min_stat.tx.pkt),
+	   good_number(stx_avg, avg_stat.tx.pkt),
+	   good_number(stx_max, max_stat.tx.pkt),
+	   "packets",
+
+	   good_number(btx_min, min_stat.tx.bytes),
+	   good_number(btx_avg, avg_stat.tx.bytes),
+	   good_number(btx_max, max_stat.tx.bytes),
+	   "bytes",
+
+	   min_stat.tx.loss, avg_stat.tx.loss, max_stat.tx.loss,
+	   "packets",
+	   
+	   min_stat.tx.loss*100.0/(min_stat.tx.pkt+min_stat.tx.loss),
+	   avg_stat.tx.loss*100.0/(avg_stat.tx.pkt+avg_stat.tx.loss),
+	   max_stat.tx.loss*100.0/(max_stat.tx.pkt+max_stat.tx.loss),
+	   "%",
+
+	   min_stat.tx.dup, avg_stat.tx.dup, max_stat.tx.dup,
+	   "packets",
+
+	   min_stat.tx.reorder, avg_stat.tx.reorder, max_stat.tx.reorder,
+	   "packets",
+
+	   min_stat.tx.jitter.min/1000.0, 
+	   avg_stat.tx.jitter.mean/1000.0, 
+	   max_stat.tx.jitter.max/1000.0,
+	   "ms",
+
+	   /* rtt */
+	   min_stat.rtt.min/1000.0, 
+	   avg_stat.rtt.mean/1000.0, 
+	   max_stat.rtt.max/1000.0,
+	   "ms"
+	   );
+
+}
+
+
+#include "siprtp_report.c"
+
+
+static void list_calls()
+{
+    unsigned i;
+    puts("List all calls:");
+    for (i=0; i<app.max_calls; ++i) {
+	if (!app.call[i].inv)
+	    continue;
+	print_call(i);
+    }
+}
+
+static void hangup_call(unsigned index)
+{
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+    if (app.call[index].inv == NULL)
+	return;
+
+    status = pjsip_inv_end_session(app.call[index].inv, 603, NULL, &tdata);
+    if (status==PJ_SUCCESS && tdata!=NULL)
+	pjsip_inv_send_msg(app.call[index].inv, tdata);
+}
+
+static void hangup_all_calls()
+{
+    unsigned i;
+    for (i=0; i<app.max_calls; ++i) {
+	if (!app.call[i].inv)
+	    continue;
+	hangup_call(i);
+	pj_thread_sleep(app.call_gap);
+    }
+    
+    /* Wait until all calls are terminated */
+    for (i=0; i<app.max_calls; ++i) {
+	while (app.call[i].inv)
+	    pj_thread_sleep(10);
+    }
+}
+
+static pj_bool_t simple_input(const char *title, char *buf, pj_size_t len)
+{
+    char *p;
+
+    printf("%s (empty to cancel): ", title); fflush(stdout);
+    if (fgets(buf, (int)len, stdin) == NULL)
+	return PJ_FALSE;
+
+    /* Remove trailing newlines. */
+    for (p=buf; ; ++p) {
+	if (*p=='\r' || *p=='\n') *p='\0';
+	else if (!*p) break;
+    }
+
+    if (!*buf)
+	return PJ_FALSE;
+    
+    return PJ_TRUE;
+}
+
+
+static const char *MENU =
+"\n"
+"Enter menu character:\n"
+"  s    Summary\n"
+"  l    List all calls\n"
+"  h    Hangup a call\n"
+"  H    Hangup all calls\n"
+"  q    Quit\n"
+"\n";
+
+
+/* Main screen menu */
+static void console_main()
+{
+    char input1[10];
+    unsigned i;
+
+    printf("%s", MENU);
+
+    for (;;) {
+	printf(">>> "); fflush(stdout);
+	if (fgets(input1, sizeof(input1), stdin) == NULL) {
+	    puts("EOF while reading stdin, will quit now..");
+	    break;
+	}
+
+	switch (input1[0]) {
+
+	case 's':
+	    print_avg_stat();
+	    break;
+
+	case 'l':
+	    list_calls();
+	    break;
+
+	case 'h':
+	    if (!simple_input("Call number to hangup", input1, sizeof(input1)))
+		break;
+
+	    i = atoi(input1);
+	    hangup_call(i);
+	    break;
+
+	case 'H':
+	    hangup_all_calls();
+	    break;
+
+	case 'q':
+	    goto on_exit;
+
+	default:
+	    puts("Invalid command");
+	    printf("%s", MENU);
+	    break;
+	}
+
+	fflush(stdout);
+    }
+
+on_exit:
+    hangup_all_calls();
+}
+
+
+/*****************************************************************************
+ * Below is a simple module to log all incoming and outgoing SIP messages
+ */
+
+
+/* Notification on incoming messages */
+static pj_bool_t logger_on_rx_msg(pjsip_rx_data *rdata)
+{
+    PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s:%d:\n"
+			 "%s\n"
+			 "--end msg--",
+			 rdata->msg_info.len,
+			 pjsip_rx_data_get_info(rdata),
+			 rdata->pkt_info.src_name,
+			 rdata->pkt_info.src_port,
+			 rdata->msg_info.msg_buf));
+    
+    /* Always return false, otherwise messages will not get processed! */
+    return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logger_on_tx_msg(pjsip_tx_data *tdata)
+{
+    
+    /* Important note:
+     *	tp_info field is only valid after outgoing messages has passed
+     *	transport layer. So don't try to access tp_info when the module
+     *	has lower priority than transport layer.
+     */
+
+    PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n"
+			 "%s\n"
+			 "--end msg--",
+			 (tdata->buf.cur - tdata->buf.start),
+			 pjsip_tx_data_get_info(tdata),
+			 tdata->tp_info.dst_name,
+			 tdata->tp_info.dst_port,
+			 tdata->buf.start));
+
+    /* Always return success, otherwise message will not get sent! */
+    return PJ_SUCCESS;
+}
+
+/* The module instance. */
+static pjsip_module msg_logger = 
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-siprtp-log", 14 },		/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &logger_on_rx_msg,			/* on_rx_request()	*/
+    &logger_on_rx_msg,			/* on_rx_response()	*/
+    &logger_on_tx_msg,			/* on_tx_request.	*/
+    &logger_on_tx_msg,			/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
+
+
+/*****************************************************************************
+ * Console application custom logging:
+ */
+
+
+static FILE *log_file;
+
+
+static void app_log_writer(int level, const char *buffer, int len)
+{
+    /* Write to both stdout and file. */
+
+    if (level <= app.app_log_level)
+	pj_log_write(level, buffer, len);
+
+    if (log_file) {
+	pj_size_t count = fwrite(buffer, len, 1, log_file);
+	PJ_UNUSED_ARG(count);
+	fflush(log_file);
+    }
+}
+
+
+pj_status_t app_logging_init(void)
+{
+    /* Redirect log function to ours */
+
+    pj_log_set_log_func( &app_log_writer );
+
+    /* If output log file is desired, create the file: */
+
+    if (app.log_filename) {
+	log_file = fopen(app.log_filename, "wt");
+	if (log_file == NULL) {
+	    PJ_LOG(1,(THIS_FILE, "Unable to open log file %s", 
+		      app.log_filename));   
+	    return -1;
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+void app_logging_shutdown(void)
+{
+    /* Close logging file, if any: */
+
+    if (log_file) {
+	fclose(log_file);
+	log_file = NULL;
+    }
+}
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    unsigned i;
+    pj_status_t status;
+
+    /* Must init PJLIB first */
+    status = pj_init();
+    if (status != PJ_SUCCESS)
+	return 1;
+
+    /* Get command line options */
+    status = init_options(argc, argv);
+    if (status != PJ_SUCCESS)
+	return 1;
+
+    /* Verify options: */
+
+    /* Auto-quit can not be specified for UAS */
+    if (app.auto_quit && app.uri_to_call.slen == 0) {
+	printf("Error: --auto-quit option only valid for outgoing "
+	       "mode (UAC) only\n");
+	return 1;
+    }
+
+    /* Init logging */
+    status = app_logging_init();
+    if (status != PJ_SUCCESS)
+	return 1;
+
+    /* Init SIP etc */
+    status = init_sip();
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Initialization has failed", status);
+	destroy_sip();
+	return 1;
+    }
+
+    /* Register module to log incoming/outgoing messages */
+    pjsip_endpt_register_module(app.sip_endpt, &msg_logger);
+
+    /* Init media */
+    status = init_media();
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Media initialization failed", status);
+	destroy_sip();
+	return 1;
+    }
+
+    /* Start worker threads */
+#if PJ_HAS_THREADS
+    for (i=0; i<app.thread_count; ++i) {
+	pj_thread_create( app.pool, "app", &sip_worker_thread, NULL,
+			  0, 0, &app.sip_thread[i]);
+    }
+#endif
+
+    /* If URL is specified, then make call immediately */
+    if (app.uri_to_call.slen) {
+	unsigned i;
+
+	PJ_LOG(3,(THIS_FILE, "Making %d calls to %s..", app.max_calls,
+		  app.uri_to_call.ptr));
+
+	for (i=0; i<app.max_calls; ++i) {
+	    status = make_call(&app.uri_to_call);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Error making call", status);
+		break;
+	    }
+	    pj_thread_sleep(app.call_gap);
+	}
+
+	if (app.auto_quit) {
+	    /* Wait for calls to complete */
+	    while (app.uac_calls < app.max_calls)
+		pj_thread_sleep(100);
+	    pj_thread_sleep(200);
+	} else {
+#if PJ_HAS_THREADS
+	    /* Start user interface loop */
+	    console_main();
+#endif
+	}
+
+    } else {
+
+	PJ_LOG(3,(THIS_FILE, "Ready for incoming calls (max=%d)", 
+		  app.max_calls));
+
+#if PJ_HAS_THREADS
+	/* Start user interface loop */
+	console_main();
+#endif
+    }
+
+#if !PJ_HAS_THREADS
+    PJ_LOG(3,(THIS_FILE, "Press Ctrl-C to quit"));
+    for (;;) {
+	pj_time_val t = {0, 10};
+	pjsip_endpt_handle_events(app.sip_endpt, &t);
+    }
+#endif
+    
+    /* Shutting down... */
+    destroy_sip();
+    destroy_media();
+
+    if (app.pool) {
+	pj_pool_release(app.pool);
+	app.pool = NULL;
+	pj_caching_pool_destroy(&app.cp);
+    }
+
+    app_logging_shutdown();
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/siprtp_report.c b/jni/libpjsip/sources/pjsip-apps/src/samples/siprtp_report.c
new file mode 100644
index 0000000..6643f9d
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/siprtp_report.c
@@ -0,0 +1,231 @@
+/* $Id: siprtp_report.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+/*
+ * DO NOT COMPILE THIS FILE ON ITS OWN!
+ *
+ * This file is included by siprtp.c to implement the reporting capability
+ * to a separate file, so that user can implement different reporting
+ * functionality (such as writing to XML file).
+ */
+
+
+static void print_call(int call_index)
+{
+    struct call *call = &app.call[call_index];
+    int len;
+    pjsip_inv_session *inv = call->inv;
+    pjsip_dialog *dlg = inv->dlg;
+    struct media_stream *audio = &call->media[0];
+    char userinfo[128];
+    char duration[80], last_update[80];
+    char bps[16], ipbps[16], packets[16], bytes[16], ipbytes[16];
+    unsigned decor;
+    pj_time_val now;
+
+
+    decor = pj_log_get_decor();
+    pj_log_set_decor(PJ_LOG_HAS_NEWLINE);
+
+    pj_gettimeofday(&now);
+
+    if (app.report_filename)
+	puts(app.report_filename);
+
+    /* Print duration */
+    if (inv->state >= PJSIP_INV_STATE_CONFIRMED && call->connect_time.sec) {
+
+	PJ_TIME_VAL_SUB(now, call->connect_time);
+
+	sprintf(duration, " [duration: %02ld:%02ld:%02ld.%03ld]",
+		now.sec / 3600,
+		(now.sec % 3600) / 60,
+		(now.sec % 60),
+		now.msec);
+
+    } else {
+	duration[0] = '\0';
+    }
+
+
+
+    /* Call number and state */
+    PJ_LOG(3, (THIS_FILE,
+	      "Call #%d: %s%s", 
+	      call_index, pjsip_inv_state_name(inv->state), 
+	      duration));
+
+
+
+    /* Call identification */
+    len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));
+    if (len < 0)
+	pj_ansi_strcpy(userinfo, "<--uri too long-->");
+    else
+	userinfo[len] = '\0';
+
+    PJ_LOG(3, (THIS_FILE, "   %s", userinfo));
+
+
+    if (call->inv == NULL || call->inv->state < PJSIP_INV_STATE_CONFIRMED ||
+	call->connect_time.sec == 0) 
+    {
+	pj_log_set_decor(decor);
+	return;
+    }
+
+
+    /* Signaling quality */
+    {
+	char pdd[64], connectdelay[64];
+	pj_time_val t;
+
+	if (call->response_time.sec) {
+	    t = call->response_time;
+	    PJ_TIME_VAL_SUB(t, call->start_time);
+	    sprintf(pdd, "got 1st response in %ld ms", PJ_TIME_VAL_MSEC(t));
+	} else {
+	    pdd[0] = '\0';
+	}
+
+	if (call->connect_time.sec) {
+	    t = call->connect_time;
+	    PJ_TIME_VAL_SUB(t, call->start_time);
+	    sprintf(connectdelay, ", connected after: %ld ms", 
+		    PJ_TIME_VAL_MSEC(t));
+	} else {
+	    connectdelay[0] = '\0';
+	}
+
+	PJ_LOG(3, (THIS_FILE, 
+		   "   Signaling quality: %s%s", pdd, connectdelay));
+    }
+
+
+    PJ_LOG(3, (THIS_FILE,
+	       "   Stream #0: audio %.*s@%dHz, %dms/frame, %sB/s (%sB/s +IP hdr)",
+   	(int)audio->si.fmt.encoding_name.slen,
+	audio->si.fmt.encoding_name.ptr,
+	audio->clock_rate,
+	audio->samples_per_frame * 1000 / audio->clock_rate,
+	good_number(bps, audio->bytes_per_frame * audio->clock_rate / audio->samples_per_frame),
+	good_number(ipbps, (audio->bytes_per_frame+32) * audio->clock_rate / audio->samples_per_frame)));
+
+    if (audio->rtcp.stat.rx.update_cnt == 0)
+	strcpy(last_update, "never");
+    else {
+	pj_gettimeofday(&now);
+	PJ_TIME_VAL_SUB(now, audio->rtcp.stat.rx.update);
+	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		now.sec / 3600,
+		(now.sec % 3600) / 60,
+		now.sec % 60,
+		now.msec);
+    }
+
+    PJ_LOG(3, (THIS_FILE, 
+	   "              RX stat last update: %s\n"
+	   "                 total %s packets %sB received (%sB +IP hdr)%s\n"
+	   "                 pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
+	   "                       (msec)    min     avg     max     last\n"
+	   "                 loss period: %7.3f %7.3f %7.3f %7.3f%s\n"
+	   "                 jitter     : %7.3f %7.3f %7.3f %7.3f%s",
+	   last_update,
+	   good_number(packets, audio->rtcp.stat.rx.pkt),
+	   good_number(bytes, audio->rtcp.stat.rx.bytes),
+	   good_number(ipbytes, audio->rtcp.stat.rx.bytes + audio->rtcp.stat.rx.pkt * 32),
+	   "",
+	   audio->rtcp.stat.rx.loss,
+	   audio->rtcp.stat.rx.loss * 100.0 / (audio->rtcp.stat.rx.pkt + audio->rtcp.stat.rx.loss),
+	   audio->rtcp.stat.rx.dup, 
+	   audio->rtcp.stat.rx.dup * 100.0 / (audio->rtcp.stat.rx.pkt + audio->rtcp.stat.rx.loss),
+	   audio->rtcp.stat.rx.reorder, 
+	   audio->rtcp.stat.rx.reorder * 100.0 / (audio->rtcp.stat.rx.pkt + audio->rtcp.stat.rx.loss),
+	   "",
+	   audio->rtcp.stat.rx.loss_period.min / 1000.0, 
+	   audio->rtcp.stat.rx.loss_period.mean / 1000.0, 
+	   audio->rtcp.stat.rx.loss_period.max / 1000.0,
+	   audio->rtcp.stat.rx.loss_period.last / 1000.0,
+	   "",
+	   audio->rtcp.stat.rx.jitter.min / 1000.0,
+	   audio->rtcp.stat.rx.jitter.mean / 1000.0,
+	   audio->rtcp.stat.rx.jitter.max / 1000.0,
+	   audio->rtcp.stat.rx.jitter.last / 1000.0,
+	   ""
+	   ));
+
+
+    if (audio->rtcp.stat.tx.update_cnt == 0)
+	strcpy(last_update, "never");
+    else {
+	pj_gettimeofday(&now);
+	PJ_TIME_VAL_SUB(now, audio->rtcp.stat.tx.update);
+	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		now.sec / 3600,
+		(now.sec % 3600) / 60,
+		now.sec % 60,
+		now.msec);
+    }
+
+    PJ_LOG(3, (THIS_FILE,
+	   "              TX stat last update: %s\n"
+	   "                 total %s packets %sB sent (%sB +IP hdr)%s\n"
+	   "                 pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
+	   "                       (msec)    min     avg     max     last\n"
+	   "                 loss period: %7.3f %7.3f %7.3f %7.3f%s\n"
+	   "                 jitter     : %7.3f %7.3f %7.3f %7.3f%s",
+	   last_update,
+	   good_number(packets, audio->rtcp.stat.tx.pkt),
+	   good_number(bytes, audio->rtcp.stat.tx.bytes),
+	   good_number(ipbytes, audio->rtcp.stat.tx.bytes + audio->rtcp.stat.tx.pkt * 32),
+	   "",
+	   audio->rtcp.stat.tx.loss,
+	   audio->rtcp.stat.tx.loss * 100.0 / (audio->rtcp.stat.tx.pkt + audio->rtcp.stat.tx.loss),
+	   audio->rtcp.stat.tx.dup, 
+	   audio->rtcp.stat.tx.dup * 100.0 / (audio->rtcp.stat.tx.pkt + audio->rtcp.stat.tx.loss),
+	   audio->rtcp.stat.tx.reorder, 
+	   audio->rtcp.stat.tx.reorder * 100.0 / (audio->rtcp.stat.tx.pkt + audio->rtcp.stat.tx.loss),
+	   "",
+	   audio->rtcp.stat.tx.loss_period.min / 1000.0, 
+	   audio->rtcp.stat.tx.loss_period.mean / 1000.0, 
+	   audio->rtcp.stat.tx.loss_period.max / 1000.0,
+	   audio->rtcp.stat.tx.loss_period.last / 1000.0,
+	   "",
+	   audio->rtcp.stat.tx.jitter.min / 1000.0,
+	   audio->rtcp.stat.tx.jitter.mean / 1000.0,
+	   audio->rtcp.stat.tx.jitter.max / 1000.0,
+	   audio->rtcp.stat.tx.jitter.last / 1000.0,
+	   ""
+	   ));
+
+
+    PJ_LOG(3, (THIS_FILE,
+	   "             RTT delay      : %7.3f %7.3f %7.3f %7.3f%s\n", 
+	   audio->rtcp.stat.rtt.min / 1000.0,
+	   audio->rtcp.stat.rtt.mean / 1000.0,
+	   audio->rtcp.stat.rtt.max / 1000.0,
+	   audio->rtcp.stat.rtt.last / 1000.0,
+	   ""
+	   ));
+
+    pj_log_set_decor(decor);
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/sipstateless.c b/jni/libpjsip/sources/pjsip-apps/src/samples/sipstateless.c
new file mode 100644
index 0000000..0de89a6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/sipstateless.c
@@ -0,0 +1,243 @@
+/* $Id: sipstateless.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/**
+ * sipcore.c
+ *
+ * A simple program to respond any incoming requests (except ACK, of course!)
+ * with any status code (taken from command line argument, with the default
+ * is 501/Not Implemented).
+ */
+
+
+/* Include all headers. */
+#include <pjsip.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+
+/* If this macro is set, UDP transport will be initialized at port 5060 */
+#define HAS_UDP_TRANSPORT
+
+/* If this macro is set, TCP transport will be initialized at port 5060 */
+#define HAS_TCP_TRANSPORT   (1 && PJ_HAS_TCP)
+
+/* Log identification */
+#define THIS_FILE	"sipstateless.c"
+
+
+/* Global SIP endpoint */
+static pjsip_endpoint *sip_endpt;
+
+/* What response code to be sent (default is 501/Not Implemented) */
+static int code = PJSIP_SC_NOT_IMPLEMENTED;
+
+/* Additional header list */
+struct pjsip_hdr hdr_list;
+
+/* usage() */
+static void usage(void)
+{
+    puts("Usage:");
+    puts("  sipstateless [code] [-H HDR] ..");
+    puts("");
+    puts("Options:");
+    puts("  code     SIP status code to send (default: 501/Not Implemented");
+    puts("  -H HDR   Specify additional headers to send with response");
+    puts("           This option may be specified more than once.");
+    puts("           Example:");
+    puts("              -H 'Expires: 300' -H 'Contact: <sip:localhost>'"); 
+}
+
+
+/* Callback to handle incoming requests. */
+static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
+{
+    /* Respond (statelessly) all incoming requests (except ACK!) 
+     * with 501 (Not Implemented)
+     */
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
+	pjsip_endpt_respond_stateless( sip_endpt, rdata, 
+				       code, NULL,
+				       &hdr_list, NULL);
+    }
+    return PJ_TRUE;
+}
+
+
+
+/*
+ * main()
+ *
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pj_pool_t *pool = NULL;
+    pjsip_module mod_app =
+    {
+	NULL, NULL,		    /* prev, next.		*/
+	{ "mod-app", 7 },	    /* Name.			*/
+	-1,				    /* Id		*/
+	PJSIP_MOD_PRIORITY_APPLICATION, /* Priority		*/
+	NULL,			    /* load()			*/
+	NULL,			    /* start()			*/
+	NULL,			    /* stop()			*/
+	NULL,			    /* unload()			*/
+	&on_rx_request,		    /* on_rx_request()		*/
+	NULL,			    /* on_rx_response()		*/
+	NULL,			    /* on_tx_request.		*/
+	NULL,			    /* on_tx_response()		*/
+	NULL,			    /* on_tsx_state()		*/
+    };
+    int c;
+    pj_status_t status;
+    
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Then init PJLIB-UTIL: */
+    status = pjlib_util_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* Create global endpoint: */
+    {
+	/* Endpoint MUST be assigned a globally unique name.
+	 * Ideally we should put hostname or public IP address, but
+	 * we'll just use an arbitrary name here.
+	 */
+
+	/* Create the endpoint: */
+	status = pjsip_endpt_create(&cp.factory, "sipstateless", 
+				    &sip_endpt);
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    }
+
+    /* Parse arguments */
+    pj_optind = 0;
+    pj_list_init(&hdr_list);
+    while ((c=pj_getopt(argc, argv , "H:")) != -1) {
+	switch (c) {
+	case 'H':
+	    if (pool == NULL) {
+		pool = pj_pool_create(&cp.factory, "sipstateless", 1000, 
+				      1000, NULL);
+	    } 
+	    
+	    if (pool) {
+		char *name;
+		name = strtok(pj_optarg, ":");
+		if (name == NULL) {
+		    puts("Error: invalid header format");
+		    return 1;
+		} else {
+		    char *val = strtok(NULL, "\r\n");
+		    pjsip_generic_string_hdr *h;
+		    pj_str_t hname, hvalue;
+
+		    hname = pj_str(name);
+		    hvalue = pj_str(val);
+
+		    h = pjsip_generic_string_hdr_create(pool, &hname, &hvalue);
+
+		    pj_list_push_back(&hdr_list, h);
+
+		    PJ_LOG(4,(THIS_FILE, "Header %s: %s added", name, val));
+		}
+	    }
+	    break;
+	default:
+	    puts("Error: invalid argument");
+	    usage();
+	    return 1;
+	}
+    }
+
+    if (pj_optind != argc) {
+	code = atoi(argv[pj_optind]);
+	if (code < 200 || code > 699) {
+	    puts("Error: invalid status code");
+	    usage();
+	    return 1;
+	}
+    }
+
+    PJ_LOG(4,(THIS_FILE, "Returning %d to incoming requests", code));
+
+
+    /* 
+     * Add UDP transport, with hard-coded port 
+     */
+#ifdef HAS_UDP_TRANSPORT
+    {
+	pj_sockaddr_in addr;
+
+	addr.sin_family = pj_AF_INET();
+	addr.sin_addr.s_addr = 0;
+	addr.sin_port = pj_htons(5060);
+
+	status = pjsip_udp_transport_start( sip_endpt, &addr, NULL, 1, NULL);
+	if (status != PJ_SUCCESS) {
+	    PJ_LOG(3,(THIS_FILE, 
+		      "Error starting UDP transport (port in use?)"));
+	    return 1;
+	}
+    }
+#endif
+
+#if HAS_TCP_TRANSPORT
+    /* 
+     * Add UDP transport, with hard-coded port 
+     */
+    {
+	pj_sockaddr_in addr;
+
+	addr.sin_family = pj_AF_INET();
+	addr.sin_addr.s_addr = 0;
+	addr.sin_port = pj_htons(5060);
+
+	status = pjsip_tcp_transport_start(sip_endpt, &addr, 1, NULL);
+	if (status != PJ_SUCCESS) {
+	    PJ_LOG(3,(THIS_FILE, 
+		      "Error starting TCP transport (port in use?)"));
+	    return 1;
+	}
+    }
+#endif
+
+    /*
+     * Register our module to receive incoming requests.
+     */
+    status = pjsip_endpt_register_module( sip_endpt, &mod_app);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Done. Loop forever to handle incoming events. */
+    PJ_LOG(3,(THIS_FILE, "Press Ctrl-C to quit.."));
+
+    for (;;) {
+	pjsip_endpt_handle_events(sip_endpt, NULL);
+    }
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/stateful_proxy.c b/jni/libpjsip/sources/pjsip-apps/src/samples/stateful_proxy.c
new file mode 100644
index 0000000..0d84353
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/stateful_proxy.c
@@ -0,0 +1,587 @@
+/* $Id: stateful_proxy.c 4420 2013-03-05 11:59:54Z bennylp $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+#define THIS_FILE   "stateful_proxy.c"
+
+/* Common proxy functions */
+#define STATEFUL    1
+#include "proxy.h"
+
+
+/*
+ * mod_stateful_proxy is the module to receive SIP request and
+ * response message that is outside any transaction context.
+ */
+static pj_bool_t proxy_on_rx_request(pjsip_rx_data *rdata );
+static pj_bool_t proxy_on_rx_response(pjsip_rx_data *rdata );
+
+static pjsip_module mod_stateful_proxy =
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-stateful-proxy", 18 },	/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_UA_PROXY_LAYER,	/* Priority		*/
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &proxy_on_rx_request,		/* on_rx_request()	*/
+    &proxy_on_rx_response,		/* on_rx_response()	*/
+    NULL,				/* on_tx_request.	*/
+    NULL,				/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+};
+
+
+/*
+ * mod_tu (tu=Transaction User) is the module to receive notification
+ * from transaction when the transaction state has changed.
+ */
+static void tu_on_tsx_state(pjsip_transaction *tsx, pjsip_event *event);
+
+static pjsip_module mod_tu =
+{
+    NULL, NULL,				/* prev, next.		*/
+    { "mod-transaction-user", 20 },	/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION,	/* Priority		*/
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    NULL,				/* on_rx_request()	*/
+    NULL,				/* on_rx_response()	*/
+    NULL,				/* on_tx_request.	*/
+    NULL,				/* on_tx_response()	*/
+    &tu_on_tsx_state,			/* on_tsx_state()	*/
+};
+
+
+/* This is the data that is attached to the UAC transaction */
+struct uac_data
+{
+    pjsip_transaction	*uas_tsx;
+    pj_timer_entry	 timer;
+};
+
+
+/* This is the data that is attached to the UAS transaction */
+struct uas_data
+{
+    pjsip_transaction	*uac_tsx;
+};
+
+
+
+static pj_status_t init_stateful_proxy(void)
+{
+    pj_status_t status;
+
+    status = pjsip_endpt_register_module( global.endpt, &mod_stateful_proxy);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    status = pjsip_endpt_register_module( global.endpt, &mod_tu);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    return PJ_SUCCESS;
+}
+
+
+/* Callback to be called to handle new incoming requests. */
+static pj_bool_t proxy_on_rx_request( pjsip_rx_data *rdata )
+{
+    pjsip_transaction *uas_tsx, *uac_tsx;
+    struct uac_data *uac_data;
+    struct uas_data *uas_data;
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD) {
+
+	/* Verify incoming request */
+	status = proxy_verify_request(rdata);
+	if (status != PJ_SUCCESS) {
+	    app_perror("RX invalid request", status);
+	    return PJ_TRUE;
+	}
+
+	/*
+	 * Request looks sane, next clone the request to create transmit data.
+	 */
+	status = pjsip_endpt_create_request_fwd(global.endpt, rdata, NULL,
+						NULL, 0, &tdata);
+	if (status != PJ_SUCCESS) {
+	    pjsip_endpt_respond_stateless(global.endpt, rdata,
+					  PJSIP_SC_INTERNAL_SERVER_ERROR, 
+					  NULL, NULL, NULL);
+	    return PJ_TRUE;
+	}
+
+
+	/* Process routing */
+	status = proxy_process_routing(tdata);
+	if (status != PJ_SUCCESS) {
+	    app_perror("Error processing route", status);
+	    return PJ_TRUE;
+	}
+
+	/* Calculate target */
+	status = proxy_calculate_target(rdata, tdata);
+	if (status != PJ_SUCCESS) {
+	    app_perror("Error calculating target", status);
+	    return PJ_TRUE;
+	}
+
+	/* Everything is set to forward the request. */
+
+	/* If this is an ACK request, forward statelessly.
+	 * This happens if the proxy records route and this ACK
+	 * is sent for 2xx response. An ACK that is sent for non-2xx
+	 * final response will be absorbed by transaction layer, and
+	 * it will not be received by on_rx_request() callback.
+	 */
+	if (tdata->msg->line.req.method.id == PJSIP_ACK_METHOD) {
+	    status = pjsip_endpt_send_request_stateless(global.endpt, tdata, 
+							NULL, NULL);
+	    if (status != PJ_SUCCESS) {
+		app_perror("Error forwarding request", status);
+		return PJ_TRUE;
+	    }
+
+	    return PJ_TRUE;
+	}
+
+	/* Create UAC transaction for forwarding the request. 
+	 * Set our module as the transaction user to receive further
+	 * events from this transaction.
+	 */
+	status = pjsip_tsx_create_uac(&mod_tu, tdata, &uac_tsx);
+	if (status != PJ_SUCCESS) {
+	    pjsip_tx_data_dec_ref(tdata);
+	    pjsip_endpt_respond_stateless(global.endpt, rdata, 
+					  PJSIP_SC_INTERNAL_SERVER_ERROR, 
+					  NULL, NULL, NULL);
+	    return PJ_TRUE;
+	}
+
+	/* Create UAS transaction to handle incoming request */
+	status = pjsip_tsx_create_uas(&mod_tu, rdata, &uas_tsx);
+	if (status != PJ_SUCCESS) {
+	    pjsip_tx_data_dec_ref(tdata);
+	    pjsip_endpt_respond_stateless(global.endpt, rdata, 
+					  PJSIP_SC_INTERNAL_SERVER_ERROR, 
+					  NULL, NULL, NULL);
+	    pjsip_tsx_terminate(uac_tsx, PJSIP_SC_INTERNAL_SERVER_ERROR);
+	    return PJ_TRUE;
+	}
+
+	/* Feed the request to the UAS transaction to drive it's state 
+	 * out of NULL state. 
+	 */
+	pjsip_tsx_recv_msg(uas_tsx, rdata);
+
+	/* Attach a data to the UAC transaction, to be used to find the
+	 * UAS transaction when we receive response in the UAC side.
+	 */
+	uac_data = (struct uac_data*)
+		   pj_pool_alloc(uac_tsx->pool, sizeof(struct uac_data));
+	uac_data->uas_tsx = uas_tsx;
+	uac_tsx->mod_data[mod_tu.id] = (void*)uac_data;
+
+	/* Attach data to the UAS transaction, to find the UAC transaction
+	 * when cancelling INVITE request.
+	 */
+	uas_data = (struct uas_data*)
+		    pj_pool_alloc(uas_tsx->pool, sizeof(struct uas_data));
+	uas_data->uac_tsx = uac_tsx;
+	uas_tsx->mod_data[mod_tu.id] = (void*)uas_data;
+
+	/* Everything is setup, forward the request */
+	status = pjsip_tsx_send_msg(uac_tsx, tdata);
+	if (status != PJ_SUCCESS) {
+	    pjsip_tx_data *err_res;
+
+	    /* Fail to send request, for some reason */
+
+	    /* Destroy transmit data */
+	    pjsip_tx_data_dec_ref(tdata);
+
+	    /* I think UAC transaction should have been destroyed when
+	     * it fails to send request, so no need to destroy it.
+	    pjsip_tsx_terminate(uac_tsx, PJSIP_SC_INTERNAL_SERVER_ERROR);
+	     */
+
+	    /* Send 500/Internal Server Error to UAS transaction */
+	    pjsip_endpt_create_response(global.endpt, rdata,
+					500, NULL, &err_res);
+	    pjsip_tsx_send_msg(uas_tsx, err_res);
+
+	    return PJ_TRUE;
+	}
+
+	/* Send 100/Trying if this is an INVITE */
+	if (rdata->msg_info.msg->line.req.method.id == PJSIP_INVITE_METHOD) {
+	    pjsip_tx_data *res100;
+
+	    pjsip_endpt_create_response(global.endpt, rdata, 100, NULL, 
+					&res100);
+	    pjsip_tsx_send_msg(uas_tsx, res100);
+	}
+
+    } else {
+	/* This is CANCEL request */
+	pjsip_transaction *invite_uas;
+	struct uas_data *uas_data;
+	pj_str_t key;
+	
+	/* Find the UAS INVITE transaction */
+	pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_UAS_ROLE,
+			     pjsip_get_invite_method(), rdata);
+	invite_uas = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE);
+	if (!invite_uas) {
+	    /* Invite transaction not found, respond CANCEL with 481 */
+	    pjsip_endpt_respond_stateless(global.endpt, rdata, 481, NULL,
+					  NULL, NULL);
+	    return PJ_TRUE;
+	}
+
+	/* Respond 200 OK to CANCEL */
+	pjsip_endpt_respond(global.endpt, NULL, rdata, 200, NULL, NULL,
+			    NULL, NULL);
+
+	/* Send CANCEL to cancel the UAC transaction.
+	 * The UAS INVITE transaction will get final response when
+	 * we receive final response from the UAC INVITE transaction.
+	 */
+	uas_data = (struct uas_data*) invite_uas->mod_data[mod_tu.id];
+	if (uas_data->uac_tsx && uas_data->uac_tsx->status_code < 200) {
+	    pjsip_tx_data *cancel;
+
+	    pj_grp_lock_acquire(uas_data->uac_tsx->grp_lock);
+
+	    pjsip_endpt_create_cancel(global.endpt, uas_data->uac_tsx->last_tx,
+				      &cancel);
+	    pjsip_endpt_send_request(global.endpt, cancel, -1, NULL, NULL);
+
+	    pj_grp_lock_release(uas_data->uac_tsx->grp_lock);
+	}
+
+	/* Unlock UAS tsx because it is locked in find_tsx() */
+	pj_grp_lock_release(invite_uas->grp_lock);
+    }
+
+    return PJ_TRUE;
+}
+
+
+/* Callback to be called to handle incoming response outside
+ * any transactions. This happens for example when 2xx/OK
+ * for INVITE is received and transaction will be destroyed
+ * immediately, so we need to forward the subsequent 2xx/OK
+ * retransmission statelessly.
+ */
+static pj_bool_t proxy_on_rx_response( pjsip_rx_data *rdata )
+{
+    pjsip_tx_data *tdata;
+    pjsip_response_addr res_addr;
+    pjsip_via_hdr *hvia;
+    pj_status_t status;
+
+    /* Create response to be forwarded upstream (Via will be stripped here) */
+    status = pjsip_endpt_create_response_fwd(global.endpt, rdata, 0, &tdata);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error creating response", status);
+	return PJ_TRUE;
+    }
+
+    /* Get topmost Via header */
+    hvia = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
+    if (hvia == NULL) {
+	/* Invalid response! Just drop it */
+	pjsip_tx_data_dec_ref(tdata);
+	return PJ_TRUE;
+    }
+
+    /* Calculate the address to forward the response */
+    pj_bzero(&res_addr, sizeof(res_addr));
+    res_addr.dst_host.type = PJSIP_TRANSPORT_UDP;
+    res_addr.dst_host.flag = 
+	pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP);
+
+    /* Destination address is Via's received param */
+    res_addr.dst_host.addr.host = hvia->recvd_param;
+    if (res_addr.dst_host.addr.host.slen == 0) {
+	/* Someone has messed up our Via header! */
+	res_addr.dst_host.addr.host = hvia->sent_by.host;
+    }
+
+    /* Destination port is the rport */
+    if (hvia->rport_param != 0 && hvia->rport_param != -1)
+	res_addr.dst_host.addr.port = hvia->rport_param;
+
+    if (res_addr.dst_host.addr.port == 0) {
+	/* Ugh, original sender didn't put rport!
+	 * At best, can only send the response to the port in Via.
+	 */
+	res_addr.dst_host.addr.port = hvia->sent_by.port;
+    }
+
+    /* Forward response */
+    status = pjsip_endpt_send_response(global.endpt, &res_addr, tdata,
+				       NULL, NULL);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error forwarding response", status);
+	return PJ_TRUE;
+    }
+
+    return PJ_TRUE;
+}
+
+
+/* Callback to be called to handle transaction state changed. */
+static void tu_on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)
+{
+    struct uac_data *uac_data;
+    pj_status_t status;
+
+    if (tsx->role == PJSIP_ROLE_UAS) {
+	if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
+	    struct uas_data *uas_data;
+
+	    uas_data = (struct uas_data*) tsx->mod_data[mod_tu.id];
+	    if (uas_data->uac_tsx) {
+		uac_data = (struct uac_data*)
+			   uas_data->uac_tsx->mod_data[mod_tu.id];
+		uac_data->uas_tsx = NULL;
+	    }
+		       
+	}
+	return;
+    }
+
+    /* Get the data that we attached to the UAC transaction previously */
+    uac_data = (struct uac_data*) tsx->mod_data[mod_tu.id];
+
+
+    /* Handle incoming response */
+    if (event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
+
+	pjsip_rx_data *rdata;
+	pjsip_response_addr res_addr;
+        pjsip_via_hdr *hvia;
+	pjsip_tx_data *tdata;
+
+	rdata = event->body.tsx_state.src.rdata;
+
+	/* Do not forward 100 response for INVITE (we already responded
+	 * INVITE with 100)
+	 */
+	if (tsx->method.id == PJSIP_INVITE_METHOD && 
+	    rdata->msg_info.msg->line.status.code == 100)
+	{
+	    return;
+	}
+
+	/* Create response to be forwarded upstream 
+	 * (Via will be stripped here) 
+	 */
+	status = pjsip_endpt_create_response_fwd(global.endpt, rdata, 0, 
+						 &tdata);
+	if (status != PJ_SUCCESS) {
+	    app_perror("Error creating response", status);
+	    return;
+	}
+
+	/* Get topmost Via header of the new response */
+	hvia = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, 
+						   NULL);
+	if (hvia == NULL) {
+	    /* Invalid response! Just drop it */
+	    pjsip_tx_data_dec_ref(tdata);
+	    return;
+	}
+
+	/* Calculate the address to forward the response */
+	pj_bzero(&res_addr, sizeof(res_addr));
+	res_addr.dst_host.type = PJSIP_TRANSPORT_UDP;
+	res_addr.dst_host.flag = 
+	    pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP);
+
+	/* Destination address is Via's received param */
+	res_addr.dst_host.addr.host = hvia->recvd_param;
+	if (res_addr.dst_host.addr.host.slen == 0) {
+	    /* Someone has messed up our Via header! */
+	    res_addr.dst_host.addr.host = hvia->sent_by.host;
+	}
+
+	/* Destination port is the rport */
+	if (hvia->rport_param != 0 && hvia->rport_param != -1)
+	    res_addr.dst_host.addr.port = hvia->rport_param;
+
+	if (res_addr.dst_host.addr.port == 0) {
+	    /* Ugh, original sender didn't put rport!
+	     * At best, can only send the response to the port in Via.
+	     */
+	    res_addr.dst_host.addr.port = hvia->sent_by.port;
+	}
+
+	/* Forward response with the UAS transaction */
+	pjsip_tsx_send_msg(uac_data->uas_tsx, tdata);
+
+    }
+
+    /* If UAC transaction is terminated, terminate the UAS as well.
+     * This could happen because of:
+     *	- timeout on the UAC side
+     *  - receipt of 2xx response to INVITE
+     */
+    if (tsx->state == PJSIP_TSX_STATE_TERMINATED && uac_data &&
+	uac_data->uas_tsx) 
+    {
+
+	pjsip_transaction *uas_tsx;
+	struct uas_data *uas_data;
+
+	uas_tsx = uac_data->uas_tsx;
+	uas_data = (struct uas_data*) uas_tsx->mod_data[mod_tu.id];
+	uas_data->uac_tsx = NULL;
+
+	if (event->body.tsx_state.type == PJSIP_EVENT_TIMER) {
+
+	    /* Send 408/Timeout if this is an INVITE transaction, since
+	     * we must have sent provisional response before. For non
+	     * INVITE transaction, just destroy it.
+	     */
+	    if (tsx->method.id == PJSIP_INVITE_METHOD) {
+
+		pjsip_tx_data *tdata = uas_tsx->last_tx;
+
+		tdata->msg->line.status.code = PJSIP_SC_REQUEST_TIMEOUT;
+		tdata->msg->line.status.reason = pj_str("Request timed out");
+		tdata->msg->body = NULL;
+
+		pjsip_tx_data_add_ref(tdata);
+		pjsip_tx_data_invalidate_msg(tdata);
+
+		pjsip_tsx_send_msg(uas_tsx, tdata);
+
+	    } else {
+		/* For non-INVITE, just destroy the UAS transaction */
+		pjsip_tsx_terminate(uas_tsx, PJSIP_SC_REQUEST_TIMEOUT);
+	    }
+
+	} else if (event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
+
+	    if (uas_tsx->state < PJSIP_TSX_STATE_TERMINATED) {
+		pjsip_msg *msg;
+		int code;
+
+		msg = event->body.tsx_state.src.rdata->msg_info.msg;
+		code = msg->line.status.code;
+
+		uac_data->uas_tsx = NULL;
+		pjsip_tsx_terminate(uas_tsx, code);
+	    }
+	}
+    }
+}
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_status_t status;
+
+    global.port = 5060;
+    global.record_route = 0;
+
+    pj_log_set_level(4);
+
+    status = init_options(argc, argv);
+    if (status != PJ_SUCCESS)
+	return 1;
+
+    status = init_stack();
+    if (status != PJ_SUCCESS) {
+	app_perror("Error initializing stack", status);
+	return 1;
+    }
+
+    status = init_proxy();
+    if (status != PJ_SUCCESS) {
+	app_perror("Error initializing proxy", status);
+	return 1;
+    }
+
+    status = init_stateful_proxy();
+    if (status != PJ_SUCCESS) {
+	app_perror("Error initializing stateful proxy", status);
+	return 1;
+    }
+
+#if PJ_HAS_THREADS
+    status = pj_thread_create(global.pool, "sproxy", &worker_thread, 
+			      NULL, 0, 0, &global.thread);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error creating thread", status);
+	return 1;
+    }
+
+    while (!global.quit_flag) {
+	char line[10];
+
+	puts("\n"
+	     "Menu:\n"
+	     "  q    quit\n"
+	     "  d    dump status\n"
+	     "  dd   dump detailed status\n"
+	     "");
+
+	if (fgets(line, sizeof(line), stdin) == NULL) {
+	    puts("EOF while reading stdin, will quit now..");
+	    global.quit_flag = PJ_TRUE;
+	    break;
+	}
+
+	if (line[0] == 'q') {
+	    global.quit_flag = PJ_TRUE;
+	} else if (line[0] == 'd') {
+	    pj_bool_t detail = (line[1] == 'd');
+	    pjsip_endpt_dump(global.endpt, detail);
+	    pjsip_tsx_layer_dump(detail);
+	}
+    }
+
+    pj_thread_join(global.thread);
+
+#else
+    puts("\nPress Ctrl-C to quit\n");
+    for (;;) {
+	pj_time_val delay = {0, 0};
+	pjsip_endpt_handle_events(global.endpt, &delay);
+    }
+#endif
+
+    destroy_stack();
+
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/stateless_proxy.c b/jni/libpjsip/sources/pjsip-apps/src/samples/stateless_proxy.c
new file mode 100644
index 0000000..826385c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/stateless_proxy.c
@@ -0,0 +1,255 @@
+/* $Id: stateless_proxy.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+#define THIS_FILE   "stateless_proxy.c"
+
+/* Common proxy functions */
+#define STATEFUL    0
+#include "proxy.h"
+
+
+/* Callback to be called to handle incoming requests. */
+static pj_bool_t on_rx_request( pjsip_rx_data *rdata );
+
+/* Callback to be called to handle incoming response. */
+static pj_bool_t on_rx_response( pjsip_rx_data *rdata );
+
+
+static pj_status_t init_stateless_proxy(void)
+{
+    static pjsip_module mod_stateless_proxy =
+    {
+	NULL, NULL,			    /* prev, next.	*/
+	{ "mod-stateless-proxy", 19 },	    /* Name.		*/
+	-1,				    /* Id		*/
+	PJSIP_MOD_PRIORITY_UA_PROXY_LAYER,  /* Priority		*/
+	NULL,				    /* load()		*/
+	NULL,				    /* start()		*/
+	NULL,				    /* stop()		*/
+	NULL,				    /* unload()		*/
+	&on_rx_request,			    /* on_rx_request()	*/
+	&on_rx_response,		    /* on_rx_response()	*/
+	NULL,				    /* on_tx_request.	*/
+	NULL,				    /* on_tx_response()	*/
+	NULL,				    /* on_tsx_state()	*/
+    };
+
+    pj_status_t status;
+
+    /* Register our module to receive incoming requests. */
+    status = pjsip_endpt_register_module( global.endpt, &mod_stateless_proxy);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    return PJ_SUCCESS;
+}
+
+
+/* Callback to be called to handle incoming requests. */
+static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
+{
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+
+    /* Verify incoming request */
+    status = proxy_verify_request(rdata);
+    if (status != PJ_SUCCESS) {
+	app_perror("RX invalid request", status);
+	return PJ_TRUE;
+    }
+
+    /*
+     * Request looks sane, next clone the request to create transmit data.
+     */
+    status = pjsip_endpt_create_request_fwd(global.endpt, rdata, NULL,
+					    NULL, 0, &tdata);
+    if (status != PJ_SUCCESS) {
+	pjsip_endpt_respond_stateless(global.endpt, rdata,
+				      PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, 
+				      NULL, NULL);
+	return PJ_TRUE;
+    }
+
+
+    /* Process routing */
+    status = proxy_process_routing(tdata);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error processing route", status);
+	return PJ_TRUE;
+    }
+
+    /* Calculate target */
+    status = proxy_calculate_target(rdata, tdata);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error calculating target", status);
+	return PJ_TRUE;
+    }
+
+    /* Target is set, forward the request */
+    status = pjsip_endpt_send_request_stateless(global.endpt, tdata, 
+						NULL, NULL);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error forwarding request", status);
+	return PJ_TRUE;
+    }
+
+    return PJ_TRUE;
+}
+
+
+/* Callback to be called to handle incoming response. */
+static pj_bool_t on_rx_response( pjsip_rx_data *rdata )
+{
+    pjsip_tx_data *tdata;
+    pjsip_response_addr res_addr;
+    pjsip_via_hdr *hvia;
+    pj_status_t status;
+
+    /* Create response to be forwarded upstream (Via will be stripped here) */
+    status = pjsip_endpt_create_response_fwd(global.endpt, rdata, 0, &tdata);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error creating response", status);
+	return PJ_TRUE;
+    }
+
+    /* Get topmost Via header */
+    hvia = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
+    if (hvia == NULL) {
+	/* Invalid response! Just drop it */
+	pjsip_tx_data_dec_ref(tdata);
+	return PJ_TRUE;
+    }
+
+    /* Calculate the address to forward the response */
+    pj_bzero(&res_addr, sizeof(res_addr));
+    res_addr.dst_host.type = PJSIP_TRANSPORT_UDP;
+    res_addr.dst_host.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP);
+
+    /* Destination address is Via's received param */
+    res_addr.dst_host.addr.host = hvia->recvd_param;
+    if (res_addr.dst_host.addr.host.slen == 0) {
+	/* Someone has messed up our Via header! */
+	res_addr.dst_host.addr.host = hvia->sent_by.host;
+    }
+
+    /* Destination port is the rpot */
+    if (hvia->rport_param != 0 && hvia->rport_param != -1)
+	res_addr.dst_host.addr.port = hvia->rport_param;
+
+    if (res_addr.dst_host.addr.port == 0) {
+	/* Ugh, original sender didn't put rport!
+	 * At best, can only send the response to the port in Via.
+	 */
+	res_addr.dst_host.addr.port = hvia->sent_by.port;
+    }
+
+    /* Forward response */
+    status = pjsip_endpt_send_response(global.endpt, &res_addr, tdata, 
+				       NULL, NULL);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error forwarding response", status);
+	return PJ_TRUE;
+    }
+
+    return PJ_TRUE;
+}
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_status_t status;
+
+    global.port = 5060;
+    pj_log_set_level(4);
+
+    status = init_options(argc, argv);
+    if (status != PJ_SUCCESS)
+	return 1;
+
+    status = init_stack();
+    if (status != PJ_SUCCESS) {
+	app_perror("Error initializing stack", status);
+	return 1;
+    }
+
+    status = init_proxy();
+    if (status != PJ_SUCCESS) {
+	app_perror("Error initializing proxy", status);
+	return 1;
+    }
+
+    status = init_stateless_proxy();
+    if (status != PJ_SUCCESS) {
+	app_perror("Error initializing stateless proxy", status);
+	return 1;
+    }
+
+#if PJ_HAS_THREADS
+    status = pj_thread_create(global.pool, "sproxy", &worker_thread, 
+			      NULL, 0, 0, &global.thread);
+    if (status != PJ_SUCCESS) {
+	app_perror("Error creating thread", status);
+	return 1;
+    }
+
+    while (!global.quit_flag) {
+	char line[10];
+
+	puts("\n"
+	     "Menu:\n"
+	     "  q    quit\n"
+	     "  d    dump status\n"
+	     "  dd   dump detailed status\n"
+	     "");
+
+	if (fgets(line, sizeof(line), stdin) == NULL) {
+	    puts("EOF while reading stdin, will quit now..");
+	    global.quit_flag = PJ_TRUE;
+	    break;
+	}
+
+	if (line[0] == 'q') {
+	    global.quit_flag = PJ_TRUE;
+	} else if (line[0] == 'd') {
+	    pj_bool_t detail = (line[1] == 'd');
+	    pjsip_endpt_dump(global.endpt, detail);
+#if STATEFUL
+	    pjsip_tsx_layer_dump(detail);
+#endif
+	}
+    }
+
+    pj_thread_join(global.thread);
+
+#else
+    puts("\nPress Ctrl-C to quit\n");
+    for (;;) {
+	pj_time_val delay = {0, 0};
+	pjsip_endpt_handle_events(global.endpt, &delay);
+    }
+#endif
+
+    destroy_stack();
+
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/stereotest.c b/jni/libpjsip/sources/pjsip-apps/src/samples/stereotest.c
new file mode 100644
index 0000000..8931270
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/stereotest.c
@@ -0,0 +1,336 @@
+/* $Id: stereotest.c 3664 2011-07-19 03:42:28Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/**
+ * \page page_pjmedia_samples_stereo_c Samples: Using Stereo Port
+ *
+ * This example demonstrates how to use @ref PJMEDIA_STEREO_PORT to
+ * change the channel count of the media streams.
+ *
+ * This file is pjsip-apps/src/samples/stereotest.c
+ *
+ * \includelineno stereotest.c
+ */
+
+#include <pjmedia.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#define REC_CLOCK_RATE	    16000
+#define PTIME		    20
+
+#define MODE_PLAY	    1
+#define MODE_RECORD	    2
+
+
+/* For logging purpose. */
+#define THIS_FILE   "stereotest.c"
+
+
+static const char *desc = 
+" FILE		    						    \n"
+"		    						    \n"
+"  stereotest.c	    						    \n"
+"		    						    \n"
+" PURPOSE	    						    \n"
+"		    						    \n"
+"  Demonstrate how use stereo port to play a WAV file to sound	    \n"
+"  device or record to a WAV file from sound device with different  \n"
+"  channel count.    						    \n"
+"		    						    \n"
+" USAGE		    						    \n"
+"		    						    \n"
+"  stereotest [options]	WAV					    \n"
+"		    						    \n"
+"  Options:							    \n"
+"  -m, --mode=N          Operation mode: 1 = playing, 2 = recording.\n"
+"  -C, --rec-ch-cnt=N    Number of channel for recording file.	    \n"
+"  -c, --snd-ch-cnt=N    Number of channel for opening sound device.\n"
+"		    						    \n";
+
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+
+    pjmedia_port *file_port = NULL;
+    pjmedia_port *stereo_port = NULL;
+    pjmedia_snd_port *snd_port = NULL;
+
+    int dev_id = -1;
+    char tmp[10];
+    pj_status_t status;
+
+    char *wav_file = NULL;
+    unsigned mode = 0;
+    unsigned rec_ch_cnt = 1;
+    unsigned snd_ch_cnt = 2;
+
+    enum {
+	OPT_MODE	= 'm',
+	OPT_REC_CHANNEL = 'C',
+	OPT_SND_CHANNEL = 'c',
+    };
+
+    struct pj_getopt_option long_options[] = {
+	{ "mode",	    1, 0, OPT_MODE },
+	{ "rec-ch-cnt",	    1, 0, OPT_REC_CHANNEL },
+	{ "snd-ch-cnt",	    1, 0, OPT_SND_CHANNEL },
+	{ NULL, 0, 0, 0 },
+    };
+
+    int c;
+    int option_index;
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Parse arguments */
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc,argv, "m:C:c:", long_options, &option_index))!=-1) {
+
+	switch (c) {
+	case OPT_MODE:
+	    if (mode) {
+		app_perror(THIS_FILE, "Cannot record and play at once!", 
+			   PJ_EINVAL);
+		return 1;
+	    }
+	    mode = atoi(pj_optarg);
+	    break;
+
+	case OPT_REC_CHANNEL:
+	    rec_ch_cnt = atoi(pj_optarg);
+	    break;
+
+	case OPT_SND_CHANNEL:
+	    snd_ch_cnt = atoi(pj_optarg);
+	    break;
+
+	default:
+	    printf("Invalid options %s\n", argv[pj_optind]);
+	    puts(desc);
+	    return 1;
+	}
+
+    }
+
+    wav_file = argv[pj_optind];
+
+    /* Verify arguments. */
+    if (!wav_file) {
+	app_perror(THIS_FILE, "WAV file not specified!", PJ_EINVAL);
+	puts(desc);
+	return 1;
+    }
+    if (!snd_ch_cnt || !rec_ch_cnt || rec_ch_cnt > 6) {
+	app_perror(THIS_FILE, "Invalid or too many channel count!", PJ_EINVAL);
+	puts(desc);
+	return 1;
+    }
+    if (mode != MODE_RECORD && mode != MODE_PLAY) {
+	app_perror(THIS_FILE, "Invalid operation mode!", PJ_EINVAL);
+	puts(desc);
+	return 1;
+    }
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "app",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    if (mode == MODE_PLAY) {
+	/* Create WAVE file player port. */
+	status = pjmedia_wav_player_port_create( pool, wav_file, PTIME, 0,
+						 0, &file_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to open file", status);
+	    return 1;
+	}
+
+	/* Create sound player port. */
+	status = pjmedia_snd_port_create_player( 
+		     pool,				/* pool		      */
+		     dev_id,				/* device id.	      */
+		     PJMEDIA_PIA_SRATE(&file_port->info),/* clock rate.	      */
+		     snd_ch_cnt,			/* # of channels.     */
+		     snd_ch_cnt * PTIME *		/* samples per frame. */
+		     PJMEDIA_PIA_SRATE(&file_port->info) / 1000,
+		     PJMEDIA_PIA_BITS(&file_port->info),/* bits per sample.   */
+		     0,					/* options	      */
+		     &snd_port				/* returned port      */
+		     );
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to open sound device", status);
+	    return 1;
+	}
+
+	if (snd_ch_cnt != PJMEDIA_PIA_CCNT(&file_port->info)) {
+	    status = pjmedia_stereo_port_create( pool,
+						 file_port,
+						 snd_ch_cnt,
+						 0,
+						 &stereo_port);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to create stereo port", status);
+		return 1;
+	    }
+
+	    status = pjmedia_snd_port_connect(snd_port, stereo_port);
+	} else {
+	    status = pjmedia_snd_port_connect(snd_port, file_port);
+	}
+
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to connect sound port", status);
+	    return 1;
+	}
+
+    } else {
+	/* Create WAVE file writer port. */
+	status = pjmedia_wav_writer_port_create(pool, wav_file,
+						REC_CLOCK_RATE,
+						rec_ch_cnt,
+						rec_ch_cnt * PTIME * 
+						REC_CLOCK_RATE / 1000,
+						NBITS,
+						0, 0, 
+						&file_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to open file", status);
+	    return 1;
+	}
+
+	/* Create sound player port. */
+	status = pjmedia_snd_port_create_rec( 
+			 pool,			    /* pool		    */
+			 dev_id,		    /* device id.	    */
+			 REC_CLOCK_RATE,	    /* clock rate.	    */
+			 snd_ch_cnt,		    /* # of channels.	    */
+			 snd_ch_cnt * PTIME * 
+			 REC_CLOCK_RATE / 1000,	    /* samples per frame.   */
+			 NBITS,			    /* bits per sample.	    */
+			 0,			    /* options		    */
+			 &snd_port		    /* returned port	    */
+		     );
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to open sound device", status);
+	    return 1;
+	}
+
+	if (rec_ch_cnt != snd_ch_cnt) {
+	    status = pjmedia_stereo_port_create( pool,
+						 file_port,
+						 snd_ch_cnt,
+						 0,
+						 &stereo_port);
+	    if (status != PJ_SUCCESS) {
+		app_perror(THIS_FILE, "Unable to create stereo port", status);
+		return 1;
+	    }
+
+	    status = pjmedia_snd_port_connect(snd_port, stereo_port);
+	} else {
+	    status = pjmedia_snd_port_connect(snd_port, file_port);
+	}
+
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to connect sound port", status);
+	    return 1;
+	}
+    }
+
+    /* Dump memory usage */
+    dump_pool_usage(THIS_FILE, &cp);
+
+    /* 
+     * File should be playing and looping now, using sound device's thread. 
+     */
+
+
+    /* Sleep to allow log messages to flush */
+    pj_thread_sleep(100);
+
+    printf("Mode = %s\n", (mode == MODE_PLAY? "playing" : "recording") );
+    printf("File  port channel count = %d\n", PJMEDIA_PIA_CCNT(&file_port->info));
+    printf("Sound port channel count = %d\n", 
+	    PJMEDIA_PIA_CCNT(&pjmedia_snd_port_get_port(snd_port)->info));
+    puts("");
+    puts("Press <ENTER> to stop and quit");
+
+    if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
+	puts("EOF while reading stdin, will quit now..");
+    }
+    
+    /* Start deinitialization: */
+
+
+    /* Destroy sound device */
+    status = pjmedia_snd_port_destroy( snd_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Destroy stereo port and file_port. 
+     * Stereo port will destroy all downstream ports (e.g. the file port)
+     */
+    status = pjmedia_port_destroy( stereo_port? stereo_port : file_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+
+    /* Done. */
+    return 0;
+
+}
+
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/streamutil.c b/jni/libpjsip/sources/pjsip-apps/src/samples/streamutil.c
new file mode 100644
index 0000000..c899c2a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/streamutil.c
@@ -0,0 +1,1176 @@
+/* $Id: streamutil.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+
+/**
+ * \page page_pjmedia_samples_streamutil_c Samples: Remote Streaming
+ *
+ * This example mainly demonstrates how to stream media file to remote
+ * peer using RTP.
+ *
+ * This file is pjsip-apps/src/samples/streamutil.c
+ *
+ * \includelineno streamutil.c
+ */
+
+#include <pjlib.h>
+#include <pjlib-util.h>
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+#include <pjmedia/transport_srtp.h>
+
+#include <stdlib.h>	/* atoi() */
+#include <stdio.h>
+
+#include "util.h"
+
+
+static const char *desc = 
+ " streamutil								\n"
+ "									\n"
+ " PURPOSE:								\n"
+ "  Demonstrate how to use pjmedia stream component to transmit/receive \n"
+ "  RTP packets to/from sound device.		    			\n"
+ "\n"
+ "\n"
+ " USAGE:								\n"
+ "  streamutil [options]                                                \n"
+ "\n"
+ "\n"
+ " Options:\n"
+ "  --codec=CODEC         Set the codec name.                           \n"
+ "  --local-port=PORT     Set local RTP port (default=4000)		\n"
+ "  --remote=IP:PORT      Set the remote peer. If this option is set,	\n"
+ "                        the program will transmit RTP audio to the	\n"
+ "                        specified address. (default: recv only)	\n"
+ "  --play-file=WAV       Send audio from the WAV file instead of from	\n"
+ "                        the sound device.				\n"
+ "  --record-file=WAV     Record incoming audio to WAV file instead of	\n"
+ "                        playing it to sound device.			\n"
+ "  --send-recv           Set stream direction to bidirectional.        \n"
+ "  --send-only           Set stream direction to send only		\n"
+ "  --recv-only           Set stream direction to recv only (default)   \n"
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ "  --use-srtp[=NAME]     Enable SRTP with crypto suite NAME            \n"
+ "                        e.g: AES_CM_128_HMAC_SHA1_80 (default),       \n"
+ "                             AES_CM_128_HMAC_SHA1_32                  \n"
+ "                        Use this option along with the TX & RX keys,  \n"
+ "                        formated of 60 hex digits (e.g: E148DA..)      \n"
+ "  --srtp-tx-key         SRTP key for transmiting                      \n"
+ "  --srtp-rx-key         SRTP key for receiving                        \n"
+#endif
+
+ "\n"
+;
+
+
+
+
+#define THIS_FILE	"stream.c"
+
+
+
+/* Prototype */
+static void print_stream_stat(pjmedia_stream *stream, 
+			      const pjmedia_codec_param *codec_param);
+
+/* Prototype for LIBSRTP utility in file datatypes.c */
+int hex_string_to_octet_string(char *raw, char *hex, int len);
+
+/* 
+ * Register all codecs. 
+ */
+static pj_status_t init_codecs(pjmedia_endpt *med_endpt)
+{
+    return pjmedia_codec_register_audio_codecs(med_endpt, NULL);
+}
+
+
+/* 
+ * Create stream based on the codec, dir, remote address, etc. 
+ */
+static pj_status_t create_stream( pj_pool_t *pool,
+				  pjmedia_endpt *med_endpt,
+				  const pjmedia_codec_info *codec_info,
+				  pjmedia_dir dir,
+				  pj_uint16_t local_port,
+				  const pj_sockaddr_in *rem_addr,
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+				  pj_bool_t use_srtp,
+				  const pj_str_t *crypto_suite,
+				  const pj_str_t *srtp_tx_key,
+				  const pj_str_t *srtp_rx_key,
+#endif
+				  pjmedia_stream **p_stream )
+{
+    pjmedia_stream_info info;
+    pjmedia_transport *transport = NULL;
+    pj_status_t status;
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    pjmedia_transport *srtp_tp = NULL;
+#endif
+
+
+    /* Reset stream info. */
+    pj_bzero(&info, sizeof(info));
+
+
+    /* Initialize stream info formats */
+    info.type = PJMEDIA_TYPE_AUDIO;
+    info.dir = dir;
+    pj_memcpy(&info.fmt, codec_info, sizeof(pjmedia_codec_info));
+    info.tx_pt = codec_info->pt;
+    info.ssrc = pj_rand();
+    
+#if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR
+    /* Set default RTCP XR enabled/disabled */
+    info.rtcp_xr_enabled = PJ_TRUE;
+#endif
+
+    /* Copy remote address */
+    pj_memcpy(&info.rem_addr, rem_addr, sizeof(pj_sockaddr_in));
+
+    /* If remote address is not set, set to an arbitrary address
+     * (otherwise stream will assert).
+     */
+    if (info.rem_addr.addr.sa_family == 0) {
+	const pj_str_t addr = pj_str("127.0.0.1");
+	pj_sockaddr_in_init(&info.rem_addr.ipv4, &addr, 0);
+    }
+
+    /* Create media transport */
+    status = pjmedia_transport_udp_create(med_endpt, NULL, local_port,
+					  0, &transport);
+    if (status != PJ_SUCCESS)
+	return status;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    /* Check if SRTP enabled */
+    if (use_srtp) {
+	pjmedia_srtp_crypto tx_plc, rx_plc;
+
+	status = pjmedia_transport_srtp_create(med_endpt, transport, 
+					       NULL, &srtp_tp);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	pj_bzero(&tx_plc, sizeof(pjmedia_srtp_crypto));
+	pj_bzero(&rx_plc, sizeof(pjmedia_srtp_crypto));
+
+	tx_plc.key = *srtp_tx_key;
+	tx_plc.name = *crypto_suite;
+	rx_plc.key = *srtp_rx_key;
+	rx_plc.name = *crypto_suite;
+	
+	status = pjmedia_transport_srtp_start(srtp_tp, &tx_plc, &rx_plc);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	transport = srtp_tp;
+    }
+#endif
+
+    /* Now that the stream info is initialized, we can create the 
+     * stream.
+     */
+
+    status = pjmedia_stream_create( med_endpt, pool, &info, 
+				    transport, 
+				    NULL, p_stream);
+
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error creating stream", status);
+	pjmedia_transport_close(transport);
+	return status;
+    }
+
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * usage()
+ */
+static void usage()
+{
+    puts(desc);
+}
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_port *rec_file_port = NULL, *play_file_port = NULL;
+    pjmedia_master_port *master_port = NULL;
+    pjmedia_snd_port *snd_port = NULL;
+    pjmedia_stream *stream = NULL;
+    pjmedia_port *stream_port;
+    char tmp[10];
+    pj_status_t status; 
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    /* SRTP variables */
+    pj_bool_t use_srtp = PJ_FALSE;
+    char tmp_tx_key[64];
+    char tmp_rx_key[64];
+    pj_str_t  srtp_tx_key = {NULL, 0};
+    pj_str_t  srtp_rx_key = {NULL, 0};
+    pj_str_t  srtp_crypto_suite = {NULL, 0};
+    int	tmp_key_len;
+#endif
+
+    /* Default values */
+    const pjmedia_codec_info *codec_info;
+    pjmedia_codec_param codec_param;
+    pjmedia_dir dir = PJMEDIA_DIR_DECODING;
+    pj_sockaddr_in remote_addr;
+    pj_uint16_t local_port = 4000;
+    char *codec_id = NULL;
+    char *rec_file = NULL;
+    char *play_file = NULL;
+
+    enum {
+	OPT_CODEC	= 'c',
+	OPT_LOCAL_PORT	= 'p',
+	OPT_REMOTE	= 'r',
+	OPT_PLAY_FILE	= 'w',
+	OPT_RECORD_FILE	= 'R',
+	OPT_SEND_RECV	= 'b',
+	OPT_SEND_ONLY	= 's',
+	OPT_RECV_ONLY	= 'i',
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+	OPT_USE_SRTP	= 'S',
+#endif
+	OPT_SRTP_TX_KEY	= 'x',
+	OPT_SRTP_RX_KEY	= 'y',
+	OPT_HELP	= 'h',
+    };
+
+    struct pj_getopt_option long_options[] = {
+	{ "codec",	    1, 0, OPT_CODEC },
+	{ "local-port",	    1, 0, OPT_LOCAL_PORT },
+	{ "remote",	    1, 0, OPT_REMOTE },
+	{ "play-file",	    1, 0, OPT_PLAY_FILE },
+	{ "record-file",    1, 0, OPT_RECORD_FILE },
+	{ "send-recv",      0, 0, OPT_SEND_RECV },
+	{ "send-only",      0, 0, OPT_SEND_ONLY },
+	{ "recv-only",      0, 0, OPT_RECV_ONLY },
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+	{ "use-srtp",	    2, 0, OPT_USE_SRTP },
+	{ "srtp-tx-key",    1, 0, OPT_SRTP_TX_KEY },
+	{ "srtp-rx-key",    1, 0, OPT_SRTP_RX_KEY },
+#endif
+	{ "help",	    0, 0, OPT_HELP },
+	{ NULL, 0, 0, 0 },
+    };
+
+    int c;
+    int option_index;
+
+
+    pj_bzero(&remote_addr, sizeof(remote_addr));
+
+
+    /* init PJLIB : */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Parse arguments */
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc,argv, "h", long_options, &option_index))!=-1) {
+
+	switch (c) {
+	case OPT_CODEC:
+	    codec_id = pj_optarg;
+	    break;
+
+	case OPT_LOCAL_PORT:
+	    local_port = (pj_uint16_t) atoi(pj_optarg);
+	    if (local_port < 1) {
+		printf("Error: invalid local port %s\n", pj_optarg);
+		return 1;
+	    }
+	    break;
+
+	case OPT_REMOTE:
+	    {
+		pj_str_t ip = pj_str(strtok(pj_optarg, ":"));
+		pj_uint16_t port = (pj_uint16_t) atoi(strtok(NULL, ":"));
+
+		status = pj_sockaddr_in_init(&remote_addr, &ip, port);
+		if (status != PJ_SUCCESS) {
+		    app_perror(THIS_FILE, "Invalid remote address", status);
+		    return 1;
+		}
+	    }
+	    break;
+
+	case OPT_PLAY_FILE:
+	    play_file = pj_optarg;
+	    break;
+
+	case OPT_RECORD_FILE:
+	    rec_file = pj_optarg;
+	    break;
+
+	case OPT_SEND_RECV:
+	    dir = PJMEDIA_DIR_ENCODING_DECODING;
+	    break;
+
+	case OPT_SEND_ONLY:
+	    dir = PJMEDIA_DIR_ENCODING;
+	    break;
+
+	case OPT_RECV_ONLY:
+	    dir = PJMEDIA_DIR_DECODING;
+	    break;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+	case OPT_USE_SRTP:
+	    use_srtp = PJ_TRUE;
+	    if (pj_optarg) {
+		pj_strset(&srtp_crypto_suite, pj_optarg, strlen(pj_optarg));
+	    } else {
+		srtp_crypto_suite = pj_str("AES_CM_128_HMAC_SHA1_80");
+	    }
+	    break;
+
+	case OPT_SRTP_TX_KEY:
+	    tmp_key_len = hex_string_to_octet_string(tmp_tx_key, pj_optarg, 
+						     (int)strlen(pj_optarg));
+	    pj_strset(&srtp_tx_key, tmp_tx_key, tmp_key_len/2);
+	    break;
+
+	case OPT_SRTP_RX_KEY:
+	    tmp_key_len = hex_string_to_octet_string(tmp_rx_key, pj_optarg, 
+						     (int)strlen(pj_optarg));
+	    pj_strset(&srtp_rx_key, tmp_rx_key, tmp_key_len/2);
+	    break;
+#endif
+
+	case OPT_HELP:
+	    usage();
+	    return 1;
+
+	default:
+	    printf("Invalid options %s\n", argv[pj_optind]);
+	    return 1;
+	}
+
+    }
+
+
+    /* Verify arguments. */
+    if (dir & PJMEDIA_DIR_ENCODING) {
+	if (remote_addr.sin_addr.s_addr == 0) {
+	    printf("Error: remote address must be set\n");
+	    return 1;
+	}
+    }
+
+    if (play_file != NULL && dir != PJMEDIA_DIR_ENCODING) {
+	printf("Direction is set to --send-only because of --play-file\n");
+	dir = PJMEDIA_DIR_ENCODING;
+    }
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    /* SRTP validation */
+    if (use_srtp) {
+	if (!srtp_tx_key.slen || !srtp_rx_key.slen)
+	{
+	    printf("Error: Key for each SRTP stream direction must be set\n");
+	    return 1;
+	}
+    }
+#endif
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for application purpose */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "app",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+
+    /* Register all supported codecs */
+    status = init_codecs(med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Find which codec to use. */
+    if (codec_id) {
+	unsigned count = 1;
+	pj_str_t str_codec_id = pj_str(codec_id);
+	pjmedia_codec_mgr *codec_mgr = pjmedia_endpt_get_codec_mgr(med_endpt);
+	status = pjmedia_codec_mgr_find_codecs_by_id( codec_mgr,
+						      &str_codec_id, &count,
+						      &codec_info, NULL);
+	if (status != PJ_SUCCESS) {
+	    printf("Error: unable to find codec %s\n", codec_id);
+	    return 1;
+	}
+    } else {
+	/* Default to pcmu */
+	pjmedia_codec_mgr_get_codec_info( pjmedia_endpt_get_codec_mgr(med_endpt),
+					  0, &codec_info);
+    }
+
+    /* Create stream based on program arguments */
+    status = create_stream(pool, med_endpt, codec_info, dir, local_port, 
+			   &remote_addr, 
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+			   use_srtp, &srtp_crypto_suite, 
+			   &srtp_tx_key, &srtp_rx_key,
+#endif
+			   &stream);
+    if (status != PJ_SUCCESS)
+	goto on_exit;
+
+    /* Get codec default param for info */
+    status = pjmedia_codec_mgr_get_default_param(
+				    pjmedia_endpt_get_codec_mgr(med_endpt), 
+				    codec_info, 
+				    &codec_param);
+    /* Should be ok, as create_stream() above succeeded */
+    pj_assert(status == PJ_SUCCESS);
+
+    /* Get the port interface of the stream */
+    status = pjmedia_stream_get_port( stream, &stream_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    if (play_file) {
+	unsigned wav_ptime;
+
+	wav_ptime = PJMEDIA_PIA_PTIME(&stream_port->info);
+	status = pjmedia_wav_player_port_create(pool, play_file, wav_ptime,
+						0, -1, &play_file_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to use file", status);
+	    goto on_exit;
+	}
+
+	status = pjmedia_master_port_create(pool, play_file_port, stream_port,
+					    0, &master_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to create master port", status);
+	    goto on_exit;
+	}
+
+	status = pjmedia_master_port_start(master_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Error starting master port", status);
+	    goto on_exit;
+	}
+
+	printf("Playing from WAV file %s..\n", play_file);
+
+    } else if (rec_file) {
+
+	status = pjmedia_wav_writer_port_create(pool, rec_file,
+					        PJMEDIA_PIA_SRATE(&stream_port->info),
+					        PJMEDIA_PIA_CCNT(&stream_port->info),
+					        PJMEDIA_PIA_SPF(&stream_port->info),
+					        PJMEDIA_PIA_BITS(&stream_port->info),
+						0, 0, &rec_file_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to use file", status);
+	    goto on_exit;
+	}
+
+	status = pjmedia_master_port_create(pool, stream_port, rec_file_port, 
+					    0, &master_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to create master port", status);
+	    goto on_exit;
+	}
+
+	status = pjmedia_master_port_start(master_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Error starting master port", status);
+	    goto on_exit;
+	}
+
+	printf("Recording to WAV file %s..\n", rec_file);
+	
+    } else {
+
+	/* Create sound device port. */
+	if (dir == PJMEDIA_DIR_ENCODING_DECODING)
+	    status = pjmedia_snd_port_create(pool, -1, -1, 
+					PJMEDIA_PIA_SRATE(&stream_port->info),
+					PJMEDIA_PIA_CCNT(&stream_port->info),
+					PJMEDIA_PIA_SPF(&stream_port->info),
+					PJMEDIA_PIA_BITS(&stream_port->info),
+					0, &snd_port);
+	else if (dir == PJMEDIA_DIR_ENCODING)
+	    status = pjmedia_snd_port_create_rec(pool, -1, 
+					PJMEDIA_PIA_SRATE(&stream_port->info),
+					PJMEDIA_PIA_CCNT(&stream_port->info),
+					PJMEDIA_PIA_SPF(&stream_port->info),
+					PJMEDIA_PIA_BITS(&stream_port->info),
+					0, &snd_port);
+	else
+	    status = pjmedia_snd_port_create_player(pool, -1, 
+					PJMEDIA_PIA_SRATE(&stream_port->info),
+					PJMEDIA_PIA_CCNT(&stream_port->info),
+					PJMEDIA_PIA_SPF(&stream_port->info),
+					PJMEDIA_PIA_BITS(&stream_port->info),
+					0, &snd_port);
+
+
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to create sound port", status);
+	    goto on_exit;
+	}
+
+	/* Connect sound port to stream */
+	status = pjmedia_snd_port_connect( snd_port, stream_port );
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    }
+
+    /* Start streaming */
+    pjmedia_stream_start(stream);
+
+
+    /* Done */
+
+    if (dir == PJMEDIA_DIR_DECODING)
+	printf("Stream is active, dir is recv-only, local port is %d\n",
+	       local_port);
+    else if (dir == PJMEDIA_DIR_ENCODING)
+	printf("Stream is active, dir is send-only, sending to %s:%d\n",
+	       pj_inet_ntoa(remote_addr.sin_addr),
+	       pj_ntohs(remote_addr.sin_port));
+    else
+	printf("Stream is active, send/recv, local port is %d, "
+	       "sending to %s:%d\n",
+	       local_port,
+	       pj_inet_ntoa(remote_addr.sin_addr),
+	       pj_ntohs(remote_addr.sin_port));
+
+
+    for (;;) {
+
+	puts("");
+	puts("Commands:");
+	puts("  s     Display media statistics");
+	puts("  q     Quit");
+	puts("");
+
+	printf("Command: "); fflush(stdout);
+
+	if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
+	    puts("EOF while reading stdin, will quit now..");
+	    break;
+	}
+
+	if (tmp[0] == 's')
+	    print_stream_stat(stream, &codec_param);
+	else if (tmp[0] == 'q')
+	    break;
+
+    }
+
+
+
+    /* Start deinitialization: */
+on_exit:
+
+    /* Destroy sound device */
+    if (snd_port) {
+	pjmedia_snd_port_destroy( snd_port );
+	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+    }
+
+    /* If there is master port, then we just need to destroy master port
+     * (it will recursively destroy upstream and downstream ports, which
+     * in this case are file_port and stream_port).
+     */
+    if (master_port) {
+	pjmedia_master_port_destroy(master_port, PJ_TRUE);
+	play_file_port = NULL;
+	stream = NULL;
+    }
+
+    /* Destroy stream */
+    if (stream) {
+	pjmedia_transport *tp;
+
+	tp = pjmedia_stream_get_transport(stream);
+	pjmedia_stream_destroy(stream);
+	
+	pjmedia_transport_close(tp);
+    }
+
+    /* Destroy file ports */
+    if (play_file_port)
+	pjmedia_port_destroy( play_file_port );
+    if (rec_file_port)
+	pjmedia_port_destroy( rec_file_port );
+
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+
+    return (status == PJ_SUCCESS) ? 0 : 1;
+}
+
+
+
+
+static const char *good_number(char *buf, pj_int32_t val)
+{
+    if (val < 1000) {
+	pj_ansi_sprintf(buf, "%d", val);
+    } else if (val < 1000000) {
+	pj_ansi_sprintf(buf, "%d.%dK", 
+			val / 1000,
+			(val % 1000) / 100);
+    } else {
+	pj_ansi_sprintf(buf, "%d.%02dM", 
+			val / 1000000,
+			(val % 1000000) / 10000);
+    }
+
+    return buf;
+}
+
+
+#define SAMPLES_TO_USEC(usec, samples, clock_rate) \
+    do { \
+	if (samples <= 4294) \
+	    usec = samples * 1000000 / clock_rate; \
+	else { \
+	    usec = samples * 1000 / clock_rate; \
+	    usec *= 1000; \
+	} \
+    } while(0)
+
+#define PRINT_VOIP_MTC_VAL(s, v) \
+    if (v == 127) \
+	sprintf(s, "(na)"); \
+    else \
+	sprintf(s, "%d", v)
+
+
+/*
+ * Print stream statistics
+ */
+static void print_stream_stat(pjmedia_stream *stream,
+			      const pjmedia_codec_param *codec_param)
+{
+    char duration[80], last_update[80];
+    char bps[16], ipbps[16], packets[16], bytes[16], ipbytes[16];
+    pjmedia_port *port;
+    pjmedia_rtcp_stat stat;
+    pj_time_val now;
+
+
+    pj_gettimeofday(&now);
+    pjmedia_stream_get_stat(stream, &stat);
+    pjmedia_stream_get_port(stream, &port);
+
+    puts("Stream statistics:");
+
+    /* Print duration */
+    PJ_TIME_VAL_SUB(now, stat.start);
+    sprintf(duration, " Duration: %02ld:%02ld:%02ld.%03ld",
+	    now.sec / 3600,
+	    (now.sec % 3600) / 60,
+	    (now.sec % 60),
+	    now.msec);
+
+
+    printf(" Info: audio %dHz, %dms/frame, %sB/s (%sB/s +IP hdr)\n",
+	PJMEDIA_PIA_SRATE(&port->info),
+	PJMEDIA_PIA_PTIME(&port->info),
+	good_number(bps, (codec_param->info.avg_bps+7)/8),
+	good_number(ipbps, ((codec_param->info.avg_bps+7)/8) + 
+			   (40 * 1000 /
+			    codec_param->setting.frm_per_pkt /
+			    codec_param->info.frm_ptime)));
+
+    if (stat.rx.update_cnt == 0)
+	strcpy(last_update, "never");
+    else {
+	pj_gettimeofday(&now);
+	PJ_TIME_VAL_SUB(now, stat.rx.update);
+	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		now.sec / 3600,
+		(now.sec % 3600) / 60,
+		now.sec % 60,
+		now.msec);
+    }
+
+    printf(" RX stat last update: %s\n"
+	   "    total %s packets %sB received (%sB +IP hdr)%s\n"
+	   "    pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
+	   "          (msec)    min     avg     max     last    dev\n"
+	   "    loss period: %7.3f %7.3f %7.3f %7.3f %7.3f%s\n"
+	   "    jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f%s\n",
+	   last_update,
+	   good_number(packets, stat.rx.pkt),
+	   good_number(bytes, stat.rx.bytes),
+	   good_number(ipbytes, stat.rx.bytes + stat.rx.pkt * 32),
+	   "",
+	   stat.rx.loss,
+	   stat.rx.loss * 100.0 / (stat.rx.pkt + stat.rx.loss),
+	   stat.rx.dup, 
+	   stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx.loss),
+	   stat.rx.reorder, 
+	   stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx.loss),
+	   "",
+	   stat.rx.loss_period.min / 1000.0, 
+	   stat.rx.loss_period.mean / 1000.0, 
+	   stat.rx.loss_period.max / 1000.0,
+	   stat.rx.loss_period.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat.rx.loss_period) / 1000.0,
+	   "",
+	   stat.rx.jitter.min / 1000.0,
+	   stat.rx.jitter.mean / 1000.0,
+	   stat.rx.jitter.max / 1000.0,
+	   stat.rx.jitter.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat.rx.jitter) / 1000.0,
+	   ""
+	   );
+
+
+    if (stat.tx.update_cnt == 0)
+	strcpy(last_update, "never");
+    else {
+	pj_gettimeofday(&now);
+	PJ_TIME_VAL_SUB(now, stat.tx.update);
+	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		now.sec / 3600,
+		(now.sec % 3600) / 60,
+		now.sec % 60,
+		now.msec);
+    }
+
+    printf(" TX stat last update: %s\n"
+	   "    total %s packets %sB sent (%sB +IP hdr)%s\n"
+	   "    pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
+	   "          (msec)    min     avg     max     last    dev\n"
+	   "    loss period: %7.3f %7.3f %7.3f %7.3f %7.3f%s\n"
+	   "    jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f%s\n",
+	   last_update,
+	   good_number(packets, stat.tx.pkt),
+	   good_number(bytes, stat.tx.bytes),
+	   good_number(ipbytes, stat.tx.bytes + stat.tx.pkt * 32),
+	   "",
+	   stat.tx.loss,
+	   stat.tx.loss * 100.0 / (stat.tx.pkt + stat.tx.loss),
+	   stat.tx.dup, 
+	   stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx.loss),
+	   stat.tx.reorder, 
+	   stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx.loss),
+	   "",
+	   stat.tx.loss_period.min / 1000.0, 
+	   stat.tx.loss_period.mean / 1000.0, 
+	   stat.tx.loss_period.max / 1000.0,
+	   stat.tx.loss_period.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat.tx.loss_period) / 1000.0,
+	   "",
+	   stat.tx.jitter.min / 1000.0,
+	   stat.tx.jitter.mean / 1000.0,
+	   stat.tx.jitter.max / 1000.0,
+	   stat.tx.jitter.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat.tx.jitter) / 1000.0,
+	   ""
+	   );
+
+
+    printf(" RTT delay     : %7.3f %7.3f %7.3f %7.3f %7.3f%s\n", 
+	   stat.rtt.min / 1000.0,
+	   stat.rtt.mean / 1000.0,
+	   stat.rtt.max / 1000.0,
+	   stat.rtt.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat.rtt) / 1000.0,
+	   ""
+	   );
+
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+    /* RTCP XR Reports */
+    do {
+	char loss[16], dup[16];
+	char jitter[80];
+	char toh[80];
+	char plc[16], jba[16], jbr[16];
+	char signal_lvl[16], noise_lvl[16], rerl[16];
+	char r_factor[16], ext_r_factor[16], mos_lq[16], mos_cq[16];
+	pjmedia_rtcp_xr_stat xr_stat;
+
+	if (pjmedia_stream_get_stat_xr(stream, &xr_stat) != PJ_SUCCESS)
+	    break;
+
+	puts("\nExtended reports:");
+
+	/* Statistics Summary */
+	puts(" Statistics Summary");
+
+	if (xr_stat.rx.stat_sum.l)
+	    sprintf(loss, "%d", xr_stat.rx.stat_sum.lost);
+	else
+	    sprintf(loss, "(na)");
+
+	if (xr_stat.rx.stat_sum.d)
+	    sprintf(dup, "%d", xr_stat.rx.stat_sum.dup);
+	else
+	    sprintf(dup, "(na)");
+
+	if (xr_stat.rx.stat_sum.j) {
+	    unsigned jmin, jmax, jmean, jdev;
+
+	    SAMPLES_TO_USEC(jmin, xr_stat.rx.stat_sum.jitter.min, 
+			    port->info.fmt.det.aud.clock_rate);
+	    SAMPLES_TO_USEC(jmax, xr_stat.rx.stat_sum.jitter.max, 
+			    port->info.fmt.det.aud.clock_rate);
+	    SAMPLES_TO_USEC(jmean, xr_stat.rx.stat_sum.jitter.mean, 
+			    port->info.fmt.det.aud.clock_rate);
+	    SAMPLES_TO_USEC(jdev, 
+			   pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.jitter),
+			   port->info.fmt.det.aud.clock_rate);
+	    sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f", 
+		    jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
+	} else
+	    sprintf(jitter, "(report not available)");
+
+	if (xr_stat.rx.stat_sum.t) {
+	    sprintf(toh, "%11d %11d %11d %11d", 
+		    xr_stat.rx.stat_sum.toh.min,
+		    xr_stat.rx.stat_sum.toh.mean,
+		    xr_stat.rx.stat_sum.toh.max,
+		    pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
+	} else
+	    sprintf(toh, "(report not available)");
+
+	if (xr_stat.rx.stat_sum.update.sec == 0)
+	    strcpy(last_update, "never");
+	else {
+	    pj_gettimeofday(&now);
+	    PJ_TIME_VAL_SUB(now, xr_stat.rx.stat_sum.update);
+	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		    now.sec / 3600,
+		    (now.sec % 3600) / 60,
+		    now.sec % 60,
+		    now.msec);
+	}
+
+	printf(" RX last update: %s\n"
+	       "    begin seq=%d, end seq=%d%s\n"
+	       "    pkt loss=%s, dup=%s%s\n"
+	       "          (msec)    min     avg     max     dev\n"
+	       "    jitter     : %s\n"
+	       "    toh        : %s\n",
+	       last_update,
+	       xr_stat.rx.stat_sum.begin_seq, xr_stat.rx.stat_sum.end_seq,
+	       "",
+	       loss, dup,
+	       "",
+	       jitter,
+	       toh
+	       );
+
+	if (xr_stat.tx.stat_sum.l)
+	    sprintf(loss, "%d", xr_stat.tx.stat_sum.lost);
+	else
+	    sprintf(loss, "(na)");
+
+	if (xr_stat.tx.stat_sum.d)
+	    sprintf(dup, "%d", xr_stat.tx.stat_sum.dup);
+	else
+	    sprintf(dup, "(na)");
+
+	if (xr_stat.tx.stat_sum.j) {
+	    unsigned jmin, jmax, jmean, jdev;
+
+	    SAMPLES_TO_USEC(jmin, xr_stat.tx.stat_sum.jitter.min, 
+			    port->info.fmt.det.aud.clock_rate);
+	    SAMPLES_TO_USEC(jmax, xr_stat.tx.stat_sum.jitter.max, 
+			    port->info.fmt.det.aud.clock_rate);
+	    SAMPLES_TO_USEC(jmean, xr_stat.tx.stat_sum.jitter.mean, 
+			    port->info.fmt.det.aud.clock_rate);
+	    SAMPLES_TO_USEC(jdev, 
+			   pj_math_stat_get_stddev(&xr_stat.tx.stat_sum.jitter),
+			   port->info.fmt.det.aud.clock_rate);
+	    sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f", 
+		    jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
+	} else
+	    sprintf(jitter, "(report not available)");
+
+	if (xr_stat.tx.stat_sum.t) {
+	    sprintf(toh, "%11d %11d %11d %11d", 
+		    xr_stat.tx.stat_sum.toh.min,
+		    xr_stat.tx.stat_sum.toh.mean,
+		    xr_stat.tx.stat_sum.toh.max,
+		    pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
+	} else
+	    sprintf(toh,    "(report not available)");
+
+	if (xr_stat.tx.stat_sum.update.sec == 0)
+	    strcpy(last_update, "never");
+	else {
+	    pj_gettimeofday(&now);
+	    PJ_TIME_VAL_SUB(now, xr_stat.tx.stat_sum.update);
+	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		    now.sec / 3600,
+		    (now.sec % 3600) / 60,
+		    now.sec % 60,
+		    now.msec);
+	}
+
+	printf(" TX last update: %s\n"
+	       "    begin seq=%d, end seq=%d%s\n"
+	       "    pkt loss=%s, dup=%s%s\n"
+	       "          (msec)    min     avg     max     dev\n"
+	       "    jitter     : %s\n"
+	       "    toh        : %s\n",
+	       last_update,
+	       xr_stat.tx.stat_sum.begin_seq, xr_stat.tx.stat_sum.end_seq,
+	       "",
+	       loss, dup,
+	       "",
+	       jitter,
+	       toh
+	       );
+
+	/* VoIP Metrics */
+	puts(" VoIP Metrics");
+
+	PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.rx.voip_mtc.signal_lvl);
+	PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.rx.voip_mtc.noise_lvl);
+	PRINT_VOIP_MTC_VAL(rerl, xr_stat.rx.voip_mtc.rerl);
+	PRINT_VOIP_MTC_VAL(r_factor, xr_stat.rx.voip_mtc.r_factor);
+	PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.rx.voip_mtc.ext_r_factor);
+	PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.rx.voip_mtc.mos_lq);
+	PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.rx.voip_mtc.mos_cq);
+
+	switch ((xr_stat.rx.voip_mtc.rx_config>>6) & 3) {
+	    case PJMEDIA_RTCP_XR_PLC_DIS:
+		sprintf(plc, "DISABLED");
+		break;
+	    case PJMEDIA_RTCP_XR_PLC_ENH:
+		sprintf(plc, "ENHANCED");
+		break;
+	    case PJMEDIA_RTCP_XR_PLC_STD:
+		sprintf(plc, "STANDARD");
+		break;
+	    case PJMEDIA_RTCP_XR_PLC_UNK:
+	    default:
+		sprintf(plc, "UNKNOWN");
+		break;
+	}
+
+	switch ((xr_stat.rx.voip_mtc.rx_config>>4) & 3) {
+	    case PJMEDIA_RTCP_XR_JB_FIXED:
+		sprintf(jba, "FIXED");
+		break;
+	    case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
+		sprintf(jba, "ADAPTIVE");
+		break;
+	    default:
+		sprintf(jba, "UNKNOWN");
+		break;
+	}
+
+	sprintf(jbr, "%d", xr_stat.rx.voip_mtc.rx_config & 0x0F);
+
+	if (xr_stat.rx.voip_mtc.update.sec == 0)
+	    strcpy(last_update, "never");
+	else {
+	    pj_gettimeofday(&now);
+	    PJ_TIME_VAL_SUB(now, xr_stat.rx.voip_mtc.update);
+	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		    now.sec / 3600,
+		    (now.sec % 3600) / 60,
+		    now.sec % 60,
+		    now.msec);
+	}
+
+	printf(" RX last update: %s\n"
+	       "    packets    : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
+	       "    burst      : density=%d (%.2f%%), duration=%d%s\n"
+	       "    gap        : density=%d (%.2f%%), duration=%d%s\n"
+	       "    delay      : round trip=%d%s, end system=%d%s\n"
+	       "    level      : signal=%s%s, noise=%s%s, RERL=%s%s\n"
+	       "    quality    : R factor=%s, ext R factor=%s\n"
+	       "                 MOS LQ=%s, MOS CQ=%s\n"
+	       "    config     : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
+	       "    JB delay   : cur=%d%s, max=%d%s, abs max=%d%s\n",
+	       last_update,
+	       /* pakcets */
+	       xr_stat.rx.voip_mtc.loss_rate, xr_stat.rx.voip_mtc.loss_rate*100.0/256,
+	       xr_stat.rx.voip_mtc.discard_rate, xr_stat.rx.voip_mtc.discard_rate*100.0/256,
+	       /* burst */
+	       xr_stat.rx.voip_mtc.burst_den, xr_stat.rx.voip_mtc.burst_den*100.0/256,
+	       xr_stat.rx.voip_mtc.burst_dur, "ms",
+	       /* gap */
+	       xr_stat.rx.voip_mtc.gap_den, xr_stat.rx.voip_mtc.gap_den*100.0/256,
+	       xr_stat.rx.voip_mtc.gap_dur, "ms",
+	       /* delay */
+	       xr_stat.rx.voip_mtc.rnd_trip_delay, "ms",
+	       xr_stat.rx.voip_mtc.end_sys_delay, "ms",
+	       /* level */
+	       signal_lvl, "dB",
+	       noise_lvl, "dB",
+	       rerl, "",
+	       /* quality */
+	       r_factor, ext_r_factor, mos_lq, mos_cq,
+	       /* config */
+	       plc, jba, jbr, xr_stat.rx.voip_mtc.gmin,
+	       /* JB delay */
+	       xr_stat.rx.voip_mtc.jb_nom, "ms",
+	       xr_stat.rx.voip_mtc.jb_max, "ms",
+	       xr_stat.rx.voip_mtc.jb_abs_max, "ms"
+	       );
+
+	PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.tx.voip_mtc.signal_lvl);
+	PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.tx.voip_mtc.noise_lvl);
+	PRINT_VOIP_MTC_VAL(rerl, xr_stat.tx.voip_mtc.rerl);
+	PRINT_VOIP_MTC_VAL(r_factor, xr_stat.tx.voip_mtc.r_factor);
+	PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.tx.voip_mtc.ext_r_factor);
+	PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.tx.voip_mtc.mos_lq);
+	PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.tx.voip_mtc.mos_cq);
+
+	switch ((xr_stat.tx.voip_mtc.rx_config>>6) & 3) {
+	    case PJMEDIA_RTCP_XR_PLC_DIS:
+		sprintf(plc, "DISABLED");
+		break;
+	    case PJMEDIA_RTCP_XR_PLC_ENH:
+		sprintf(plc, "ENHANCED");
+		break;
+	    case PJMEDIA_RTCP_XR_PLC_STD:
+		sprintf(plc, "STANDARD");
+		break;
+	    case PJMEDIA_RTCP_XR_PLC_UNK:
+	    default:
+		sprintf(plc, "unknown");
+		break;
+	}
+
+	switch ((xr_stat.tx.voip_mtc.rx_config>>4) & 3) {
+	    case PJMEDIA_RTCP_XR_JB_FIXED:
+		sprintf(jba, "FIXED");
+		break;
+	    case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
+		sprintf(jba, "ADAPTIVE");
+		break;
+	    default:
+		sprintf(jba, "unknown");
+		break;
+	}
+
+	sprintf(jbr, "%d", xr_stat.tx.voip_mtc.rx_config & 0x0F);
+
+	if (xr_stat.tx.voip_mtc.update.sec == 0)
+	    strcpy(last_update, "never");
+	else {
+	    pj_gettimeofday(&now);
+	    PJ_TIME_VAL_SUB(now, xr_stat.tx.voip_mtc.update);
+	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		    now.sec / 3600,
+		    (now.sec % 3600) / 60,
+		    now.sec % 60,
+		    now.msec);
+	}
+
+	printf(" TX last update: %s\n"
+	       "    packets    : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
+	       "    burst      : density=%d (%.2f%%), duration=%d%s\n"
+	       "    gap        : density=%d (%.2f%%), duration=%d%s\n"
+	       "    delay      : round trip=%d%s, end system=%d%s\n"
+	       "    level      : signal=%s%s, noise=%s%s, RERL=%s%s\n"
+	       "    quality    : R factor=%s, ext R factor=%s\n"
+	       "                 MOS LQ=%s, MOS CQ=%s\n"
+	       "    config     : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
+	       "    JB delay   : cur=%d%s, max=%d%s, abs max=%d%s\n",
+	       last_update,
+	       /* pakcets */
+	       xr_stat.tx.voip_mtc.loss_rate, xr_stat.tx.voip_mtc.loss_rate*100.0/256,
+	       xr_stat.tx.voip_mtc.discard_rate, xr_stat.tx.voip_mtc.discard_rate*100.0/256,
+	       /* burst */
+	       xr_stat.tx.voip_mtc.burst_den, xr_stat.tx.voip_mtc.burst_den*100.0/256,
+	       xr_stat.tx.voip_mtc.burst_dur, "ms",
+	       /* gap */
+	       xr_stat.tx.voip_mtc.gap_den, xr_stat.tx.voip_mtc.gap_den*100.0/256,
+	       xr_stat.tx.voip_mtc.gap_dur, "ms",
+	       /* delay */
+	       xr_stat.tx.voip_mtc.rnd_trip_delay, "ms",
+	       xr_stat.tx.voip_mtc.end_sys_delay, "ms",
+	       /* level */
+	       signal_lvl, "dB",
+	       noise_lvl, "dB",
+	       rerl, "",
+	       /* quality */
+	       r_factor, ext_r_factor, mos_lq, mos_cq,
+	       /* config */
+	       plc, jba, jbr, xr_stat.tx.voip_mtc.gmin,
+	       /* JB delay */
+	       xr_stat.tx.voip_mtc.jb_nom, "ms",
+	       xr_stat.tx.voip_mtc.jb_max, "ms",
+	       xr_stat.tx.voip_mtc.jb_abs_max, "ms"
+	       );
+
+
+	/* RTT delay (by receiver side) */
+	printf("          (msec)    min     avg     max     last    dev\n");
+	printf(" RTT delay     : %7.3f %7.3f %7.3f %7.3f %7.3f%s\n", 
+	       xr_stat.rtt.min / 1000.0,
+	       xr_stat.rtt.mean / 1000.0,
+	       xr_stat.rtt.max / 1000.0,
+	       xr_stat.rtt.last / 1000.0,
+	       pj_math_stat_get_stddev(&xr_stat.rtt) / 1000.0,
+	       ""
+	       );
+    } while (0);
+#endif /* PJMEDIA_HAS_RTCP_XR */
+
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/strerror.c b/jni/libpjsip/sources/pjsip-apps/src/samples/strerror.c
new file mode 100644
index 0000000..b03e8c1
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/strerror.c
@@ -0,0 +1,71 @@
+/* $Id: strerror.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/**
+ * \page page_strerror_c Samples: Print out error message
+ *
+ * This file is pjsip-apps/src/samples/strerror.c
+ *
+ * \includelineno strerror.c
+ */
+
+
+#include <pjlib.h>
+#include <pjlib-util.h>
+#include <pjsip.h>
+#include <pjmedia.h>
+#include <pjnath.h>
+#include <pjsip_simple.h>
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_ept;
+    pjsip_endpoint *sip_ept;
+    char errmsg[PJ_ERR_MSG_SIZE];
+    pj_status_t code;
+
+    if (argc != 2) {
+	puts("Usage: strerror ERRNUM");
+	return 1;
+    }
+
+    pj_log_set_level(3);
+
+    pj_init();
+    pj_caching_pool_init(&cp, NULL, 0);
+    pjlib_util_init();
+    pjnath_init();
+    pjmedia_endpt_create(&cp.factory, NULL, 0, &med_ept);
+    pjsip_endpt_create(&cp.factory, "localhost", &sip_ept);
+    pjsip_evsub_init_module(sip_ept);
+
+    code = atoi(argv[1]);
+    pj_strerror(code, errmsg, sizeof(errmsg));
+
+    printf("Status %d: %s\n", code, errmsg);
+
+    pj_shutdown();
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/tonegen.c b/jni/libpjsip/sources/pjsip-apps/src/samples/tonegen.c
new file mode 100644
index 0000000..ea9480b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/tonegen.c
@@ -0,0 +1,159 @@
+/* $Id: tonegen.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 
+ */
+
+/**
+ * \page page_pjmedia_samples_tonegen_c Samples: Sine Wave/Dual-Tone Generation
+ *
+ * This is a simple program to generate a tone and write the samples to
+ * a raw PCM file. The main purpose of this file is to analyze the
+ * quality of the tones/sine wave generated by PJMEDIA tone/sine wave
+ * generator.
+ *
+ * This file is pjsip-apps/src/samples/tonegen.c
+ *
+ * \includelineno tonegen.c
+ */
+
+
+#include <pjmedia.h>
+#include <pjlib.h>
+
+#define SAMPLES_PER_FRAME   64
+#define ON_DURATION	    100
+#define OFF_DURATION	    100
+
+
+/*
+ * main()
+ */
+int main()
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_port *port;
+    unsigned i;
+    pj_status_t status;
+
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "app",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    status = pjmedia_tonegen_create(pool, 8000, 1, SAMPLES_PER_FRAME, 16, 0, &port);
+    if (status != PJ_SUCCESS)
+	return 1;
+
+    {
+	pjmedia_tone_desc tones[3];
+
+	tones[0].freq1 = 200;
+	tones[0].freq2 = 0;
+	tones[0].on_msec = ON_DURATION;
+	tones[0].off_msec = OFF_DURATION;
+
+	tones[1].freq1 = 400;
+	tones[1].freq2 = 0;
+	tones[1].on_msec = ON_DURATION;
+	tones[1].off_msec = OFF_DURATION;
+
+	tones[2].freq1 = 800;
+	tones[2].freq2 = 0;
+	tones[2].on_msec = ON_DURATION;
+	tones[2].off_msec = OFF_DURATION;
+
+	status = pjmedia_tonegen_play(port, 3, tones, 0);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, 1);
+    }
+
+    {
+	pjmedia_tone_digit digits[2];
+
+	digits[0].digit = '0';
+	digits[0].on_msec = ON_DURATION;
+	digits[0].off_msec = OFF_DURATION;
+
+	digits[1].digit = '0';
+	digits[1].on_msec = ON_DURATION;
+	digits[1].off_msec = OFF_DURATION;
+
+	status = pjmedia_tonegen_play_digits(port, 2, digits, 0);
+	PJ_ASSERT_RETURN(status==PJ_SUCCESS, 1);
+    }
+
+    {
+	pjmedia_frame frm;
+	FILE *f;
+	void *buf;
+
+	buf = pj_pool_alloc(pool, 2*8000);
+	frm.buf = buf;
+
+	f = fopen("tonegen.pcm", "wb");
+
+	for (i=0; i<8000/SAMPLES_PER_FRAME; ++i) {
+	    pj_size_t count;
+	    pjmedia_port_get_frame(port, &frm);
+	    count = fwrite(buf, SAMPLES_PER_FRAME, 2, f);
+	    if (count != 2)
+		break;
+	}
+
+	pj_assert(pjmedia_tonegen_is_busy(port) == 0);
+	fclose(f);
+    }
+
+    /* Delete port */
+    pjmedia_port_destroy(port);
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+
+    /* Done. */
+    return 0;
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/util.h b/jni/libpjsip/sources/pjsip-apps/src/samples/util.h
new file mode 100644
index 0000000..e68056f
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/util.h
@@ -0,0 +1,173 @@
+/* $Id: util.h 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 <stdlib.h>	/* strtol() */
+
+/* Util to display the error message for the specified error code  */
+static int app_perror( const char *sender, const char *title, 
+		       pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+
+    PJ_LOG(3,(sender, "%s: %s [code=%d]", title, errmsg, status));
+    return 1;
+}
+
+
+
+/* Constants */
+#define CLOCK_RATE	44100
+#define NSAMPLES	(CLOCK_RATE * 20 / 1000)
+#define NCHANNELS	1
+#define NBITS		16
+
+/*
+ * Common sound options.
+ */
+#define SND_USAGE   \
+"  -d, --dev=NUM        Sound device use device id NUM (default=-1)	 \n"\
+"  -r, --rate=HZ        Set clock rate in samples per sec (default=44100)\n"\
+"  -c, --channel=NUM    Set # of channels (default=1 for mono).		 \n"\
+"  -f, --frame=NUM      Set # of samples per frame (default equival 20ms)\n"\
+"  -b, --bit=NUM        Set # of bits per sample (default=16)		 \n"
+
+
+/*
+ * This utility function parses the command line and look for
+ * common sound options.
+ */
+pj_status_t get_snd_options(const char *app_name,
+			    int argc, 
+			    char *argv[],
+			    int *dev_id,
+			    int *clock_rate,
+			    int *channel_count,
+			    int *samples_per_frame,
+			    int *bits_per_sample)
+{
+    struct pj_getopt_option long_options[] = {
+	{ "dev",	1, 0, 'd' },
+	{ "rate",	1, 0, 'r' },
+	{ "channel",	1, 0, 'c' },
+	{ "frame",	1, 0, 'f' },
+	{ "bit",	1, 0, 'b' },
+	{ NULL, 0, 0, 0 },
+    };
+    int c;
+    int option_index;
+    long val;
+    char *err;
+
+    *samples_per_frame = 0;
+
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc,argv, "d:r:c:f:b:", 
+			    long_options, &option_index))!=-1) 
+    {
+
+	switch (c) {
+	case 'd':
+	    /* device */
+	    val = strtol(pj_optarg, &err, 10);
+	    if (*err) {
+		PJ_LOG(3,(app_name, "Error: invalid value for device id"));
+		return PJ_EINVAL;
+	    }
+	    *dev_id = val;
+	    break;
+
+	case 'r':
+	    /* rate */
+	    val = strtol(pj_optarg, &err, 10);
+	    if (*err) {
+		PJ_LOG(3,(app_name, "Error: invalid value for clock rate"));
+		return PJ_EINVAL;
+	    }
+	    *clock_rate = val;
+	    break;
+
+	case 'c':
+	    /* channel count */
+	    val = strtol(pj_optarg, &err, 10);
+	    if (*err) {
+		PJ_LOG(3,(app_name, "Error: invalid channel count"));
+		return PJ_EINVAL;
+	    }
+	    *channel_count = val;
+	    break;
+
+	case 'f':
+	    /* frame count/samples per frame */
+	    val = strtol(pj_optarg, &err, 10);
+	    if (*err) {
+		PJ_LOG(3,(app_name, "Error: invalid samples per frame"));
+		return PJ_EINVAL;
+	    }
+	    *samples_per_frame = val;
+	    break;
+
+	case 'b':
+	    /* bit per sample */
+	    val = strtol(pj_optarg, &err, 10);
+	    if (*err) {
+		PJ_LOG(3,(app_name, "Error: invalid samples bits per sample"));
+		return PJ_EINVAL;
+	    }
+	    *bits_per_sample = val;
+	    break;
+
+	default:
+	    /* Unknown options */
+	    PJ_LOG(3,(app_name, "Error: unknown options '%c'", pj_optopt));
+	    return PJ_EINVAL;
+	}
+
+    }
+
+    if (*samples_per_frame == 0) {
+	*samples_per_frame = *clock_rate * *channel_count * 20 / 1000;
+    }
+
+    return 0;
+}
+
+
+/* Dump memory pool usage. */
+void dump_pool_usage( const char *app_name, pj_caching_pool *cp )
+{
+#if !defined(PJ_HAS_POOL_ALT_API) || PJ_HAS_POOL_ALT_API==0
+    pj_pool_t   *p;
+    pj_size_t    total_alloc = 0;
+    pj_size_t    total_used = 0;
+
+    /* Accumulate memory usage in active list. */
+    p = cp->used_list.next;
+    while (p != (pj_pool_t*) &cp->used_list) {
+	total_alloc += pj_pool_get_capacity(p);
+	total_used += pj_pool_get_used_size(p);
+	p = p->next;
+    }
+
+    PJ_LOG(3, (app_name, "Total pool memory allocated=%d KB, used=%d KB",
+	       total_alloc / 1000,
+	       total_used / 1000));
+#endif
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/samples/vid_streamutil.c b/jni/libpjsip/sources/pjsip-apps/src/samples/vid_streamutil.c
new file mode 100644
index 0000000..6b250b9
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/samples/vid_streamutil.c
@@ -0,0 +1,968 @@
+/* $Id: vid_streamutil.c 4537 2013-06-19 06:47:43Z riza $ */
+/* 
+ * Copyright (C) 2011 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 
+ */
+
+
+/**
+ * \page page_pjmedia_samples_vid_streamutil_c Samples: Video Streaming
+ *
+ * This example mainly demonstrates how to stream video to remote
+ * peer using RTP.
+ *
+ * This file is pjsip-apps/src/samples/vid_streamutil.c
+ *
+ * \includelineno vid_streamutil.c
+ */
+
+#include <pjlib.h>
+#include <pjlib-util.h>
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+#include <pjmedia/transport_srtp.h>
+
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+
+
+#include <stdlib.h>	/* atoi() */
+#include <stdio.h>
+
+#include "util.h"
+
+
+static const char *desc = 
+ " vid_streamutil                                                       \n"
+ "\n"
+ " PURPOSE:                                                             \n"
+ "  Demonstrate how to use pjmedia video stream component to		\n"
+ "  transmit/receive RTP packets to/from video device/file.		\n"
+ "\n"
+ "\n"
+ " USAGE:                                                               \n"
+ "  vid_streamutil [options]                                            \n"
+ "\n"
+ "\n"
+ " Options:                                                             \n"
+ "  --codec=CODEC         Set the codec name.                           \n"
+ "  --local-port=PORT     Set local RTP port (default=4000)             \n"
+ "  --remote=IP:PORT      Set the remote peer. If this option is set,   \n"
+ "                        the program will transmit RTP audio to the    \n"
+ "                        specified address. (default: recv only)       \n"
+ "  --play-file=AVI       Send video from the AVI file instead of from  \n"
+ "                        the video device.                             \n"
+ "  --send-recv           Set stream direction to bidirectional.        \n"
+ "  --send-only           Set stream direction to send only             \n"
+ "  --recv-only           Set stream direction to recv only (default)   \n"
+ 
+ "  --send-width          Video width to be sent                        \n"
+ "  --send-height         Video height to be sent                       \n"
+ "                        --send-width and --send-height not applicable \n"
+ "                        for file streaming (see --play-file)          \n"
+
+ "  --send-pt             Payload type for sending                      \n"
+ "  --recv-pt             Payload type for receiving                    \n"
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ "  --use-srtp[=NAME]     Enable SRTP with crypto suite NAME            \n"
+ "                        e.g: AES_CM_128_HMAC_SHA1_80 (default),       \n"
+ "                             AES_CM_128_HMAC_SHA1_32                  \n"
+ "                        Use this option along with the TX & RX keys,  \n"
+ "                        formated of 60 hex digits (e.g: E148DA..)     \n"
+ "  --srtp-tx-key         SRTP key for transmiting                      \n"
+ "  --srtp-rx-key         SRTP key for receiving                        \n"
+#endif
+
+ "\n"
+;
+
+#define THIS_FILE	"vid_streamutil.c"
+
+
+/* If set, local renderer will be created to play original file */
+#define HAS_LOCAL_RENDERER_FOR_PLAY_FILE    1
+
+
+/* Default width and height for the renderer, better be set to maximum
+ * acceptable size.
+ */
+#define DEF_RENDERER_WIDTH		    640
+#define DEF_RENDERER_HEIGHT		    480
+
+
+/* Prototype */
+static void print_stream_stat(pjmedia_vid_stream *stream,
+			      const pjmedia_vid_codec_param *codec_param);
+
+/* Prototype for LIBSRTP utility in file datatypes.c */
+int hex_string_to_octet_string(char *raw, char *hex, int len);
+
+/* 
+ * Register all codecs. 
+ */
+static pj_status_t init_codecs(pj_pool_factory *pf)
+{
+    pj_status_t status;
+
+    /* To suppress warning about unused var when all codecs are disabled */
+    PJ_UNUSED_ARG(status);
+
+#if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC != 0
+    status = pjmedia_codec_ffmpeg_vid_init(NULL, pf);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+#endif
+
+    return PJ_SUCCESS;
+}
+
+/* 
+ * Register all codecs. 
+ */
+static void deinit_codecs()
+{
+#if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC != 0
+    pjmedia_codec_ffmpeg_vid_deinit();
+#endif
+}
+
+static pj_status_t create_file_player( pj_pool_t *pool,
+				       const char *file_name,
+				       pjmedia_port **p_play_port)
+{
+    pjmedia_avi_streams *avi_streams;
+    pjmedia_avi_stream *vid_stream;
+    pjmedia_port *play_port;
+    pj_status_t status;
+
+    status = pjmedia_avi_player_create_streams(pool, file_name, 0, &avi_streams);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
+                                                         0,
+                                                         PJMEDIA_TYPE_VIDEO);
+    if (!vid_stream)
+	return PJ_ENOTFOUND;
+
+    play_port = pjmedia_avi_stream_get_port(vid_stream);
+    pj_assert(play_port);
+
+    *p_play_port = play_port;
+
+    return PJ_SUCCESS;
+}
+
+/* 
+ * Create stream based on the codec, dir, remote address, etc. 
+ */
+static pj_status_t create_stream( pj_pool_t *pool,
+				  pjmedia_endpt *med_endpt,
+				  const pjmedia_vid_codec_info *codec_info,
+                                  pjmedia_vid_codec_param *codec_param,
+				  pjmedia_dir dir,
+				  pj_int8_t rx_pt,
+				  pj_int8_t tx_pt,
+				  pj_uint16_t local_port,
+				  const pj_sockaddr_in *rem_addr,
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+				  pj_bool_t use_srtp,
+				  const pj_str_t *crypto_suite,
+				  const pj_str_t *srtp_tx_key,
+				  const pj_str_t *srtp_rx_key,
+#endif
+				  pjmedia_vid_stream **p_stream )
+{
+    pjmedia_vid_stream_info info;
+    pjmedia_transport *transport = NULL;
+    pj_status_t status;
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    pjmedia_transport *srtp_tp = NULL;
+#endif
+
+    /* Reset stream info. */
+    pj_bzero(&info, sizeof(info));
+
+    /* Initialize stream info formats */
+    info.type = PJMEDIA_TYPE_VIDEO;
+    info.dir = dir;
+    info.codec_info = *codec_info;
+    info.tx_pt = (tx_pt == -1)? codec_info->pt : tx_pt;
+    info.rx_pt = (rx_pt == -1)? codec_info->pt : rx_pt;
+    info.ssrc = pj_rand();
+    if (codec_param)
+        info.codec_param = codec_param;
+    
+    /* Copy remote address */
+    pj_memcpy(&info.rem_addr, rem_addr, sizeof(pj_sockaddr_in));
+
+    /* If remote address is not set, set to an arbitrary address
+     * (otherwise stream will assert).
+     */
+    if (info.rem_addr.addr.sa_family == 0) {
+	const pj_str_t addr = pj_str("127.0.0.1");
+	pj_sockaddr_in_init(&info.rem_addr.ipv4, &addr, 0);
+    }
+
+    /* Create media transport */
+    status = pjmedia_transport_udp_create(med_endpt, NULL, local_port,
+					  0, &transport);
+    if (status != PJ_SUCCESS)
+	return status;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    /* Check if SRTP enabled */
+    if (use_srtp) {
+	pjmedia_srtp_crypto tx_plc, rx_plc;
+
+	status = pjmedia_transport_srtp_create(med_endpt, transport, 
+					       NULL, &srtp_tp);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	pj_bzero(&tx_plc, sizeof(pjmedia_srtp_crypto));
+	pj_bzero(&rx_plc, sizeof(pjmedia_srtp_crypto));
+
+	tx_plc.key = *srtp_tx_key;
+	tx_plc.name = *crypto_suite;
+	rx_plc.key = *srtp_rx_key;
+	rx_plc.name = *crypto_suite;
+	
+	status = pjmedia_transport_srtp_start(srtp_tp, &tx_plc, &rx_plc);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	transport = srtp_tp;
+    }
+#endif
+
+    /* Now that the stream info is initialized, we can create the 
+     * stream.
+     */
+
+    status = pjmedia_vid_stream_create( med_endpt, pool, &info, 
+					transport, 
+					NULL, p_stream);
+
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Error creating stream", status);
+	pjmedia_transport_close(transport);
+	return status;
+    }
+
+
+    return PJ_SUCCESS;
+}
+
+
+typedef struct play_file_data
+{
+    const char *file_name;
+    pjmedia_port *play_port;
+    pjmedia_port *stream_port;
+    pjmedia_vid_codec *decoder;
+    pjmedia_port *renderer;
+    void *read_buf;
+    pj_size_t read_buf_size;
+    void *dec_buf;
+    pj_size_t dec_buf_size;
+} play_file_data;
+
+
+static void clock_cb(const pj_timestamp *ts, void *user_data)
+{
+    play_file_data *play_file = (play_file_data*)user_data;
+    pjmedia_frame read_frame, write_frame;
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(ts);
+
+    /* Read frame from file */
+    read_frame.buf = play_file->read_buf;
+    read_frame.size = play_file->read_buf_size;
+    pjmedia_port_get_frame(play_file->play_port, &read_frame);
+
+    /* Decode frame, if needed */
+    if (play_file->decoder) {
+	pjmedia_vid_codec *decoder = play_file->decoder;
+
+	write_frame.buf = play_file->dec_buf;
+	write_frame.size = play_file->dec_buf_size;
+	status = pjmedia_vid_codec_decode(decoder, 1, &read_frame,
+	                                  (unsigned)write_frame.size, 
+					  &write_frame);
+	if (status != PJ_SUCCESS)
+	    return;
+    } else {
+	write_frame = read_frame;
+    }
+
+    /* Display frame locally */
+    if (play_file->renderer)
+	pjmedia_port_put_frame(play_file->renderer, &write_frame);
+
+    /* Send frame */
+    pjmedia_port_put_frame(play_file->stream_port, &write_frame);
+}
+
+
+/*
+ * usage()
+ */
+static void usage()
+{
+    puts(desc);
+}
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_vid_stream *stream = NULL;
+    pjmedia_port *enc_port, *dec_port;
+    pj_status_t status; 
+
+    pjmedia_vid_port *capture=NULL, *renderer=NULL;
+    pjmedia_vid_port_param vpp;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    /* SRTP variables */
+    pj_bool_t use_srtp = PJ_FALSE;
+    char tmp_tx_key[64];
+    char tmp_rx_key[64];
+    pj_str_t  srtp_tx_key = {NULL, 0};
+    pj_str_t  srtp_rx_key = {NULL, 0};
+    pj_str_t  srtp_crypto_suite = {NULL, 0};
+    int	tmp_key_len;
+#endif
+
+    /* Default values */
+    const pjmedia_vid_codec_info *codec_info;
+    pjmedia_vid_codec_param codec_param;
+    pjmedia_dir dir = PJMEDIA_DIR_DECODING;
+    pj_sockaddr_in remote_addr;
+    pj_uint16_t local_port = 4000;
+    char *codec_id = NULL;
+    pjmedia_rect_size tx_size = {0};
+    pj_int8_t rx_pt = -1, tx_pt = -1;
+
+    play_file_data play_file = { NULL };
+    pjmedia_port *play_port = NULL;
+    pjmedia_vid_codec *play_decoder = NULL;
+    pjmedia_clock *play_clock = NULL;
+
+    enum {
+	OPT_CODEC	= 'c',
+	OPT_LOCAL_PORT	= 'p',
+	OPT_REMOTE	= 'r',
+	OPT_PLAY_FILE	= 'f',
+	OPT_SEND_RECV	= 'b',
+	OPT_SEND_ONLY	= 's',
+	OPT_RECV_ONLY	= 'i',
+	OPT_SEND_WIDTH	= 'W',
+	OPT_SEND_HEIGHT	= 'H',
+	OPT_RECV_PT	= 't',
+	OPT_SEND_PT	= 'T',
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+	OPT_USE_SRTP	= 'S',
+#endif
+	OPT_SRTP_TX_KEY	= 'x',
+	OPT_SRTP_RX_KEY	= 'y',
+	OPT_HELP	= 'h',
+    };
+
+    struct pj_getopt_option long_options[] = {
+	{ "codec",	    1, 0, OPT_CODEC },
+	{ "local-port",	    1, 0, OPT_LOCAL_PORT },
+	{ "remote",	    1, 0, OPT_REMOTE },
+	{ "play-file",	    1, 0, OPT_PLAY_FILE },
+	{ "send-recv",      0, 0, OPT_SEND_RECV },
+	{ "send-only",      0, 0, OPT_SEND_ONLY },
+	{ "recv-only",      0, 0, OPT_RECV_ONLY },
+	{ "send-width",     1, 0, OPT_SEND_WIDTH },
+	{ "send-height",    1, 0, OPT_SEND_HEIGHT },
+	{ "recv-pt",        1, 0, OPT_RECV_PT },
+	{ "send-pt",        1, 0, OPT_SEND_PT },
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+	{ "use-srtp",	    2, 0, OPT_USE_SRTP },
+	{ "srtp-tx-key",    1, 0, OPT_SRTP_TX_KEY },
+	{ "srtp-rx-key",    1, 0, OPT_SRTP_RX_KEY },
+#endif
+	{ "help",	    0, 0, OPT_HELP },
+	{ NULL, 0, 0, 0 },
+    };
+
+    int c;
+    int option_index;
+
+
+    pj_bzero(&remote_addr, sizeof(remote_addr));
+
+
+    /* init PJLIB : */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Parse arguments */
+    pj_optind = 0;
+    while((c=pj_getopt_long(argc,argv, "h", long_options, &option_index))!=-1)
+    {
+	switch (c) {
+	case OPT_CODEC:
+	    codec_id = pj_optarg;
+	    break;
+
+	case OPT_LOCAL_PORT:
+	    local_port = (pj_uint16_t) atoi(pj_optarg);
+	    if (local_port < 1) {
+		printf("Error: invalid local port %s\n", pj_optarg);
+		return 1;
+	    }
+	    break;
+
+	case OPT_REMOTE:
+	    {
+		pj_str_t ip = pj_str(strtok(pj_optarg, ":"));
+		pj_uint16_t port = (pj_uint16_t) atoi(strtok(NULL, ":"));
+
+		status = pj_sockaddr_in_init(&remote_addr, &ip, port);
+		if (status != PJ_SUCCESS) {
+		    app_perror(THIS_FILE, "Invalid remote address", status);
+		    return 1;
+		}
+	    }
+	    break;
+
+	case OPT_PLAY_FILE:
+	    play_file.file_name = pj_optarg;
+	    break;
+
+	case OPT_SEND_RECV:
+	    dir = PJMEDIA_DIR_ENCODING_DECODING;
+	    break;
+
+	case OPT_SEND_ONLY:
+	    dir = PJMEDIA_DIR_ENCODING;
+	    break;
+
+	case OPT_RECV_ONLY:
+	    dir = PJMEDIA_DIR_DECODING;
+	    break;
+
+	case OPT_SEND_WIDTH:
+	    tx_size.w = (unsigned)atoi(pj_optarg);
+	    break;
+
+	case OPT_SEND_HEIGHT:
+	    tx_size.h = (unsigned)atoi(pj_optarg);
+	    break;
+
+	case OPT_RECV_PT:
+	    rx_pt = (pj_int8_t)atoi(pj_optarg);
+	    break;
+
+	case OPT_SEND_PT:
+	    tx_pt = (pj_int8_t)atoi(pj_optarg);
+	    break;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+	case OPT_USE_SRTP:
+	    use_srtp = PJ_TRUE;
+	    if (pj_optarg) {
+		pj_strset(&srtp_crypto_suite, pj_optarg, strlen(pj_optarg));
+	    } else {
+		srtp_crypto_suite = pj_str("AES_CM_128_HMAC_SHA1_80");
+	    }
+	    break;
+
+	case OPT_SRTP_TX_KEY:
+	    tmp_key_len = hex_string_to_octet_string(tmp_tx_key, pj_optarg, 
+						     (int)strlen(pj_optarg));
+	    pj_strset(&srtp_tx_key, tmp_tx_key, tmp_key_len/2);
+	    break;
+
+	case OPT_SRTP_RX_KEY:
+	    tmp_key_len = hex_string_to_octet_string(tmp_rx_key, pj_optarg,
+						     (int)strlen(pj_optarg));
+	    pj_strset(&srtp_rx_key, tmp_rx_key, tmp_key_len/2);
+	    break;
+#endif
+
+	case OPT_HELP:
+	    usage();
+	    return 1;
+
+	default:
+	    printf("Invalid options %s\n", argv[pj_optind]);
+	    return 1;
+	}
+
+    }
+
+
+    /* Verify arguments. */
+    if (dir & PJMEDIA_DIR_ENCODING) {
+	if (remote_addr.sin_addr.s_addr == 0) {
+	    printf("Error: remote address must be set\n");
+	    return 1;
+	}
+    }
+
+    if (play_file.file_name != NULL && dir != PJMEDIA_DIR_ENCODING) {
+	printf("Direction is set to --send-only because of --play-file\n");
+	dir = PJMEDIA_DIR_ENCODING;
+    }
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+    /* SRTP validation */
+    if (use_srtp) {
+	if (!srtp_tx_key.slen || !srtp_rx_key.slen)
+	{
+	    printf("Error: Key for each SRTP stream direction must be set\n");
+	    return 1;
+	}
+    }
+#endif
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for application purpose */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "app",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    /* Init video format manager */
+    pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
+
+    /* Init video converter manager */
+    pjmedia_converter_mgr_create(pool, NULL);
+
+    /* Init event manager */
+    pjmedia_event_mgr_create(pool, 0, NULL);
+
+    /* Init video codec manager */
+    pjmedia_vid_codec_mgr_create(pool, NULL);
+
+    /* Init video subsystem */
+    pjmedia_vid_dev_subsys_init(&cp.factory);
+
+    /* Register all supported codecs */
+    status = init_codecs(&cp.factory);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+    /* Find which codec to use. */
+    if (codec_id) {
+	unsigned count = 1;
+	pj_str_t str_codec_id = pj_str(codec_id);
+
+        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
+						         &str_codec_id, &count,
+						         &codec_info, NULL);
+	if (status != PJ_SUCCESS) {
+	    printf("Error: unable to find codec %s\n", codec_id);
+	    return 1;
+	}
+    } else {
+        static pjmedia_vid_codec_info info[1];
+        unsigned count = PJ_ARRAY_SIZE(info);
+
+	/* Default to first codec */
+	pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, NULL);
+        codec_info = &info[0];
+    }
+
+    /* Get codec default param for info */
+    status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info, 
+				                     &codec_param);
+    pj_assert(status == PJ_SUCCESS);
+    
+    /* Set outgoing video size */
+    if (tx_size.w && tx_size.h)
+        codec_param.enc_fmt.det.vid.size = tx_size;
+
+#if DEF_RENDERER_WIDTH && DEF_RENDERER_HEIGHT
+    /* Set incoming video size */
+    if (DEF_RENDERER_WIDTH > codec_param.dec_fmt.det.vid.size.w)
+	codec_param.dec_fmt.det.vid.size.w = DEF_RENDERER_WIDTH;
+    if (DEF_RENDERER_HEIGHT > codec_param.dec_fmt.det.vid.size.h)
+	codec_param.dec_fmt.det.vid.size.h = DEF_RENDERER_HEIGHT;
+#endif
+
+    if (play_file.file_name) {
+	pjmedia_video_format_detail *file_vfd;
+        pjmedia_clock_param clock_param;
+        char fmt_name[5];
+
+	/* Create file player */
+	status = create_file_player(pool, play_file.file_name, &play_port);
+	if (status != PJ_SUCCESS)
+	    goto on_exit;
+
+	/* Collect format info */
+	file_vfd = pjmedia_format_get_video_format_detail(&play_port->info.fmt,
+							  PJ_TRUE);
+	PJ_LOG(2, (THIS_FILE, "Reading video stream %dx%d %s @%.2ffps",
+		   file_vfd->size.w, file_vfd->size.h,
+		   pjmedia_fourcc_name(play_port->info.fmt.id, fmt_name),
+		   (1.0*file_vfd->fps.num/file_vfd->fps.denum)));
+
+	/* Allocate file read buffer */
+	play_file.read_buf_size = PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE;
+	play_file.read_buf = pj_pool_zalloc(pool, play_file.read_buf_size);
+
+	/* Create decoder, if the file and the stream uses different codec */
+	if (codec_info->fmt_id != (pjmedia_format_id)play_port->info.fmt.id) {
+	    const pjmedia_video_format_info *dec_vfi;
+	    pjmedia_video_apply_fmt_param dec_vafp = {0};
+	    const pjmedia_vid_codec_info *codec_info2;
+	    pjmedia_vid_codec_param codec_param2;
+
+	    /* Find decoder */
+	    status = pjmedia_vid_codec_mgr_get_codec_info2(NULL,
+							   play_port->info.fmt.id,
+							   &codec_info2);
+	    if (status != PJ_SUCCESS)
+		goto on_exit;
+
+	    /* Init decoder */
+	    status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info2,
+						       &play_decoder);
+	    if (status != PJ_SUCCESS)
+		goto on_exit;
+
+	    status = play_decoder->op->init(play_decoder, pool);
+	    if (status != PJ_SUCCESS)
+		goto on_exit;
+
+	    /* Open decoder */
+	    status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info2,
+							     &codec_param2);
+	    if (status != PJ_SUCCESS)
+		goto on_exit;
+
+	    codec_param2.dir = PJMEDIA_DIR_DECODING;
+	    status = play_decoder->op->open(play_decoder, &codec_param2);
+	    if (status != PJ_SUCCESS)
+		goto on_exit;
+
+	    /* Get decoder format info and apply param */
+	    dec_vfi = pjmedia_get_video_format_info(NULL,
+						    codec_info2->dec_fmt_id[0]);
+	    if (!dec_vfi || !dec_vfi->apply_fmt) {
+		status = PJ_ENOTSUP;
+		goto on_exit;
+	    }
+	    dec_vafp.size = file_vfd->size;
+	    (*dec_vfi->apply_fmt)(dec_vfi, &dec_vafp);
+
+	    /* Allocate buffer to receive decoder output */
+	    play_file.dec_buf_size = dec_vafp.framebytes;
+	    play_file.dec_buf = pj_pool_zalloc(pool, play_file.dec_buf_size);
+	}
+
+	/* Create player clock */
+        clock_param.usec_interval = PJMEDIA_PTIME(&file_vfd->fps);
+        clock_param.clock_rate = codec_info->clock_rate;
+	status = pjmedia_clock_create2(pool, &clock_param,
+				       PJMEDIA_CLOCK_NO_HIGHEST_PRIO,
+				       &clock_cb, &play_file, &play_clock);
+	if (status != PJ_SUCCESS)
+	    goto on_exit;
+
+	/* Override stream codec param for encoding direction */
+	codec_param.enc_fmt.det.vid.size = file_vfd->size;
+	codec_param.enc_fmt.det.vid.fps  = file_vfd->fps;
+
+    } else {
+        pjmedia_vid_port_param_default(&vpp);
+
+        /* Set as active for all video devices */
+        vpp.active = PJ_TRUE;
+
+	/* Create video device port. */
+        if (dir & PJMEDIA_DIR_ENCODING) {
+            /* Create capture */
+            status = pjmedia_vid_dev_default_param(
+					pool,
+					PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
+					&vpp.vidparam);
+            if (status != PJ_SUCCESS)
+	        goto on_exit;
+
+            pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.enc_fmt);
+	    vpp.vidparam.fmt.id = codec_param.dec_fmt.id;
+            vpp.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+            
+            status = pjmedia_vid_port_create(pool, &vpp, &capture);
+            if (status != PJ_SUCCESS)
+	        goto on_exit;
+        }
+	
+        if (dir & PJMEDIA_DIR_DECODING) {
+            /* Create renderer */
+            status = pjmedia_vid_dev_default_param(
+					pool,
+					PJMEDIA_VID_DEFAULT_RENDER_DEV,
+					&vpp.vidparam);
+            if (status != PJ_SUCCESS)
+	        goto on_exit;
+
+            pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.dec_fmt);
+            vpp.vidparam.dir = PJMEDIA_DIR_RENDER;
+            vpp.vidparam.disp_size = vpp.vidparam.fmt.det.vid.size;
+	    vpp.vidparam.flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS;
+	    vpp.vidparam.window_flags = PJMEDIA_VID_DEV_WND_BORDER |
+					PJMEDIA_VID_DEV_WND_RESIZABLE;
+
+            status = pjmedia_vid_port_create(pool, &vpp, &renderer);
+            if (status != PJ_SUCCESS)
+	        goto on_exit;
+        }
+    }
+
+    /* Set to ignore fmtp */
+    codec_param.ignore_fmtp = PJ_TRUE;
+
+    /* Create stream based on program arguments */
+    status = create_stream(pool, med_endpt, codec_info, &codec_param,
+                           dir, rx_pt, tx_pt, local_port, &remote_addr, 
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+			   use_srtp, &srtp_crypto_suite, 
+			   &srtp_tx_key, &srtp_rx_key,
+#endif
+			   &stream);
+    if (status != PJ_SUCCESS)
+	goto on_exit;
+
+    /* Get the port interface of the stream */
+    status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_ENCODING,
+				         &enc_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_DECODING,
+				         &dec_port);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Start streaming */
+    status = pjmedia_vid_stream_start(stream);
+    if (status != PJ_SUCCESS)
+        goto on_exit;
+
+    /* Start renderer */
+    if (renderer) {
+        status = pjmedia_vid_port_connect(renderer, dec_port, PJ_FALSE);
+        if (status != PJ_SUCCESS)
+	    goto on_exit;
+        status = pjmedia_vid_port_start(renderer);
+        if (status != PJ_SUCCESS)
+            goto on_exit;
+    }
+
+    /* Start capture */
+    if (capture) {
+        status = pjmedia_vid_port_connect(capture, enc_port, PJ_FALSE);
+        if (status != PJ_SUCCESS)
+	    goto on_exit;
+        status = pjmedia_vid_port_start(capture);
+        if (status != PJ_SUCCESS)
+            goto on_exit;
+    }
+
+    /* Start playing file */
+    if (play_file.file_name) {
+
+#if HAS_LOCAL_RENDERER_FOR_PLAY_FILE
+        /* Create local renderer */
+        pjmedia_vid_port_param_default(&vpp);
+        vpp.active = PJ_FALSE;
+        status = pjmedia_vid_dev_default_param(
+				pool,
+				PJMEDIA_VID_DEFAULT_RENDER_DEV,
+				&vpp.vidparam);
+        if (status != PJ_SUCCESS)
+	    goto on_exit;
+
+        vpp.vidparam.dir = PJMEDIA_DIR_RENDER;
+        pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.dec_fmt);
+	vpp.vidparam.fmt.det.vid.size = play_port->info.fmt.det.vid.size;
+	vpp.vidparam.fmt.det.vid.fps = play_port->info.fmt.det.vid.fps;
+        vpp.vidparam.disp_size = vpp.vidparam.fmt.det.vid.size;
+	vpp.vidparam.flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS;
+	vpp.vidparam.window_flags = PJMEDIA_VID_DEV_WND_BORDER |
+				    PJMEDIA_VID_DEV_WND_RESIZABLE;
+
+	status = pjmedia_vid_port_create(pool, &vpp, &renderer);
+        if (status != PJ_SUCCESS)
+	    goto on_exit;
+        status = pjmedia_vid_port_start(renderer);
+        if (status != PJ_SUCCESS)
+            goto on_exit;
+#endif
+
+	/* Init play file data */
+	play_file.play_port = play_port;
+	play_file.stream_port = enc_port;
+	play_file.decoder = play_decoder;
+	if (renderer) {
+	    play_file.renderer = pjmedia_vid_port_get_passive_port(renderer);
+	}
+
+	status = pjmedia_clock_start(play_clock);
+	if (status != PJ_SUCCESS)
+	    goto on_exit;
+    }
+
+    /* Done */
+
+    if (dir == PJMEDIA_DIR_DECODING)
+	printf("Stream is active, dir is recv-only, local port is %d\n",
+	       local_port);
+    else if (dir == PJMEDIA_DIR_ENCODING)
+	printf("Stream is active, dir is send-only, sending to %s:%d\n",
+	       pj_inet_ntoa(remote_addr.sin_addr),
+	       pj_ntohs(remote_addr.sin_port));
+    else
+	printf("Stream is active, send/recv, local port is %d, "
+	       "sending to %s:%d\n",
+	       local_port,
+	       pj_inet_ntoa(remote_addr.sin_addr),
+	       pj_ntohs(remote_addr.sin_port));
+
+    if (dir & PJMEDIA_DIR_ENCODING)
+	PJ_LOG(2, (THIS_FILE, "Sending %dx%d %.*s @%.2ffps",
+		   codec_param.enc_fmt.det.vid.size.w,
+		   codec_param.enc_fmt.det.vid.size.h,
+		   codec_info->encoding_name.slen,
+		   codec_info->encoding_name.ptr,
+		   (1.0*codec_param.enc_fmt.det.vid.fps.num/
+		    codec_param.enc_fmt.det.vid.fps.denum)));
+
+    for (;;) {
+	char tmp[10];
+
+	puts("");
+	puts("Commands:");
+	puts("  q     Quit");
+	puts("");
+
+	printf("Command: "); fflush(stdout);
+
+	if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
+	    puts("EOF while reading stdin, will quit now..");
+	    break;
+	}
+
+	if (tmp[0] == 'q')
+	    break;
+
+    }
+
+
+
+    /* Start deinitialization: */
+on_exit:
+
+    /* Stop video devices */
+    if (capture)
+        pjmedia_vid_port_stop(capture);
+    if (renderer)
+        pjmedia_vid_port_stop(renderer);
+
+    /* Stop and destroy file clock */
+    if (play_clock) {
+	pjmedia_clock_stop(play_clock);
+	pjmedia_clock_destroy(play_clock);
+    }
+
+    /* Destroy file reader/player */
+    if (play_port)
+	pjmedia_port_destroy(play_port);
+
+    /* Destroy file decoder */
+    if (play_decoder) {
+	play_decoder->op->close(play_decoder);
+	pjmedia_vid_codec_mgr_dealloc_codec(NULL, play_decoder);
+    }
+
+    /* Destroy video devices */
+    if (capture)
+	pjmedia_vid_port_destroy(capture);
+    if (renderer)
+	pjmedia_vid_port_destroy(renderer);
+
+    /* Destroy stream */
+    if (stream) {
+	pjmedia_transport *tp;
+
+	tp = pjmedia_vid_stream_get_transport(stream);
+	pjmedia_vid_stream_destroy(stream);
+	
+	pjmedia_transport_close(tp);
+    }
+
+    /* Deinit codecs */
+    deinit_codecs();
+
+    /* Shutdown video subsystem */
+    pjmedia_vid_dev_subsys_shutdown();
+
+    /* Destroy event manager */
+    pjmedia_event_mgr_destroy(NULL);
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+    return (status == PJ_SUCCESS) ? 0 : 1;
+}
+
+
+#else
+
+int main(int argc, char *argv[])
+{
+    PJ_UNUSED_ARG(argc);
+    PJ_UNUSED_ARG(argv);
+    puts("Error: this sample requires video capability (PJMEDIA_HAS_VIDEO == 1)");
+    return -1;
+}
+
+#endif /* PJMEDIA_HAS_VIDEO */
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/Makefile b/jni/libpjsip/sources/pjsip-apps/src/swig/Makefile
new file mode 100644
index 0000000..815e0e1
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/Makefile
@@ -0,0 +1,32 @@
+include ../../../build.mak
+
+ifneq ($(findstring android,$(TARGET_NAME)),)
+  # no python for android
+  DIRS = java
+else
+  DIRS = python java
+endif
+
+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
+
+.PHONY: all clean dep depend distclean print realclean install uninstall
+
+all: symbols.i
+
+all clean dep depend distclean print realclean install uninstall:
+	for dir in $(DIRS); do \
+		if $(MAKE) $(MAKE_FLAGS) -C $$dir $@; then \
+		    true; \
+		else \
+		    exit 1; \
+		fi; \
+	done
+
+symbols.i: symbols.lst
+	python importsym.py
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/importsym.py b/jni/libpjsip/sources/pjsip-apps/src/swig/importsym.py
new file mode 100644
index 0000000..94377d8
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/importsym.py
@@ -0,0 +1,193 @@
+# $Id: importsym.py 4704 2014-01-16 05:30:46Z ming $
+#
+# importsym.py: Import C symbol decls (structs, enums, etc) and write them
+#               to another file 
+#
+# Copyright (C)2013 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 
+#
+import pycparser
+from pycparser import c_generator
+import sys
+import os
+
+def which(program):
+	import os
+	def is_exe(fpath):
+		return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+	
+	if sys.platform == 'win32' and not program.endswith(".exe"):
+		program += ".exe"
+
+	fpath, fname = os.path.split(program)
+	if fpath:
+		if is_exe(program):
+			return program
+	else:
+		for path in os.environ["PATH"].split(os.pathsep):
+			path = path.strip('"')
+			exe_file = os.path.join(path, program)
+			if is_exe(exe_file):
+				return exe_file
+	return None
+
+#
+PJ_ROOT_PATH = "../../../"
+   
+# CPP is needed by pycparser.
+CPP_PATH = which("cpp")
+if not CPP_PATH:
+	print 'Error: need to have cpp in PATH'
+	sys.exit(1)
+
+# Hardcoded!
+if sys.platform == 'win32':
+	PYCPARSER_DIR="C:/devs/tools/pycparser"
+elif sys.platform == "linux2":
+	PYCPARSER_DIR="/home/bennylp/Desktop/opt/src/pycparser-master"
+else:
+	PYCPARSER_DIR="/Library/Python/2.7/site-packages/pycparser"
+
+if not os.path.exists(PYCPARSER_DIR + '/utils/fake_libc_include'):
+	print "Error: couldn't find pycparser utils in '%s'" % PYPARSER_DIR 
+	sys.exit(1)
+
+# Heading, to be placed before the source files
+C_HEADING_SECTION = """
+#define PJ_AUTOCONF		1
+#define jmp_buf			int
+#define __attribute__(x)
+"""
+
+# CPP (C preprocessor) settings
+CPP_CFLAGS   = [
+	'-I' + PYCPARSER_DIR + '/utils/fake_libc_include',
+	"-I" + PJ_ROOT_PATH + "pjlib/include",
+	"-I" + PJ_ROOT_PATH + "pjlib-util/include",
+	"-I" + PJ_ROOT_PATH + "pjnath/include",
+	"-I" + PJ_ROOT_PATH + "pjmedia/include",
+	"-I" + PJ_ROOT_PATH + "pjsip/include"
+	]
+
+
+class SymbolVisitor(pycparser.c_ast.NodeVisitor):
+	def __init__(self, names):
+		self.nodeDict = {}
+		for name in names:
+			self.nodeDict[name] = None
+		
+	def _add(self, node):
+		if self.nodeDict.has_key(node.name):
+			self.nodeDict[node.name] = node
+		
+	def visit_Struct(self, node):
+		self._add(node)
+		
+	def visit_Enum(self, node):
+		self._add(node)
+
+	def visit_Typename(self, node):
+		self._add(node)
+		
+	def visit_Typedef(self, node):
+		self._add(node)
+
+		
+TEMP_FILE="tmpsrc.h"
+		
+class SymbolImporter:
+	"""
+	Import C selected declarations from C source file and move it
+	to another file.
+	
+	Parameters:
+	 - listfile	Path of file containing list of C source file
+	                and identifier names to be imported. The format
+	                of the listfile is:
+	                
+	                filename        name1  name2  name3
+	                
+	                for example:
+	                
+	                pj/sock_qos.h	pj_qos_type  pj_qos_flag
+	                pj/types.h	pj_status_t  PJ_SUCCESS
+	"""
+	def __init__(self):
+		pass
+	
+	def process(self, listfile, outfile):
+		
+		# Read listfile
+		f = open(listfile)
+		lines = f.readlines()
+		f.close()
+		
+		# Process each line in list file, while generating the
+		# temporary C file to be processed by pycparser
+		f = open(TEMP_FILE, "w")
+		f.write(C_HEADING_SECTION)
+		names = []
+		fcnt = 0
+		for line in lines:
+			spec = line.split()
+			if len(spec) < 2:
+				continue
+			fcnt += 1
+			f.write("#include <%s>\n" % spec[0])
+			names.extend(spec[1:])
+		f.close()
+		print 'Parsing %d symbols from %d files..' % (len(names), fcnt)
+		
+		# Parse the temporary C file
+		ast = pycparser.parse_file(TEMP_FILE, use_cpp=True, cpp_path=CPP_PATH, cpp_args=CPP_CFLAGS)
+		os.remove(TEMP_FILE)
+		
+		# Filter the declarations that we wanted
+		print 'Filtering..'
+		visitor = SymbolVisitor(names)
+		visitor.visit(ast)
+	
+		# Print symbol declarations to outfile
+		print 'Writing declarations..'
+		f = open(outfile, 'w')
+		f.write("// This file is autogenerated by importsym script, do not modify!\n\n")
+		gen = pycparser.c_generator.CGenerator()
+		for name in names:
+			node = visitor.nodeDict[name]
+			if not node:
+				print "  ** Warning: declaration for '%s' is not found **" % k
+			else:
+				print "  writing '%s'.." % name
+				output = gen.visit(node) + ";\n\n"
+				f.write(output)
+		f.close()
+		print "Done."
+
+
+if __name__ == "__main__":
+	print "Importing symbols: 'symbols.lst' --> 'symbols.i'"
+	si = SymbolImporter()
+	si.process("symbols.lst", "symbols.i")
+	try:
+		os.remove("lextab.py")
+	except OSError:
+		pass
+	try:
+		os.remove("yacctab.py")
+	except OSError:
+		pass
+	
+	
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/Makefile b/jni/libpjsip/sources/pjsip-apps/src/swig/java/Makefile
new file mode 100644
index 0000000..1946891
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/Makefile
@@ -0,0 +1,124 @@
+include ../../../../build.mak
+
+ifneq ($(findstring android,$(TARGET_NAME)),)
+ OS=android
+else
+ ifneq ($(findstring darwin,$(TARGET_NAME)),)
+  OS=darwin
+ endif
+endif
+
+OUT_DIR=output
+ifeq ($(OS),Windows_NT)
+  LIBPJSUA2_SO=$(OUT_DIR)/pjsua2.dll
+else
+  ifeq ($(OS),darwin)
+    LIBPJSUA2_SO=$(OUT_DIR)/libpjsua2.jnilib
+  else
+    ifeq ($(OS),android)
+      LIBPJSUA2_SO=android/libs/armeabi/libpjsua2.so
+    else
+      LIBPJSUA2_SO=$(OUT_DIR)/libpjsua2.so
+    endif
+  endif
+endif
+
+# Get JDK location
+ifeq ("$(JAVA_HOME)","")
+  # Get javac location to determine JDK location
+  JAVAC_PATH = $(shell which javac)
+  ifeq ("$(JAVAC_PATH)","")
+    $(error Cannot determine JDK location using 'which' command. Please define JAVA_HOME envvar)
+  endif
+
+  JAVAC_PATH := $(realpath $(JAVAC_PATH))
+  JAVA_BIN := $(dir $(JAVAC_PATH))
+  JAVA_HOME := $(patsubst %/bin/,%,$(JAVA_BIN))
+else
+  ifeq (exists, $(shell test -d $(JAVA_HOME)/bin && echo exists ))
+    JAVA_BIN := $(JAVA_HOME)/bin
+  else
+    JAVA_BIN := $(JAVA_HOME)
+  endif
+endif
+
+# OS specific
+ifeq ($(OS),Windows_NT)
+  MY_JNI_LDFLAGS	= -L$(MY_JDK)/lib -Wl,--kill-at
+else
+  MY_JNI_CFLAGS	 	= -fPIC
+  MY_JNI_LDFLAGS	= -L$(MY_JDK)/lib
+  ifeq ($(OS),darwin)
+    MY_JNI_LDFLAGS 	:= $(MY_JNI_LDFLAGS) -Wl,-soname,pjsua2.so
+  endif
+  ifeq ($(OS),android)
+    MY_JNI_CFLAGS	:= $(MY_JNI_CFLAGS) -D__ANDROID__
+  endif
+endif
+
+# Env settings, e.g: path to SWIG, JDK, java(.exe), javac(.exe)
+MY_SWIG		 = swig
+MY_JDK		 = $(JAVA_HOME)
+ifneq ($(findstring bin,$(JAVA_BIN)),)
+  MY_JAVA	 = $(MY_JDK)/bin/java
+  MY_JAVAC	 = $(MY_JDK)/bin/javac
+else
+  MY_JAVA	 = $(MY_JDK)/java
+  MY_JAVAC	 = $(MY_JDK)/javac
+endif
+MY_JNI_CFLAGS	 := $(MY_JNI_CFLAGS) -I$(MY_JDK)/include -I$(MY_JDK)/include/win32 \
+		    -I$(MY_JDK)/include/linux -I.
+
+# Build settings
+MY_CFLAGS	 = $(PJ_CFLAGS) $(MY_JNI_CFLAGS)
+MY_LDFLAGS	 = $(PJ_LDFLAGS) -lpjsua2-$(TARGET_NAME) $(PJ_LDLIBS) $(MY_JNI_LDFLAGS)
+MY_PACKAGE_NAME	 = org.pjsip.pjsua2
+ifeq ($(OS),android)
+  MY_PACKAGE_PATH  = android/src/$(subst .,/,$(MY_PACKAGE_NAME))
+else
+  MY_PACKAGE_PATH  = $(OUT_DIR)/$(subst .,/,$(MY_PACKAGE_NAME))
+endif
+
+MY_APP_JAVA = android/src/$(subst .,/,$(MY_PACKAGE_NAME))/app/MyApp.java
+
+.PHONY: all java install uninstall
+
+all: $(LIBPJSUA2_SO) java
+
+$(LIBPJSUA2_SO): $(OUT_DIR)/pjsua2_wrap.o
+	$(PJ_CXX) -shared -o $(LIBPJSUA2_SO) $(OUT_DIR)/pjsua2_wrap.o $(MY_CFLAGS) $(MY_LDFLAGS)
+
+$(OUT_DIR)/pjsua2_wrap.o: $(OUT_DIR)/pjsua2_wrap.cpp Makefile
+	$(PJ_CXX) -c $(OUT_DIR)/pjsua2_wrap.cpp -o $(OUT_DIR)/pjsua2_wrap.o $(MY_CFLAGS) $(MY_LDFLAGS)
+
+$(OUT_DIR)/pjsua2_wrap.cpp: ../pjsua2.i ../symbols.i $(SRCS)
+	mkdir -p $(MY_PACKAGE_PATH)
+	swig $(SWIG_FLAGS) -java  -package $(MY_PACKAGE_NAME) -outdir $(MY_PACKAGE_PATH) -o $(OUT_DIR)/pjsua2_wrap.cpp ../pjsua2.i
+
+clean distclean realclean:
+	rm -rf $(LIBPJSUA2_SO) $(OUT_DIR)/* $(MY_PACKAGE_PATH)/*.java $(MY_PACKAGE_PATH)/*.class
+
+java: $(MY_PACKAGE_PATH)/Error.class $(MY_PACKAGE_PATH)/test.class $(MY_PACKAGE_PATH)/sample.class
+
+$(MY_PACKAGE_PATH)/Error.class: $(MY_PACKAGE_PATH)/Error.java
+	$(MY_JAVAC) -d $(OUT_DIR) $(MY_PACKAGE_PATH)/*.java $(MY_APP_JAVA)
+
+$(MY_PACKAGE_PATH)/test.class: test.java
+	$(MY_JAVAC) -d $(OUT_DIR) -classpath "$(OUT_DIR)" test.java
+	
+$(MY_PACKAGE_PATH)/sample.class: sample.java
+	$(MY_JAVAC) -d $(OUT_DIR) -classpath "$(OUT_DIR)" sample.java
+
+test:
+	@# Need to specify classpath and library path, alternatively, they can be set via
+	@# CLASSPATH and java.library.path env settings
+	$(MY_JAVA) -cp "$(OUT_DIR)" -Djava.library.path="$(OUT_DIR)" test
+	
+sample:
+	@# Need to specify classpath and library path, alternatively, they can be set via
+	@# CLASSPATH and java.library.path env settings
+	$(MY_JAVA) -cp "$(OUT_DIR)" -Djava.library.path="$(OUT_DIR)" org.pjsip.pjsua2.app.sample	
+
+install:
+uninstall:
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/.settings/org.eclipse.jdt.core.prefs b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..48ab4c6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6

+org.eclipse.jdt.core.compiler.compliance=1.6

+org.eclipse.jdt.core.compiler.source=1.6

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/AndroidManifest.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/AndroidManifest.xml
new file mode 100644
index 0000000..5a9b0ae
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.pjsip.pjsua2.app"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="11"
+        android:targetSdkVersion="15" />
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="org.pjsip.pjsua2.app.MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name="org.pjsip.pjsua2.app.CallActivity"
+            android:label="@string/title_activity_call" >
+        </activity>
+    </application>
+
+</manifest>
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/ic_launcher-web.png b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/ic_launcher-web.png
new file mode 100644
index 0000000..a18cbb4
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/ic_launcher-web.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/jni/Android.mk b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/jni/Android.mk
new file mode 100644
index 0000000..94912ba
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/jni/Android.mk
@@ -0,0 +1,12 @@
+include ../../../../../build.mak
+
+LOCAL_PATH	:= $(PJDIR)/pjsip-apps/src/swig/java/android
+include $(CLEAR_VARS)
+
+LOCAL_MODULE    := libpjsua2
+LOCAL_CFLAGS    := $(APP_CFLAGS) -frtti -fexceptions
+LOCAL_LDFLAGS   := $(APP_LDFLAGS)
+LOCAL_LDLIBS    := $(APP_LDLIBS)
+LOCAL_SRC_FILES := ../output/pjsua2_wrap.cpp
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/jni/Application.mk b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/jni/Application.mk
new file mode 100644
index 0000000..87124dd
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/jni/Application.mk
@@ -0,0 +1 @@
+APP_STL := gnustl_static
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/proguard-project.txt b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/project.properties b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/project.properties
new file mode 100644
index 0000000..0840b4a
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-15
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-hdpi/ic_launcher.png b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..288b665
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-mdpi/ic_launcher.png b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..6ae570b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-xhdpi/ic_launcher.png b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..d4fb7cd
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-xxhdpi/ic_launcher.png b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..85a6081
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable/bkg.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable/bkg.xml
new file mode 100644
index 0000000..f505233
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/drawable/bkg.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>

+<selector xmlns:android="http://schemas.android.com/apk/res/android">

+    <item android:state_pressed="true" android:drawable="@color/pressed_color" />

+    <item android:drawable="@color/default_color" />

+</selector>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/activity_call.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/activity_call.xml
new file mode 100644
index 0000000..3745eb3
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/activity_call.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>

+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

+    android:layout_width="match_parent"

+    android:layout_height="match_parent"

+    android:gravity="center"

+    android:paddingBottom="@dimen/activity_vertical_margin"

+    android:paddingLeft="@dimen/activity_horizontal_margin"

+    android:paddingRight="@dimen/activity_horizontal_margin"

+    android:paddingTop="@dimen/activity_vertical_margin"

+    android:orientation="vertical" >

+

+    <TextView

+        android:id="@+id/textViewPeer"

+        android:layout_width="match_parent"

+        android:layout_height="wrap_content"

+        android:gravity="center_horizontal"

+        android:text="Peer URI"

+        android:textAppearance="?android:attr/textAppearanceLarge" />

+

+    <TextView

+        android:id="@+id/textViewCallState"

+        android:layout_width="match_parent"

+        android:layout_height="wrap_content"

+        android:gravity="center"

+        android:text="Call state" />

+

+    <Button

+        android:id="@+id/buttonAccept"

+        android:layout_width="match_parent"

+        android:layout_height="wrap_content"

+        android:onClick="acceptCall"

+        android:text="Accept" />

+

+    <Button

+        android:id="@+id/buttonHangup"

+        android:layout_width="match_parent"

+        android:layout_height="wrap_content"

+        android:onClick="hangupCall"

+        android:text="Reject" />

+

+</LinearLayout>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/activity_main.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/activity_main.xml
new file mode 100644
index 0000000..c63c021
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

+    xmlns:tools="http://schemas.android.com/tools"

+    android:layout_width="match_parent"

+    android:layout_height="match_parent"

+    android:orientation="vertical"

+    android:paddingBottom="@dimen/activity_vertical_margin"

+    android:paddingLeft="@dimen/activity_horizontal_margin"

+    android:paddingRight="@dimen/activity_horizontal_margin"

+    android:paddingTop="@dimen/activity_vertical_margin"

+    tools:context=".MainActivity" >

+

+    <ListView

+        android:id="@+id/listViewBuddy"

+        android:layout_width="match_parent"

+        android:layout_height="match_parent"

+        android:layout_weight="1"

+    	android:listSelector="@drawable/bkg" >

+    </ListView>

+

+    <LinearLayout

+        android:layout_width="match_parent"

+        android:layout_height="wrap_content"

+        android:orientation="horizontal" >

+

+        <ImageButton

+            android:id="@+id/buttonCall"

+            android:layout_width="wrap_content"

+            android:layout_height="wrap_content"

+            android:layout_weight="1"

+            android:onClick="makeCall"

+            android:src="@android:drawable/ic_menu_call" />

+

+        <TextView

+            android:layout_width="wrap_content"

+            android:layout_height="match_parent"

+            android:layout_weight="1"

+			android:text="   "/>

+

+        <ImageButton

+            android:id="@+id/buttonAddBuddy"

+            android:layout_width="wrap_content"

+            android:layout_height="wrap_content"

+            android:layout_weight="1"

+            android:onClick="addBuddy"

+            android:src="@android:drawable/ic_menu_add" />

+        

+        <ImageButton

+            android:id="@+id/buttonEditBuddy"

+            android:layout_width="wrap_content"

+            android:layout_height="wrap_content"

+            android:layout_weight="1"

+            android:onClick="editBuddy"

+            android:src="@android:drawable/ic_menu_edit" />

+        

+        <ImageButton

+            android:id="@+id/buttonDelBuddy"

+            android:layout_width="wrap_content"

+            android:layout_height="wrap_content"

+            android:layout_weight="1"

+            android:onClick="delBuddy"

+            android:src="@android:drawable/ic_menu_delete" />

+

+        </LinearLayout>

+

+</LinearLayout>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/dlg_account_config.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/dlg_account_config.xml
new file mode 100644
index 0000000..71111f1
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/dlg_account_config.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>

+<TableLayout

+    xmlns:android="http://schemas.android.com/apk/res/android"

+    android:padding = "20dp"

+    android:layout_width="match_parent"

+    android:layout_height="match_parent">

+

+    <TextView

+        android:id="@+id/textViewInfo"

+        android:textAppearance="?android:attr/textAppearanceSmall"

+    	android:paddingBottom="20dp"

+        android:textColor="#b0b0b0" >

+    </TextView>

+    

+	<TableRow>

+        <TextView android:text="ID">

+        </TextView>  

+

+	    <EditText

+	        android:id="@+id/editTextId"

+	        android:layout_width="match_parent"

+	        android:layout_height="wrap_content"

+	        android:layout_weight="1"

+	        android:inputType="textUri" >

+

+	        <requestFocus />

+	    </EditText>

+    </TableRow>

+	<TableRow>

+        <TextView android:text="Registrar">

+        </TextView>  

+	    <EditText

+	        android:id="@+id/editTextRegistrar"

+	        android:layout_width="match_parent"

+	        android:layout_height="wrap_content"

+	        android:layout_weight="1"

+	        android:inputType="textUri" >

+	    </EditText>

+    </TableRow>

+	<TableRow>

+        <TextView android:text="Proxy">

+        </TextView>  

+	    <EditText

+	        android:id="@+id/editTextProxy"

+	        android:layout_width="match_parent"

+	        android:layout_height="wrap_content"

+	        android:layout_weight="1"

+	        android:inputType="textUri" >

+	    </EditText>

+    </TableRow>

+	<TableRow>

+        <TextView android:text="Username">

+        </TextView>  

+

+	    <EditText

+	        android:id="@+id/editTextUsername"

+	        android:layout_width="match_parent"

+	        android:layout_height="wrap_content"

+	        android:layout_weight="1"

+	        android:inputType="text" >

+

+	    </EditText>

+    </TableRow>

+	<TableRow>

+        <TextView android:text="Password">

+        </TextView>  

+

+	    <EditText

+	        android:id="@+id/editTextPassword"

+	        android:layout_width="match_parent"

+	        android:layout_height="wrap_content"

+	        android:layout_weight="1"

+	        android:inputType="textPassword" >

+

+	    </EditText>

+    </TableRow>

+</TableLayout>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/dlg_add_buddy.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/dlg_add_buddy.xml
new file mode 100644
index 0000000..f13e700
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/layout/dlg_add_buddy.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>

+<TableLayout

+    xmlns:android="http://schemas.android.com/apk/res/android"

+    android:padding = "20dp"

+    android:layout_width="match_parent"

+    android:layout_height="match_parent">

+	<TableRow>

+        <TextView android:text="Buddy URI">

+        </TextView>  

+

+	    <EditText

+	        android:id="@+id/editTextUri"

+	        android:layout_weight="1"

+	        android:inputType="textUri" >

+	        <requestFocus />

+	    </EditText>

+    </TableRow>

+	<TableRow>

+        <CheckBox

+            android:id="@+id/checkBoxSubscribe"

+            android:layout_column="1"

+            android:text="Subscribe presence" />

+    </TableRow>

+</TableLayout>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/menu/call.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/menu/call.xml
new file mode 100644
index 0000000..d122a4b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/menu/call.xml
@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >

+

+    <item

+        android:id="@+id/action_settings"

+        android:orderInCategory="100"

+        android:showAsAction="never"

+        android:title="@string/action_settings"/>

+

+</menu>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/menu/main.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/menu/main.xml
new file mode 100644
index 0000000..be94829
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/menu/main.xml
@@ -0,0 +1,14 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >

+

+    <item

+        android:id="@+id/action_acc_config"

+        android:icon="@android:drawable/ic_menu_manage"

+        android:showAsAction="ifRoom"

+        android:title="Account Config"/>

+    <item

+        android:id="@+id/action_quit"

+        android:icon="@android:drawable/ic_menu_close_clear_cancel"

+        android:showAsAction="ifRoom"

+        android:title="Quit"/>

+    

+</menu>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-sw600dp/dimens.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-sw600dp/dimens.xml
new file mode 100644
index 0000000..c876987
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-sw600dp/dimens.xml
@@ -0,0 +1,8 @@
+<resources>

+

+    <!--

+         Customize dimensions originally defined in res/values/dimens.xml (such as
+         screen margins) for sw600dp devices (e.g. 7" tablets) here.

+    -->

+

+</resources>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-sw720dp-land/dimens.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..0df3067
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,9 @@
+<resources>

+

+    <!--

+         Customize dimensions originally defined in res/values/dimens.xml (such as
+         screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.

+    -->

+    <dimen name="activity_horizontal_margin">128dp</dimen>

+

+</resources>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-v11/styles.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-v11/styles.xml
new file mode 100644
index 0000000..e3ef53d
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-v11/styles.xml
@@ -0,0 +1,11 @@
+<resources>

+

+    <!--

+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.

+    -->

+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">

+        <!-- API 11 theme customizations can go here. -->

+    </style>

+

+</resources>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-v14/styles.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-v14/styles.xml
new file mode 100644
index 0000000..94dd245
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>

+

+    <!--

+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.

+    -->

+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">

+        <!-- API 14 theme customizations can go here. -->

+    </style>

+

+</resources>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/colors.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/colors.xml
new file mode 100644
index 0000000..9ce61cf
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/colors.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>

+<resources>

+    <color name="pressed_color">#B8F2F5</color>

+    <color name="default_color">#E8FEFF</color>

+</resources>
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/dimens.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/dimens.xml
new file mode 100644
index 0000000..2e0e2ae
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/dimens.xml
@@ -0,0 +1,7 @@
+<resources>

+

+    <!-- Default screen margins, per the Android Design guidelines. -->

+    <dimen name="activity_horizontal_margin">16dp</dimen>

+    <dimen name="activity_vertical_margin">16dp</dimen>

+

+</resources>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/strings.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/strings.xml
new file mode 100644
index 0000000..2ee52b6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/strings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>

+<resources>

+

+    <string name="app_name">Pjsua2</string>

+    <string name="action_settings">Settings</string>

+    <string name="title_activity_call">Call</string>

+    <string name="hello_world">Hello world!</string>

+

+</resources>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/styles.xml b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/styles.xml
new file mode 100644
index 0000000..4ea9326
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/res/values/styles.xml
@@ -0,0 +1,20 @@
+<resources>

+

+    <!--

+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.

+    -->

+    <style name="AppBaseTheme" parent="android:Theme.Light">

+        <!--

+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.

+        -->

+    </style>

+

+    <!-- Application theme. -->

+    <style name="AppTheme" parent="AppBaseTheme">

+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->

+    </style>

+

+</resources>

diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/CallActivity.java b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/CallActivity.java
new file mode 100644
index 0000000..ea2d89e
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/CallActivity.java
@@ -0,0 +1,146 @@
+/* $Id: CallActivity.java 4704 2014-01-16 05:30:46Z ming $ */
+/*
+ * Copyright (C) 2013 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
+ */
+package org.pjsip.pjsua2.app;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+import android.app.Activity;
+
+import org.pjsip.pjsua2.*;
+
+public class CallActivity extends Activity implements Handler.Callback {
+	
+	public static Handler handler_;
+
+	private final Handler handler = new Handler(this);
+	private static CallInfo lastCallInfo;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_call);
+		
+		handler_ = handler;
+		if (MainActivity.currentCall != null) {
+			try {
+				lastCallInfo = MainActivity.currentCall.getInfo();
+				updateCallState(lastCallInfo);
+			} catch (Exception e) {
+				System.out.println(e);
+			}
+		} else {
+			updateCallState(lastCallInfo);
+		}
+	}
+
+    @Override
+    protected void onDestroy() {
+    	super.onDestroy();
+    	handler_ = null;
+    }
+	
+	public void acceptCall(View view) {
+		CallOpParam prm = new CallOpParam();
+		prm.setStatusCode(pjsip_status_code.PJSIP_SC_OK);
+		try {
+			MainActivity.currentCall.answer(prm);
+		} catch (Exception e) {
+			System.out.println(e);
+		}
+		
+		view.setVisibility(View.GONE);
+	}
+
+	public void hangupCall(View view) {
+		handler_ = null;
+		finish();
+		
+		if (MainActivity.currentCall != null) {
+			CallOpParam prm = new CallOpParam();
+			prm.setStatusCode(pjsip_status_code.PJSIP_SC_DECLINE);
+			try {
+				MainActivity.currentCall.hangup(prm);
+			} catch (Exception e) {
+				System.out.println(e);
+			}
+
+			MainActivity.currentCall = null;
+		}
+	}
+	
+	@Override
+	public boolean handleMessage(Message m) {
+		
+		if (m.what == MainActivity.MSG_TYPE.CALL_STATE) {
+			
+			lastCallInfo = (CallInfo) m.obj;
+			updateCallState(lastCallInfo);
+			
+		} else {
+			
+			/* Message not handled */
+			return false;
+			
+		}
+			
+		return true;
+	}
+	
+	private void updateCallState(CallInfo ci) {
+		TextView tvPeer  = (TextView) findViewById(R.id.textViewPeer);
+		TextView tvState = (TextView) findViewById(R.id.textViewCallState);
+		Button buttonHangup = (Button) findViewById(R.id.buttonHangup);
+		Button buttonAccept = (Button) findViewById(R.id.buttonAccept);
+		String call_state = "";
+		
+		if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAC) {
+			buttonAccept.setVisibility(View.GONE);
+		}
+				
+		if (ci.getState().swigValue() < pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue())
+		{
+			if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAS) {
+				call_state = "Incoming call..";
+				/* Default button texts are already 'Accept' & 'Reject' */
+			} else {
+				buttonHangup.setText("Cancel");
+				call_state = ci.getStateText();
+			}
+		}
+		else if (ci.getState().swigValue() >= pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue())
+		{
+			buttonAccept.setVisibility(View.GONE);
+			call_state = ci.getStateText();
+			if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED) {
+				buttonHangup.setText("Hangup");
+			} else if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) {
+				buttonHangup.setText("OK");
+				call_state = "Call disconnected: " + ci.getLastReason();
+				MainActivity.currentCall = null;
+			}
+		}
+		
+		tvPeer.setText(ci.getRemoteUri());
+		tvState.setText(call_state);
+	}
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MainActivity.java b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MainActivity.java
new file mode 100644
index 0000000..01806d9
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MainActivity.java
@@ -0,0 +1,497 @@
+/* $Id: MainActivity.java 4704 2014-01-16 05:30:46Z ming $ */
+/*
+ * Copyright (C) 2013 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
+ */
+package org.pjsip.pjsua2.app;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.pjsip.pjsua2.*;
+
+public class MainActivity extends Activity implements Handler.Callback, MyAppObserver {
+	public static MyApp app = null;
+	public static MyCall currentCall = null;
+	public static MyAccount account = null;
+	public static AccountConfig accCfg = null;
+	
+	private ListView buddyListView;
+	private SimpleAdapter buddyListAdapter;
+	private int buddyListSelectedIdx = -1;
+    ArrayList<Map<String, String>> buddyList;
+    private String lastRegStatus = "";
+
+	private final Handler handler = new Handler(this);
+	public class MSG_TYPE {
+		public final static int INCOMING_CALL = 1;
+		public final static int CALL_STATE = 2;
+		public final static int REG_STATE = 3;
+		public final static int BUDDY_STATE = 4;
+	}
+
+	private HashMap<String, String> putData(String uri, String status) {
+		HashMap<String, String> item = new HashMap<String, String>();
+		item.put("uri", uri);
+		item.put("status", status);
+		return item;
+	}
+	
+	private void showCallActivity() {
+        Intent intent = new Intent(this, CallActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        startActivity(intent);
+	}
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_main);
+		
+		if (app == null) {
+			app = new MyApp();
+			/* Wait for GDB to init */
+			if ((getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+				try {
+					Thread.sleep(5000);
+				} catch (InterruptedException e) {}
+			}
+			
+		    app.init(this, getFilesDir().getAbsolutePath());
+		}
+		
+	    if (app.accList.size() == 0) {
+	    	accCfg = new AccountConfig();
+	    	accCfg.setIdUri("sip:localhost");
+	    	account = app.addAcc(accCfg);
+	    } else {
+	    	account = app.accList.get(0);
+	    	accCfg = account.cfg;
+	    }
+	    
+		buddyList = new ArrayList<Map<String, String>>();
+		for (int i = 0; i < account.buddyList.size(); i++) {
+			buddyList.add(putData(account.buddyList.get(i).cfg.getUri(),
+								  account.buddyList.get(i).getStatusText()));
+		}
+
+		String[] from = { "uri", "status" };
+	    int[] to = { android.R.id.text1, android.R.id.text2 };
+	    buddyListAdapter = new SimpleAdapter(this, buddyList, android.R.layout.simple_list_item_2, from, to);
+	    
+		buddyListView = (ListView) findViewById(R.id.listViewBuddy);;
+	    buddyListView.setAdapter(buddyListAdapter);
+	    buddyListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+	    	@Override
+	    	public void onItemClick(AdapterView<?> parent, final View view,
+	    			int position, long id) 
+	    	{
+	    		view.setSelected(true);
+	    		buddyListSelectedIdx = position;
+	    	}
+	    });
+	    
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.main, menu);
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item) {
+		switch (item.getItemId()) {
+		case R.id.action_acc_config:
+			dlgAccountSetting();
+			break;
+
+		case R.id.action_quit:
+			Message m = Message.obtain(handler, 0);
+			m.sendToTarget();
+			break;
+			
+		default:
+			break;
+		}
+
+		return true;
+	} 	
+
+	@Override
+	public boolean handleMessage(Message m) {
+		
+		if (m.what == 0) {
+			
+			app.deinit();
+			finish();
+			Runtime.getRuntime().gc();
+			android.os.Process.killProcess(android.os.Process.myPid());
+			
+		} else if (m.what == MSG_TYPE.CALL_STATE) {
+			
+			CallInfo ci = (CallInfo) m.obj;
+			
+			/* Forward the message to CallActivity */
+			if (CallActivity.handler_ != null) {
+				Message m2 = Message.obtain(CallActivity.handler_, MSG_TYPE.CALL_STATE, ci);
+				m2.sendToTarget();
+			}
+			
+			if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED)
+				currentCall = null;
+			
+		} else if (m.what == MSG_TYPE.BUDDY_STATE) {
+			
+			MyBuddy buddy = (MyBuddy) m.obj;
+			int idx = account.buddyList.indexOf(buddy);
+			if (idx >= 0) {
+				buddyList.get(idx).put("status", buddy.getStatusText());
+				buddyListAdapter.notifyDataSetChanged();
+				// TODO: selection color/mark is gone after this,
+				//       dont know how to return it back.
+				//buddyListView.setSelection(buddyListSelectedIdx);
+				//buddyListView.performItemClick(buddyListView, buddyListSelectedIdx,
+				//							   buddyListView.getItemIdAtPosition(buddyListSelectedIdx));
+				
+				/* Return back Call activity */
+				notifyCallState(currentCall);
+			}
+			
+		} else if (m.what == MSG_TYPE.REG_STATE) {
+			
+			String msg_str = (String) m.obj;
+			lastRegStatus = msg_str;
+			
+		} else if (m.what == MSG_TYPE.INCOMING_CALL) {
+			
+			/* Incoming call */
+			final MyCall call = (MyCall) m.obj;
+			CallOpParam prm = new CallOpParam();
+			
+			/* Only one call at anytime */
+			if (currentCall != null) {
+				prm.setStatusCode(pjsip_status_code.PJSIP_SC_BUSY_HERE);
+				try {
+					call.hangup(prm);
+				} catch (Exception e) {}
+				return true;
+			}
+
+			/* Answer with ringing */
+			prm.setStatusCode(pjsip_status_code.PJSIP_SC_RINGING);
+			try {
+				call.answer(prm);
+			} catch (Exception e) {}
+			
+			currentCall = call;
+			showCallActivity();
+
+		} else {
+			
+			/* Message not handled */
+			return false;
+			
+		}
+			
+		return true;
+	}
+	
+
+	private void dlgAccountSetting() {
+		
+		LayoutInflater li = LayoutInflater.from(this);
+		View view = li.inflate(R.layout.dlg_account_config, null);
+		
+		if (!lastRegStatus.isEmpty()) {
+			TextView tvInfo = (TextView)view.findViewById(R.id.textViewInfo);
+			tvInfo.setText("Last status: " + lastRegStatus);
+		}
+
+		AlertDialog.Builder adb = new AlertDialog.Builder(this);
+		adb.setView(view);
+		adb.setTitle("Account Settings");
+
+		final EditText etId    = (EditText)view.findViewById(R.id.editTextId);
+		final EditText etReg   = (EditText)view.findViewById(R.id.editTextRegistrar);
+		final EditText etProxy = (EditText)view.findViewById(R.id.editTextProxy);
+		final EditText etUser  = (EditText)view.findViewById(R.id.editTextUsername);
+		final EditText etPass  = (EditText)view.findViewById(R.id.editTextPassword);
+		
+		etId.   setText(accCfg.getIdUri());
+		etReg.  setText(accCfg.getRegConfig().getRegistrarUri());
+		StringVector proxies = accCfg.getSipConfig().getProxies();
+		if (proxies.size() > 0)
+			etProxy.setText(proxies.get(0));
+		else
+			etProxy.setText("");
+		AuthCredInfoVector creds = accCfg.getSipConfig().getAuthCreds();
+		if (creds.size() > 0) {
+			etUser. setText(creds.get(0).getUsername());
+			etPass. setText(creds.get(0).getData());
+		} else {
+			etUser. setText("");
+			etPass. setText("");
+		}
+		
+		adb.setCancelable(false);
+		adb.setPositiveButton("OK",
+			  new DialogInterface.OnClickListener() {
+			    public void onClick(DialogInterface dialog,int id) {
+			    	String acc_id 	 = etId.getText().toString();
+			    	String registrar = etReg.getText().toString();
+			    	String proxy 	 = etProxy.getText().toString();
+			    	String username  = etUser.getText().toString();
+			    	String password  = etPass.getText().toString();
+			    	
+			    	accCfg.setIdUri(acc_id);
+			    	accCfg.getRegConfig().setRegistrarUri(registrar);
+					AuthCredInfoVector creds = accCfg.getSipConfig().getAuthCreds();
+					creds.clear();
+					if (!username.isEmpty()) {
+						creds.add(new AuthCredInfo("Digest", "*", username, 0, password));
+					}
+					StringVector proxies = accCfg.getSipConfig().getProxies();
+					proxies.clear();
+					if (!proxy.isEmpty()) {
+						proxies.add(proxy);
+					}
+					
+					/* Finally */
+					lastRegStatus = "";
+					try {
+						account.modify(accCfg);
+					} catch (Exception e) {}
+			    }
+			  });
+		adb.setNegativeButton("Cancel",
+			  new DialogInterface.OnClickListener() {
+			    public void onClick(DialogInterface dialog,int id) {
+				dialog.cancel();
+			    }
+			  });
+
+		AlertDialog ad = adb.create();
+		ad.show();
+	}
+	
+	
+	public void makeCall(View view) {
+		if (buddyListSelectedIdx == -1)
+			return;
+		
+		/* Only one call at anytime */
+		if (currentCall != null) {
+			return;
+		}
+		
+		HashMap<String, String> item = (HashMap<String, String>) buddyListView.getItemAtPosition(buddyListSelectedIdx);
+		String buddy_uri = item.get("uri");
+		
+		MyCall call = new MyCall(account, -1);
+		CallOpParam prm = new CallOpParam();
+		CallSetting opt = prm.getOpt();
+		opt.setAudioCount(1);
+		opt.setVideoCount(0);
+
+		try {
+			call.makeCall(buddy_uri, prm);
+		} catch (Exception e) {
+			currentCall = null;
+			return;
+		}
+		
+		currentCall = call;
+		showCallActivity();
+	}
+
+	private void dlgAddEditBuddy(BuddyConfig initial) {
+		final BuddyConfig cfg = new BuddyConfig();
+		final BuddyConfig old_cfg = initial;
+		final boolean is_add = initial == null;
+		
+		LayoutInflater li = LayoutInflater.from(this);
+		View view = li.inflate(R.layout.dlg_add_buddy, null);
+
+		AlertDialog.Builder adb = new AlertDialog.Builder(this);
+		adb.setView(view);
+
+		final EditText etUri    = (EditText)view.findViewById(R.id.editTextUri);
+		final CheckBox cbSubs  = (CheckBox)view.findViewById(R.id.checkBoxSubscribe);
+
+		if (is_add) {
+			adb.setTitle("Add Buddy");
+		} else {
+			adb.setTitle("Edit Buddy");
+			etUri. setText(initial.getUri());
+			cbSubs.setChecked(initial.getSubscribe());
+		}
+
+		adb.setCancelable(false);
+		adb.setPositiveButton("OK",
+			  new DialogInterface.OnClickListener() {
+			    public void onClick(DialogInterface dialog,int id) {
+			    	cfg.setUri(etUri.getText().toString());
+			    	cfg.setSubscribe(cbSubs.isChecked());
+			    	
+			    	if (is_add) {
+			    		account.addBuddy(cfg);
+						buddyList.add(putData(cfg.getUri(), ""));
+						buddyListAdapter.notifyDataSetChanged();
+						buddyListSelectedIdx = -1;
+			    	} else {
+			    		if (!old_cfg.getUri().equals(cfg.getUri())) {
+			    			account.delBuddy(buddyListSelectedIdx);
+			    			account.addBuddy(cfg);
+							buddyList.remove(buddyListSelectedIdx);
+							buddyList.add(putData(cfg.getUri(), ""));
+			    			buddyListAdapter.notifyDataSetChanged();
+			    			buddyListSelectedIdx = -1;
+			    		} else if (old_cfg.getSubscribe() != cfg.getSubscribe()) {
+			    			MyBuddy bud = account.buddyList.get(buddyListSelectedIdx);
+							try {
+				    			bud.subscribePresence(cfg.getSubscribe());
+							} catch (Exception e) {}
+			    		}
+			    	}
+			    }
+			  });
+		adb.setNegativeButton("Cancel",
+			  new DialogInterface.OnClickListener() {
+			    public void onClick(DialogInterface dialog,int id) {
+				dialog.cancel();
+			    }
+			  });
+
+		AlertDialog ad = adb.create();
+		ad.show();
+	}
+	
+	public void addBuddy(View view) {
+		dlgAddEditBuddy(null);
+	}
+
+	public void editBuddy(View view) {
+		if (buddyListSelectedIdx == -1)
+			return;
+		
+		BuddyConfig old_cfg = account.buddyList.get(buddyListSelectedIdx).cfg;
+		dlgAddEditBuddy(old_cfg);
+	}
+	
+	public void delBuddy(View view) {
+		if (buddyListSelectedIdx == -1)
+			return;
+		
+		final HashMap<String, String> item = (HashMap<String, String>) buddyListView.getItemAtPosition(buddyListSelectedIdx);
+		String buddy_uri = item.get("uri");
+		
+		DialogInterface.OnClickListener ocl = new DialogInterface.OnClickListener() {
+		    @Override
+		    public void onClick(DialogInterface dialog, int which) {
+		        switch (which) {
+		        case DialogInterface.BUTTON_POSITIVE:
+		        	account.delBuddy(buddyListSelectedIdx);
+		    		buddyList.remove(item);
+		    		buddyListAdapter.notifyDataSetChanged();
+		    		buddyListSelectedIdx = -1;
+		            break;
+		        case DialogInterface.BUTTON_NEGATIVE:
+		            break;
+		        }
+		    }
+		};
+
+		AlertDialog.Builder adb = new AlertDialog.Builder(this);
+		adb.setTitle(buddy_uri);
+		adb.setMessage("\nDelete this buddy?\n");
+		adb.setPositiveButton("Yes", ocl);
+		adb.setNegativeButton("No", ocl);
+		adb.show();
+	}
+	
+	
+	/*
+	 * === MyAppObserver ===
+	 * 
+	 * As we cannot do UI from worker thread, the callbacks mostly just send
+	 * a message to UI/main thread.
+	 */
+	
+	public void notifyIncomingCall(MyCall call) {
+		Message m = Message.obtain(handler, MSG_TYPE.INCOMING_CALL, call);
+		m.sendToTarget();
+	}
+
+	public void notifyRegState(pjsip_status_code code, String reason, int expiration) {
+		String msg_str = "";
+		if (expiration == 0)
+			msg_str += "Unregistration";
+		else
+			msg_str += "Registration";
+		
+		if (code.swigValue()/100 == 2)
+			msg_str += " successful";
+		else
+			msg_str += " failed: " + reason;
+		
+		Message m = Message.obtain(handler, MSG_TYPE.REG_STATE, msg_str);
+		m.sendToTarget();
+	}
+	
+	public void notifyCallState(MyCall call) {
+		if (currentCall == null || call.getId() != currentCall.getId())
+			return;
+		
+		CallInfo ci;
+		try {
+			ci = call.getInfo();
+		} catch (Exception e) {
+			ci = null;
+		}
+		Message m = Message.obtain(handler, MSG_TYPE.CALL_STATE, ci);
+		m.sendToTarget();
+	}
+	
+	public void notifyBuddyState(MyBuddy buddy) {
+		Message m = Message.obtain(handler, MSG_TYPE.BUDDY_STATE, buddy);
+		m.sendToTarget();
+	}
+
+	/* === end of MyAppObserver ==== */
+
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java
new file mode 100644
index 0000000..cfaafe1
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java
@@ -0,0 +1,449 @@
+/* $Id: MyApp.java 4704 2014-01-16 05:30:46Z ming $ */
+/*
+ * Copyright (C) 2013 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
+ */
+package org.pjsip.pjsua2.app;
+
+import java.io.File;
+import java.util.ArrayList;
+import org.pjsip.pjsua2.*;
+
+
+/* Interface to separate UI & engine a bit better */
+interface MyAppObserver {
+	abstract void notifyRegState(pjsip_status_code code, String reason, int expiration);
+	abstract void notifyIncomingCall(MyCall call);
+	abstract void notifyCallState(MyCall call);
+	abstract void notifyBuddyState(MyBuddy buddy);
+}
+
+
+class MyLogWriter extends LogWriter {
+	@Override
+	public void write(LogEntry entry) {
+		System.out.println(entry.getMsg());
+	}
+}
+
+
+class MyCall extends Call {
+	MyCall(MyAccount acc, int call_id) {
+		super(acc, call_id);
+	}
+
+	@Override
+	public void onCallState(OnCallStateParam prm) {
+		MyApp.observer.notifyCallState(this);
+	}
+	
+	@Override
+	public void onCallMediaState(OnCallMediaStateParam prm) {
+		CallInfo ci;
+		try {
+			ci = getInfo();
+		} catch (Exception e) {
+			return;
+		}
+		
+		CallMediaInfoVector cmiv = ci.getMedia();
+		
+		for (int i = 0; i < cmiv.size(); i++) {
+			CallMediaInfo cmi = cmiv.get(i);
+			if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_AUDIO &&
+			    (cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE ||
+			     cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD))
+			{
+				// unfortunately, on Java too, the returned Media cannot be downcasted to AudioMedia 
+				Media m = getMedia(i);
+				AudioMedia am = AudioMedia.typecastFromMedia(m);
+				
+				// connect ports
+				try {
+					MyApp.ep.audDevManager().getCaptureDevMedia().startTransmit(am);
+					am.startTransmit(MyApp.ep.audDevManager().getPlaybackDevMedia());
+				} catch (Exception e) {
+					continue;
+				}
+			}
+		}
+	}
+}
+
+
+class MyAccount extends Account {
+	public ArrayList<MyBuddy> buddyList = new ArrayList<MyBuddy>();
+	public AccountConfig cfg;
+	
+	MyAccount(AccountConfig config) {
+		super();
+		cfg = config;
+	}
+	
+	public MyBuddy addBuddy(BuddyConfig bud_cfg)
+	{
+		/* Create Buddy */
+		MyBuddy bud = new MyBuddy(bud_cfg);
+		try {
+			bud.create(this, bud_cfg);
+		} catch (Exception e) {
+			bud = null;
+		}
+		
+		if (bud != null) {
+			buddyList.add(bud);
+			if (bud_cfg.getSubscribe())
+				try {
+					bud.subscribePresence(true);
+				} catch (Exception e) {}
+		}
+		
+		return bud;
+	}
+	
+	public void delBuddy(MyBuddy buddy) {
+		buddyList.remove(buddy);
+	}
+	
+	public void delBuddy(int index) {
+		buddyList.remove(index);
+	}
+	
+	@Override
+	public void onRegState(OnRegStateParam prm) {
+		MyApp.observer.notifyRegState(prm.getCode(), prm.getReason(), prm.getExpiration());
+	}
+
+	@Override
+	public void onIncomingCall(OnIncomingCallParam prm) {
+		System.out.println("======== Incoming call ======== ");
+		MyCall call = new MyCall(this, prm.getCallId());
+		MyApp.observer.notifyIncomingCall(call);
+	}
+	
+	@Override
+	public void onInstantMessage(OnInstantMessageParam prm) {
+		System.out.println("======== Incoming pager ======== ");
+		System.out.println("From 		: " + prm.getFromUri());
+		System.out.println("To			: " + prm.getToUri());
+		System.out.println("Contact		: " + prm.getContactUri());
+		System.out.println("Mimetype	: " + prm.getContentType());
+		System.out.println("Body		: " + prm.getMsgBody());
+	}
+}
+
+
+class MyBuddy extends Buddy {
+	public BuddyConfig cfg;
+	
+	MyBuddy(BuddyConfig config) {
+		super();
+		cfg = config;
+	}
+	
+	String getStatusText() {
+		BuddyInfo bi;
+		
+		try {
+			bi = getInfo();
+		} catch (Exception e) {
+			return "?";
+		}
+		
+		String status = "";
+		if (bi.getSubState() == pjsip_evsub_state.PJSIP_EVSUB_STATE_ACTIVE) {
+			if (bi.getPresStatus().getStatus() == pjsua_buddy_status.PJSUA_BUDDY_STATUS_ONLINE) {
+				status = bi.getPresStatus().getStatusText();
+				if (status == null || status.isEmpty()) {
+					status = "Online";
+				}
+			} else if (bi.getPresStatus().getStatus() == pjsua_buddy_status.PJSUA_BUDDY_STATUS_OFFLINE) {
+				status = "Offline";
+			} else {
+				status = "Unknown";
+			}
+		}
+		return status;
+	}
+
+	@Override
+	public void onBuddyState() {
+		MyApp.observer.notifyBuddyState(this);
+	}
+	
+}
+
+
+class MyAccountConfig {
+	public AccountConfig accCfg = new AccountConfig();
+	public ArrayList<BuddyConfig> buddyCfgs = new ArrayList<BuddyConfig>();
+	
+	public void readObject(ContainerNode node) {
+		try {
+			ContainerNode acc_node = node.readContainer("Account");
+			accCfg.readObject(acc_node);
+			ContainerNode buddies_node = acc_node.readArray("buddies");
+			buddyCfgs.clear();
+			while (buddies_node.hasUnread()) {
+				BuddyConfig bud_cfg = new BuddyConfig(); 
+				bud_cfg.readObject(buddies_node);
+				buddyCfgs.add(bud_cfg);
+			}
+		} catch (Exception e) {}
+	}
+	
+	public void writeObject(ContainerNode node) {
+		try {
+			ContainerNode acc_node = node.writeNewContainer("Account");
+			accCfg.writeObject(acc_node);
+			ContainerNode buddies_node = acc_node.writeNewArray("buddies");
+			for (int j = 0; j < buddyCfgs.size(); j++) {
+				buddyCfgs.get(j).writeObject(buddies_node);
+			}
+		} catch (Exception e) {}
+	}
+}
+
+
+class MyApp {
+	static {
+		System.loadLibrary("pjsua2");
+		System.out.println("Library loaded");
+	}
+	
+	public static Endpoint ep = new Endpoint();
+	public static MyAppObserver observer;
+	public ArrayList<MyAccount> accList = new ArrayList<MyAccount>();
+
+	private ArrayList<MyAccountConfig> accCfgs = new ArrayList<MyAccountConfig>();
+	private EpConfig epConfig = new EpConfig();
+	private TransportConfig sipTpConfig = new TransportConfig();
+	private String appDir;
+	
+	/* Maintain reference to log writer to avoid premature cleanup by GC */
+	private MyLogWriter logWriter;
+
+	private final String configName = "pjsua2.json";
+	private final int SIP_PORT  = 6000;
+	private final int LOG_LEVEL = 4;
+	
+	public void init(MyAppObserver obs, String app_dir) {
+		init(obs, app_dir, false);
+	}
+	
+	public void init(MyAppObserver obs, String app_dir, boolean own_worker_thread) {
+		observer = obs;
+		appDir = app_dir;
+		
+		/* Create endpoint */
+		try {
+			ep.libCreate();
+		} catch (Exception e) {
+			return;
+		}
+			
+		
+		/* Load config */
+		String configPath = appDir + "/" + configName;
+		File f = new File(configPath);
+		if (f.exists()) {
+			loadConfig(configPath);
+		} else {
+			/* Set 'default' values */
+			sipTpConfig.setPort(SIP_PORT);
+		}
+		
+		/* Override log level setting */
+		epConfig.getLogConfig().setLevel(LOG_LEVEL);
+		epConfig.getLogConfig().setConsoleLevel(LOG_LEVEL);
+		
+		/* Set log config. */
+		LogConfig log_cfg = epConfig.getLogConfig();
+		logWriter = new MyLogWriter();
+		log_cfg.setWriter(logWriter);
+		log_cfg.setDecor(log_cfg.getDecor() & 
+						 ~(pj_log_decoration.PJ_LOG_HAS_CR.swigValue() | 
+						   pj_log_decoration.PJ_LOG_HAS_NEWLINE.swigValue()));
+		
+		/* Set ua config. */
+		UaConfig ua_cfg = epConfig.getUaConfig();
+		ua_cfg.setUserAgent("Pjsua2And" + ep.libVersion().getFull());
+		if (own_worker_thread) {
+			ua_cfg.setThreadCnt(0);
+			ua_cfg.setMainThreadOnly(true);
+		}
+		
+		/* Init endpoint */
+		try {
+			ep.libInit(epConfig);
+		} catch (Exception e) {
+			return;
+		}
+		
+		/* Create transports. */
+		try {
+			ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_UDP, sipTpConfig);
+		} catch (Exception e) {
+			System.out.println(e);
+		}
+
+		try {
+			ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TCP, sipTpConfig);
+		} catch (Exception e) {
+			System.out.println(e);
+		}
+		
+		/* Create accounts. */
+		for (int i = 0; i < accCfgs.size(); i++) {
+			MyAccountConfig my_cfg = accCfgs.get(i);
+			MyAccount acc = addAcc(my_cfg.accCfg);
+			if (acc == null)
+				continue;
+			
+			/* Add Buddies */
+			for (int j = 0; j < my_cfg.buddyCfgs.size(); j++) {
+				BuddyConfig bud_cfg = my_cfg.buddyCfgs.get(j);
+				acc.addBuddy(bud_cfg);
+			}
+		}
+
+		/* Start. */
+		try {
+			ep.libStart();
+		} catch (Exception e) {
+			return;
+		}
+	}
+	
+	public MyAccount addAcc(AccountConfig cfg) {
+		MyAccount acc = new MyAccount(cfg);
+		try {
+			acc.create(cfg);
+		} catch (Exception e) {
+			acc = null;
+			return null;
+		}
+		
+		accList.add(acc);
+		return acc;
+	}
+	
+	public void delAcc(MyAccount acc) {
+		accList.remove(acc);
+	}
+	
+	private void loadConfig(String filename) {
+		JsonDocument json = new JsonDocument();
+		
+		try {
+			/* Load file */
+			json.loadFile(filename);
+			ContainerNode root = json.getRootContainer();
+			
+			/* Read endpoint config */
+			epConfig.readObject(root);
+			
+			/* Read transport config */
+			ContainerNode tp_node = root.readContainer("SipTransport");
+			sipTpConfig.readObject(tp_node);
+			
+			/* Read account configs */
+			accCfgs.clear();
+			ContainerNode accs_node = root.readArray("accounts");
+			while (accs_node.hasUnread()) {
+				MyAccountConfig acc_cfg = new MyAccountConfig();
+				acc_cfg.readObject(accs_node);
+				accCfgs.add(acc_cfg);
+			}
+		} catch (Exception e) {
+			System.out.println(e);
+		}
+		
+		/* Force delete json now, as I found that Java somehow destroys it
+		 * after lib has been destroyed and from non-registered thread.
+		 */
+		json.delete();
+	}
+
+	private void buildAccConfigs() {
+		/* Sync accCfgs from accList */
+		accCfgs.clear();
+		for (int i = 0; i < accList.size(); i++) {
+			MyAccount acc = accList.get(i);
+			MyAccountConfig my_acc_cfg = new MyAccountConfig();
+			my_acc_cfg.accCfg = acc.cfg;
+			
+			my_acc_cfg.buddyCfgs.clear();
+			for (int j = 0; j < acc.buddyList.size(); j++) {
+				MyBuddy bud = acc.buddyList.get(j);
+				my_acc_cfg.buddyCfgs.add(bud.cfg);
+			}
+			
+			accCfgs.add(my_acc_cfg);
+		}
+	}
+	
+	private void saveConfig(String filename) {
+		JsonDocument json = new JsonDocument();
+		
+		try {
+			/* Write endpoint config */
+			json.writeObject(epConfig);
+			
+			/* Write transport config */
+			ContainerNode tp_node = json.writeNewContainer("SipTransport");
+			sipTpConfig.writeObject(tp_node);
+			
+			/* Write account configs */
+			buildAccConfigs();
+			ContainerNode accs_node = json.writeNewArray("accounts");
+			for (int i = 0; i < accCfgs.size(); i++) {
+				accCfgs.get(i).writeObject(accs_node);
+			}
+			
+			/* Save file */
+			json.saveFile(filename);
+		} catch (Exception e) {}
+
+		/* Force delete json now, as I found that Java somehow destroys it
+		 * after lib has been destroyed and from non-registered thread.
+		 */
+		json.delete();
+	}
+	
+	public void deinit() {
+		String configPath = appDir + "/" + configName;
+		saveConfig(configPath);
+		
+		/* Try force GC to avoid late destroy of PJ objects as they should be
+		 * deleted before lib is destroyed.
+		 */
+		Runtime.getRuntime().gc();
+		
+		/* Shutdown pjsua. Note that Endpoint destructor will also invoke
+		 * libDestroy(), so this will be a test of double libDestroy().
+		 */
+		try {
+			ep.libDestroy();
+		} catch (Exception e) {}
+		
+		/* Force delete Endpoint here, to avoid deletion from a non-
+		 * registered thread (by GC?). 
+		 */
+		ep.delete();
+		ep = null;
+	} 
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/sample.java b/jni/libpjsip/sources/pjsip-apps/src/swig/java/sample.java
new file mode 100644
index 0000000..ffcc887
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/sample.java
@@ -0,0 +1,140 @@
+/* $Id: sample.java 4704 2014-01-16 05:30:46Z ming $ */
+/* 
+ * Copyright (C) 2013 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 
+ */
+ 
+package org.pjsip.pjsua2.app;
+
+import java.io.IOException;
+import org.pjsip.pjsua2.*;
+import org.pjsip.pjsua2.app.*;
+
+class MyObserver implements MyAppObserver {
+	private static MyCall currentCall = null;
+	
+	@Override
+	public void notifyRegState(pjsip_status_code code, String reason, int expiration) {}
+	
+	@Override
+	public void notifyIncomingCall(MyCall call) {
+		/* Auto answer. */
+		CallOpParam call_param = new CallOpParam();
+		call_param.setStatusCode(pjsip_status_code.PJSIP_SC_OK);
+		try {
+			currentCall = call;
+			currentCall.answer(call_param);
+		} catch (Exception e) {
+			System.out.println(e);
+			return;
+		}			
+	}
+	
+	@Override
+	public void notifyCallState(MyCall call) {
+		if (currentCall == null || call.getId() != currentCall.getId())
+			return;
+		
+		CallInfo ci;
+		try {
+			ci = call.getInfo();
+		} catch (Exception e) {
+			ci = null;
+		}
+		if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED)
+			currentCall = null;		
+	}
+	
+	@Override
+	public void notifyBuddyState(MyBuddy buddy) {}	
+}
+
+class MyShutdownHook extends Thread {
+	Thread thread;
+	MyShutdownHook(Thread thr) {
+		thread = thr;
+	}
+	public void run() {
+		thread.interrupt();
+		try {
+			thread.join();
+		} catch (Exception e) {
+			;
+		}
+	}
+}	
+
+public class sample {
+	private static MyApp app = new MyApp();
+	private static MyAppObserver observer = new MyObserver();
+	private static MyAccount account = null;
+	private static AccountConfig accCfg = null;			
+	
+	private static void runWorker() {
+		try {					
+			app.init(observer, ".", true);
+		} catch (Exception e) {
+			System.out.println(e);
+			app.deinit();
+			System.exit(-1);
+		} 
+
+		if (app.accList.size() == 0) {
+			accCfg = new AccountConfig();
+			accCfg.setIdUri("sip:localhost");
+			account = app.addAcc(accCfg);
+
+			accCfg.setIdUri("sip:301@pjsip.org");
+			AccountSipConfig sipCfg = accCfg.getSipConfig();		
+			AuthCredInfoVector ciVec = sipCfg.getAuthCreds();
+			ciVec.add(new AuthCredInfo("Digest", 
+					"*",
+					"301",
+					0,
+					"pw301"));
+
+			StringVector proxy = sipCfg.getProxies();
+			proxy.add("sip:pjsip.org;transport=tcp");							
+
+			AccountRegConfig regCfg = accCfg.getRegConfig();
+			regCfg.setRegistrarUri("sip:pjsip.org");
+			account = app.addAcc(accCfg);
+		} else {
+			account = app.accList.get(0);
+			accCfg = account.cfg;
+		}				
+
+		try {
+			account.modify(accCfg);
+		} catch (Exception e) {}				
+
+		while (!Thread.currentThread().isInterrupted()) {
+			MyApp.ep.libHandleEvents(10);
+			try {						
+				Thread.currentThread().sleep(50);
+			} catch (InterruptedException ie) {						
+				break;
+			}					
+		}
+		app.deinit();
+	}	
+		
+	public static void main(String argv[]) {
+		Runtime.getRuntime().addShutdownHook(new MyShutdownHook(Thread.currentThread()));
+
+		runWorker();
+    }
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/java/test.java b/jni/libpjsip/sources/pjsip-apps/src/swig/java/test.java
new file mode 100644
index 0000000..f616460
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/java/test.java
@@ -0,0 +1,17 @@
+import org.pjsip.pjsua2.*;
+
+public class test {
+  static {
+    System.loadLibrary("pjsua2");
+    System.out.println("Library loaded");
+  }
+
+  public static void main(String argv[]) {
+
+	AuthCredInfo cred = new AuthCredInfo();
+
+	cred.setRealm("Hello world");
+    
+	System.out.println(cred.getRealm());
+  }
+}
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/pjsua2.i b/jni/libpjsip/sources/pjsip-apps/src/swig/pjsua2.i
new file mode 100644
index 0000000..2cc41d4
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/pjsua2.i
@@ -0,0 +1,111 @@
+%module(directors="1") pjsua2
+
+//
+// Suppress few warnings
+//
+#pragma SWIG nowarn=312		// 312: nested struct (in types.h, sip_auth.h)
+
+//
+// Header section
+//
+%{
+#include "pjsua2.hpp"
+using namespace std;
+using namespace pj;
+%}
+
+#ifdef SWIGPYTHON
+  %feature("director:except") {
+    if( $error != NULL ) {
+      PyObject *ptype, *pvalue, *ptraceback;
+      PyErr_Fetch( &ptype, &pvalue, &ptraceback );
+      PyErr_Restore( ptype, pvalue, ptraceback );
+      PyErr_Print();
+      //Py_Exit(1);
+    }
+  }
+#endif
+
+// Allow C++ exceptions to be handled in Java
+#ifdef SWIGJAVA
+  %typemap(throws, throws="java.lang.Exception") pj::Error {
+  jclass excep = jenv->FindClass("java/lang/Exception");
+  if (excep)
+    jenv->ThrowNew(excep, $1.info(true).c_str());
+  return $null;
+}
+
+  // Force the Error Java class to extend java.lang.Exception
+  %typemap(javabase) pj::Error "java.lang.Exception";
+
+  // Override getMessage()
+  %typemap(javacode) pj::Error %{
+  public String getMessage() {
+    return getTitle();
+  }
+%}
+#endif
+
+
+// Constants from PJSIP libraries
+%include "symbols.i"
+
+
+//
+// Classes that can be extended in the target language
+//
+%feature("director") LogWriter;
+%feature("director") Endpoint; 
+%feature("director") Account;
+%feature("director") Call;
+%feature("director") Buddy;
+%feature("director") FindBuddyMatch;
+
+//
+// STL stuff.
+//
+%include "std_string.i"
+%include "std_vector.i"
+
+%template(StringVector)			std::vector<std::string>;
+%template(IntVector) 			std::vector<int>;
+
+//
+// Ignore stuffs in pjsua2
+//
+%ignore fromPj;
+%ignore toPj;
+
+//
+// Now include the API itself.
+//
+%include "pjsua2/types.hpp"
+
+%ignore pj::ContainerNode::op;
+%ignore pj::ContainerNode::data;
+%ignore container_node_op;
+%ignore container_node_internal_data;
+%include "pjsua2/persistent.hpp"
+
+%include "pjsua2/siptypes.hpp"
+
+%template(SipHeaderVector)		std::vector<pj::SipHeader>;
+%template(AuthCredInfoVector)		std::vector<pj::AuthCredInfo>;
+%template(SipMultipartPartVector)	std::vector<pj::SipMultipartPart>;
+%template(BuddyVector)			std::vector<pj::Buddy*>;
+%template(AudioMediaVector)		std::vector<pj::AudioMedia*>;
+%template(MediaFormatVector)		std::vector<pj::MediaFormat*>;
+%template(AudioDevInfoVector)		std::vector<pj::AudioDevInfo*>;
+%template(CodecInfoVector)		std::vector<pj::CodecInfo*>;
+
+%include "pjsua2/media.hpp"
+%include "pjsua2/endpoint.hpp"
+%include "pjsua2/presence.hpp"
+%include "pjsua2/account.hpp"
+%include "pjsua2/call.hpp"
+
+%template(CallMediaInfoVector)          std::vector<pj::CallMediaInfo>;
+
+%ignore pj::JsonDocument::allocElement;
+%ignore pj::JsonDocument::getPool;
+%include "pjsua2/json.hpp"
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/python/Makefile b/jni/libpjsip/sources/pjsip-apps/src/swig/python/Makefile
new file mode 100644
index 0000000..80af9bf
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/python/Makefile
@@ -0,0 +1,29 @@
+PYTHON_SO=_pjsua2.so
+
+#PYTHON_SETUP_FLAGS = --inplace 
+ifeq ($(OS),Windows_NT)
+  PYTHON_SETUP_FLAGS += --compiler=mingw32
+endif
+
+SWIG_FLAGS += -w312
+
+.PHONY: all install uninstall
+
+all: $(PYTHON_SO)
+
+$(PYTHON_SO): pjsua2_wrap.cpp setup.py
+	python setup.py build $(PYTHON_SETUP_FLAGS)
+
+pjsua2_wrap.cpp: ../pjsua2.i ../symbols.i Makefile $(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
+
+install:
+	python setup.py install --user
+
+uninstall:
+	rm -f $(HOME)/.local/lib/python2.7/site-packages/pjsua2*
+	rm -f $(HOME)/.local/lib/python2.7/site-packages/_pjsua2*
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/python/helper.mak b/jni/libpjsip/sources/pjsip-apps/src/swig/python/helper.mak
new file mode 100644
index 0000000..41baf2b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/python/helper.mak
@@ -0,0 +1,20 @@
+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
+
+target_name:
+	@echo $(TARGET_NAME)
+	
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/python/setup.py b/jni/libpjsip/sources/pjsip-apps/src/swig/python/setup.py
new file mode 100644
index 0000000..a4cca08
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/python/setup.py
@@ -0,0 +1,118 @@
+# $Id: setup.py 4704 2014-01-16 05:30:46Z ming $
+#
+# 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 + '"'
+
+# Get targetname
+f = os.popen("make --no-print-directory -f helper.mak target_name")
+pj_target_name = f.read().rstrip("\r\n")
+f.close()
+
+# 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-' + pj_target_name]
+f = os.popen("make --no-print-directory -f helper.mak libs")
+for line in f:
+    pj_libs.append(line.rstrip("\r\n"))
+f.close()
+
+# Fill in extra link args
+extra_link_args = ['-static-libstdc++']
+if platform.system() == 'Darwin':
+    # Mac OS X depedencies
+    extra_link_args += ["-framework", "CoreFoundation", 
+                        "-framework", "AudioToolbox",
+			"-framework", "QTKit"]
+    # OS X Lion support
+    if platform.mac_ver()[0].startswith("10.7"):
+        extra_link_args += ["-framework", "AudioUnit"]
+
+
+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"]
+     )
+
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/python/test.py b/jni/libpjsip/sources/pjsip-apps/src/swig/python/test.py
new file mode 100644
index 0000000..dc805c7
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/python/test.py
@@ -0,0 +1,112 @@
+import pjsua2 as pj
+import sys
+
+#
+# Basic data structure test, to make sure basic struct
+# and array operations work
+#
+def ua_data_test():
+	#
+	# AuthCredInfo
+	#
+	print "UA data types test.."
+	the_realm = "pjsip.org"
+	ci = pj.AuthCredInfo()
+	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()
+	ep.libCreate()
+	got_exception = False
+	try:
+		ep.natDetectType()
+	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 == 370050
+		assert e.reason.find("PJNATH_ESTUNINSERVER") >= 0
+		assert e.title == "pjsua_detect_nat_type()"
+	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()
+	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()
+	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)
+
+	
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/symbols.i b/jni/libpjsip/sources/pjsip-apps/src/swig/symbols.i
new file mode 100644
index 0000000..e101e77
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/symbols.i
@@ -0,0 +1,130 @@
+// This file is autogenerated by importsym script, do not modify!
+
+typedef int pj_status_t;
+
+enum pj_constants_ {PJ_SUCCESS = 0, PJ_TRUE = 1, PJ_FALSE = 0};
+
+typedef unsigned char pj_uint8_t;
+
+typedef int pj_int32_t;
+
+typedef unsigned int pj_uint32_t;
+
+typedef unsigned short pj_uint16_t;
+
+enum pj_file_access {PJ_O_RDONLY = 0x1101, PJ_O_WRONLY = 0x1102, PJ_O_RDWR = 0x1103, PJ_O_APPEND = 0x1108};
+
+enum pj_log_decoration {PJ_LOG_HAS_DAY_NAME = 1, PJ_LOG_HAS_YEAR = 2, PJ_LOG_HAS_MONTH = 4, PJ_LOG_HAS_DAY_OF_MON = 8, PJ_LOG_HAS_TIME = 16, PJ_LOG_HAS_MICRO_SEC = 32, PJ_LOG_HAS_SENDER = 64, PJ_LOG_HAS_NEWLINE = 128, PJ_LOG_HAS_CR = 256, PJ_LOG_HAS_SPACE = 512, PJ_LOG_HAS_COLOR = 1024, PJ_LOG_HAS_LEVEL_TEXT = 2048, PJ_LOG_HAS_THREAD_ID = 4096, PJ_LOG_HAS_THREAD_SWC = 8192, PJ_LOG_HAS_INDENT = 16384};
+
+typedef enum pj_qos_type {PJ_QOS_TYPE_BEST_EFFORT, PJ_QOS_TYPE_BACKGROUND, PJ_QOS_TYPE_VIDEO, PJ_QOS_TYPE_VOICE, PJ_QOS_TYPE_CONTROL} pj_qos_type;
+
+typedef enum pj_qos_flag {PJ_QOS_PARAM_HAS_DSCP = 1, PJ_QOS_PARAM_HAS_SO_PRIO = 2, PJ_QOS_PARAM_HAS_WMM = 4} pj_qos_flag;
+
+typedef enum pj_qos_wmm_prio {PJ_QOS_WMM_PRIO_BULK_EFFORT, PJ_QOS_WMM_PRIO_BULK, PJ_QOS_WMM_PRIO_VIDEO, PJ_QOS_WMM_PRIO_VOICE} pj_qos_wmm_prio;
+
+typedef struct pj_qos_params
+{
+  pj_uint8_t flags;
+  pj_uint8_t dscp_val;
+  pj_uint8_t so_prio;
+  pj_qos_wmm_prio wmm_prio;
+} pj_qos_params;
+
+typedef enum pj_ssl_cipher {PJ_TLS_NULL_WITH_NULL_NULL = 0x00000000, PJ_TLS_RSA_WITH_NULL_MD5 = 0x00000001, PJ_TLS_RSA_WITH_NULL_SHA = 0x00000002, PJ_TLS_RSA_WITH_NULL_SHA256 = 0x0000003B, PJ_TLS_RSA_WITH_RC4_128_MD5 = 0x00000004, PJ_TLS_RSA_WITH_RC4_128_SHA = 0x00000005, PJ_TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x0000000A, PJ_TLS_RSA_WITH_AES_128_CBC_SHA = 0x0000002F, PJ_TLS_RSA_WITH_AES_256_CBC_SHA = 0x00000035, PJ_TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x0000003C, PJ_TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x0000003D, PJ_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x0000000D, PJ_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x00000010, PJ_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x00000013, PJ_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x00000016, PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x00000030, PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x00000031, PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x00000032, PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x00000033, PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x00000036, PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x00000037, PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x00000038, PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x00000039, PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x0000003E, PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x0000003F, PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x00000040, PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x00000067, PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x00000068, PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x00000069, PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x0000006A, PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x0000006B, PJ_TLS_DH_anon_WITH_RC4_128_MD5 = 0x00000018, PJ_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x0000001B, PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x00000034, PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x0000003A, PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x0000006C, PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x0000006D, PJ_TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x00000003, PJ_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x00000006, PJ_TLS_RSA_WITH_IDEA_CBC_SHA = 0x00000007, PJ_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x00000008, PJ_TLS_RSA_WITH_DES_CBC_SHA = 0x00000009, PJ_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0000000B, PJ_TLS_DH_DSS_WITH_DES_CBC_SHA = 0x0000000C, PJ_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0000000E, PJ_TLS_DH_RSA_WITH_DES_CBC_SHA = 0x0000000F, PJ_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x00000011, PJ_TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x00000012, PJ_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x00000014, PJ_TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x00000015, PJ_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x00000017, PJ_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x00000019, PJ_TLS_DH_anon_WITH_DES_CBC_SHA = 0x0000001A, PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA = 0x0000001C, PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA = 0x0000001D, PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA = 0x0000001E, PJ_SSL_CK_RC4_128_WITH_MD5 = 0x00010080, PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5 = 0x00020080, PJ_SSL_CK_RC2_128_CBC_WITH_MD5 = 0x00030080, PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 = 0x00040080, PJ_SSL_CK_IDEA_128_CBC_WITH_MD5 = 0x00050080, PJ_SSL_CK_DES_64_CBC_WITH_MD5 = 0x00060040, PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5 = 0x000700C0} pj_ssl_cipher;
+
+typedef enum pj_stun_nat_type {PJ_STUN_NAT_TYPE_UNKNOWN, PJ_STUN_NAT_TYPE_ERR_UNKNOWN, PJ_STUN_NAT_TYPE_OPEN, PJ_STUN_NAT_TYPE_BLOCKED, PJ_STUN_NAT_TYPE_SYMMETRIC_UDP, PJ_STUN_NAT_TYPE_FULL_CONE, PJ_STUN_NAT_TYPE_SYMMETRIC, PJ_STUN_NAT_TYPE_RESTRICTED, PJ_STUN_NAT_TYPE_PORT_RESTRICTED} pj_stun_nat_type;
+
+typedef enum pj_turn_tp_type {PJ_TURN_TP_UDP = 17, PJ_TURN_TP_TCP = 6, PJ_TURN_TP_TLS = 255} pj_turn_tp_type;
+
+typedef enum pjmedia_event_type {PJMEDIA_EVENT_NONE, PJMEDIA_EVENT_FMT_CHANGED = ((('H' << 24) | ('C' << 16)) | ('M' << 8)) | 'F', PJMEDIA_EVENT_WND_CLOSING = ((('L' << 24) | ('C' << 16)) | ('N' << 8)) | 'W', PJMEDIA_EVENT_WND_CLOSED = ((('O' << 24) | ('C' << 16)) | ('N' << 8)) | 'W', PJMEDIA_EVENT_WND_RESIZED = ((('Z' << 24) | ('R' << 16)) | ('N' << 8)) | 'W', PJMEDIA_EVENT_MOUSE_BTN_DOWN = ((('N' << 24) | ('D' << 16)) | ('S' << 8)) | 'M', PJMEDIA_EVENT_KEYFRAME_FOUND = ((('F' << 24) | ('R' << 16)) | ('F' << 8)) | 'I', PJMEDIA_EVENT_KEYFRAME_MISSING = ((('M' << 24) | ('R' << 16)) | ('F' << 8)) | 'I', PJMEDIA_EVENT_ORIENT_CHANGED = ((('T' << 24) | ('N' << 16)) | ('R' << 8)) | 'O'} pjmedia_event_type;
+
+typedef enum pjmedia_srtp_use {PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, PJMEDIA_SRTP_MANDATORY} pjmedia_srtp_use;
+
+typedef enum pjmedia_vid_stream_rc_method {PJMEDIA_VID_STREAM_RC_NONE = 0, PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING = 1} pjmedia_vid_stream_rc_method;
+
+typedef pj_int32_t pjmedia_vid_dev_index;
+
+enum pjmedia_vid_dev_std_index {PJMEDIA_VID_DEFAULT_CAPTURE_DEV = -1, PJMEDIA_VID_DEFAULT_RENDER_DEV = -2, PJMEDIA_VID_INVALID_DEV = -3};
+
+typedef enum pjmedia_aud_dev_route {PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0, PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1, PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2, PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH = 4} pjmedia_aud_dev_route;
+
+typedef enum pjmedia_aud_dev_cap {PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1, PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2, PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4, PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16, PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32, PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64, PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128, PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256, PJMEDIA_AUD_DEV_CAP_EC = 512, PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024, PJMEDIA_AUD_DEV_CAP_VAD = 2048, PJMEDIA_AUD_DEV_CAP_CNG = 4096, PJMEDIA_AUD_DEV_CAP_PLC = 8192, PJMEDIA_AUD_DEV_CAP_MAX = 16384} pjmedia_aud_dev_cap;
+
+enum pjmedia_file_writer_option {PJMEDIA_FILE_WRITE_PCM = 0, PJMEDIA_FILE_WRITE_ALAW = 1, PJMEDIA_FILE_WRITE_ULAW = 2};
+
+enum pjmedia_file_player_option {PJMEDIA_FILE_NO_LOOP = 1};
+
+typedef enum pjmedia_type {PJMEDIA_TYPE_NONE, PJMEDIA_TYPE_AUDIO, PJMEDIA_TYPE_VIDEO, PJMEDIA_TYPE_APPLICATION, PJMEDIA_TYPE_UNKNOWN} pjmedia_type;
+
+typedef enum pjmedia_dir {PJMEDIA_DIR_NONE = 0, PJMEDIA_DIR_ENCODING = 1, PJMEDIA_DIR_CAPTURE = PJMEDIA_DIR_ENCODING, PJMEDIA_DIR_DECODING = 2, PJMEDIA_DIR_PLAYBACK = PJMEDIA_DIR_DECODING, PJMEDIA_DIR_RENDER = PJMEDIA_DIR_DECODING, PJMEDIA_DIR_ENCODING_DECODING = 3, PJMEDIA_DIR_CAPTURE_PLAYBACK = PJMEDIA_DIR_ENCODING_DECODING, PJMEDIA_DIR_CAPTURE_RENDER = PJMEDIA_DIR_ENCODING_DECODING} pjmedia_dir;
+
+typedef enum pjmedia_tp_proto {PJMEDIA_TP_PROTO_NONE = 0, PJMEDIA_TP_PROTO_RTP_AVP, PJMEDIA_TP_PROTO_RTP_SAVP, PJMEDIA_TP_PROTO_UNKNOWN} pjmedia_tp_proto;
+
+typedef enum pjmedia_format_id {PJMEDIA_FORMAT_L16 = 0, PJMEDIA_FORMAT_PCM = PJMEDIA_FORMAT_L16, PJMEDIA_FORMAT_PCMA = ((('W' << 24) | ('A' << 16)) | ('L' << 8)) | 'A', PJMEDIA_FORMAT_ALAW = PJMEDIA_FORMAT_PCMA, PJMEDIA_FORMAT_PCMU = ((('W' << 24) | ('A' << 16)) | ('L' << 8)) | 'u', PJMEDIA_FORMAT_ULAW = PJMEDIA_FORMAT_PCMU, PJMEDIA_FORMAT_AMR = ((('R' << 24) | ('M' << 16)) | ('A' << 8)) | ' ', PJMEDIA_FORMAT_G729 = ((('9' << 24) | ('2' << 16)) | ('7' << 8)) | 'G', PJMEDIA_FORMAT_ILBC = ((('C' << 24) | ('B' << 16)) | ('L' << 8)) | 'I', PJMEDIA_FORMAT_RGB24 = ((('3' << 24) | ('B' << 16)) | ('G' << 8)) | 'R', PJMEDIA_FORMAT_RGBA = ((('A' << 24) | ('B' << 16)) | ('G' << 8)) | 'R', PJMEDIA_FORMAT_BGRA = ((('A' << 24) | ('R' << 16)) | ('G' << 8)) | 'B', PJMEDIA_FORMAT_RGB32 = PJMEDIA_FORMAT_RGBA, PJMEDIA_FORMAT_DIB = (((' ' << 24) | ('B' << 16)) | ('I' << 8)) | 'D', PJMEDIA_FORMAT_GBRP = ((('P' << 24) | ('R' << 16)) | ('B' << 8)) | 'G', PJMEDIA_FORMAT_AYUV = ((('V' << 24) | ('U' << 16)) | ('Y' << 8)) | 'A', PJMEDIA_FORMAT_YUY2 = ((('2' << 24) | ('Y' << 16)) | ('U' << 8)) | 'Y', PJMEDIA_FORMAT_UYVY = ((('Y' << 24) | ('V' << 16)) | ('Y' << 8)) | 'U', PJMEDIA_FORMAT_YVYU = ((('U' << 24) | ('Y' << 16)) | ('V' << 8)) | 'Y', PJMEDIA_FORMAT_I420 = ((('0' << 24) | ('2' << 16)) | ('4' << 8)) | 'I', PJMEDIA_FORMAT_IYUV = PJMEDIA_FORMAT_I420, PJMEDIA_FORMAT_YV12 = ((('2' << 24) | ('1' << 16)) | ('V' << 8)) | 'Y', PJMEDIA_FORMAT_I422 = ((('2' << 24) | ('2' << 16)) | ('4' << 8)) | 'I', PJMEDIA_FORMAT_I420JPEG = ((('0' << 24) | ('2' << 16)) | ('4' << 8)) | 'J', PJMEDIA_FORMAT_I422JPEG = ((('2' << 24) | ('2' << 16)) | ('4' << 8)) | 'J', PJMEDIA_FORMAT_H261 = ((('1' << 24) | ('6' << 16)) | ('2' << 8)) | 'H', PJMEDIA_FORMAT_H263 = ((('3' << 24) | ('6' << 16)) | ('2' << 8)) | 'H', PJMEDIA_FORMAT_H263P = ((('3' << 24) | ('6' << 16)) | ('2' << 8)) | 'P', PJMEDIA_FORMAT_H264 = ((('4' << 24) | ('6' << 16)) | ('2' << 8)) | 'H', PJMEDIA_FORMAT_MJPEG = ((('G' << 24) | ('P' << 16)) | ('J' << 8)) | 'M', PJMEDIA_FORMAT_MPEG1VIDEO = ((('V' << 24) | ('1' << 16)) | ('P' << 8)) | 'M', PJMEDIA_FORMAT_MPEG2VIDEO = ((('V' << 24) | ('2' << 16)) | ('P' << 8)) | 'M', PJMEDIA_FORMAT_MPEG4 = ((('4' << 24) | ('G' << 16)) | ('P' << 8)) | 'M'} pjmedia_format_id;
+
+typedef enum pjsip_cred_data_type {PJSIP_CRED_DATA_PLAIN_PASSWD = 0, PJSIP_CRED_DATA_DIGEST = 1, PJSIP_CRED_DATA_EXT_AKA = 16} pjsip_cred_data_type;
+
+typedef enum pjsip_dialog_cap_status {PJSIP_DIALOG_CAP_UNSUPPORTED = 0, PJSIP_DIALOG_CAP_SUPPORTED = 1, PJSIP_DIALOG_CAP_UNKNOWN = 2} pjsip_dialog_cap_status;
+
+typedef enum pjsip_event_id_e {PJSIP_EVENT_UNKNOWN, PJSIP_EVENT_TIMER, PJSIP_EVENT_TX_MSG, PJSIP_EVENT_RX_MSG, PJSIP_EVENT_TRANSPORT_ERROR, PJSIP_EVENT_TSX_STATE, PJSIP_EVENT_USER} pjsip_event_id_e;
+
+typedef enum pjsip_status_code {PJSIP_SC_TRYING = 100, PJSIP_SC_RINGING = 180, PJSIP_SC_CALL_BEING_FORWARDED = 181, PJSIP_SC_QUEUED = 182, PJSIP_SC_PROGRESS = 183, PJSIP_SC_OK = 200, PJSIP_SC_ACCEPTED = 202, PJSIP_SC_MULTIPLE_CHOICES = 300, PJSIP_SC_MOVED_PERMANENTLY = 301, PJSIP_SC_MOVED_TEMPORARILY = 302, PJSIP_SC_USE_PROXY = 305, PJSIP_SC_ALTERNATIVE_SERVICE = 380, PJSIP_SC_BAD_REQUEST = 400, PJSIP_SC_UNAUTHORIZED = 401, PJSIP_SC_PAYMENT_REQUIRED = 402, PJSIP_SC_FORBIDDEN = 403, PJSIP_SC_NOT_FOUND = 404, PJSIP_SC_METHOD_NOT_ALLOWED = 405, PJSIP_SC_NOT_ACCEPTABLE = 406, PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED = 407, PJSIP_SC_REQUEST_TIMEOUT = 408, PJSIP_SC_GONE = 410, PJSIP_SC_REQUEST_ENTITY_TOO_LARGE = 413, PJSIP_SC_REQUEST_URI_TOO_LONG = 414, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE = 415, PJSIP_SC_UNSUPPORTED_URI_SCHEME = 416, PJSIP_SC_BAD_EXTENSION = 420, PJSIP_SC_EXTENSION_REQUIRED = 421, PJSIP_SC_SESSION_TIMER_TOO_SMALL = 422, PJSIP_SC_INTERVAL_TOO_BRIEF = 423, PJSIP_SC_TEMPORARILY_UNAVAILABLE = 480, PJSIP_SC_CALL_TSX_DOES_NOT_EXIST = 481, PJSIP_SC_LOOP_DETECTED = 482, PJSIP_SC_TOO_MANY_HOPS = 483, PJSIP_SC_ADDRESS_INCOMPLETE = 484, PJSIP_AC_AMBIGUOUS = 485, PJSIP_SC_BUSY_HERE = 486, PJSIP_SC_REQUEST_TERMINATED = 487, PJSIP_SC_NOT_ACCEPTABLE_HERE = 488, PJSIP_SC_BAD_EVENT = 489, PJSIP_SC_REQUEST_UPDATED = 490, PJSIP_SC_REQUEST_PENDING = 491, PJSIP_SC_UNDECIPHERABLE = 493, PJSIP_SC_INTERNAL_SERVER_ERROR = 500, PJSIP_SC_NOT_IMPLEMENTED = 501, PJSIP_SC_BAD_GATEWAY = 502, PJSIP_SC_SERVICE_UNAVAILABLE = 503, PJSIP_SC_SERVER_TIMEOUT = 504, PJSIP_SC_VERSION_NOT_SUPPORTED = 505, PJSIP_SC_MESSAGE_TOO_LARGE = 513, PJSIP_SC_PRECONDITION_FAILURE = 580, PJSIP_SC_BUSY_EVERYWHERE = 600, PJSIP_SC_DECLINE = 603, PJSIP_SC_DOES_NOT_EXIST_ANYWHERE = 604, PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE = 606, PJSIP_SC_TSX_TIMEOUT = PJSIP_SC_REQUEST_TIMEOUT, PJSIP_SC_TSX_TRANSPORT_ERROR = PJSIP_SC_SERVICE_UNAVAILABLE, PJSIP_SC__force_32bit = 0x7FFFFFFF} pjsip_status_code;
+
+typedef enum pjsip_hdr_e {PJSIP_H_ACCEPT, PJSIP_H_ACCEPT_ENCODING_UNIMP, PJSIP_H_ACCEPT_LANGUAGE_UNIMP, PJSIP_H_ALERT_INFO_UNIMP, PJSIP_H_ALLOW, PJSIP_H_AUTHENTICATION_INFO_UNIMP, PJSIP_H_AUTHORIZATION, PJSIP_H_CALL_ID, PJSIP_H_CALL_INFO_UNIMP, PJSIP_H_CONTACT, PJSIP_H_CONTENT_DISPOSITION_UNIMP, PJSIP_H_CONTENT_ENCODING_UNIMP, PJSIP_H_CONTENT_LANGUAGE_UNIMP, PJSIP_H_CONTENT_LENGTH, PJSIP_H_CONTENT_TYPE, PJSIP_H_CSEQ, PJSIP_H_DATE_UNIMP, PJSIP_H_ERROR_INFO_UNIMP, PJSIP_H_EXPIRES, PJSIP_H_FROM, PJSIP_H_IN_REPLY_TO_UNIMP, PJSIP_H_MAX_FORWARDS, PJSIP_H_MIME_VERSION_UNIMP, PJSIP_H_MIN_EXPIRES, PJSIP_H_ORGANIZATION_UNIMP, PJSIP_H_PRIORITY_UNIMP, PJSIP_H_PROXY_AUTHENTICATE, PJSIP_H_PROXY_AUTHORIZATION, PJSIP_H_PROXY_REQUIRE_UNIMP, PJSIP_H_RECORD_ROUTE, PJSIP_H_REPLY_TO_UNIMP, PJSIP_H_REQUIRE, PJSIP_H_RETRY_AFTER, PJSIP_H_ROUTE, PJSIP_H_SERVER_UNIMP, PJSIP_H_SUBJECT_UNIMP, PJSIP_H_SUPPORTED, PJSIP_H_TIMESTAMP_UNIMP, PJSIP_H_TO, PJSIP_H_UNSUPPORTED, PJSIP_H_USER_AGENT_UNIMP, PJSIP_H_VIA, PJSIP_H_WARNING_UNIMP, PJSIP_H_WWW_AUTHENTICATE, PJSIP_H_OTHER} pjsip_hdr_e;
+
+typedef enum pjsip_transport_type_e {PJSIP_TRANSPORT_UNSPECIFIED, PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_TCP, PJSIP_TRANSPORT_TLS, PJSIP_TRANSPORT_SCTP, PJSIP_TRANSPORT_LOOP, PJSIP_TRANSPORT_LOOP_DGRAM, PJSIP_TRANSPORT_START_OTHER, PJSIP_TRANSPORT_IPV6 = 128, PJSIP_TRANSPORT_UDP6 = PJSIP_TRANSPORT_UDP + PJSIP_TRANSPORT_IPV6, PJSIP_TRANSPORT_TCP6 = PJSIP_TRANSPORT_TCP + PJSIP_TRANSPORT_IPV6, PJSIP_TRANSPORT_TLS6 = PJSIP_TRANSPORT_TLS + PJSIP_TRANSPORT_IPV6} pjsip_transport_type_e;
+
+enum pjsip_transport_flags_e {PJSIP_TRANSPORT_RELIABLE = 1, PJSIP_TRANSPORT_SECURE = 2, PJSIP_TRANSPORT_DATAGRAM = 4};
+
+typedef enum pjsip_transport_state {PJSIP_TP_STATE_CONNECTED, PJSIP_TP_STATE_DISCONNECTED} pjsip_transport_state;
+
+typedef enum pjsip_ssl_method {PJSIP_SSL_UNSPECIFIED_METHOD = 0, PJSIP_TLSV1_METHOD = 31, PJSIP_SSLV2_METHOD = 20, PJSIP_SSLV3_METHOD = 30, PJSIP_SSLV23_METHOD = 23} pjsip_ssl_method;
+
+typedef enum pjsip_tsx_state_e {PJSIP_TSX_STATE_NULL, PJSIP_TSX_STATE_CALLING, PJSIP_TSX_STATE_TRYING, PJSIP_TSX_STATE_PROCEEDING, PJSIP_TSX_STATE_COMPLETED, PJSIP_TSX_STATE_CONFIRMED, PJSIP_TSX_STATE_TERMINATED, PJSIP_TSX_STATE_DESTROYED, PJSIP_TSX_STATE_MAX} pjsip_tsx_state_e;
+
+typedef enum pjsip_role_e {PJSIP_ROLE_UAC, PJSIP_ROLE_UAS, PJSIP_UAC_ROLE = PJSIP_ROLE_UAC, PJSIP_UAS_ROLE = PJSIP_ROLE_UAS} pjsip_role_e;
+
+typedef enum pjsip_redirect_op {PJSIP_REDIRECT_REJECT, PJSIP_REDIRECT_ACCEPT, PJSIP_REDIRECT_ACCEPT_REPLACE, PJSIP_REDIRECT_PENDING, PJSIP_REDIRECT_STOP} pjsip_redirect_op;
+
+typedef enum pjrpid_activity {PJRPID_ACTIVITY_UNKNOWN, PJRPID_ACTIVITY_AWAY, PJRPID_ACTIVITY_BUSY} pjrpid_activity;
+
+typedef enum pjsip_evsub_state {PJSIP_EVSUB_STATE_NULL, PJSIP_EVSUB_STATE_SENT, PJSIP_EVSUB_STATE_ACCEPTED, PJSIP_EVSUB_STATE_PENDING, PJSIP_EVSUB_STATE_ACTIVE, PJSIP_EVSUB_STATE_TERMINATED, PJSIP_EVSUB_STATE_UNKNOWN} pjsip_evsub_state;
+
+typedef enum pjsip_inv_state {PJSIP_INV_STATE_NULL, PJSIP_INV_STATE_CALLING, PJSIP_INV_STATE_INCOMING, PJSIP_INV_STATE_EARLY, PJSIP_INV_STATE_CONNECTING, PJSIP_INV_STATE_CONFIRMED, PJSIP_INV_STATE_DISCONNECTED} pjsip_inv_state;
+
+enum pjsua_invalid_id_const_ {PJSUA_INVALID_ID = -1};
+
+typedef enum pjsua_state {PJSUA_STATE_NULL, PJSUA_STATE_CREATED, PJSUA_STATE_INIT, PJSUA_STATE_STARTING, PJSUA_STATE_RUNNING, PJSUA_STATE_CLOSING} pjsua_state;
+
+typedef enum pjsua_stun_use {PJSUA_STUN_USE_DEFAULT, PJSUA_STUN_USE_DISABLED} pjsua_stun_use;
+
+typedef enum pjsua_call_hold_type {PJSUA_CALL_HOLD_TYPE_RFC3264, PJSUA_CALL_HOLD_TYPE_RFC2543} pjsua_call_hold_type;
+
+typedef int pjsua_acc_id;
+
+typedef enum pjsua_destroy_flag {PJSUA_DESTROY_NO_RX_MSG = 1, PJSUA_DESTROY_NO_TX_MSG = 2, PJSUA_DESTROY_NO_NETWORK = PJSUA_DESTROY_NO_RX_MSG | PJSUA_DESTROY_NO_TX_MSG} pjsua_destroy_flag;
+
+typedef enum pjsua_100rel_use {PJSUA_100REL_NOT_USED, PJSUA_100REL_MANDATORY, PJSUA_100REL_OPTIONAL} pjsua_100rel_use;
+
+typedef enum pjsua_sip_timer_use {PJSUA_SIP_TIMER_INACTIVE, PJSUA_SIP_TIMER_OPTIONAL, PJSUA_SIP_TIMER_REQUIRED, PJSUA_SIP_TIMER_ALWAYS} pjsua_sip_timer_use;
+
+typedef enum pjsua_ipv6_use {PJSUA_IPV6_DISABLED, PJSUA_IPV6_ENABLED} pjsua_ipv6_use;
+
+typedef enum pjsua_buddy_status {PJSUA_BUDDY_STATUS_UNKNOWN, PJSUA_BUDDY_STATUS_ONLINE, PJSUA_BUDDY_STATUS_OFFLINE} pjsua_buddy_status;
+
+typedef enum pjsua_call_media_status {PJSUA_CALL_MEDIA_NONE, PJSUA_CALL_MEDIA_ACTIVE, PJSUA_CALL_MEDIA_LOCAL_HOLD, PJSUA_CALL_MEDIA_REMOTE_HOLD, PJSUA_CALL_MEDIA_ERROR} pjsua_call_media_status;
+
+typedef int pjsua_vid_win_id;
+
+typedef int pjsua_call_id;
+
+typedef enum pjsua_med_tp_st {PJSUA_MED_TP_NULL, PJSUA_MED_TP_CREATING, PJSUA_MED_TP_IDLE, PJSUA_MED_TP_INIT, PJSUA_MED_TP_RUNNING, PJSUA_MED_TP_DISABLED} pjsua_med_tp_st;
+
+typedef enum pjsua_call_vid_strm_op {PJSUA_CALL_VID_STRM_NO_OP, PJSUA_CALL_VID_STRM_ADD, PJSUA_CALL_VID_STRM_REMOVE, PJSUA_CALL_VID_STRM_CHANGE_DIR, PJSUA_CALL_VID_STRM_CHANGE_CAP_DEV, PJSUA_CALL_VID_STRM_START_TRANSMIT, PJSUA_CALL_VID_STRM_STOP_TRANSMIT, PJSUA_CALL_VID_STRM_SEND_KEYFRAME} pjsua_call_vid_strm_op;
+
+typedef enum pjsua_vid_req_keyframe_method {PJSUA_VID_REQ_KEYFRAME_SIP_INFO = 1, PJSUA_VID_REQ_KEYFRAME_RTCP_PLI = 2} pjsua_vid_req_keyframe_method;
+
+typedef enum pjsua_call_flag {PJSUA_CALL_UNHOLD = 1, PJSUA_CALL_UPDATE_CONTACT = 2, PJSUA_CALL_INCLUDE_DISABLED_MEDIA = 4} pjsua_call_flag;
+
+typedef enum pjsua_create_media_transport_flag {PJSUA_MED_TP_CLOSE_MEMBER = 1} pjsua_create_media_transport_flag;
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/swig/symbols.lst b/jni/libpjsip/sources/pjsip-apps/src/swig/symbols.lst
new file mode 100644
index 0000000..685c371
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/swig/symbols.lst
@@ -0,0 +1,34 @@
+pj/types.h			pj_status_t pj_constants_ pj_uint8_t pj_int32_t pj_uint32_t pj_uint16_t
+pj/file_io.h			pj_file_access
+pj/log.h			pj_log_decoration
+pj/sock_qos.h			pj_qos_type pj_qos_flag pj_qos_wmm_prio pj_qos_params
+pj/ssl_sock.h			pj_ssl_cipher
+
+pjnath/nat_detect.h          	pj_stun_nat_type
+pjnath/turn_session.h          	pj_turn_tp_type
+
+pjmedia/event.h                 pjmedia_event_type
+pjmedia/transport_srtp.h	pjmedia_srtp_use
+pjmedia/vid_stream.h		pjmedia_vid_stream_rc_method
+pjmedia-videodev/videodev.h	pjmedia_vid_dev_index pjmedia_vid_dev_std_index
+pjmedia-audiodev/audiodev.h 	pjmedia_aud_dev_route pjmedia_aud_dev_cap
+pjmedia/wav_port.h              pjmedia_file_writer_option pjmedia_file_player_option
+pjmedia/types.h                 pjmedia_type pjmedia_dir pjmedia_tp_proto
+pjmedia/format.h		pjmedia_format_id
+
+pjsip/sip_auth.h		pjsip_cred_data_type
+pjsip/sip_dialog.h              pjsip_dialog_cap_status
+pjsip/sip_event.h               pjsip_event_id_e
+pjsip/sip_msg.h			pjsip_status_code pjsip_hdr_e
+pjsip/sip_transport.h		pjsip_transport_type_e pjsip_transport_flags_e pjsip_transport_state
+pjsip/sip_transport_tls.h	pjsip_ssl_method
+pjsip/sip_transaction.h         pjsip_tsx_state_e
+pjsip/sip_types.h               pjsip_role_e
+pjsip/sip_util.h                pjsip_redirect_op
+
+pjsip-simple/rpid.h          	pjrpid_activity
+pjsip-simple/evsub.h		pjsip_evsub_state
+
+pjsip-ua/sip_inv.h              pjsip_inv_state
+
+pjsua-lib/pjsua.h		pjsua_invalid_id_const_ pjsua_state pjsua_stun_use pjsua_call_hold_type pjsua_acc_id pjsua_destroy_flag pjsua_100rel_use pjsua_sip_timer_use pjsua_ipv6_use pjsua_buddy_status pjsua_call_media_status pjsua_vid_win_id pjsua_call_id pjsua_med_tp_st pjsua_call_vid_strm_op pjsua_vid_req_keyframe_method pjsua_call_flag pjsua_create_media_transport_flag
diff --git a/jni/libpjsip/sources/pjsip-apps/src/symsndtest/app_main.cpp b/jni/libpjsip/sources/pjsip-apps/src/symsndtest/app_main.cpp
new file mode 100644
index 0000000..d4f5523
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/symsndtest/app_main.cpp
@@ -0,0 +1,434 @@
+/* $Id: app_main.cpp 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 <pjmedia-audiodev/audiodev.h>
+#include <pjmedia/delaybuf.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/os.h>
+#include <pj/log.h>
+#include <pj/string.h>
+#include <pj/unicode.h>
+#include <e32cons.h>
+
+#define THIS_FILE		"app_main.cpp"
+#define CLOCK_RATE		8000
+#define CHANNEL_COUNT		1
+#define PTIME			20
+#define SAMPLES_PER_FRAME	(CLOCK_RATE*PTIME/1000)
+#define BITS_PER_SAMPLE		16
+
+extern CConsoleBase* console;
+
+static pj_caching_pool cp;
+static pjmedia_aud_stream *strm;
+static unsigned rec_cnt, play_cnt;
+static pj_time_val t_start;
+static pjmedia_aud_param param;
+static pj_pool_t *pool;
+static pjmedia_delay_buf *delaybuf;
+static char frame_buf[256];
+
+static void copy_frame_ext(pjmedia_frame_ext *f_dst, 
+                           const pjmedia_frame_ext *f_src) 
+{
+    pj_bzero(f_dst, sizeof(*f_dst));
+    if (f_src->subframe_cnt) {
+	f_dst->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
+	for (unsigned i = 0; i < f_src->subframe_cnt; ++i) {
+	    pjmedia_frame_ext_subframe *sf;
+	    sf = pjmedia_frame_ext_get_subframe(f_src, i);
+	    pjmedia_frame_ext_append_subframe(f_dst, sf->data, sf->bitlen, 
+					      param.samples_per_frame);
+	}
+    } else {
+	f_dst->base.type = PJMEDIA_FRAME_TYPE_NONE;
+    }
+}
+
+/* Logging callback */
+static void log_writer(int level, const char *buf, unsigned len)
+{
+    static wchar_t buf16[PJ_LOG_MAX_SIZE];
+
+    PJ_UNUSED_ARG(level);
+
+    pj_ansi_to_unicode(buf, len, buf16, PJ_ARRAY_SIZE(buf16));
+
+    TPtrC16 aBuf((const TUint16*)buf16, (TInt)len);
+    console->Write(aBuf);
+}
+
+/* perror util */
+static void app_perror(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(1,(THIS_FILE, "Error: %s: %s", title, errmsg));
+}
+
+/* Application init */
+static pj_status_t app_init()
+{
+    unsigned i, count;
+    pj_status_t status;
+
+    /* Redirect log */
+    pj_log_set_log_func((void (*)(int,const char*,int)) &log_writer);
+    pj_log_set_decor(PJ_LOG_HAS_NEWLINE);
+    pj_log_set_level(3);
+
+    /* Init pjlib */
+    status = pj_init();
+    if (status != PJ_SUCCESS) {
+    	app_perror("pj_init()", status);
+    	return status;
+    }
+
+    pj_caching_pool_init(&cp, NULL, 0);
+
+    /* Init sound subsystem */
+    status = pjmedia_aud_subsys_init(&cp.factory);
+    if (status != PJ_SUCCESS) {
+    	app_perror("pjmedia_snd_init()", status);
+        pj_caching_pool_destroy(&cp);
+    	pj_shutdown();
+    	return status;
+    }
+
+    count = pjmedia_aud_dev_count();
+    PJ_LOG(3,(THIS_FILE, "Device count: %d", count));
+    for (i=0; i<count; ++i) {
+    	pjmedia_aud_dev_info info;
+    	pj_status_t status;
+
+    	status = pjmedia_aud_dev_get_info(i, &info);
+    	pj_assert(status == PJ_SUCCESS);
+    	PJ_LOG(3, (THIS_FILE, "%d: %s %d/%d %dHz",
+    		   i, info.name, info.input_count, info.output_count,
+    		   info.default_samples_per_sec));
+    	
+	unsigned j;
+
+	/* Print extended formats supported by this audio device */
+	PJ_LOG(3, (THIS_FILE, "   Extended formats supported:"));
+	for (j = 0; j < info.ext_fmt_cnt; ++j) {
+	    const char *fmt_name = NULL;
+	    
+	    switch (info.ext_fmt[j].id) {
+	    case PJMEDIA_FORMAT_PCMA:
+		fmt_name = "PCMA";
+		break;
+	    case PJMEDIA_FORMAT_PCMU:
+		fmt_name = "PCMU";
+		break;
+	    case PJMEDIA_FORMAT_AMR:
+		fmt_name = "AMR-NB";
+		break;
+	    case PJMEDIA_FORMAT_G729:
+		fmt_name = "G729";
+		break;
+	    case PJMEDIA_FORMAT_ILBC:
+		fmt_name = "ILBC";
+		break;
+	    case PJMEDIA_FORMAT_PCM:
+		fmt_name = "PCM";
+		break;
+	    default:
+		fmt_name = "Unknown";
+		break;
+	    }
+	    PJ_LOG(3, (THIS_FILE, "   - %s", fmt_name));
+	}
+    }
+
+    /* Create pool */
+    pool = pj_pool_create(&cp.factory, THIS_FILE, 512, 512, NULL);
+    if (pool == NULL) {
+    	app_perror("pj_pool_create()", status);
+        pj_caching_pool_destroy(&cp);
+    	pj_shutdown();
+    	return status;
+    }
+
+    /* Init delay buffer */
+    status = pjmedia_delay_buf_create(pool, THIS_FILE, CLOCK_RATE,
+				      SAMPLES_PER_FRAME, CHANNEL_COUNT,
+				      0, 0, &delaybuf);
+    if (status != PJ_SUCCESS) {
+    	app_perror("pjmedia_delay_buf_create()", status);
+        //pj_caching_pool_destroy(&cp);
+    	//pj_shutdown();
+    	//return status;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/* Sound capture callback */
+static pj_status_t rec_cb(void *user_data,
+			  pjmedia_frame *frame)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    if (param.ext_fmt.id == PJMEDIA_FORMAT_PCM) {
+	pjmedia_delay_buf_put(delaybuf, (pj_int16_t*)frame->buf);
+    
+	if (frame->size != SAMPLES_PER_FRAME*2) {
+		    PJ_LOG(3, (THIS_FILE, "Size captured = %u",
+			       frame->size));
+	}
+    } else {
+	pjmedia_frame_ext *f_src = (pjmedia_frame_ext*)frame;
+	pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frame_buf;
+	
+	copy_frame_ext(f_dst, f_src);
+    }
+
+    ++rec_cnt;
+    return PJ_SUCCESS;
+}
+
+/* Play cb */
+static pj_status_t play_cb(void *user_data,
+			   pjmedia_frame *frame)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    if (param.ext_fmt.id == PJMEDIA_FORMAT_PCM) {
+	pjmedia_delay_buf_get(delaybuf, (pj_int16_t*)frame->buf);
+	frame->size = SAMPLES_PER_FRAME*2;
+	frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+    } else {
+	pjmedia_frame_ext *f_src = (pjmedia_frame_ext*)frame_buf;
+	pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frame;
+
+	copy_frame_ext(f_dst, f_src);
+    }
+
+    ++play_cnt;
+    return PJ_SUCCESS;
+}
+
+/* Start sound */
+static pj_status_t snd_start(unsigned flag)
+{
+    pj_status_t status;
+
+    if (strm != NULL) {
+    	app_perror("snd already open", PJ_EINVALIDOP);
+    	return PJ_EINVALIDOP;
+    }
+
+    pjmedia_aud_dev_default_param(0, &param);
+    param.channel_count = CHANNEL_COUNT;
+    param.clock_rate = CLOCK_RATE;
+    param.samples_per_frame = SAMPLES_PER_FRAME;
+    param.dir = (pjmedia_dir) flag;
+    param.ext_fmt.id = PJMEDIA_FORMAT_AMR;
+    param.ext_fmt.bitrate = 12200;
+    param.output_route = PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
+
+    status = pjmedia_aud_stream_create(&param, &rec_cb, &play_cb, NULL, &strm);
+    if (status != PJ_SUCCESS) {
+    	app_perror("snd open", status);
+    	return status;
+    }
+
+    rec_cnt = play_cnt = 0;
+    pj_gettimeofday(&t_start);
+
+    pjmedia_delay_buf_reset(delaybuf);
+
+    status = pjmedia_aud_stream_start(strm);
+    if (status != PJ_SUCCESS) {
+    	app_perror("snd start", status);
+    	pjmedia_aud_stream_destroy(strm);
+    	strm = NULL;
+    	return status;
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* Stop sound */
+static pj_status_t snd_stop()
+{
+    pj_time_val now;
+    pj_status_t status;
+
+    if (strm == NULL) {
+    	app_perror("snd not open", PJ_EINVALIDOP);
+    	return PJ_EINVALIDOP;
+    }
+
+    status = pjmedia_aud_stream_stop(strm);
+    if (status != PJ_SUCCESS) {
+    	app_perror("snd failed to stop", status);
+    }
+    status = pjmedia_aud_stream_destroy(strm);
+    strm = NULL;
+
+    pj_gettimeofday(&now);
+    PJ_TIME_VAL_SUB(now, t_start);
+
+    PJ_LOG(3,(THIS_FILE, "Duration: %d.%03d", now.sec, now.msec));
+    PJ_LOG(3,(THIS_FILE, "Captured: %d", rec_cnt));
+    PJ_LOG(3,(THIS_FILE, "Played: %d", play_cnt));
+
+    return status;
+}
+
+/* Shutdown application */
+static void app_fini()
+{
+    if (strm)
+    	snd_stop();
+
+    pjmedia_aud_subsys_shutdown();
+    pjmedia_delay_buf_destroy(delaybuf);
+    pj_pool_release(pool);
+    pj_caching_pool_destroy(&cp);
+    pj_shutdown();
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+/*
+ * The interractive console UI
+ */
+#include <e32base.h>
+
+class ConsoleUI : public CActive
+{
+public:
+    ConsoleUI(CConsoleBase *con);
+
+    // Run console UI
+    void Run();
+
+    // Stop
+    void Stop();
+
+protected:
+    // Cancel asynchronous read.
+    void DoCancel();
+
+    // Implementation: called when read has completed.
+    void RunL();
+
+private:
+    CConsoleBase *con_;
+};
+
+
+ConsoleUI::ConsoleUI(CConsoleBase *con)
+: CActive(EPriorityUserInput), con_(con)
+{
+    CActiveScheduler::Add(this);
+}
+
+// Run console UI
+void ConsoleUI::Run()
+{
+    con_->Read(iStatus);
+    SetActive();
+}
+
+// Stop console UI
+void ConsoleUI::Stop()
+{
+    DoCancel();
+}
+
+// Cancel asynchronous read.
+void ConsoleUI::DoCancel()
+{
+    con_->ReadCancel();
+}
+
+static void PrintMenu()
+{
+    PJ_LOG(3, (THIS_FILE, "\n\n"
+	    "Menu:\n"
+	    "  a    Start bidir sound\n"
+	    "  t    Start recorder\n"
+	    "  p    Start player\n"
+	    "  d    Stop & close sound\n"
+	    "  w    Quit\n"));
+}
+
+// Implementation: called when read has completed.
+void ConsoleUI::RunL()
+{
+    TKeyCode kc = con_->KeyCode();
+    pj_bool_t reschedule = PJ_TRUE;
+
+    switch (kc) {
+    case 'w':
+	    snd_stop();
+	    CActiveScheduler::Stop();
+	    reschedule = PJ_FALSE;
+	    break;
+    case 'a':
+    	snd_start(PJMEDIA_DIR_CAPTURE_PLAYBACK);
+	break;
+    case 't':
+    	snd_start(PJMEDIA_DIR_CAPTURE);
+	break;
+    case 'p':
+    	snd_start(PJMEDIA_DIR_PLAYBACK);
+    break;
+    case 'd':
+    	snd_stop();
+	break;
+    default:
+	    PJ_LOG(3,(THIS_FILE, "Keycode '%c' (%d) is pressed",
+		      kc, kc));
+	    break;
+    }
+
+    PrintMenu();
+
+    if (reschedule)
+	Run();
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+int app_main()
+{
+    if (app_init() != PJ_SUCCESS)
+        return -1;
+
+    // Run the UI
+    ConsoleUI *con = new ConsoleUI(console);
+
+    con->Run();
+
+    PrintMenu();
+    CActiveScheduler::Start();
+
+    delete con;
+
+    app_fini();
+    return 0;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/symsndtest/main_symbian.cpp b/jni/libpjsip/sources/pjsip-apps/src/symsndtest/main_symbian.cpp
new file mode 100644
index 0000000..d160a6c
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/symsndtest/main_symbian.cpp
@@ -0,0 +1,83 @@
+/* $Id: main_symbian.cpp 3553 2011-05-05 06:14:19Z nanang $ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * 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 <e32std.h>
+#include <e32base.h>
+#include <e32std.h>
+#include <e32cons.h>
+#include <stdlib.h>
+
+
+//  Global Variables
+CConsoleBase* console;
+
+// Needed by APS
+TPtrC APP_UID = _L("A000000E");
+
+int app_main();
+
+
+////////////////////////////////////////////////////////////////////////////
+
+LOCAL_C void DoStartL()
+{
+    CActiveScheduler *scheduler = new (ELeave) CActiveScheduler;
+    CleanupStack::PushL(scheduler);
+    CActiveScheduler::Install(scheduler);
+
+    app_main();
+
+    CActiveScheduler::Install(NULL);
+    CleanupStack::Pop(scheduler);
+    delete scheduler;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+// E32Main()
+GLDEF_C TInt E32Main()
+{
+    // Mark heap usage
+    __UHEAP_MARK;
+
+    // Create cleanup stack
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+
+    // Create output console
+    TRAPD(createError, console = Console::NewL(_L("Console"), TSize(KConsFullScreen,KConsFullScreen)));
+    if (createError)
+        return createError;
+
+    TRAPD(startError, DoStartL());
+
+    //console->Printf(_L("[press any key to close]\n"));
+    //console->Getch();
+
+    delete console;
+    delete cleanup;
+
+    CloseSTDLIB();
+
+    // Mark end of heap usage, detect memory leaks
+    __UHEAP_MARKEND;
+    return KErrNone;
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/symsndtest/symsndtest_reg.rss b/jni/libpjsip/sources/pjsip-apps/src/symsndtest/symsndtest_reg.rss
new file mode 100644
index 0000000..642f7bf
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/symsndtest/symsndtest_reg.rss
@@ -0,0 +1,10 @@
+#include <appinfo.rh>

+

+UID2 KUidAppRegistrationResourceFile

+UID3 0xA000000E

+

+RESOURCE APP_REGISTRATION_INFO

+{

+    app_file="symsndtest";

+}

+

diff --git a/jni/libpjsip/sources/pjsip-apps/src/vidgui/INSTALL.TXT b/jni/libpjsip/sources/pjsip-apps/src/vidgui/INSTALL.TXT
new file mode 100644
index 0000000..6f94c93
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/vidgui/INSTALL.TXT
@@ -0,0 +1,32 @@
+
+                       vidgui
+                       
+This directory contains a Qt based video GUI sample. 
+
+Requirements:
+========================
+  - pjsip built with video support
+  - Qt SDK version 4.5 or above (version <4.5 doesn't have Cocoa support)
+
+Build instructions:
+===================
+  - Build pjsip first
+  - Follow the instructions for the appropriate platform below:
+
+    Visual Studio
+    -------------
+      - Run this to generate Visual Studio project file:
+         c:> qmake -tp vc
+      - Open vidgui.vcproj and build the app
+
+
+    Mac OS X
+    --------
+      $ qmake -spec macx-g++
+      $ make
+
+    Linux 
+    -----
+      $ qmake
+      $ make
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/vidgui/pj-pkgconfig.mak b/jni/libpjsip/sources/pjsip-apps/src/vidgui/pj-pkgconfig.mak
new file mode 100644
index 0000000..9139dc1
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/vidgui/pj-pkgconfig.mak
@@ -0,0 +1,10 @@
+include ../../../build.mak
+
+cflags:
+	@echo $(PJ_CFLAGS) $(CFLAGS)
+
+cxxflags: cflags
+
+ldflags:
+	@echo $(PJ_LDFLAGS) $(PJ_LDLIBS) $(LDFLAGS)
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidgui.cpp b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidgui.cpp
new file mode 100644
index 0000000..9e1d540
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidgui.cpp
@@ -0,0 +1,735 @@
+/* $Id: vidgui.cpp 4060 2012-04-17 09:55:30Z ming $ */
+/* 
+ * Copyright (C) 2011-2011 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 "vidgui.h"
+#include "vidwin.h"
+
+#if defined(PJ_WIN32)
+#   define SDL_MAIN_HANDLED
+#endif
+
+#include <SDL.h>
+#include <assert.h>
+#include <QMessageBox>
+
+#define LOG_FILE		"vidgui.log"
+#define THIS_FILE		"vidgui.cpp"
+
+///////////////////////////////////////////////////////////////////////////
+//
+// SETTINGS
+//
+
+//
+// These configure SIP registration
+//
+#define USE_REGISTRATION	0
+#define SIP_DOMAIN		"pjsip.org"
+#define SIP_USERNAME		"vidgui"
+#define SIP_PASSWORD		"secret"
+#define SIP_PORT		5080
+#define SIP_TCP			1
+
+//
+// NAT helper settings
+//
+#define USE_ICE			1
+#define USE_STUN		0
+#define STUN_SRV		"stun.pjsip.org"
+
+//
+// Devices settings
+//
+#define DEFAULT_CAP_DEV		PJMEDIA_VID_DEFAULT_CAPTURE_DEV
+//#define DEFAULT_CAP_DEV		1
+#define DEFAULT_REND_DEV	PJMEDIA_VID_DEFAULT_RENDER_DEV
+
+
+//
+// End of Settings
+///////////////////////////////////////////////////////////////////////////
+
+
+MainWin *MainWin::theInstance_;
+
+MainWin::MainWin(QWidget *parent)
+: QWidget(parent), accountId_(-1), currentCall_(-1),
+  preview_on(false), video_(NULL), video_prev_(NULL)
+{
+    theInstance_ = this;
+
+    initLayout();
+    emit signalCallReleased();
+}
+
+MainWin::~MainWin()
+{
+    quit();
+    theInstance_ = NULL;
+}
+
+MainWin *MainWin::instance()
+{
+    return theInstance_;
+}
+
+void MainWin::initLayout()
+{
+    //statusBar_ = new QStatusBar(this);
+
+    /* main layout */
+    QHBoxLayout *hbox_main = new QHBoxLayout;
+    //QVBoxLayout *vbox_left = new QVBoxLayout;
+    vbox_left = new QVBoxLayout;
+    QVBoxLayout *vbox_right = new QVBoxLayout;
+    hbox_main->addLayout(vbox_left);
+    hbox_main->addLayout(vbox_right);
+
+    /* Left pane */
+    QHBoxLayout *hbox_url = new QHBoxLayout;
+    hbox_url->addWidget(new QLabel(tr("Url:")));
+    hbox_url->addWidget(url_=new QLineEdit(tr("sip:")), 1);
+    vbox_left->addLayout(hbox_url);
+
+    /* Right pane */
+    vbox_right->addWidget((localUri_ = new QLabel));
+    vbox_right->addWidget((vidEnabled_ = new QCheckBox(tr("Enable &video"))));
+    vbox_right->addWidget((previewButton_=new QPushButton(tr("Start &Preview"))));
+    vbox_right->addWidget((callButton_=new QPushButton(tr("Call"))));
+    vbox_right->addWidget((hangupButton_=new QPushButton(tr("Hangup"))));
+    vbox_right->addWidget((quitButton_=new QPushButton(tr("Quit"))));
+
+#if PJMEDIA_HAS_VIDEO
+    vidEnabled_->setCheckState(Qt::Checked);
+#else
+    vidEnabled_->setCheckState(Qt::Unchecked);
+    vidEnabled_->setEnabled(false);
+#endif
+
+    /* Outest layout */
+    QVBoxLayout *vbox_outest = new QVBoxLayout;
+    vbox_outest->addLayout(hbox_main);
+    vbox_outest->addWidget((statusBar_ = new QLabel));
+
+    setLayout(vbox_outest);
+
+    connect(previewButton_, SIGNAL(clicked()), this, SLOT(preview()));
+    connect(callButton_, SIGNAL(clicked()), this, SLOT(call()));
+    connect(hangupButton_, SIGNAL(clicked()), this, SLOT(hangup()));
+    connect(quitButton_, SIGNAL(clicked()), this, SLOT(quit()));
+    //connect(this, SIGNAL(close()), this, SLOT(quit()));
+    connect(vidEnabled_, SIGNAL(stateChanged(int)), this, SLOT(onVidEnabledChanged(int)));
+
+    // UI updates must be done in the UI thread!
+    connect(this, SIGNAL(signalNewCall(int, bool)),
+	    this, SLOT(onNewCall(int, bool)));
+    connect(this, SIGNAL(signalCallReleased()),
+	    this, SLOT(onCallReleased()));
+    connect(this, SIGNAL(signalInitVideoWindow()),
+	    this, SLOT(initVideoWindow()));
+    connect(this, SIGNAL(signalShowStatus(const QString&)),
+	    this, SLOT(doShowStatus(const QString&)));
+}
+
+void MainWin::quit()
+{
+    delete video_prev_;
+    video_prev_ = NULL;
+    delete video_;
+    video_ = NULL;
+
+    pjsua_destroy();
+    qApp->quit();
+}
+
+void MainWin::showStatus(const char *msg)
+{
+    PJ_LOG(3,(THIS_FILE, "%s", msg));
+
+    QString msg_ = QString::fromUtf8(msg);
+    emit signalShowStatus(msg_);
+}
+
+void MainWin::doShowStatus(const QString& msg)
+{
+    //statusBar_->showMessage(msg);
+    statusBar_->setText(msg);
+}
+
+void MainWin::showError(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    char errline[120];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    snprintf(errline, sizeof(errline), "%s error: %s", title, errmsg);
+    showStatus(errline);
+}
+
+void MainWin::onVidEnabledChanged(int state)
+{
+    pjsua_call_setting call_setting;
+
+    if (currentCall_ == -1)
+	return;
+
+    pjsua_call_setting_default(&call_setting);
+    call_setting.vid_cnt = (state == Qt::Checked);
+
+    pjsua_call_reinvite2(currentCall_, &call_setting, NULL);
+}
+
+void MainWin::onNewCall(int cid, bool incoming)
+{
+    pjsua_call_info ci;
+
+    pj_assert(currentCall_ == -1);
+    currentCall_ = cid;
+
+    pjsua_call_get_info(cid, &ci);
+    url_->setText(ci.remote_info.ptr);
+    url_->setEnabled(false);
+    hangupButton_->setEnabled(true);
+
+    if (incoming) {
+	callButton_->setText(tr("Answer"));
+	callButton_->setEnabled(true);
+    } else {
+	callButton_->setEnabled(false);
+    }
+
+    //video_->setText(ci.remote_contact.ptr);
+    //video_->setWindowTitle(ci.remote_contact.ptr);
+}
+
+void MainWin::onCallReleased()
+{
+    url_->setEnabled(true);
+    callButton_->setEnabled(true);
+    callButton_->setText(tr("Call"));
+    hangupButton_->setEnabled(false);
+    currentCall_ = -1;
+
+    delete video_;
+    video_ = NULL;
+}
+
+void MainWin::preview()
+{
+    if (preview_on) {
+	delete video_prev_;
+	video_prev_ = NULL;
+
+	pjsua_vid_preview_stop(DEFAULT_CAP_DEV);
+
+	showStatus("Preview stopped");
+	previewButton_->setText(tr("Start &Preview"));
+    } else {
+	pjsua_vid_win_id wid;
+	pjsua_vid_win_info wi;
+	pjsua_vid_preview_param pre_param;
+	pj_status_t status;
+
+	pjsua_vid_preview_param_default(&pre_param);
+	pre_param.rend_id = DEFAULT_REND_DEV;
+	pre_param.show = PJ_FALSE;
+
+	status = pjsua_vid_preview_start(DEFAULT_CAP_DEV, &pre_param);
+	if (status != PJ_SUCCESS) {
+	    char errmsg[PJ_ERR_MSG_SIZE];
+	    pj_strerror(status, errmsg, sizeof(errmsg));
+	    QMessageBox::critical(0, "Error creating preview", errmsg);
+	    return;
+	}
+	wid = pjsua_vid_preview_get_win(DEFAULT_CAP_DEV);
+	pjsua_vid_win_get_info(wid, &wi);
+
+	video_prev_ = new VidWin(&wi.hwnd);
+        video_prev_->putIntoLayout(vbox_left);
+	//Using this will cause SDL window to display blank
+	//screen sometimes, probably because it's using different
+	//X11 Display
+	//status = pjsua_vid_win_set_show(wid, PJ_TRUE);
+	//This is handled by VidWin now
+	//video_prev_->show_sdl();
+	showStatus("Preview started");
+
+	previewButton_->setText(tr("Stop &Preview"));
+    }
+    preview_on = !preview_on;
+}
+
+
+void MainWin::call()
+{
+    if (callButton_->text() == "Answer") {
+	pjsua_call_setting call_setting;
+
+	pj_assert(currentCall_ != -1);
+
+	pjsua_call_setting_default(&call_setting);
+	call_setting.vid_cnt = (vidEnabled_->checkState()==Qt::Checked);
+
+	pjsua_call_answer2(currentCall_, &call_setting, 200, NULL, NULL);
+	callButton_->setEnabled(false);
+    } else {
+	pj_status_t status;
+	QString dst = url_->text();
+	char uri[256];
+	pjsua_call_setting call_setting;
+
+	pj_ansi_strncpy(uri, dst.toAscii().data(), sizeof(uri));
+	pj_str_t uri2 = pj_str((char*)uri);
+
+	pj_assert(currentCall_ == -1);
+
+	pjsua_call_setting_default(&call_setting);
+	call_setting.vid_cnt = (vidEnabled_->checkState()==Qt::Checked);
+
+	status = pjsua_call_make_call(accountId_, &uri2, &call_setting,
+				      NULL, NULL, &currentCall_);
+	if (status != PJ_SUCCESS) {
+	    showError("make call", status);
+	    return;
+	}
+    }
+}
+
+void MainWin::hangup()
+{
+    pj_assert(currentCall_ != -1);
+    //pjsua_call_hangup(currentCall_, PJSIP_SC_BUSY_HERE, NULL, NULL);
+    pjsua_call_hangup_all();
+    emit signalCallReleased();
+}
+
+
+void MainWin::initVideoWindow()
+{
+    pjsua_call_info ci;
+    unsigned i;
+
+    if (currentCall_ == -1)
+	return;
+
+    delete video_;
+    video_ = NULL;
+
+    pjsua_call_get_info(currentCall_, &ci);
+    for (i = 0; i < ci.media_cnt; ++i) {
+	if ((ci.media[i].type == PJMEDIA_TYPE_VIDEO) &&
+	    (ci.media[i].dir & PJMEDIA_DIR_DECODING))
+	{
+	    pjsua_vid_win_info wi;
+	    pjsua_vid_win_get_info(ci.media[i].stream.vid.win_in, &wi);
+
+	    video_= new VidWin(&wi.hwnd);
+            video_->putIntoLayout(vbox_left);
+
+	    break;
+	}
+    }
+}
+
+void MainWin::on_reg_state(pjsua_acc_id acc_id)
+{
+    pjsua_acc_info info;
+
+    pjsua_acc_get_info(acc_id, &info);
+
+    char reg_status[80];
+    char status[120];
+
+    if (!info.has_registration) {
+	pj_ansi_snprintf(reg_status, sizeof(reg_status), "%.*s",
+			 (int)info.status_text.slen,
+			 info.status_text.ptr);
+
+    } else {
+	pj_ansi_snprintf(reg_status, sizeof(reg_status),
+			 "%d/%.*s (expires=%d)",
+			 info.status,
+			 (int)info.status_text.slen,
+			 info.status_text.ptr,
+			 info.expires);
+
+    }
+
+    snprintf(status, sizeof(status),
+	     "%.*s: %s\n",
+	     (int)info.acc_uri.slen, info.acc_uri.ptr,
+	     reg_status);
+    showStatus(status);
+}
+
+void MainWin::on_call_state(pjsua_call_id call_id, pjsip_event *e)
+{
+    pjsua_call_info ci;
+
+    PJ_UNUSED_ARG(e);
+
+    pjsua_call_get_info(call_id, &ci);
+
+    if (currentCall_ == -1 && ci.state < PJSIP_INV_STATE_DISCONNECTED &&
+	ci.role == PJSIP_ROLE_UAC)
+    {
+	emit signalNewCall(call_id, false);
+    }
+
+    char status[80];
+    if (ci.state == PJSIP_INV_STATE_DISCONNECTED) {
+	snprintf(status, sizeof(status), "Call is %s (%s)",
+	         ci.state_text.ptr,
+	         ci.last_status_text.ptr);
+	showStatus(status);
+	emit signalCallReleased();
+    } else {
+	snprintf(status, sizeof(status), "Call is %s", pjsip_inv_state_name(ci.state));
+	showStatus(status);
+    }
+}
+
+void MainWin::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
+                               pjsip_rx_data *rdata)
+{
+    PJ_UNUSED_ARG(acc_id);
+    PJ_UNUSED_ARG(rdata);
+
+    if (currentCall_ != -1) {
+	pjsua_call_answer(call_id, PJSIP_SC_BUSY_HERE, NULL, NULL);
+	return;
+    }
+
+    emit signalNewCall(call_id, true);
+
+    pjsua_call_info ci;
+    char status[80];
+
+    pjsua_call_get_info(call_id, &ci);
+    snprintf(status, sizeof(status), "Incoming call from %.*s",
+             (int)ci.remote_info.slen, ci.remote_info.ptr);
+    showStatus(status);
+}
+
+void MainWin::on_call_media_state(pjsua_call_id call_id)
+{
+    pjsua_call_info ci;
+
+    pjsua_call_get_info(call_id, &ci);
+
+    for (unsigned i=0; i<ci.media_cnt; ++i) {
+	if (ci.media[i].type == PJMEDIA_TYPE_AUDIO) {
+	    switch (ci.media[i].status) {
+	    case PJSUA_CALL_MEDIA_ACTIVE:
+		pjsua_conf_connect(ci.media[i].stream.aud.conf_slot, 0);
+		pjsua_conf_connect(0, ci.media[i].stream.aud.conf_slot);
+		break;
+	    default:
+		break;
+	    }
+	} else if (ci.media[i].type == PJMEDIA_TYPE_VIDEO) {
+	    emit signalInitVideoWindow();
+	}
+    }
+}
+
+//
+// pjsua callbacks
+//
+static void on_reg_state(pjsua_acc_id acc_id)
+{
+    MainWin::instance()->on_reg_state(acc_id);
+}
+
+static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
+{
+    MainWin::instance()->on_call_state(call_id, e);
+}
+
+static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
+                             pjsip_rx_data *rdata)
+{
+    MainWin::instance()->on_incoming_call(acc_id, call_id, rdata);
+}
+
+static void on_call_media_state(pjsua_call_id call_id)
+{
+    MainWin::instance()->on_call_media_state(call_id);
+}
+
+//
+// initStack()
+//
+bool MainWin::initStack()
+{
+    pj_status_t status;
+
+    //showStatus("Creating stack..");
+    status = pjsua_create();
+    if (status != PJ_SUCCESS) {
+	showError("pjsua_create", status);
+	return false;
+    }
+
+    showStatus("Initializing stack..");
+
+    pjsua_config ua_cfg;
+    pjsua_config_default(&ua_cfg);
+    pjsua_callback ua_cb;
+    pj_bzero(&ua_cb, sizeof(ua_cb));
+    ua_cfg.cb.on_reg_state = &::on_reg_state;
+    ua_cfg.cb.on_call_state = &::on_call_state;
+    ua_cfg.cb.on_incoming_call = &::on_incoming_call;
+    ua_cfg.cb.on_call_media_state = &::on_call_media_state;
+#if USE_STUN
+    ua_cfg.stun_srv_cnt = 1;
+    ua_cfg.stun_srv[0] = pj_str((char*)STUN_SRV);
+#endif
+
+    pjsua_logging_config log_cfg;
+    pjsua_logging_config_default(&log_cfg);
+    log_cfg.log_filename = pj_str((char*)LOG_FILE);
+
+    pjsua_media_config med_cfg;
+    pjsua_media_config_default(&med_cfg);
+    med_cfg.enable_ice = USE_ICE;
+
+    status = pjsua_init(&ua_cfg, &log_cfg, &med_cfg);
+    if (status != PJ_SUCCESS) {
+	showError("pjsua_init", status);
+	goto on_error;
+    }
+
+    //
+    // Create UDP and TCP transports
+    //
+    pjsua_transport_config udp_cfg;
+    pjsua_transport_id udp_id;
+    pjsua_transport_config_default(&udp_cfg);
+    udp_cfg.port = SIP_PORT;
+
+    status = pjsua_transport_create(PJSIP_TRANSPORT_UDP,
+                                    &udp_cfg, &udp_id);
+    if (status != PJ_SUCCESS) {
+	showError("UDP transport creation", status);
+	goto on_error;
+    }
+
+    pjsua_transport_info udp_info;
+    status = pjsua_transport_get_info(udp_id, &udp_info);
+    if (status != PJ_SUCCESS) {
+	showError("UDP transport info", status);
+	goto on_error;
+    }
+
+#if SIP_TCP
+    pjsua_transport_config tcp_cfg;
+    pjsua_transport_config_default(&tcp_cfg);
+    tcp_cfg.port = 0;
+
+    status = pjsua_transport_create(PJSIP_TRANSPORT_TCP,
+                                    &tcp_cfg, NULL);
+    if (status != PJ_SUCCESS) {
+	showError("TCP transport creation", status);
+	goto on_error;
+    }
+#endif
+
+    //
+    // Create account
+    //
+    pjsua_acc_config acc_cfg;
+    pjsua_acc_config_default(&acc_cfg);
+#if USE_REGISTRATION
+    acc_cfg.id = pj_str( (char*)"<sip:" SIP_USERNAME "@" SIP_DOMAIN ">");
+    acc_cfg.reg_uri = pj_str((char*) ("sip:" SIP_DOMAIN));
+    acc_cfg.cred_count = 1;
+    acc_cfg.cred_info[0].realm = pj_str((char*)"*");
+    acc_cfg.cred_info[0].scheme = pj_str((char*)"digest");
+    acc_cfg.cred_info[0].username = pj_str((char*)SIP_USERNAME);
+    acc_cfg.cred_info[0].data = pj_str((char*)SIP_PASSWORD);
+
+# if SIP_TCP
+    acc_cfg.proxy[acc_cfg.proxy_cnt++] = pj_str((char*) "<sip:" SIP_DOMAIN ";transport=tcp>");
+# endif
+
+#else
+    char sip_id[80];
+    snprintf(sip_id, sizeof(sip_id),
+	     "sip:%s@%.*s:%u", SIP_USERNAME,
+	     (int)udp_info.local_name.host.slen,
+	     udp_info.local_name.host.ptr,
+	     udp_info.local_name.port);
+    acc_cfg.id = pj_str(sip_id);
+#endif
+
+    acc_cfg.vid_cap_dev = DEFAULT_CAP_DEV;
+    acc_cfg.vid_rend_dev = DEFAULT_REND_DEV;
+    acc_cfg.vid_in_auto_show = PJ_TRUE;
+    acc_cfg.vid_out_auto_transmit = PJ_TRUE;
+
+    status = pjsua_acc_add(&acc_cfg, PJ_TRUE, &accountId_);
+    if (status != PJ_SUCCESS) {
+	showError("Account creation", status);
+	goto on_error;
+    }
+
+    localUri_->setText(acc_cfg.id.ptr);
+
+    //
+    // Start pjsua!
+    //
+    showStatus("Starting stack..");
+    status = pjsua_start();
+    if (status != PJ_SUCCESS) {
+	showError("pjsua_start", status);
+	goto on_error;
+    }
+
+    showStatus("Ready");
+
+    return true;
+
+on_error:
+    pjsua_destroy();
+    return false;
+}
+
+/*
+ * A simple registrar, invoked by default_mod_on_rx_request()
+ */
+static void simple_registrar(pjsip_rx_data *rdata)
+{
+    pjsip_tx_data *tdata;
+    const pjsip_expires_hdr *exp;
+    const pjsip_hdr *h;
+    unsigned cnt = 0;
+    pjsip_generic_string_hdr *srv;
+    pj_status_t status;
+
+    status = pjsip_endpt_create_response(pjsua_get_pjsip_endpt(),
+				 rdata, 200, NULL, &tdata);
+    if (status != PJ_SUCCESS)
+	return;
+
+    exp = (pjsip_expires_hdr*)
+	  pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
+
+    h = rdata->msg_info.msg->hdr.next;
+    while (h != &rdata->msg_info.msg->hdr) {
+	if (h->type == PJSIP_H_CONTACT) {
+	    const pjsip_contact_hdr *c = (const pjsip_contact_hdr*)h;
+	    int e = c->expires;
+
+	    if (e < 0) {
+		if (exp)
+		    e = exp->ivalue;
+		else
+		    e = 3600;
+	    }
+
+	    if (e > 0) {
+		pjsip_contact_hdr *nc = (pjsip_contact_hdr*)
+					pjsip_hdr_clone(tdata->pool, h);
+		nc->expires = e;
+		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)nc);
+		++cnt;
+	    }
+	}
+	h = h->next;
+    }
+
+    srv = pjsip_generic_string_hdr_create(tdata->pool, NULL, NULL);
+    srv->name = pj_str((char*)"Server");
+    srv->hvalue = pj_str((char*)"pjsua simple registrar");
+    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)srv);
+
+    pjsip_endpt_send_response2(pjsua_get_pjsip_endpt(),
+                               rdata, tdata, NULL, NULL);
+}
+
+/* Notification on incoming request */
+static pj_bool_t default_mod_on_rx_request(pjsip_rx_data *rdata)
+{
+    /* Simple registrar */
+    if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
+                         &pjsip_register_method) == 0)
+    {
+	simple_registrar(rdata);
+	return PJ_TRUE;
+    }
+
+    return PJ_FALSE;
+}
+
+/* The module instance. */
+static pjsip_module mod_default_handler =
+{
+    NULL, NULL,				/* prev, next.		*/
+    { (char*)"mod-default-handler", 19 },	/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION+99,	/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &default_mod_on_rx_request,		/* on_rx_request()	*/
+    NULL,				/* on_rx_response()	*/
+    NULL,				/* on_tx_request.	*/
+    NULL,				/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
+int main(int argc, char *argv[])
+{
+    /* At least on Linux, we have to initialize SDL video subsystem prior to
+     * creating/initializing QApplication, otherwise we'll segfault miserably
+     * in SDL_CreateWindow(). Here's a stack trace if you're interested:
+
+	Thread [7] (Suspended: Signal 'SIGSEGV' received. Description: Segmentation fault.)
+	13 XCreateIC()
+	12 SetupWindowData()
+	11 X11_CreateWindow()
+	10 SDL_CreateWindow()
+	..
+     */
+    if ( SDL_InitSubSystem(SDL_INIT_VIDEO) < 0 ) {
+        printf("Unable to init SDL: %s\n", SDL_GetError());
+        return 1;
+    }
+
+    QApplication app(argc, argv);
+
+    MainWin win;
+    win.show();
+
+    if (!win.initStack()) {
+	win.quit();
+	return 1;
+    }
+
+    /* We want to be registrar too! */
+    if (pjsua_get_pjsip_endpt()) {
+	pjsip_endpt_register_module(pjsua_get_pjsip_endpt(),
+				    &mod_default_handler);
+    }
+
+    return app.exec();
+}
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidgui.h b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidgui.h
new file mode 100644
index 0000000..7b7ce7b
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidgui.h
@@ -0,0 +1,102 @@
+/* $Id: vidgui.h 3926 2011-12-27 12:50:17Z bennylp $ */
+/*
+ * Copyright (C) 2011-2011 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 VIDGUI_H_
+#define VIDGUI_H_
+
+#include <QApplication>
+#include <QCheckBox>
+#include <QFont>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMainWindow>
+#include <QObject>
+#include <QPushButton>
+#include <QStatusBar>
+#include <QTextEdit>
+#include <QVBoxLayout>
+#include <QWidget>
+
+#include <pjsua.h>
+
+class VidWin;
+
+class MainWin : public QWidget
+{
+    Q_OBJECT
+
+public:
+    MainWin(QWidget *parent = 0);
+    virtual ~MainWin();
+
+    static MainWin *instance();
+
+    bool initStack();
+    void showError(const char *title, pj_status_t status);
+    void showStatus(const char *msg);
+
+    void on_reg_state(pjsua_acc_id acc_id);
+    void on_call_state(pjsua_call_id call_id, pjsip_event *e);
+    void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata);
+    void on_call_media_state(pjsua_call_id call_id);
+
+signals:
+    void signalNewCall(int, bool);
+    void signalCallReleased();
+    void signalInitVideoWindow();
+    void signalShowStatus(const QString&);
+    
+public slots:
+    void preview();
+    void call();
+    void hangup();
+    void quit();
+    void onVidEnabledChanged(int state);
+
+    void onNewCall(int cid, bool incoming);
+    void onCallReleased();
+    void initVideoWindow();
+    void doShowStatus(const QString& msg);
+
+private:
+    static MainWin *theInstance_;
+    pjsua_acc_id accountId_;
+    pjsua_call_id currentCall_;
+    bool preview_on;
+
+private:
+    QPushButton *callButton_,
+		*hangupButton_,
+		*quitButton_,
+		*previewButton_;
+    QCheckBox   *vidEnabled_;
+    QLineEdit *url_;
+    VidWin *video_;
+    VidWin *video_prev_;
+    //QStatusBar *statusBar_;
+    QLabel *statusBar_;
+    QLabel *localUri_;
+
+    QVBoxLayout *vbox_left;
+
+    void initLayout();
+};
+
+
+
+#endif /* VIDGUI_H_ */
diff --git a/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidgui.pro b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidgui.pro
new file mode 100644
index 0000000..806b2b6
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidgui.pro
@@ -0,0 +1,36 @@
+win32 {
+  DEFINES += PJ_WIN32=1
+  INCLUDEPATH += ../../../pjlib/include ../../../pjlib-util/include \
+		 ../../../pjnath/include ../../../pjmedia/include \
+		 ../../../pjsip/include
+
+  # These to enable static linking
+  #CONFIG += static
+  #DEFINES += STATIC
+
+  CONFIG(debug) {
+    LIBS += ../../../lib/libpjproject-i386-Win32-vc8-Debug.lib
+  } else {
+    LIBS += ../../../lib/libpjproject-i386-Win32-vc8-Release.lib
+  }
+  LIBS += Iphlpapi.lib  dsound.lib \
+  	  dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib \
+  	  odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib 
+} else {
+  LIBS += $$system(make -f pj-pkgconfig.mak ldflags)
+  QMAKE_CXXFLAGS += $$system(make --silent -f pj-pkgconfig.mak cflags)
+
+  macx {
+    QMAKE_CXXFLAGS += -ObjC++
+  }
+}
+
+TEMPLATE = app
+CONFIG += thread debug
+TARGET = 
+DEPENDPATH += .
+
+# Input
+HEADERS += vidgui.h vidwin.h
+SOURCES += vidgui.cpp vidwin.cpp 
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidwin.cpp b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidwin.cpp
new file mode 100644
index 0000000..1caee89
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidwin.cpp
@@ -0,0 +1,309 @@
+/* $Id: vidwin.cpp 4060 2012-04-17 09:55:30Z ming $ */
+/*
+ * Copyright (C) 2011 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 "vidwin.h"
+#include <QEvent>
+
+#define THIS_FILE	"vidwin.cpp"
+#define TRACE_(...)	PJ_LOG(4,(THIS_FILE, __VA_ARGS__))
+
+VidWin::VidWin(const pjmedia_vid_dev_hwnd *hwnd_,
+	       QWidget* parent,
+	       Qt::WindowFlags f) :
+    QWidget(parent, f), orig_parent(NULL),
+    size_hint(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
+{
+    setAttribute(Qt::WA_NativeWindow);
+
+    /* Make this widget a bit "lighter" */
+    setAttribute(Qt::WA_UpdatesDisabled);
+    setAttribute(Qt::WA_PaintOnScreen);
+    setAttribute(Qt::WA_NoSystemBackground);
+    setAttribute(Qt::WA_PaintOutsidePaintEvent);
+    setUpdatesEnabled(false);
+
+    pj_bzero(&hwnd, sizeof(hwnd));
+    if (hwnd_) {
+	hwnd = *hwnd_;
+    }
+}
+
+
+VidWin::~VidWin()
+{
+    show_sdl(false);
+    detach();
+}
+
+void VidWin::putIntoLayout(QBoxLayout *box)
+{
+    box->addWidget(this, 1);
+    show();
+    activateWindow();
+}
+
+bool VidWin::event(QEvent *e)
+{
+    switch(e->type()) {
+
+    case QEvent::Resize:
+	set_size();
+	break;
+
+    case QEvent::ParentChange:
+	get_size();
+	if (0) {
+	    QRect qr = rect();
+	    if (qr.width() > size_hint.width())
+		size_hint.setWidth(qr.width());
+	    if (qr.height() > size_hint.height())
+		size_hint.setWidth(qr.height());
+	}
+	setFixedSize(size_hint);
+	attach();
+	break;
+
+    case QEvent::Show:
+	show_sdl(true);
+	// revert to default size hint, make it resizable
+	setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+	break;
+
+    case QEvent::Hide:
+	show_sdl(false);
+	break;
+
+    default:
+	break;
+    }
+
+    return QWidget::event(e);
+}
+
+/* Platform specific code */
+
+#if defined(_WIN32) && !defined(_WIN32_WINCE)
+
+#include <windows.h>
+
+void VidWin::attach()
+{
+    if (!hwnd.info.win.hwnd) return;
+
+    HWND w = (HWND)hwnd.info.win.hwnd;
+    HWND new_parent = (HWND)winId();
+    orig_parent = GetParent(w);
+
+    //SetWindowLong(w, GWL_STYLE, WS_CHILD);
+    SetParent(w, new_parent);
+    TRACE_("%p new parent handle = %p", w, new_parent);
+}
+
+void VidWin::detach()
+{
+    if (!hwnd.info.win.hwnd) return;
+
+    HWND w = (HWND)hwnd.info.win.hwnd;
+    SetParent(w, (HWND)orig_parent);
+    TRACE_("%p revert parent handle to %p", w, orig_parent);
+}
+
+void VidWin::set_size()
+{
+    if (!hwnd.info.win.hwnd) return;
+
+    HWND w = (HWND)hwnd.info.win.hwnd;
+    QRect qr = rect();
+    UINT swp_flag = SWP_NOACTIVATE;
+    SetWindowPos(w, HWND_TOP, 0, 0, qr.width(), qr.height(), swp_flag);
+    TRACE_("%p new size = %dx%d", w, qr.width(), qr.height());
+}
+
+void VidWin::get_size()
+{
+    if (!hwnd.info.win.hwnd) return;
+
+    HWND w = (HWND)hwnd.info.win.hwnd;
+    RECT r;
+    if (GetWindowRect(w, &r))
+	size_hint = QSize(r.right-r.left+1, r.bottom-r.top+1);
+    TRACE_("%p size = %dx%d", w, size_hint.width(), size_hint.height());
+}
+
+void VidWin::show_sdl(bool visible)
+{
+    if (!hwnd.info.win.hwnd) return;
+
+    HWND w = (HWND)hwnd.info.win.hwnd;
+    ShowWindow(w, visible ? SW_SHOW : SW_HIDE);
+}
+
+#elif defined(__APPLE__)
+
+#import<Cocoa/Cocoa.h>
+
+void VidWin::attach()
+{
+    if (!hwnd.info.cocoa.window) return;
+
+    /* Embed hwnd to widget */
+    NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
+    NSWindow *parent = [(NSView*)winId() window];
+    orig_parent = [w parentWindow];
+
+    //[w setStyleMask:NSBorderlessWindowMask];
+
+    //Can't use this, as sometime the video window may not get reparented.
+    //[w setParentWindow:parent];
+
+    [parent addChildWindow:w ordered:NSWindowAbove];
+    TRACE_("%p new parent handle = %p", w, parent);
+}
+
+
+void VidWin::detach()
+{
+    if (!hwnd.info.cocoa.window) return;
+
+    NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
+    NSWindow *parent = [(NSView*)winId() window];
+    [parent removeChildWindow:w]; 
+}
+
+
+void VidWin::set_size()
+{
+    if (!hwnd.info.cocoa.window) return;
+
+    /* Update position and size */
+    NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
+    NSRect r;
+
+    NSView* v = (NSView*)winId();
+    r = [v bounds];
+    r = [v convertRectToBase:r];
+    r.origin = [[v window] convertBaseToScreen:r.origin];
+
+    QRect qr = rect();
+    [w setFrame:r display:NO]; 
+
+    TRACE_("%p new size = %dx%d", w, qr.width(), qr.height());
+}
+
+void VidWin::get_size()
+{
+    if (!hwnd.info.cocoa.window) return;
+
+    NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
+
+    size_hint = QSize(300, 200);
+
+    TRACE_("%p size = %dx%d", 0, size_hint.width(), size_hint.height());
+}
+
+void VidWin::show_sdl(bool visible)
+{
+    if (!hwnd.info.cocoa.window) return;
+
+    NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
+
+    if (visible) {
+        [[w contentView]setHidden:NO];
+    } else {
+        [[w contentView]setHidden:YES];
+    }
+}
+
+#elif defined(linux) || defined(__linux)
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <QX11Info>
+#include <stdio.h>
+
+#define GET_DISPLAY()	QX11Info::display()
+//#define GET_DISPLAY()	(Display*)hwnd.info.x11.display
+
+void VidWin::attach()
+{
+    if (!hwnd.info.x11.window) return;
+
+    /* Embed hwnd to widget */
+
+    // Use Qt X11 display here, using window creator X11 display may cause
+    // the window failing to embed to this QWidget.
+    //Display *d = (Display*)hwnd.info.x11.display;
+    Display *d = GET_DISPLAY();
+    Window w = (Window)hwnd.info.x11.window;
+    Window parent = (Window)this->winId();
+    int err = XReparentWindow(d, w, parent, 0, 0);
+    TRACE_("%p new parent handle = %p, err = %d",
+	   (void*)w,(void*)parent, err);
+}
+
+
+void VidWin::detach()
+{
+}
+
+
+void VidWin::set_size()
+{
+    if (!hwnd.info.x11.window) return;
+
+    /* Update position and size */
+    Display *d = GET_DISPLAY();
+    Window w = (Window)hwnd.info.x11.window;
+    QRect qr = rect();
+
+    int err = XResizeWindow(d, w, qr.width(), qr.height());
+    TRACE_("[%p,%p] new size = %dx%d, err = %d",
+	   (void*)d, (void*)w, qr.width(), qr.height(), err);
+}
+
+void VidWin::get_size()
+{
+    if (!hwnd.info.x11.window) return;
+
+    Display *d = GET_DISPLAY();
+    Window w = (Window)hwnd.info.x11.window;
+
+    XWindowAttributes attr;
+    XGetWindowAttributes(d, w, &attr);
+    size_hint = QSize(attr.width, attr.height);
+    TRACE_("%p size = %dx%d", w, size_hint.width(), size_hint.height());
+}
+
+void VidWin::show_sdl(bool visible)
+{
+    if (!hwnd.info.x11.window) return;
+
+    Display *d = GET_DISPLAY();
+    Window w = (Window)hwnd.info.x11.window;
+
+    if (visible) {
+	XMapRaised(d, w);
+    } else {
+	XUnmapWindow(d, w);
+    }
+
+    XFlush(d);
+}
+
+#endif
+
diff --git a/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidwin.h b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidwin.h
new file mode 100644
index 0000000..3ab10b2
--- /dev/null
+++ b/jni/libpjsip/sources/pjsip-apps/src/vidgui/vidwin.h
@@ -0,0 +1,55 @@
+/* $Id: vidwin.h 4060 2012-04-17 09:55:30Z ming $ */
+/*
+ * Copyright (C) 2011 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 VIDWIN_H
+#define VIDWIN_H
+
+#include <pjsua.h>
+#include <QWidget>
+#include <QBoxLayout>
+
+class VidWin : public QWidget
+{
+    Q_OBJECT
+
+public:
+    VidWin(const pjmedia_vid_dev_hwnd *hwnd,
+	   QWidget* parent = 0,
+	   Qt::WindowFlags f = 0);
+    virtual ~VidWin();
+    QSize sizeHint() const { return size_hint; }
+
+    void putIntoLayout(QBoxLayout *layout);
+
+protected:
+    virtual bool event(QEvent *e);
+
+private:
+    pjmedia_vid_dev_hwnd hwnd;
+    void *orig_parent;
+    QSize size_hint;
+
+    void attach();
+    void detach();
+    void set_size();
+    void get_size();
+    void show_sdl(bool visible=true);
+};
+
+#endif
+