[Pkg-voip-commits] [pjproject] 01/03: New upstream version 2.7.1~dfsg

Bernhard Schmidt berni at moszumanska.debian.org
Thu Nov 9 22:55:37 UTC 2017


This is an automated email from the git hooks/post-receive script.

berni pushed a commit to branch master
in repository pjproject.

commit 162973fb878dbdbd75c0b0d9e3f5662829245424
Author: Bernhard Schmidt <berni at debian.org>
Date:   Thu Nov 9 23:19:49 2017 +0100

    New upstream version 2.7.1~dfsg
---
 aconfigure                               |  18 +++-
 aconfigure.ac                            |   4 -
 build.mak.in                             |   6 +-
 configure-android                        |  15 ++-
 pjlib/build/pjlib.vcproj                 |   8 ++
 pjlib/build/pjlib.vcxproj                |   4 +-
 pjlib/build/pjlib.vcxproj.filters        |   6 ++
 pjlib/include/pj/compat/limits.h         |  65 ++++++++++++
 pjlib/include/pj/compat/os_win32.h       |   3 +-
 pjlib/include/pj/config.h                |   4 +-
 pjlib/include/pj/limits.h                |  51 ++++++++++
 pjlib/include/pj/string.h                |  48 ++++++++-
 pjlib/include/pj/types.h                 |   5 +-
 pjlib/src/pj/activesock.c                |  21 +++-
 pjlib/src/pj/ioqueue_epoll.c             |  22 +++-
 pjlib/src/pj/ioqueue_select.c            |  21 +++-
 pjlib/src/pj/ssl_sock_ossl.c             |   4 +-
 pjlib/src/pj/string.c                    | 121 +++++++++++++++++++++-
 pjlib/src/pj/timer.c                     |   3 +-
 pjmedia/include/pjmedia/audiodev.h       |   6 +-
 pjmedia/src/pjmedia-audiodev/alsa_dev.c  |   6 +-
 pjmedia/src/pjmedia-codec/ilbc.c         |  25 +++--
 pjmedia/src/pjmedia/stream.c             |   8 +-
 pjmedia/src/pjmedia/transport_srtp.c     |  19 +++-
 pjmedia/src/pjmedia/vid_codec_util.c     |   4 +-
 pjmedia/src/pjmedia/vid_port.c           |   7 +-
 pjmedia/src/pjmedia/vid_stream.c         |   6 +-
 pjnath/src/pjnath/ice_session.c          |  10 +-
 pjnath/src/pjnath/stun_sock.c            |   4 +-
 pjsip-apps/build/Footprint.mak           |   2 +-
 pjsip-apps/src/pjsua/pjsua_app.c         |   8 +-
 pjsip-apps/src/samples/pcaputil.c        |   6 +-
 pjsip-apps/src/samples/streamutil.c      |   8 +-
 pjsip-apps/src/swig/symbols.i            |   4 +
 pjsip-apps/src/swig/symbols.lst          |   4 +-
 pjsip/build/Makefile                     |   4 +-
 pjsip/include/pjsip/sip_config.h         |  12 ++-
 pjsip/include/pjsip/sip_parser.h         |  27 ++++-
 pjsip/include/pjsua-lib/pjsua.h          | 108 ++++++++++++++++++--
 pjsip/include/pjsua-lib/pjsua_internal.h |   4 +-
 pjsip/include/pjsua2/call.hpp            |  16 ++-
 pjsip/include/pjsua2/endpoint.hpp        |  11 +-
 pjsip/include/pjsua2/presence.hpp        |  25 ++++-
 pjsip/src/pjsip/sip_endpoint.c           |  10 +-
 pjsip/src/pjsip/sip_parser.c             | 168 ++++++++++++++++++++++++-------
 pjsip/src/pjsip/sip_transaction.c        |   6 +-
 pjsip/src/pjsip/sip_transport.c          |   9 +-
 pjsip/src/pjsua-lib/pjsua_aud.c          |  70 ++++++++-----
 pjsip/src/pjsua2/endpoint.cpp            |  40 ++++++--
 pjsip/src/pjsua2/siptypes.cpp            |  33 ++++--
 pjsip/src/test/regc_test.c               |  10 +-
 tests/pjsua/tools/Makefile               |   2 +-
 version.mak                              |   2 +-
 53 files changed, 915 insertions(+), 198 deletions(-)

diff --git a/aconfigure b/aconfigure
index 72963db..aec2a28 100755
--- a/aconfigure
+++ b/aconfigure
@@ -758,6 +758,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -882,6 +883,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1134,6 +1136,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1271,7 +1282,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1424,6 +1435,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -2586,12 +2598,8 @@ ac_config_files="$ac_config_files build.mak build/os-auto.mak build/cc-auto.mak
 
 if test "$CFLAGS" = ""; then
   CFLAGS="-O2"
-else
-  CFLAGS="$CFLAGS"
 fi
 
-CXXFLAGS="$CFLAGS $CXXFLAGS"
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
diff --git a/aconfigure.ac b/aconfigure.ac
index 46009c7..e9770b7 100644
--- a/aconfigure.ac
+++ b/aconfigure.ac
@@ -27,12 +27,8 @@ dnl Setup default CFLAGS
 dnl
 if test "$CFLAGS" = ""; then
   CFLAGS="-O2"
-else
-  CFLAGS="$CFLAGS"
 fi
 
-CXXFLAGS="$CFLAGS $CXXFLAGS"
-
 dnl #
 dnl # Configure tools
 dnl #
diff --git a/build.mak.in b/build.mak.in
index 6c263a9..d831ea5 100644
--- a/build.mak.in
+++ b/build.mak.in
@@ -204,7 +204,7 @@ export APP_CFLAGS := -DPJ_AUTOCONF=1\
 	-I$(PJDIR)/pjnath/include\
 	-I$(PJDIR)/pjmedia/include\
 	-I$(PJDIR)/pjsip/include
-export APP_CXXFLAGS := $(APP_CFLAGS)
+export APP_CXXFLAGS := @CXXFLAGS@ $(APP_CFLAGS)
 export APP_LDFLAGS := -L$(PJDIR)/pjlib/lib\
 	-L$(PJDIR)/pjlib-util/lib\
 	-L$(PJDIR)/pjnath/lib\
@@ -314,6 +314,6 @@ export PJ_LIBXX_FILES := $(APP_LIBXX_FILES)
 export PJ_INSTALL_DIR := @prefix@
 export PJ_INSTALL_INC_DIR := @includedir@
 export PJ_INSTALL_LIB_DIR := @libdir@
-export PJ_INSTALL_CFLAGS := -I$(PJ_INSTALL_INC_DIR) -DPJ_AUTOCONF=1	@CFLAGS@
-export PJ_INSTALL_CXXFLAGS := $(PJ_INSTALL_CFLAGS)
+export PJ_INSTALL_CFLAGS := -I$(PJ_INSTALL_INC_DIR) -DPJ_AUTOCONF=1 @CFLAGS@
+export PJ_INSTALL_CXXFLAGS := @CXXFLAGS@ $(PJ_INSTALL_CFLAGS)
 export PJ_INSTALL_LDFLAGS := -L$(PJ_INSTALL_LIB_DIR) $(APP_LDLIBS)
diff --git a/configure-android b/configure-android
index 25b862a..df5495e 100755
--- a/configure-android
+++ b/configure-android
@@ -76,9 +76,9 @@ if test "$1" = "--use-ndk-cflags"; then
     exit 1
   fi
 
-  echo "====="
-  echo "NDK_OUT : ${NDK_OUT}"
-  echo "====="
+  # echo "====="
+  # echo "NDK_OUT : ${NDK_OUT}"
+  # echo "====="
 
   for i in $NDK_OUT; do
     if test "x${NDK_CXX}" != "x" -a "$i" = "-o"; then break; fi
@@ -141,8 +141,13 @@ if test "$1" = "--use-ndk-cflags"; then
     export RANLIB=`echo ${NDK_CXX}|sed 's/-g++/-ranlib/'`;
     export LDFLAGS="${LDFLAGS} --sysroot=${ANDROID_SYSROOT}"
   else
-    #export AR="${NDK_TOOLCHAIN}/bin/${NDK_TARGET}-ar"
-    #export RANLIB="${NDK_TOOLCHAIN}/bin/${NDK_TARGET}-ranlib"
+    # find ar and ranlib
+    TC_AR=`find ${NDK_TOOLCHAIN}/bin/ -name "*-ar" | grep -v "gcc"`
+    TC_RANLIB=`find ${NDK_TOOLCHAIN}/bin/ -name "*-ranlib" | grep -v "gcc"`
+    if test "x${TC_AR}" != "x" -a "x${TC_RANLIB}" != "x"; then
+      export AR=$TC_AR
+      export RANLIB=$TC_RANLIB
+    fi 
     TARGET_HOST="arm-linux-androideabi"
     export LDFLAGS="${LDFLAGS} --sysroot=${ANDROID_SYSROOT} -target ${NDK_TARGET} -gcc-toolchain ${NDK_TOOLCHAIN}"
   fi  
diff --git a/pjlib/build/pjlib.vcproj b/pjlib/build/pjlib.vcproj
index 6a217a0..37842fa 100644
--- a/pjlib/build/pjlib.vcproj
+++ b/pjlib/build/pjlib.vcproj
@@ -14970,6 +14970,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\include\pj\limits.h"
+				>
+			</File>
+			<File
 				RelativePath="..\include\pj\list.h"
 				>
 			</File>
@@ -15073,6 +15077,10 @@
 					>
 				</File>
 				<File
+					RelativePath="..\include\pj\compat\limits.h"
+					>
+				</File>
+				<File
 					RelativePath="..\include\pj\compat\m_alpha.h"
 					>
 				</File>
diff --git a/pjlib/build/pjlib.vcxproj b/pjlib/build/pjlib.vcxproj
index abf09ec..e41731e 100644
--- a/pjlib/build/pjlib.vcxproj
+++ b/pjlib/build/pjlib.vcxproj
@@ -494,7 +494,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
-    <ClCompile Include="..\src\pj\file_io_win32.c" />    
+    <ClCompile Include="..\src\pj\file_io_win32.c" />
     <ClCompile Include="..\src\pj\guid.c" />
     <ClCompile Include="..\src\pj\guid_simple.c">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|Win32'">true</ExcludedFromBuild>
@@ -890,6 +890,7 @@
     <ClInclude Include="..\include\pj\compat\ctype.h" />
     <ClInclude Include="..\include\pj\compat\errno.h" />
     <ClInclude Include="..\include\pj\compat\high_precision.h" />
+    <ClInclude Include="..\include\pj\compat\limits.h" />
     <ClInclude Include="..\include\pj\compat\malloc.h" />
     <ClInclude Include="..\include\pj\compat\m_alpha.h" />
     <ClInclude Include="..\include\pj\compat\m_i386.h" />
@@ -925,6 +926,7 @@
     <ClInclude Include="..\include\pj\hash.h" />
     <ClInclude Include="..\include\pj\ioqueue.h" />
     <ClInclude Include="..\include\pj\ip_helper.h" />
+    <ClInclude Include="..\include\pj\limits.h" />
     <ClInclude Include="..\include\pj\list.h" />
     <ClInclude Include="..\include\pj\list_i.h" />
     <ClInclude Include="..\include\pj\lock.h" />
diff --git a/pjlib/build/pjlib.vcxproj.filters b/pjlib/build/pjlib.vcxproj.filters
index 0b5cbf1..6f343b0 100644
--- a/pjlib/build/pjlib.vcxproj.filters
+++ b/pjlib/build/pjlib.vcxproj.filters
@@ -439,5 +439,11 @@
     <ClInclude Include="..\include\pj\compat\os_winuwp.h">
       <Filter>Header Files\compat</Filter>
     </ClInclude>
+    <ClInclude Include="..\include\pj\limits.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\pj\compat\limits.h">
+      <Filter>Header Files\compat</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/pjlib/include/pj/compat/limits.h b/pjlib/include/pj/compat/limits.h
new file mode 100644
index 0000000..673d5b4
--- /dev/null
+++ b/pjlib/include/pj/compat/limits.h
@@ -0,0 +1,65 @@
+/* $Id: limits.h 5682 2017-11-08 02:58:18Z riza $ */
+/*
+ * Copyright (C) 2017 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2017 George Joseph <gjoseph at digium.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 __PJ_COMPAT_LIMITS_H__
+#define __PJ_COMPAT_LIMITS_H__
+
+/**
+ * @file limits.h
+ * @brief Provides integer limits normally found in limits.h.
+ */
+
+#if defined(PJ_HAS_LIMITS_H) && PJ_HAS_LIMITS_H != 0
+#  include <limits.h>
+#else
+
+#  ifdef _MSC_VER
+#  pragma message("limits.h is not found or not supported. LONG_MIN and "\
+		 "LONG_MAX will be defined by the library in "\
+		 "pj/compats/limits.h and overridable in config_site.h")
+#  else
+#  warning "limits.h is not found or not supported. LONG_MIN and LONG_MAX " \
+           "will be defined by the library in pj/compats/limits.h and "\
+           "overridable in config_site.h"
+#  endif
+
+/* Minimum and maximum values a `signed long int' can hold.  */
+#  ifndef LONG_MAX
+#    if __WORDSIZE == 64
+#      define LONG_MAX     9223372036854775807L
+#    else
+#      define LONG_MAX     2147483647L
+#    endif
+#  endif
+
+#  ifndef LONG_MIN
+#    define LONG_MIN      (-LONG_MAX - 1L)
+#  endif
+
+/* Maximum value an `unsigned long int' can hold.  (Minimum is 0.)  */
+#  ifndef ULONG_MAX
+#    if __WORDSIZE == 64
+#      define ULONG_MAX    18446744073709551615UL
+#    else    
+#      define ULONG_MAX    4294967295UL
+#    endif
+#  endif
+#endif
+
+#endif  /* __PJ_COMPAT_LIMITS_H__ */
diff --git a/pjlib/include/pj/compat/os_win32.h b/pjlib/include/pj/compat/os_win32.h
index f1bd597..e86959e 100644
--- a/pjlib/include/pj/compat/os_win32.h
+++ b/pjlib/include/pj/compat/os_win32.h
@@ -1,4 +1,4 @@
-/* $Id: os_win32.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* $Id: os_win32.h 5682 2017-11-08 02:58:18Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -57,6 +57,7 @@
 #define PJ_HAS_SYS_TYPES_H	    1
 #define PJ_HAS_TIME_H		    1
 #define PJ_HAS_UNISTD_H		    0
+#define PJ_HAS_LIMITS_H		    1
 
 #define PJ_HAS_MSWSOCK_H	    1
 #define PJ_HAS_WINSOCK_H	    0
diff --git a/pjlib/include/pj/config.h b/pjlib/include/pj/config.h
index b3dd6d7..fda0c4b 100644
--- a/pjlib/include/pj/config.h
+++ b/pjlib/include/pj/config.h
@@ -1,4 +1,4 @@
-/* $Id: config.h 5661 2017-09-25 04:20:21Z ming $ */
+/* $Id: config.h 5683 2017-11-08 03:03:22Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -1293,7 +1293,7 @@ PJ_BEGIN_DECL
 #define PJ_VERSION_NUM_MINOR	7
 
 /** PJLIB version revision number. */
-#define PJ_VERSION_NUM_REV	0
+#define PJ_VERSION_NUM_REV	1
 
 /**
  * Extra suffix for the version (e.g. "-trunk"), or empty for
diff --git a/pjlib/include/pj/limits.h b/pjlib/include/pj/limits.h
new file mode 100644
index 0000000..193237a
--- /dev/null
+++ b/pjlib/include/pj/limits.h
@@ -0,0 +1,51 @@
+/* $Id: limits.h 5682 2017-11-08 02:58:18Z riza $ */
+/*
+ * Copyright (C) 2017 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2017 George Joseph <gjoseph at digium.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 __PJ_LIMITS_H__
+#define __PJ_LIMITS_H__
+
+/**
+ * @file limits.h
+ * @brief Common min and max values
+ */
+
+#include <pj/compat/limits.h>
+
+/** Maximum value for signed 32-bit integer. */
+#define PJ_MAXINT32	0x7fffffff
+
+/** Minimum value for signed 32-bit integer. */
+#define PJ_MININT32	0x80000000
+
+/** Maximum value for unsigned 16-bit integer. */
+#define PJ_MAXUINT16	0xffff
+
+/** Maximum value for unsigned char. */
+#define PJ_MAXUINT8	0xff
+
+/** Maximum value for long. */
+#define PJ_MAXLONG	LONG_MAX
+
+/** Minimum value for long. */
+#define PJ_MINLONG	LONG_MIN
+
+/** Minimum value for unsigned long. */
+#define PJ_MAXULONG	ULONG_MAX
+
+#endif  /* __PJ_LIMITS_H__ */
diff --git a/pjlib/include/pj/string.h b/pjlib/include/pj/string.h
index fdcf816..70f5bb6 100644
--- a/pjlib/include/pj/string.h
+++ b/pjlib/include/pj/string.h
@@ -1,4 +1,4 @@
-/* $Id: string.h 5520 2017-01-11 04:38:29Z riza $ */
+/* $Id: string.h 5682 2017-11-08 02:58:18Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -28,7 +28,6 @@
 #include <pj/types.h>
 #include <pj/compat/string.h>
 
-
 PJ_BEGIN_DECL
 
 /**
@@ -636,6 +635,29 @@ PJ_DECL(char*) pj_create_random_string(char *str, pj_size_t length);
 PJ_DECL(long) pj_strtol(const pj_str_t *str);
 
 /**
+ * Convert string to signed long integer. The conversion will stop as
+ * soon as non-digit character is found or all the characters have
+ * been processed.
+ *
+ * @param str   the string.
+ * @param value Pointer to a long to receive the value.
+ *
+ * @return PJ_SUCCESS if successful.  Otherwise:
+ *         PJ_ETOOSMALL if the value was an impossibly long negative number.
+ *         In this case *value will be set to LONG_MIN.
+ *         \n
+ *         PJ_ETOOBIG if the value was an impossibly long positive number.
+ *         In this case, *value will be set to LONG_MAX.
+ *         \n
+ *         PJ_EINVAL if the input string was NULL, the value pointer was NULL 
+ *         or the input string could not be parsed at all such as starting with
+ *         a character other than a '+', '-' or not in the '0' - '9' range.
+ *         In this case, *value will be left untouched.
+ */
+PJ_DECL(pj_status_t) pj_strtol2(const pj_str_t *str, long *value);
+
+
+/**
  * Convert string to unsigned integer. The conversion will stop as
  * soon as non-digit character is found or all the characters have
  * been processed.
@@ -664,6 +686,27 @@ PJ_DECL(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr,
 				   unsigned base);
 
 /**
+ * Convert string to unsigned long integer. The conversion will stop as
+ * soon as non-digit character is found or all the characters have
+ * been processed.
+ *
+ * @param str       The input string.
+ * @param value     Pointer to an unsigned long to receive the value.
+ * @param base	    Number base to use.
+ *
+ * @return PJ_SUCCESS if successful.  Otherwise:
+ *         PJ_ETOOBIG if the value was an impossibly long positive number.
+ *         In this case, *value will be set to ULONG_MAX.
+ *         \n
+ *         PJ_EINVAL if the input string was NULL, the value pointer was NULL 
+ *         or the input string could not be parsed at all such as starting 
+ *         with a character outside the base character range.  In this case,
+ *         *value will be left untouched.
+ */
+PJ_DECL(pj_status_t) pj_strtoul3(const pj_str_t *str, unsigned long *value,
+				 unsigned base);
+
+/**
  * Convert string to float.
  *
  * @param str	the string.
@@ -786,7 +829,6 @@ PJ_INLINE(void*) pj_memchr(const void *buf, int c, pj_size_t size)
     return (void*)memchr((void*)buf, c, size);
 }
 
-
 /**
  * @}
  */
diff --git a/pjlib/include/pj/types.h b/pjlib/include/pj/types.h
index a592703..47e2274 100644
--- a/pjlib/include/pj/types.h
+++ b/pjlib/include/pj/types.h
@@ -1,4 +1,4 @@
-/* $Id: types.h 4704 2014-01-16 05:30:46Z ming $ */
+/* $Id: types.h 5682 2017-11-08 02:58:18Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -280,9 +280,6 @@ typedef int pj_exception_id_t;
 /** Utility macro to compute the number of elements in static array. */
 #define PJ_ARRAY_SIZE(a)    (sizeof(a)/sizeof(a[0]))
 
-/** Maximum value for signed 32-bit integer. */
-#define PJ_MAXINT32  0x7FFFFFFFL
-
 /**
  * Length of object names.
  */
diff --git a/pjlib/src/pj/activesock.c b/pjlib/src/pj/activesock.c
index b9dee42..7869446 100644
--- a/pjlib/src/pj/activesock.c
+++ b/pjlib/src/pj/activesock.c
@@ -1,4 +1,4 @@
-/* $Id: activesock.c 5119 2015-06-25 08:53:02Z ming $ */
+/* $Id: activesock.c 5680 2017-11-03 06:54:54Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -296,17 +296,28 @@ PJ_DEF(pj_status_t) pj_activesock_create_udp( pj_pool_t *pool,
 
 PJ_DEF(pj_status_t) pj_activesock_close(pj_activesock_t *asock)
 {
+    pj_ioqueue_key_t *key;
+    pj_bool_t unregister = PJ_FALSE;
+
     PJ_ASSERT_RETURN(asock, PJ_EINVAL);
     asock->shutdown = SHUT_RX | SHUT_TX;
-    if (asock->key) {
-	pj_ioqueue_unregister(asock->key);
+
+    /* Avoid double unregistration on the key */
+    key = asock->key;
+    if (key) {
+	pj_ioqueue_lock_key(key);
+	unregister = (asock->key != NULL);
+	asock->key = NULL;
+	pj_ioqueue_unlock_key(key);
+    }
+
+    if (unregister) {
+	pj_ioqueue_unregister(key);
 
 #if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
     PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
 	activesock_destroy_iphone_os_stream(asock);
 #endif	
-
-	asock->key = NULL;
     }
     return PJ_SUCCESS;
 }
diff --git a/pjlib/src/pj/ioqueue_epoll.c b/pjlib/src/pj/ioqueue_epoll.c
index 3af7758..4c07125 100644
--- a/pjlib/src/pj/ioqueue_epoll.c
+++ b/pjlib/src/pj/ioqueue_epoll.c
@@ -1,4 +1,4 @@
-/* $Id: ioqueue_epoll.c 5194 2015-11-06 04:18:46Z nanang $ */
+/* $Id: ioqueue_epoll.c 5680 2017-11-03 06:54:54Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -516,11 +516,26 @@ PJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key)
      */
     pj_ioqueue_lock_key(key);
 
+    /* Best effort to avoid double key-unregistration */
+    if (IS_CLOSING(key)) {
+	pj_ioqueue_unlock_key(key);
+	return PJ_SUCCESS;
+    }
+
     /* Also lock ioqueue */
     pj_lock_acquire(ioqueue->lock);
 
-    pj_assert(ioqueue->count > 0);
-    --ioqueue->count;
+    /* Avoid "negative" ioqueue count */
+    if (ioqueue->count > 0) {
+	--ioqueue->count;
+    } else {
+	/* If this happens, very likely there is double unregistration
+	 * of a key.
+	 */
+	pj_assert(!"Bad ioqueue count in key unregistration!");
+	PJ_LOG(1,(THIS_FILE, "Bad ioqueue count in key unregistration!"));
+    }
+
 #if !PJ_IOQUEUE_HAS_SAFE_UNREG
     pj_list_erase(key);
 #endif
@@ -531,6 +546,7 @@ PJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key)
     if (status != 0) {
 	pj_status_t rc = pj_get_os_error();
 	pj_lock_release(ioqueue->lock);
+	pj_ioqueue_unlock_key(key);
 	return rc;
     }
 
diff --git a/pjlib/src/pj/ioqueue_select.c b/pjlib/src/pj/ioqueue_select.c
index 5f125a8..dbb65d9 100644
--- a/pjlib/src/pj/ioqueue_select.c
+++ b/pjlib/src/pj/ioqueue_select.c
@@ -1,4 +1,4 @@
-/* $Id: ioqueue_select.c 5539 2017-01-23 04:32:34Z nanang $ */
+/* $Id: ioqueue_select.c 5680 2017-11-03 06:54:54Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -478,11 +478,26 @@ PJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key)
      */
     pj_ioqueue_lock_key(key);
 
+    /* Best effort to avoid double key-unregistration */
+    if (IS_CLOSING(key)) {
+	pj_ioqueue_unlock_key(key);
+	return PJ_SUCCESS;
+    }
+
     /* Also lock ioqueue */
     pj_lock_acquire(ioqueue->lock);
 
-    pj_assert(ioqueue->count > 0);
-    --ioqueue->count;
+    /* Avoid "negative" ioqueue count */
+    if (ioqueue->count > 0) {
+	--ioqueue->count;
+    } else {
+	/* If this happens, very likely there is double unregistration
+	 * of a key.
+	 */
+	pj_assert(!"Bad ioqueue count in key unregistration!");
+	PJ_LOG(1,(THIS_FILE, "Bad ioqueue count in key unregistration!"));
+    }
+
 #if !PJ_IOQUEUE_HAS_SAFE_UNREG
     /* Ticket #520, key will be erased more than once */
     pj_list_erase(key);
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
index 0a5eee4..58eb965 100644
--- a/pjlib/src/pj/ssl_sock_ossl.c
+++ b/pjlib/src/pj/ssl_sock_ossl.c
@@ -1,4 +1,4 @@
-/* $Id: ssl_sock_ossl.c 5648 2017-09-14 05:03:45Z riza $ */
+/* $Id: ssl_sock_ossl.c 5678 2017-11-01 04:55:29Z riza $ */
 /* 
  * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -98,7 +98,7 @@ static unsigned get_cid_from_nid(unsigned nid)
 	}
     }
     return cid;
-};
+}
 
 static unsigned get_nid_from_cid(unsigned cid)
 {
diff --git a/pjlib/src/pj/string.c b/pjlib/src/pj/string.c
index ab0a098..f4733ed 100644
--- a/pjlib/src/pj/string.c
+++ b/pjlib/src/pj/string.c
@@ -1,4 +1,4 @@
-/* $Id: string.c 5520 2017-01-11 04:38:29Z riza $ */
+/* $Id: string.c 5682 2017-11-08 02:58:18Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -23,11 +23,14 @@
 #include <pj/ctype.h>
 #include <pj/rand.h>
 #include <pj/os.h>
+#include <pj/errno.h>
+#include <pj/limits.h>
 
 #if PJ_FUNCTIONS_ARE_INLINED==0
 #  include <pj/string_i.h>
 #endif
 
+
 PJ_DEF(pj_ssize_t) pj_strspn(const pj_str_t *str, const pj_str_t *set_char)
 {
     pj_ssize_t i, j, count = 0;
@@ -230,6 +233,55 @@ PJ_DEF(long) pj_strtol(const pj_str_t *str)
         return pj_strtoul(str);
 }
 
+
+PJ_DEF(pj_status_t) pj_strtol2(const pj_str_t *str, long *value)
+{
+    pj_str_t s;
+    unsigned long retval = 0;
+    pj_bool_t is_negative = PJ_FALSE;
+    int rc = 0;
+
+    PJ_CHECK_STACK();
+
+    if (!str || !value) {
+        return PJ_EINVAL;
+    }
+
+    s = *str;
+    pj_strltrim(&s);
+
+    if (s.slen == 0)
+        return PJ_EINVAL;
+
+    if (s.ptr[0] == '+' || s.ptr[0] == '-') {
+        is_negative = (s.ptr[0] == '-');
+        s.ptr += 1;
+        s.slen -= 1;
+    }
+
+    rc = pj_strtoul3(&s, &retval, 10);
+    if (rc == PJ_EINVAL) {
+        return rc;
+    } else if (rc != PJ_SUCCESS) {
+        *value = is_negative ? PJ_MINLONG : PJ_MAXLONG;
+        return is_negative ? PJ_ETOOSMALL : PJ_ETOOBIG;
+    }
+
+    if (retval > PJ_MAXLONG && !is_negative) {
+        *value = PJ_MAXLONG;
+        return PJ_ETOOBIG;
+    }
+
+    if (retval > (PJ_MAXLONG + 1UL) && is_negative) {
+        *value = PJ_MINLONG;
+        return PJ_ETOOSMALL;
+    }
+
+    *value = is_negative ? -(long)retval : retval;
+
+    return PJ_SUCCESS;
+}
+
 PJ_DEF(unsigned long) pj_strtoul(const pj_str_t *str)
 {
     unsigned long value;
@@ -282,6 +334,71 @@ PJ_DEF(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr,
     return value;
 }
 
+PJ_DEF(pj_status_t) pj_strtoul3(const pj_str_t *str, unsigned long *value,
+				unsigned base)
+{
+    pj_str_t s;
+    unsigned i;
+
+    PJ_CHECK_STACK();
+
+    if (!str || !value) {
+        return PJ_EINVAL;
+    }
+
+    s = *str;
+    pj_strltrim(&s);
+
+    if (s.slen == 0 || s.ptr[0] < '0' ||
+	(base <= 10 && (unsigned)s.ptr[0] > ('0' - 1) + base) ||
+	(base == 16 && !pj_isxdigit(s.ptr[0])))
+    {
+        return PJ_EINVAL;
+    }
+
+    *value = 0;
+    if (base <= 10) {
+	for (i=0; i<(unsigned)s.slen; ++i) {
+	    unsigned c = s.ptr[i] - '0';
+	    if (s.ptr[i] < '0' || (unsigned)s.ptr[i] > ('0' - 1) + base) {
+		break;
+	    }
+	    if (*value > PJ_MAXULONG / base) {
+		*value = PJ_MAXULONG;
+		return PJ_ETOOBIG;
+	    }
+
+	    *value *= base;
+	    if ((PJ_MAXULONG - *value) < c) {
+		*value = PJ_MAXULONG;
+		return PJ_ETOOBIG;
+	    }
+	    *value += c;
+	}
+    } else if (base == 16) {
+	for (i=0; i<(unsigned)s.slen; ++i) {
+	    unsigned c = pj_hex_digit_to_val(s.ptr[i]);
+	    if (!pj_isxdigit(s.ptr[i]))
+		break;
+
+	    if (*value > PJ_MAXULONG / base) {
+		*value = PJ_MAXULONG;
+		return PJ_ETOOBIG;
+	    }
+	    *value *= base;
+	    if ((PJ_MAXULONG - *value) < c) {
+		*value = PJ_MAXULONG;
+		return PJ_ETOOBIG;
+	    }
+	    *value += c;
+	}
+    } else {
+	pj_assert(!"Unsupported base");
+	return PJ_EINVAL;
+    }
+    return PJ_SUCCESS;
+}
+
 PJ_DEF(float) pj_strtof(const pj_str_t *str)
 {
     pj_str_t part;
@@ -356,5 +473,3 @@ PJ_DEF(int) pj_utoa_pad( unsigned long val, char *buf, int min_dig, int pad)
 
     return len;
 }
-
-
diff --git a/pjlib/src/pj/timer.c b/pjlib/src/pj/timer.c
index 7fd08fa..bffe75b 100644
--- a/pjlib/src/pj/timer.c
+++ b/pjlib/src/pj/timer.c
@@ -1,4 +1,4 @@
-/* $Id: timer.c 4855 2014-06-04 09:23:10Z bennylp $ */
+/* $Id: timer.c 5682 2017-11-08 02:58:18Z riza $ */
 /* 
  * The PJLIB's timer heap is based (or more correctly, copied and modied)
  * from ACE library by Douglas C. Schmidt. ACE is an excellent OO framework
@@ -36,6 +36,7 @@
 #include <pj/lock.h>
 #include <pj/log.h>
 #include <pj/rand.h>
+#include <pj/limits.h>
 
 #define THIS_FILE	"timer.c"
 
diff --git a/pjmedia/include/pjmedia/audiodev.h b/pjmedia/include/pjmedia/audiodev.h
index 2aa694a..fb122d1 100644
--- a/pjmedia/include/pjmedia/audiodev.h
+++ b/pjmedia/include/pjmedia/audiodev.h
@@ -1,4 +1,4 @@
-/* $Id: audiodev.h 5430 2016-08-25 03:28:54Z ming $ */
+/* $Id: audiodev.h 5677 2017-10-27 06:30:50Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -49,7 +49,7 @@ typedef pj_int32_t pjmedia_aud_dev_index;
 /**
  * Device index constants.
  */
-enum
+typedef enum pjmedia_aud_dev_id
 {
     /** 
      * Constant to denote default capture device 
@@ -65,7 +65,7 @@ enum
      * Constant to denote invalid device index.
      */
     PJMEDIA_AUD_INVALID_DEV = -3
-};
+} pjmedia_aud_dev_id;
 
 
 #define PJMEDIA_AUD_MAX_DRIVERS	16
diff --git a/pjmedia/src/pjmedia-audiodev/alsa_dev.c b/pjmedia/src/pjmedia-audiodev/alsa_dev.c
index 3748aed..473e43e 100644
--- a/pjmedia/src/pjmedia-audiodev/alsa_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/alsa_dev.c
@@ -1,4 +1,4 @@
-/* $Id: alsa_dev.c 5646 2017-09-08 11:16:09Z ming $ */
+/* $Id: alsa_dev.c 5678 2017-11-01 04:55:29Z riza $ */
 /*
  * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2007-2009 Keystream AB and Konftel AB, All rights reserved.
@@ -937,7 +937,9 @@ static pj_status_t alsa_stream_set_cap(pjmedia_aud_stream *strm,
 {
     struct alsa_factory *af = ((struct alsa_stream*)strm)->af;
 
-    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING && af->pb_mixer_name) {
+    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING && 
+	pj_ansi_strlen(af->pb_mixer_name)) 
+    {
 	pj_ssize_t min, max;
 	snd_mixer_t *handle;
 	snd_mixer_selem_id_t *sid;
diff --git a/pjmedia/src/pjmedia-codec/ilbc.c b/pjmedia/src/pjmedia-codec/ilbc.c
index 3d258ec..5b03305 100644
--- a/pjmedia/src/pjmedia-codec/ilbc.c
+++ b/pjmedia/src/pjmedia-codec/ilbc.c
@@ -1,4 +1,4 @@
-/* $Id: ilbc.c 5187 2015-10-07 03:57:17Z ming $ */
+/* $Id: ilbc.c 5674 2017-10-16 10:20:18Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -177,6 +177,11 @@ PJ_DEF(pj_status_t) pjmedia_codec_ilbc_init( pjmedia_endpt *endpt,
     PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL);
     PJ_ASSERT_RETURN(mode==0 || mode==20 || mode==30, PJ_EINVAL);
 
+    if (ilbc_factory.endpt != NULL) {
+	/* Already initialized. */
+	return PJ_SUCCESS;
+    }
+
     /* Create iLBC codec factory. */
     ilbc_factory.base.op = &ilbc_factory_op;
     ilbc_factory.base.factory_data = NULL;
@@ -188,22 +193,25 @@ PJ_DEF(pj_status_t) pjmedia_codec_ilbc_init( pjmedia_endpt *endpt,
     ilbc_factory.mode = mode;
 
     if (mode == 20) {
-	ilbc_factory.bps = 15200;	
+	ilbc_factory.bps = 15200;
     } else {
 	ilbc_factory.bps = 13333;
     }
 
     /* Get the codec manager. */
     codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
-    if (!codec_mgr)
+    if (!codec_mgr) {
+	ilbc_factory.endpt = NULL;
 	return PJ_EINVALIDOP;
+    }
 
     /* Register codec factory to endpoint. */
     status = pjmedia_codec_mgr_register_factory(codec_mgr, 
 						&ilbc_factory.base);
-    if (status != PJ_SUCCESS)
+    if (status != PJ_SUCCESS) {
+	ilbc_factory.endpt = NULL;
 	return status;
-
+    }
 
     /* Done. */
     return PJ_SUCCESS;
@@ -220,6 +228,10 @@ PJ_DEF(pj_status_t) pjmedia_codec_ilbc_deinit(void)
     pjmedia_codec_mgr *codec_mgr;
     pj_status_t status;
 
+    if (ilbc_factory.endpt == NULL) {
+	/* Not registered. */
+	return PJ_SUCCESS;
+    }
 
     /* Get the codec manager. */
     codec_mgr = pjmedia_endpt_get_codec_mgr(ilbc_factory.endpt);
@@ -229,7 +241,8 @@ PJ_DEF(pj_status_t) pjmedia_codec_ilbc_deinit(void)
     /* Unregister iLBC codec factory. */
     status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
 						  &ilbc_factory.base);
-    
+    ilbc_factory.endpt = NULL;
+
     return status;
 }
 
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c
index 7636cd7..2230ebb 100644
--- a/pjmedia/src/pjmedia/stream.c
+++ b/pjmedia/src/pjmedia/stream.c
@@ -1,4 +1,4 @@
-/* $Id: stream.c 5534 2017-01-19 07:41:25Z nanang $ */
+/* $Id: stream.c 5671 2017-10-06 06:54:37Z riza $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -2223,6 +2223,8 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
     /* How many consecutive PLC frames can be generated */
     stream->max_plc_cnt = (MAX_PLC_MSEC+stream->codec_param.info.frm_ptime-1)/
 			    stream->codec_param.info.frm_ptime;
+    /* Disable PLC until a "NORMAL" frame is gotten from the jitter buffer. */
+    stream->plc_cnt = stream->max_plc_cnt;
 
 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
     stream->rtp_rx_check_cnt = 50;
@@ -2346,11 +2348,13 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
 	stream->out_rtcp_pkt_size = PJMEDIA_MAX_MTU;
 
     stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size);
+    pj_bzero(&att_param, sizeof(att_param));
     att_param.stream = stream;
     att_param.media_type = PJMEDIA_TYPE_AUDIO;
     att_param.user_data = stream;
     pj_sockaddr_cp(&att_param.rem_addr, &info->rem_addr);
-    pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp);
+    if (pj_sockaddr_has_addr(&info->rem_rtcp.addr))
+	pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp);
     att_param.addr_len = pj_sockaddr_get_len(&info->rem_addr);
     att_param.rtp_cb = &on_rx_rtp;
     att_param.rtcp_cb = &on_rx_rtcp;
diff --git a/pjmedia/src/pjmedia/transport_srtp.c b/pjmedia/src/pjmedia/transport_srtp.c
index 1cc01f0..4f758ab 100644
--- a/pjmedia/src/pjmedia/transport_srtp.c
+++ b/pjmedia/src/pjmedia/transport_srtp.c
@@ -1,4 +1,4 @@
-/* $Id: transport_srtp.c 5656 2017-09-22 02:42:22Z ming $ */
+/* $Id: transport_srtp.c 5670 2017-10-05 04:40:20Z riza $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -65,12 +65,29 @@
 #define SRTP_NULL_CIPHER		NULL_CIPHER
 #define SRTP_NULL_AUTH			NULL_AUTH
 #define SRTP_AES_ICM_128		AES_ICM
+#define SRTP_AES_ICM_192		AES_ICM
 #define SRTP_AES_ICM_256		AES_ICM
+#define SRTP_AES_GCM_128		AES_128_GCM
+#define SRTP_AES_GCM_256		AES_256_GCM
 #define SRTP_HMAC_SHA1			HMAC_SHA1
+#define srtp_aes_gcm_256_openssl        aes_gcm_256_openssl
+#define srtp_aes_gcm_128_openssl        aes_gcm_128_openssl
 
 #else				 	/* External SRTP 2.x */
 #  include <srtp2/srtp.h>
 #  include <srtp2/cipher.h>
+
+/* In libsrtp 2.0.0, the macro SRTP_AES_ICM_128 is not available. 
+ * Instead it was named with ICM at the end: SRTP_AES_128_ICM. 
+ */
+#  ifdef SRTP_AES_128_ICM
+#    define SRTP_AES_ICM_128		SRTP_AES_128_ICM
+#    define SRTP_AES_ICM_192		SRTP_AES_192_ICM
+#    define SRTP_AES_ICM_256		SRTP_AES_256_ICM
+#    define SRTP_AES_GCM_128		SRTP_AES_128_GCM
+#    define SRTP_AES_GCM_256		SRTP_AES_256_GCM
+#  endif
+
 #endif
 
 #else					/* Bundled SRTP */
diff --git a/pjmedia/src/pjmedia/vid_codec_util.c b/pjmedia/src/pjmedia/vid_codec_util.c
index 98ab8af..b60b071 100644
--- a/pjmedia/src/pjmedia/vid_codec_util.c
+++ b/pjmedia/src/pjmedia/vid_codec_util.c
@@ -1,4 +1,4 @@
-/* $Id: vid_codec_util.c 5659 2017-09-25 02:58:42Z riza $ */
+/* $Id: vid_codec_util.c 5678 2017-11-01 04:55:29Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -173,7 +173,7 @@ static unsigned fps_to_mpi(const pjmedia_ratio *fps)
     if (mpi < 1) mpi = 1;
 
     return mpi;
-};
+}
 
 PJ_DEF(pj_status_t) pjmedia_vid_codec_h263_apply_fmtp(
 				pjmedia_vid_codec_param *param)
diff --git a/pjmedia/src/pjmedia/vid_port.c b/pjmedia/src/pjmedia/vid_port.c
index 029f384..2958f09 100644
--- a/pjmedia/src/pjmedia/vid_port.c
+++ b/pjmedia/src/pjmedia/vid_port.c
@@ -1,4 +1,4 @@
-/* $Id: vid_port.c 5595 2017-05-23 02:44:19Z ming $ */
+/* $Id: vid_port.c 5678 2017-11-01 04:55:29Z riza $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -482,7 +482,6 @@ PJ_DEF(pj_status_t) pjmedia_vid_port_create( pj_pool_t *pool,
 {
     pjmedia_vid_port *vp;
     pjmedia_video_format_detail *vfd;
-    char dev_name[64];
     char fmt_name[5];
     pjmedia_vid_dev_cb vid_cb;
     pj_bool_t need_frame_buf = PJ_FALSE;
@@ -490,6 +489,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_port_create( pj_pool_t *pool,
     unsigned ptime_usec;
     pjmedia_vid_dev_param vparam;
     pjmedia_vid_dev_info di;
+    char dev_name[sizeof(di.name) + sizeof(di.driver) + 4];
 
     PJ_ASSERT_RETURN(pool && prm && p_vid_port, PJ_EINVAL);
     PJ_ASSERT_RETURN(prm->vidparam.fmt.type == PJMEDIA_TYPE_VIDEO &&
@@ -522,8 +522,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_port_create( pj_pool_t *pool,
     vparam = prm->vidparam;
     dev_name[0] = '\0';
 
-    pj_ansi_snprintf(dev_name, sizeof(dev_name), "%s [%s]",
-                     di.name, di.driver);
+    pj_ansi_snprintf(dev_name, sizeof(dev_name), "%s [%s]", di.name, di.driver);
     pjmedia_fourcc_name(vparam.fmt.id, fmt_name);
     PJ_LOG(4,(THIS_FILE,
 	      "Opening device %s for %s: format=%s, size=%dx%d @%d:%d fps",
diff --git a/pjmedia/src/pjmedia/vid_stream.c b/pjmedia/src/pjmedia/vid_stream.c
index 802ba76..b666982 100644
--- a/pjmedia/src/pjmedia/vid_stream.c
+++ b/pjmedia/src/pjmedia/vid_stream.c
@@ -1,4 +1,4 @@
-/* $Id: vid_stream.c 5534 2017-01-19 07:41:25Z nanang $ */
+/* $Id: vid_stream.c 5671 2017-10-06 06:54:37Z riza $ */
 /* 
  * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -1665,11 +1665,13 @@ PJ_DEF(pj_status_t) pjmedia_vid_stream_create(
 	stream->out_rtcp_pkt_size = PJMEDIA_MAX_MTU;
 
     stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size);
+    pj_bzero(&att_param, sizeof(att_param));
     att_param.stream = stream;
     att_param.media_type = PJMEDIA_TYPE_VIDEO;
     att_param.user_data = stream;
     pj_sockaddr_cp(&att_param.rem_addr, &info->rem_addr);
-    pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp);
+    if (pj_sockaddr_has_addr(&info->rem_rtcp.addr))
+	pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp);    
     att_param.addr_len = pj_sockaddr_get_len(&info->rem_addr);
     att_param.rtp_cb = &on_rx_rtp;
     att_param.rtcp_cb = &on_rx_rtcp;
diff --git a/pjnath/src/pjnath/ice_session.c b/pjnath/src/pjnath/ice_session.c
index 9cb6360..b1b4b53 100644
--- a/pjnath/src/pjnath/ice_session.c
+++ b/pjnath/src/pjnath/ice_session.c
@@ -1,4 +1,4 @@
-/* $Id: ice_session.c 5654 2017-09-20 04:34:27Z riza $ */
+/* $Id: ice_session.c 5665 2017-09-28 03:44:53Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -1217,10 +1217,12 @@ static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now)
 	msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data);
 	msg_data->transport_id = the_check->lcand->transport_id;
 
-	/* Temporarily disable FINGERPRINT. The Binding Indication 
-	 * SHOULD NOT contain any attributes.
+	/* RFC 5245 Section 10:
+	 * The Binding Indication SHOULD contain the FINGERPRINT attribute
+	 * to aid in demultiplexing, but SHOULD NOT contain any other
+	 * attributes.
 	 */
-	saved = pj_stun_session_use_fingerprint(comp->stun_sess, PJ_FALSE);
+	saved = pj_stun_session_use_fingerprint(comp->stun_sess, PJ_TRUE);
 
 	/* Send to session */
 	addr_len = pj_sockaddr_get_len(&the_check->rcand->addr);
diff --git a/pjnath/src/pjnath/stun_sock.c b/pjnath/src/pjnath/stun_sock.c
index 914705d..d3b47bb 100644
--- a/pjnath/src/pjnath/stun_sock.c
+++ b/pjnath/src/pjnath/stun_sock.c
@@ -1,4 +1,4 @@
-/* $Id: stun_sock.c 5534 2017-01-19 07:41:25Z nanang $ */
+/* $Id: stun_sock.c 5678 2017-11-01 04:55:29Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -136,7 +136,7 @@ PJ_DEF(const char*) pj_stun_sock_op_name(pj_stun_sock_op op)
     };
 
     return op < PJ_ARRAY_SIZE(names) ? names[op] : "???";
-};
+}
 
 
 /*
diff --git a/pjsip-apps/build/Footprint.mak b/pjsip-apps/build/Footprint.mak
index cc63179..7427a50 100644
--- a/pjsip-apps/build/Footprint.mak
+++ b/pjsip-apps/build/Footprint.mak
@@ -10,7 +10,7 @@ include ../../build/common.mak
 # Gather all flags.
 #
 export _CFLAGS 	:= $(APP_CFLAGS) $(CFLAGS)
-export _CXXFLAGS:= $(_CFLAGS)
+export _CXXFLAGS:= $(APP_CXXFLAGS) $(CXXFLAGS)
 
 export _LDFLAGS := $(APP_LDFLAGS) $(APP_LDLIBS) $(LDFLAGS)
 
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c
index e447ec4..5f89bcc 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -1,4 +1,4 @@
-/* $Id: pjsua_app.c 5534 2017-01-19 07:41:25Z nanang $ */
+/* $Id: pjsua_app.c 5677 2017-10-27 06:30:50Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -959,7 +959,11 @@ static void on_ice_transport_error(int index, pj_ice_strans_op op,
  */
 static pj_status_t on_snd_dev_operation(int operation)
 {
-    PJ_LOG(3,(THIS_FILE, "Turning sound device %s", (operation? "ON":"OFF")));
+    int cap_dev, play_dev;
+
+    pjsua_get_snd_dev(&cap_dev, &play_dev);
+    PJ_LOG(3,(THIS_FILE, "Turning sound device %d %d %s", cap_dev, play_dev,
+    	      (operation? "ON":"OFF")));
     return PJ_SUCCESS;
 }
 
diff --git a/pjsip-apps/src/samples/pcaputil.c b/pjsip-apps/src/samples/pcaputil.c
index 7529733..c23bf05 100644
--- a/pjsip-apps/src/samples/pcaputil.c
+++ b/pjsip-apps/src/samples/pcaputil.c
@@ -1,4 +1,4 @@
-/* $Id: pcaputil.c 5170 2015-08-25 08:45:46Z nanang $ */
+/* $Id: pcaputil.c 5664 2017-09-28 02:56:36Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -287,11 +287,13 @@ static void pcap2wav(const pj_str_t *codec,
 #if PJMEDIA_HAS_SRTP
     if (srtp_crypto->slen) {
 	pjmedia_srtp_crypto crypto;
+	pjmedia_transport *tp;
 
 	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_loop_create(app.mept, &tp) );
+	T( pjmedia_transport_srtp_create(app.mept, tp, NULL, &app.srtp) );
 	T( pjmedia_transport_srtp_start(app.srtp, &crypto, &crypto) );
     }
 #else
diff --git a/pjsip-apps/src/samples/streamutil.c b/pjsip-apps/src/samples/streamutil.c
index 110989a..0c16e05 100644
--- a/pjsip-apps/src/samples/streamutil.c
+++ b/pjsip-apps/src/samples/streamutil.c
@@ -1,4 +1,4 @@
-/* $Id: streamutil.c 5621 2017-07-05 05:37:24Z nanang $ */
+/* $Id: streamutil.c 5681 2017-11-06 10:30:07Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -566,7 +566,11 @@ int main(int argc, char *argv[])
 
 
     /* Verify arguments. */
-    if (dir & PJMEDIA_DIR_ENCODING || is_dtls_client || is_dtls_server) {
+    if (dir & PJMEDIA_DIR_ENCODING
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+        || is_dtls_client || is_dtls_server
+#endif
+       ) {
 	if (remote_addr.sin_addr.s_addr == 0) {
 	    printf("Error: remote address must be set\n");
 	    return 1;
diff --git a/pjsip-apps/src/swig/symbols.i b/pjsip-apps/src/swig/symbols.i
index 25d13dc..a961dd4 100644
--- a/pjsip-apps/src/swig/symbols.i
+++ b/pjsip-apps/src/swig/symbols.i
@@ -56,6 +56,8 @@ enum pjmedia_vid_dev_std_index {PJMEDIA_VID_DEFAULT_CAPTURE_DEV = -1, PJMEDIA_VI
 
 typedef enum pjmedia_vid_dev_cap {PJMEDIA_VID_DEV_CAP_FORMAT = 1, PJMEDIA_VID_DEV_CAP_INPUT_SCALE = 2, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW = 4, PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE = 8, PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION = 16, PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE = 32, PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW = 64, PJMEDIA_VID_DEV_CAP_ORIENTATION = 128, PJMEDIA_VID_DEV_CAP_SWITCH = 256, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS = 512, PJMEDIA_VID_DEV_CAP_MAX = 16384} pjmedia_vid_dev_cap;
 
+typedef enum pjmedia_aud_dev_id {PJMEDIA_AUD_DEFAULT_CAPTURE_DEV = -1, PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV = -2, PJMEDIA_AUD_INVALID_DEV = -3} pjmedia_aud_dev_id;
+
 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_CUSTOM = 128} 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_INPUT_SOURCE = 128, PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256, PJMEDIA_AUD_DEV_CAP_EC = 512, PJMEDIA_A [...]
@@ -173,6 +175,8 @@ typedef enum pjsua_call_flag {PJSUA_CALL_UNHOLD = 1, PJSUA_CALL_UPDATE_CONTACT =
 
 typedef enum pjsua_create_media_transport_flag {PJSUA_MED_TP_CLOSE_MEMBER = 1} pjsua_create_media_transport_flag;
 
+typedef enum pjsua_snd_dev_id {PJSUA_SND_DEFAULT_CAPTURE_DEV = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, PJSUA_SND_DEFAULT_PLAYBACK_DEV = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV, PJSUA_SND_NO_DEV = PJMEDIA_AUD_INVALID_DEV, PJSUA_SND_NULL_DEV = -99} pjsua_snd_dev_id;
+
 typedef enum pjsua_snd_dev_mode {PJSUA_SND_DEV_SPEAKER_ONLY = 1, PJSUA_SND_DEV_NO_IMMEDIATE_OPEN = 2} pjsua_snd_dev_mode;
 
 typedef enum pjsua_ip_change_op {PJSUA_IP_CHANGE_OP_NULL, PJSUA_IP_CHANGE_OP_RESTART_LIS, PJSUA_IP_CHANGE_OP_ACC_SHUTDOWN_TP, PJSUA_IP_CHANGE_OP_ACC_UPDATE_CONTACT, PJSUA_IP_CHANGE_OP_ACC_HANGUP_CALLS, PJSUA_IP_CHANGE_OP_ACC_REINVITE_CALLS} pjsua_ip_change_op;
diff --git a/pjsip-apps/src/swig/symbols.lst b/pjsip-apps/src/swig/symbols.lst
index 7d1ce17..8e8c5a7 100644
--- a/pjsip-apps/src/swig/symbols.lst
+++ b/pjsip-apps/src/swig/symbols.lst
@@ -11,7 +11,7 @@ pjmedia/event.h                 pjmedia_event_type
 pjmedia/transport_srtp.h	pjmedia_srtp_use pjmedia_srtp_crypto_option
 pjmedia/vid_stream.h		pjmedia_vid_stream_rc_method
 pjmedia-videodev/videodev.h	pjmedia_vid_dev_index pjmedia_vid_dev_std_index pjmedia_vid_dev_cap
-pjmedia-audiodev/audiodev.h 	pjmedia_aud_dev_route pjmedia_aud_dev_cap
+pjmedia-audiodev/audiodev.h 	pjmedia_aud_dev_id pjmedia_aud_dev_route pjmedia_aud_dev_cap
 pjmedia/wav_port.h              pjmedia_file_writer_option pjmedia_file_player_option
 pjmedia/tonegen.h		pjmedia_tone_digit pjmedia_tone_digit_map pjmedia_tone_desc
 pjmedia/types.h                 pjmedia_type pjmedia_dir pjmedia_tp_proto pjmedia_orient
@@ -33,4 +33,4 @@ 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_nat64_opt 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 pjsua_snd_dev_mode pjsua_ip_change_op
+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_nat64_opt 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 pjsua_snd_dev_id pjsua_snd_dev_mode pjsua_ip_change_op
diff --git a/pjsip/build/Makefile b/pjsip/build/Makefile
index a9bd5ad..451fd50 100644
--- a/pjsip/build/Makefile
+++ b/pjsip/build/Makefile
@@ -140,7 +140,7 @@ export PJSUA2_LIB_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
 			   account.o endpoint.o json.o persistent.o types.o \
 			   siptypes.o call.o presence.o media.o
 export PJSUA2_LIB_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS)
-export PJSUA2_LIB_CXXFLAGS = $(PJSUA2_LIB_CFLAGS) 
+export PJSUA2_LIB_CXXFLAGS = $(_CXXFLAGS) $(PJSUA2_LIB_CFLAGS) 
 export PJSUA2_LIB_LDFLAGS += $(PJSUA_LIB_LDLIB) \
 			     $(PJSIP_UA_LDLIB) \
 			     $(PJSIP_SIMPLE_LDLIB) \
@@ -163,7 +163,7 @@ export PJSUA2_TEST_SRCDIR = ../src/pjsua2-test
 export PJSUA2_TEST_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
 			   main.o
 export PJSUA2_TEST_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS)
-export PJSUA2_TEST_CXXFLAGS = $(PJSUA2_LIB_CFLAGS) 
+export PJSUA2_TEST_CXXFLAGS = $(_CXXFLAGS) $(PJSUA2_LIB_CFLAGS) 
 export PJSUA2_TEST_LDFLAGS += $(PJ_LDXXFLAGS) $(PJ_LDXXLIBS) $(LDFLAGS)
 export PJSUA2_TEST_EXE := pjsua2-test-$(TARGET_NAME)$(HOST_EXE)
 
diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
index d67424c..c7a9f68 100644
--- a/pjsip/include/pjsip/sip_config.h
+++ b/pjsip/include/pjsip/sip_config.h
@@ -1,4 +1,4 @@
-/* $Id: sip_config.h 5557 2017-02-20 01:23:54Z ming $ */
+/* $Id: sip_config.h 5668 2017-09-29 02:43:05Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -376,6 +376,16 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
 #   define PJSIP_DONT_SWITCH_TO_TLS	0
 #endif
 
+/**
+ * Specify if #pjsip_endpt_handle_events() should sleep if ioqueue poll
+ * returns error.
+ *
+ * Default is 1 (yes).
+ */
+
+#ifndef PJSIP_HANDLE_EVENTS_HAS_SLEEP_ON_ERR
+#   define PJSIP_HANDLE_EVENTS_HAS_SLEEP_ON_ERR	    1
+#endif
 
 /**
  * Specify whether the call media session should be updated to the latest
diff --git a/pjsip/include/pjsip/sip_parser.h b/pjsip/include/pjsip/sip_parser.h
index 1f6f656..f87cb44 100644
--- a/pjsip/include/pjsip/sip_parser.h
+++ b/pjsip/include/pjsip/sip_parser.h
@@ -1,4 +1,4 @@
-/* $Id: sip_parser.h 4445 2013-03-20 11:29:08Z nanang $ */
+/* $Id: sip_parser.h 5682 2017-11-08 02:58:18Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -39,6 +39,26 @@ PJ_BEGIN_DECL
  */
 
 /**
+ * Contants for limit checks
+ */
+#define PJSIP_MIN_CONTENT_LENGTH    0
+#define PJSIP_MAX_CONTENT_LENGTH    PJ_MAXINT32
+#define PJSIP_MIN_PORT		    0
+#define PJSIP_MAX_PORT		    PJ_MAXUINT16
+#define PJSIP_MIN_TTL		    0
+#define PJSIP_MAX_TTL		    PJ_MAXUINT8
+#define PJSIP_MIN_STATUS_CODE	    100
+#define PJSIP_MAX_STATUS_CODE	    999
+#define PJSIP_MIN_Q1000		    0
+#define PJSIP_MAX_Q1000		    PJ_MAXINT32 / 1000
+#define PJSIP_MIN_EXPIRES	    0
+#define PJSIP_MAX_EXPIRES	    PJ_MAXINT32
+#define PJSIP_MIN_CSEQ		    0
+#define PJSIP_MAX_CSEQ		    PJ_MAXINT32
+#define PJSIP_MIN_RETRY_AFTER	    0
+#define PJSIP_MAX_RETRY_AFTER	    PJ_MAXINT32
+
+/**
  * URI Parsing options.
  */
 enum
@@ -64,6 +84,11 @@ enum
 extern int PJSIP_SYN_ERR_EXCEPTION;
 
 /**
+ * Invalid value error exception value.
+ */
+extern int PJSIP_EINVAL_ERR_EXCEPTION;
+
+/**
  * This structure is used to get error reporting from parser.
  */
 typedef struct pjsip_parser_err_report
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index c077e4d..7e8d81a 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -1,4 +1,4 @@
-/* $Id: pjsua.h 5649 2017-09-15 05:32:08Z riza $ */
+/* $Id: pjsua.h 5677 2017-10-27 06:30:50Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -487,6 +487,42 @@ typedef struct pjsua_reg_info
 } pjsua_reg_info;
 
 
+/**
+ * Structure to be passed to on stream created callback.
+ * See #on_stream_created2().
+ */
+typedef struct pjsua_on_stream_created_param
+{
+    /**
+     * The media stream, read-only.
+     */
+    pjmedia_stream 	*stream;
+
+    /**
+     * Stream index in the media session, read-only.
+     */
+    unsigned 		 stream_idx;
+
+    /**
+     * Specify if PJSUA should take ownership of the port returned in
+     * the port parameter below. If set to PJ_TRUE,
+     * pjmedia_port_destroy() will be called on the port when it is
+     * no longer needed.
+     *
+     * Default: PJ_FALSE
+     */
+    pj_bool_t 		 destroy_port;
+
+    /**
+     * On input, it specifies the media port of the stream. Application
+     * may modify this pointer to point to different media port to be
+     * registered to the conference bridge.
+     */
+    pjmedia_port        *port;
+
+} pjsua_on_stream_created_param;
+
+
 /** 
  * Enumeration of media transport state types.
  */
@@ -821,6 +857,9 @@ typedef struct pjsua_callback
      * media port if it has added media processing port to the stream. This
      * media port then will be added to the conference bridge instead.
      *
+     * Note: if implemented, #on_stream_created2() callback will be called
+     * instead of this one. 
+     *
      * @param call_id	    Call identification.
      * @param strm	    Media stream.
      * @param stream_idx    Stream index in the media session.
@@ -835,6 +874,18 @@ typedef struct pjsua_callback
 			      pjmedia_port **p_port);
 
     /**
+     * Notify application when media session is created and before it is
+     * registered to the conference bridge. Application may return different
+     * media port if it has added media processing port to the stream. This
+     * media port then will be added to the conference bridge instead.
+     *
+     * @param call_id	    Call identification.
+     * @param param	    The on stream created callback parameter.
+     */
+    void (*on_stream_created2)(pjsua_call_id call_id,
+			       pjsua_on_stream_created_param *param);
+
+    /**
      * Notify application when media session has been unregistered from the
      * conference bridge and about to be destroyed.
      *
@@ -1395,7 +1446,10 @@ typedef struct pjsua_callback
      * This callback will be called even when null sound device or no
      * sound device is configured by the application (i.e. the
      * #pjsua_set_null_snd_dev() and #pjsua_set_no_snd_dev() APIs).
-     * This API is mostly useful when the application wants to manage
+     * Application can use the API #pjsua_get_snd_dev() to get the info
+     * about which sound device is going to be opened/closed.
+     *
+     * This callback is mostly useful when the application wants to manage
      * the sound device by itself (i.e. with #pjsua_set_no_snd_dev()),
      * to get notified when it should open or close the sound device.
      *
@@ -3658,14 +3712,19 @@ typedef struct pjsua_acc_config
     pj_bool_t	     srtp_optional_dup_offer;
 
     /**
-     * Specify interval of auto registration retry upon registration failure
-     * (including caused by transport problem), in second. Set to 0 to
-     * disable auto re-registration. Note that if the registration retry
-     * occurs because of transport failure, the first retry will be done
-     * after \a reg_first_retry_interval seconds instead. Also note that
-     * the interval will be randomized slightly by some seconds (specified
-     * in \a reg_retry_random_interval) to avoid all clients re-registering
-     * at the same time.
+     * Specify interval of auto registration retry upon registration failure,
+     * in seconds. Set to 0 to disable auto re-registration. Note that
+     * registration will only be automatically retried for temporal failures
+     * considered to be recoverable in relatively short term, such as:
+     * 408 (Request Timeout), 480 (Temporarily Unavailable),
+     * 500 (Internal Server Error), 502 (Bad Gateway),
+     * 503 (Service Unavailable), 504 (Server Timeout),
+     * 6xx (global failure), and failure caused by transport problem.
+     * For registration retry caused by transport failure, the first retry
+     * will be done after \a reg_first_retry_interval seconds instead.
+     * Note that the interval will be randomized slightly by some seconds
+     * (specified in \a reg_retry_random_interval) to avoid all clients
+     * re-registering at the same time.
      *
      * See also \a reg_first_retry_interval setting.
      *
@@ -6350,6 +6409,34 @@ typedef struct pjsua_media_transport
 
 } pjsua_media_transport;
 
+
+/**
+ * Sound device index constants.
+ */
+typedef enum pjsua_snd_dev_id
+{
+    /** 
+     * Constant to denote default capture device.
+     */
+    PJSUA_SND_DEFAULT_CAPTURE_DEV = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV,
+
+    /** 
+     * Constant to denote default playback device.
+     */
+    PJSUA_SND_DEFAULT_PLAYBACK_DEV = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV,
+
+    /**
+     * Constant to denote that no sound device is being used.
+     */
+    PJSUA_SND_NO_DEV = PJMEDIA_AUD_INVALID_DEV,
+
+    /**
+     * Constant to denote null sound device.
+     */
+    PJSUA_SND_NULL_DEV = -99
+
+} pjsua_snd_dev_id;
+
 /**
  * This enumeration specifies the sound device mode.
  */
@@ -6769,6 +6856,7 @@ PJ_DECL(pj_status_t) pjsua_enum_snd_devs(pjmedia_snd_dev_info info[],
  * 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.
+ * See also #pjsua_snd_dev_id constants.
  *
  * @param capture_dev   On return it will be filled with device ID of the 
  *			capture device.
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index 3ba792e..379b211 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -1,4 +1,4 @@
-/* $Id: pjsua_internal.h 5649 2017-09-15 05:32:08Z riza $ */
+/* $Id: pjsua_internal.h 5676 2017-10-24 07:31:39Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -51,6 +51,8 @@ struct pjsua_call_media
 	/** Audio stream */
 	struct {
 	    pjmedia_stream *stream;    /**< The audio stream.		    */
+	    pjmedia_port   *media_port;/**< The media port.                 */
+	    pj_bool_t	    destroy_port;/**< Destroy the media port?	    */
 	    int		    conf_slot; /**< Slot # in conference bridge.    */
 	} a;
 
diff --git a/pjsip/include/pjsua2/call.hpp b/pjsip/include/pjsua2/call.hpp
index 6f6fd42..45a6aa6 100644
--- a/pjsip/include/pjsua2/call.hpp
+++ b/pjsip/include/pjsua2/call.hpp
@@ -1,4 +1,4 @@
-/* $Id: call.hpp 5645 2017-09-06 03:44:35Z riza $ */
+/* $Id: call.hpp 5676 2017-10-24 07:31:39Z ming $ */
 /*
  * Copyright (C) 2012-2013 Teluu Inc. (http://www.teluu.com)
  *
@@ -691,16 +691,26 @@ struct OnCallSdpCreatedParam
 struct OnStreamCreatedParam
 {
     /**
-     * Media stream.
+     * Media stream, read-only.
      */
     MediaStream stream;
     
     /**
-     * Stream index in the media session.
+     * Stream index in the media session, read-only.
      */
     unsigned    streamIdx;
     
     /**
+     * Specify if PJSUA2 should take ownership of the port returned in
+     * the pPort parameter below. If set to PJ_TRUE,
+     * pjmedia_port_destroy() will be called on the port when it is
+     * no longer needed.
+     *
+     * Default: PJ_FALSE
+     */
+    bool 	destroyPort;
+
+    /**
      * On input, it specifies the media port of the stream. Application
      * may modify this pointer to point to different media port to be
      * registered to the conference bridge.
diff --git a/pjsip/include/pjsua2/endpoint.hpp b/pjsip/include/pjsua2/endpoint.hpp
index 822fe69..184feda 100644
--- a/pjsip/include/pjsua2/endpoint.hpp
+++ b/pjsip/include/pjsua2/endpoint.hpp
@@ -1,4 +1,4 @@
-/* $Id: endpoint.hpp 5649 2017-09-15 05:32:08Z riza $ */
+/* $Id: endpoint.hpp 5676 2017-10-24 07:31:39Z ming $ */
 /* 
  * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
  *
@@ -1651,6 +1651,9 @@ private:
     static void on_acc_find_for_incoming(const pjsip_rx_data *rdata,
 				     	 pjsua_acc_id* acc_id);
     static void on_buddy_state(pjsua_buddy_id buddy_id);
+    static void on_buddy_evsub_state(pjsua_buddy_id buddy_id,
+				     pjsip_evsub *sub,
+				     pjsip_event *event);
     // Call callbacks
     static void on_call_state(pjsua_call_id call_id, pjsip_event *e);
     static void on_call_tsx_state(pjsua_call_id call_id,
@@ -1661,10 +1664,8 @@ private:
                                     pjmedia_sdp_session *sdp,
                                     pj_pool_t *pool,
                                     const pjmedia_sdp_session *rem_sdp);
-    static void on_stream_created(pjsua_call_id call_id,
-                                  pjmedia_stream *strm,
-                                  unsigned stream_idx,
-                                  pjmedia_port **p_port);
+    static void on_stream_created2(pjsua_call_id call_id,
+				   pjsua_on_stream_created_param *param);
     static void on_stream_destroyed(pjsua_call_id call_id,
                                     pjmedia_stream *strm,
                                     unsigned stream_idx);
diff --git a/pjsip/include/pjsua2/presence.hpp b/pjsip/include/pjsua2/presence.hpp
index 17b0fb4..b7442e7 100644
--- a/pjsip/include/pjsua2/presence.hpp
+++ b/pjsip/include/pjsua2/presence.hpp
@@ -1,4 +1,4 @@
-/* $Id: presence.hpp 4704 2014-01-16 05:30:46Z ming $ */
+/* $Id: presence.hpp 5672 2017-10-06 08:14:31Z riza $ */
 /*
  * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
  *
@@ -176,6 +176,18 @@ public:
 
 
 /**
+ * This structure contains parameters for Buddy::onBuddyEvSubState() callback.
+ */
+struct OnBuddyEvSubStateParam
+{
+    /**
+     * * The event which triggers state change event.
+     */
+    SipEvent    e;
+};
+
+
+/**
  * Buddy.
  */
 class Buddy
@@ -269,6 +281,17 @@ public:
      */
     virtual void onBuddyState()
     {}
+
+    /**
+     * Notify application when the state of client subscription session
+     * associated with a buddy has changed. Application may use this
+     * callback to retrieve more detailed information about the state
+     * changed event.
+     *
+     * @param prm	Callback parameter.
+     */
+    virtual void onBuddyEvSubState(OnBuddyEvSubStateParam &prm)
+    { PJ_UNUSED_ARG(prm); }
      
 private:
      /**
diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c
index 2bb5553..470c7f7 100644
--- a/pjsip/src/pjsip/sip_endpoint.c
+++ b/pjsip/src/pjsip/sip_endpoint.c
@@ -1,4 +1,4 @@
-/* $Id: sip_endpoint.c 5397 2016-07-26 02:58:44Z nanang $ */
+/* $Id: sip_endpoint.c 5668 2017-09-29 02:43:05Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -34,6 +34,7 @@
 #include <pj/assert.h>
 #include <pj/errno.h>
 #include <pj/lock.h>
+#include <pj/math.h>
 
 #define PJSIP_EX_NO_MEMORY  pj_NO_MEMORY_EXCEPTION()
 #define THIS_FILE	    "sip_endpoint.c"
@@ -699,6 +700,7 @@ PJ_DEF(pj_status_t) pjsip_endpt_handle_events2(pjsip_endpoint *endpt,
 					       const pj_time_val *max_timeout,
 					       unsigned *p_count)
 {
+    enum { MAX_TIMEOUT_ON_ERR = 10 };
     /* timeout is 'out' var. This just to make compiler happy. */
     pj_time_val timeout = { 0, 0};
     unsigned count = 0, net_event_count = 0;
@@ -742,7 +744,11 @@ PJ_DEF(pj_status_t) pjsip_endpt_handle_events2(pjsip_endpoint *endpt,
 	c = pj_ioqueue_poll( endpt->ioqueue, &timeout);
 	if (c < 0) {
 	    pj_status_t err = pj_get_netos_error();
-	    pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout));
+#if PJSIP_HANDLE_EVENTS_HAS_SLEEP_ON_ERR
+	    unsigned msec = PJ_TIME_VAL_MSEC(timeout);
+	    pj_thread_sleep(PJ_MIN(msec, MAX_TIMEOUT_ON_ERR));
+#endif
+
 	    if (p_count)
 		*p_count = count;
 	    return err;
diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c
index e870e1e..d22a85f 100644
--- a/pjsip/src/pjsip/sip_parser.c
+++ b/pjsip/src/pjsip/sip_parser.c
@@ -1,4 +1,4 @@
-/* $Id: sip_parser.c 5280 2016-04-20 01:58:15Z ming $ */
+/* $Id: sip_parser.c 5682 2017-11-08 02:58:18Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -34,6 +34,7 @@
 #include <pj/string.h>
 #include <pj/ctype.h>
 #include <pj/assert.h>
+#include <pj/limits.h>
 
 #define THIS_FILE	    "sip_parser.c"
 
@@ -93,6 +94,7 @@ static unsigned uri_handler_count;
  * Global vars (also extern).
  */
 int PJSIP_SYN_ERR_EXCEPTION = -1;
+int PJSIP_EINVAL_ERR_EXCEPTION = -2;
 
 /* Parser constants */
 static pjsip_parser_const_t pconst =
@@ -205,7 +207,6 @@ static unsigned long pj_strtoul_mindigit(const pj_str_t *str,
 /* Case insensitive comparison */
 #define parser_stricmp(s1, s2)  (s1.slen!=s2.slen || pj_stricmp_alnum(&s1, &s2))
 
-
 /* Get a token and unescape */
 PJ_INLINE(void) parser_get_and_unescape(pj_scanner *scanner, pj_pool_t *pool,
 					const pj_cis_t *spec, 
@@ -223,8 +224,6 @@ PJ_INLINE(void) parser_get_and_unescape(pj_scanner *scanner, pj_pool_t *pool,
 #endif
 }
 
-
-
 /* Syntax error handler for parser. */
 static void on_syntax_error(pj_scanner *scanner)
 {
@@ -232,6 +231,60 @@ static void on_syntax_error(pj_scanner *scanner)
     PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 }
 
+/* Syntax error handler for parser. */
+static void on_str_parse_error(const pj_str_t *str, int rc)
+{
+    char *s;
+
+    switch(rc) {
+    case PJ_EINVAL:
+        s = "NULL input string, invalid input string, or NULL return "\
+	    "value pointer";
+        break;
+    case PJ_ETOOSMALL:
+        s = "String value was less than the minimum allowed value.";
+        break;
+    case PJ_ETOOBIG:
+        s = "String value was greater than the maximum allowed value.";
+        break;
+    default:
+        s = "Unknown error";
+    }
+
+    if (str) {
+        PJ_LOG(1, (THIS_FILE, "Error parsing '%.*s': %s",
+                   (int)str->slen, str->ptr, s));
+    } else {
+        PJ_LOG(1, (THIS_FILE, "Can't parse input string: %s", s));
+    }
+    PJ_THROW(PJSIP_EINVAL_ERR_EXCEPTION);
+}
+
+static void strtoi_validate(const pj_str_t *str, int min_val,
+			    int max_val, int *value)
+{ 
+    long retval;
+    pj_status_t status;
+
+    if (!str || !value) {
+        on_str_parse_error(str, PJ_EINVAL);
+    }
+    status = pj_strtol2(str, &retval);
+    if (status != PJ_EINVAL) {
+	if (min_val > retval) {
+	    *value = min_val;
+	    status = PJ_ETOOSMALL;
+	} else if (retval > max_val) {
+	    *value = max_val;
+	    status = PJ_ETOOBIG;
+	} else
+	    *value = (int)retval;
+    }
+
+    if (status != PJ_SUCCESS)
+	on_str_parse_error(str, status);
+}
+
 /* Get parser constants. */
 PJ_DEF(const pjsip_parser_const_t*) pjsip_parser_const(void)
 {
@@ -285,6 +338,14 @@ static pj_status_t init_parser()
     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
     /*
+     * Invalid value exception.
+     */
+    pj_assert (PJSIP_EINVAL_ERR_EXCEPTION == -2);
+    status = pj_exception_id_alloc("PJSIP invalid value error", 
+				   &PJSIP_EINVAL_ERR_EXCEPTION);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+    /*
      * Init character input spec (cis)
      */
 
@@ -502,6 +563,9 @@ void deinit_sip_parser(void)
 	/* Deregister exception ID */
 	pj_exception_id_free(PJSIP_SYN_ERR_EXCEPTION);
 	PJSIP_SYN_ERR_EXCEPTION = -1;
+
+	pj_exception_id_free(PJSIP_EINVAL_ERR_EXCEPTION);
+	PJSIP_EINVAL_ERR_EXCEPTION = -2;
     }
     pj_leave_critical_section();
 }
@@ -766,7 +830,7 @@ PJ_DEF(pjsip_msg *) pjsip_parse_rdata( char *buf, pj_size_t size,
 }
 
 /* Determine if a message has been received. */
-PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size, 
+PJ_DEF(pj_status_t) pjsip_find_msg( const char *buf, pj_size_t size, 
 				  pj_bool_t is_datagram, pj_size_t *msg_size)
 {
 #if PJ_HAS_TCP
@@ -776,6 +840,7 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size,
     const char *line;
     int content_length = -1;
     pj_str_t cur_msg;
+    pj_status_t status = PJ_SUCCESS;
     const pj_str_t end_hdr = { "\n\r\n", 3};
 
     *msg_size = size;
@@ -836,9 +901,16 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size,
 		pj_scan_get_newline(&scanner);
 
 		/* Found a valid Content-Length header. */
-		content_length = pj_strtoul(&str_clen);
+		strtoi_validate(&str_clen, PJSIP_MIN_CONTENT_LENGTH,
+				PJSIP_MAX_CONTENT_LENGTH, &content_length);
 	    }
 	    PJ_CATCH_ANY {
+		int eid = PJ_GET_EXCEPTION();
+		if (eid == PJSIP_SYN_ERR_EXCEPTION) {
+		    status = PJSIP_EMISSINGHDR;
+		} else if (eid == PJSIP_EINVAL_ERR_EXCEPTION) {
+		    status = PJSIP_EINVALIDHDR;
+		}
 		content_length = -1;
 	    }
 	    PJ_END
@@ -858,7 +930,7 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size,
 
     /* Found Content-Length? */
     if (content_length == -1) {
-	return PJSIP_EMISSINGHDR;
+	return status;
     }
 
     /* Enough packet received? */
@@ -938,10 +1010,14 @@ static pj_bool_t is_next_sip_version(pj_scanner *scanner)
 static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
 				 pjsip_parser_err_report *err_list)
 {
-    pj_bool_t parsing_headers;
-    pjsip_msg *msg = NULL;
+    /* These variables require "volatile" so their values get
+     * preserved when re-entering the PJ_TRY block after an error.
+     */
+    volatile pj_bool_t parsing_headers;
+    pjsip_msg *volatile msg = NULL;
+    pjsip_ctype_hdr *volatile ctype_hdr = NULL;
+
     pj_str_t hname;
-    pjsip_ctype_hdr *ctype_hdr = NULL;
     pj_scanner *scanner = ctx->scanner;
     pj_pool_t *pool = ctx->pool;
     PJ_USE_EXCEPTION;
@@ -1023,7 +1099,6 @@ parse_headers:
 		hdr->name = hdr->sname = hname;
 	    }
 	    
-	
 	    /* Single parse of header line can produce multiple headers.
 	     * For example, if one Contact: header contains Contact list
 	     * separated by comma, then these Contacts will be split into
@@ -1267,7 +1342,7 @@ static void int_parse_uri_host_port( pj_scanner *scanner,
 	pj_str_t port;
 	pj_scan_get_char(scanner);
 	pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &port);
-	*p_port = pj_strtoul(&port);
+	strtoi_validate(&port, PJSIP_MIN_PORT, PJSIP_MAX_PORT, p_port);
     } else {
 	*p_port = 0;
     }
@@ -1458,8 +1533,8 @@ static void* int_parse_sip_url( pj_scanner *scanner,
 	    url->transport_param = pvalue;
 
 	} else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) {
-	    url->ttl_param = pj_strtoul(&pvalue);
-
+	    strtoi_validate(&pvalue, PJSIP_MIN_TTL, PJSIP_MAX_TTL,
+			    &url->ttl_param);
 	} else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) {
 	    url->maddr_param = pvalue;
 
@@ -1595,7 +1670,8 @@ static void int_parse_status_line( pj_scanner *scanner,
 
     parse_sip_version(scanner);
     pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &token);
-    status_line->code = pj_strtoul(&token);
+    strtoi_validate(&token, PJSIP_MIN_STATUS_CODE, PJSIP_MAX_STATUS_CODE,
+                    &status_line->code);
     if (*scanner->curptr != '\r' && *scanner->curptr != '\n')
 	pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &status_line->reason);
     else
@@ -1780,20 +1856,34 @@ static void int_parse_contact_param( pjsip_contact_hdr *hdr,
 	if (!parser_stricmp(pname, pconst.pjsip_Q_STR) && pvalue.slen) {
 	    char *dot_pos = (char*) pj_memchr(pvalue.ptr, '.', pvalue.slen);
 	    if (!dot_pos) {
-		hdr->q1000 = pj_strtoul(&pvalue) * 1000;
+		strtoi_validate(&pvalue, PJSIP_MIN_Q1000, PJSIP_MAX_Q1000,
+                                &hdr->q1000);
+		hdr->q1000 *= 1000;
 	    } else {
 		pj_str_t tmp = pvalue;
+		unsigned long qval_frac;
 
 		tmp.slen = dot_pos - pvalue.ptr;
-		hdr->q1000 = pj_strtoul(&tmp) * 1000;
+		strtoi_validate(&tmp, PJSIP_MIN_Q1000, PJSIP_MAX_Q1000,
+                                &hdr->q1000);
+                hdr->q1000 *= 1000;
 
 		pvalue.slen = (pvalue.ptr+pvalue.slen) - (dot_pos+1);
 		pvalue.ptr = dot_pos + 1;
-		hdr->q1000 += pj_strtoul_mindigit(&pvalue, 3);
+		if (pvalue.slen > 3) {
+		    pvalue.slen = 3;
+		}
+		qval_frac = pj_strtoul_mindigit(&pvalue, 3);
+		if ((unsigned)hdr->q1000 > (PJ_MAXINT32 - qval_frac)) {
+		    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
+		}
+		hdr->q1000 += qval_frac;
 	    }    
-	} else if (!parser_stricmp(pname, pconst.pjsip_EXPIRES_STR) && pvalue.slen) {
-	    hdr->expires = pj_strtoul(&pvalue);
-
+	} else if (!parser_stricmp(pname, pconst.pjsip_EXPIRES_STR) && 
+                   pvalue.slen) 
+        {
+	    strtoi_validate(&pvalue, PJSIP_MIN_EXPIRES, PJSIP_MAX_EXPIRES,
+                            &hdr->expires);
 	} else {
 	    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
 	    p->name = pname;
@@ -1890,19 +1980,22 @@ static pjsip_hdr* parse_hdr_content_type( pjsip_parse_ctx *ctx )
 static pjsip_hdr* parse_hdr_cseq( pjsip_parse_ctx *ctx )
 {
     pj_str_t cseq, method;
-    pjsip_cseq_hdr *hdr;
+    pjsip_cseq_hdr *hdr = NULL;
+    int cseq_val = 0;
 
-    hdr = pjsip_cseq_hdr_create(ctx->pool);
     pj_scan_get( ctx->scanner, &pconst.pjsip_DIGIT_SPEC, &cseq);
-    hdr->cseq = pj_strtoul(&cseq);
+    strtoi_validate(&cseq, PJSIP_MIN_CSEQ, PJSIP_MAX_CSEQ, &cseq_val);
 
-    pj_scan_get( ctx->scanner, &pconst.pjsip_TOKEN_SPEC, &method);
-    pjsip_method_init_np(&hdr->method, &method);
+    hdr = pjsip_cseq_hdr_create(ctx->pool);
+    hdr->cseq = cseq_val;
 
+    pj_scan_get( ctx->scanner, &pconst.pjsip_TOKEN_SPEC, &method);
     parse_hdr_end( ctx->scanner );
 
-    if (ctx->rdata)
+    pjsip_method_init_np(&hdr->method, &method);
+    if (ctx->rdata) {
         ctx->rdata->msg_info.cseq = hdr;
+    }
 
     return (pjsip_hdr*)hdr;
 }
@@ -1984,7 +2077,8 @@ static pjsip_hdr* parse_hdr_retry_after(pjsip_parse_ctx *ctx)
     hdr = pjsip_retry_after_hdr_create(ctx->pool, 0);
     
     pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &tmp);
-    hdr->ivalue = pj_strtoul(&tmp);
+    strtoi_validate(&tmp, PJSIP_MIN_RETRY_AFTER, PJSIP_MAX_RETRY_AFTER,
+                    &hdr->ivalue);
 
     while (!pj_scan_is_eof(scanner) && *scanner->curptr!='\r' &&
 	   *scanner->curptr!='\n')
@@ -2073,7 +2167,8 @@ static void int_parse_via_param( pjsip_via_hdr *hdr, pj_scanner *scanner,
 	    hdr->branch_param = pvalue;
 
 	} else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) {
-	    hdr->ttl_param = pj_strtoul(&pvalue);
+	    strtoi_validate(&pvalue, PJSIP_MIN_TTL, PJSIP_MAX_TTL,
+                            &hdr->ttl_param);
 	    
 	} else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) {
 	    hdr->maddr_param = pvalue;
@@ -2082,9 +2177,10 @@ static void int_parse_via_param( pjsip_via_hdr *hdr, pj_scanner *scanner,
 	    hdr->recvd_param = pvalue;
 
 	} else if (!parser_stricmp(pname, pconst.pjsip_RPORT_STR)) {
-	    if (pvalue.slen)
-		hdr->rport_param = pj_strtoul(&pvalue);
-	    else
+	    if (pvalue.slen) {
+		strtoi_validate(&pvalue, PJSIP_MIN_PORT, PJSIP_MAX_PORT,
+			        &hdr->rport_param);
+            } else
 		hdr->rport_param = 0;
 	} else {
 	    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
@@ -2213,7 +2309,8 @@ static pjsip_hdr* parse_hdr_via( pjsip_parse_ctx *ctx )
 	    pj_str_t digit;
 	    pj_scan_get_char(scanner);
 	    pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &digit);
-	    hdr->sent_by.port = pj_strtoul(&digit);
+	    strtoi_validate(&digit, PJSIP_MIN_PORT, PJSIP_MAX_PORT,
+                            &hdr->sent_by.port);
 	}
 	
 	int_parse_via_param(hdr, scanner, ctx->pool);
@@ -2298,9 +2395,10 @@ PJ_DEF(pj_status_t) pjsip_parse_headers( pj_pool_t *pool, char *input,
 				         unsigned options)
 {
     enum { STOP_ON_ERROR = 1 };
+    pj_str_t hname;
     pj_scanner scanner;
     pjsip_parse_ctx ctx;
-    pj_str_t hname;
+
     PJ_USE_EXCEPTION;
 
     pj_scan_init(&scanner, input, size, PJ_SCAN_AUTOSKIP_WS_HEADER,
@@ -2323,7 +2421,7 @@ retry_parse:
 	     */
 	    hname.slen = 0;
 
-	    /* Get hname. */
+	    /* Get hname. */            
 	    pj_scan_get( &scanner, &pconst.pjsip_TOKEN_SPEC, &hname);
 	    if (pj_scan_get_char( &scanner ) != ':') {
 		PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 37e9904..dd99729 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -1,4 +1,4 @@
-/* $Id: sip_transaction.c 5613 2017-07-04 00:13:24Z ming $ */
+/* $Id: sip_transaction.c 5682 2017-11-08 02:58:18Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -289,11 +289,11 @@ static pj_status_t create_tsx_key_2543( pj_pool_t *pool,
 
     /* Calculate length required. */
     len_required = method->name.slen +      /* Method */
-                   9 +			    /* CSeq number */
+                   11 +			    /* CSeq number */
 		   rdata->msg_info.from->tag.slen +   /* From tag. */
 		   rdata->msg_info.cid->id.slen +    /* Call-ID */
 		   host->slen +		    /* Via host. */
-		   9 +			    /* Via port. */
+		   11 +			    /* Via port. */
 		   16;			    /* Separator+Allowance. */
     key = p = (char*) pj_pool_alloc(pool, len_required);
 
diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
index 9efa4ee..b72f3ff 100644
--- a/pjsip/src/pjsip/sip_transport.c
+++ b/pjsip/src/pjsip/sip_transport.c
@@ -1,4 +1,4 @@
-/* $Id: sip_transport.c 5564 2017-03-08 04:33:47Z riza $ */
+/* $Id: sip_transport.c 5682 2017-11-08 02:58:18Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -1848,7 +1848,7 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,
 	/* Check for parsing syntax error */
 	if (msg==NULL || !pj_list_empty(&rdata->msg_info.parse_err)) {
 	    pjsip_parser_err_report *err;
-	    char buf[128];
+	    char buf[256];
 	    pj_str_t tmp;
 
 	    /* Gather syntax error information */
@@ -1862,7 +1862,10 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,
 				       pj_exception_id_name(err->except_code),
 				       (int)err->hname.slen, err->hname.ptr,
 				       err->line, err->col);
-		if (len > 0 && len < (int) (sizeof(buf)-tmp.slen)) {
+		if (len >= (int)sizeof(buf)-tmp.slen) {
+		    len = (int)sizeof(buf)-tmp.slen;
+		}
+		if (len > 0) {
 		    tmp.slen += len;
 		}
 		err = err->next;
diff --git a/pjsip/src/pjsua-lib/pjsua_aud.c b/pjsip/src/pjsua-lib/pjsua_aud.c
index 8055a51..a57f013 100644
--- a/pjsip/src/pjsua-lib/pjsua_aud.c
+++ b/pjsip/src/pjsua-lib/pjsua_aud.c
@@ -1,4 +1,4 @@
-/* $Id: pjsua_aud.c 5651 2017-09-19 10:21:42Z nanang $ */
+/* $Id: pjsua_aud.c 5677 2017-10-27 06:30:50Z ming $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -23,7 +23,6 @@
 #if defined(PJSUA_MEDIA_HAS_PJMEDIA) && PJSUA_MEDIA_HAS_PJMEDIA != 0
 
 #define THIS_FILE		"pjsua_aud.c"
-#define NULL_SND_DEV_ID		-99
 
 /*****************************************************************************
  *
@@ -531,6 +530,12 @@ void pjsua_aud_stop_stream(pjsua_call_media *call_med)
 	                                            strm, call_med->idx);
 	}
 
+	if (call_med->strm.a.media_port) {
+	    if (call_med->strm.a.destroy_port)
+		pjmedia_port_destroy(call_med->strm.a.media_port);
+	    call_med->strm.a.media_port = NULL;
+	}
+
 	pjmedia_stream_destroy(strm);
 	call_med->strm.a.stream = NULL;
     }
@@ -575,7 +580,6 @@ pj_status_t pjsua_aud_channel_update(pjsua_call_media *call_med,
 				     const pjmedia_sdp_session *remote_sdp)
 {
     pjsua_call *call = call_med->call;
-    pjmedia_port *media_port;
     unsigned strm_idx = call_med->idx;
     pj_status_t status = PJ_SUCCESS;
 
@@ -645,16 +649,30 @@ pj_status_t pjsua_aud_channel_update(pjsua_call_media *call_med,
 	/* Get the port interface of the first stream in the session.
 	 * We need the port interface to add to the conference bridge.
 	 */
-	pjmedia_stream_get_port(call_med->strm.a.stream, &media_port);
+	pjmedia_stream_get_port(call_med->strm.a.stream,
+				&call_med->strm.a.media_port);
 
 	/* Notify application about stream creation.
 	 * Note: application may modify media_port to point to different
 	 * media port
 	 */
-	if (pjsua_var.ua_cfg.cb.on_stream_created) {
-	    pjsua_var.ua_cfg.cb.on_stream_created(call->index,
+	if (pjsua_var.ua_cfg.cb.on_stream_created2) {
+	    pjsua_on_stream_created_param prm;
+	    
+	    prm.stream = call_med->strm.a.stream;
+	    prm.stream_idx = strm_idx;
+	    prm.destroy_port = PJ_FALSE;
+	    prm.port = call_med->strm.a.media_port;
+	    (*pjsua_var.ua_cfg.cb.on_stream_created2)(call->index, &prm);
+	    
+	    call_med->strm.a.destroy_port = prm.destroy_port;
+	    call_med->strm.a.media_port = prm.port;
+
+	} else if (pjsua_var.ua_cfg.cb.on_stream_created) {
+	    (*pjsua_var.ua_cfg.cb.on_stream_created)(call->index,
 						  call_med->strm.a.stream,
-						  strm_idx, &media_port);
+						  strm_idx,
+						  &call_med->strm.a.media_port);
 	}
 
 	/*
@@ -671,12 +689,12 @@ pj_status_t pjsua_aud_channel_update(pjsua_call_media *call_med,
 	    if (port_name.slen < 1) {
 		port_name = pj_str("call");
 	    }
-	    status = pjmedia_conf_add_port( pjsua_var.mconf,
-					    call->inv->pool,
-					    media_port,
-					    &port_name,
-					    (unsigned*)
-					    &call_med->strm.a.conf_slot);
+	    status = pjmedia_conf_add_port(pjsua_var.mconf,
+					   call->inv->pool,
+					   call_med->strm.a.media_port,
+					   &port_name,
+					   (unsigned*)
+					   &call_med->strm.a.conf_slot);
 	    if (status != PJ_SUCCESS) {
 		goto on_return;
 	    }
@@ -861,7 +879,7 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
 	}
 
 	if (need_reopen) {
-	    if (pjsua_var.cap_dev != NULL_SND_DEV_ID) {
+	    if (pjsua_var.cap_dev != PJSUA_SND_NULL_DEV) {
 		pjmedia_snd_port_param param;
 
 		pjmedia_snd_port_param_default(&param);
@@ -1708,8 +1726,8 @@ static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
     PJ_ASSERT_RETURN(param, PJ_EINVAL);
 
     /* Check if NULL sound device is used */
-    if (NULL_SND_DEV_ID==param->base.rec_id ||
-	NULL_SND_DEV_ID==param->base.play_id)
+    if (PJSUA_SND_NULL_DEV==param->base.rec_id ||
+	PJSUA_SND_NULL_DEV==param->base.play_id)
     {
 	return pjsua_set_null_snd_dev();
     }
@@ -1717,6 +1735,10 @@ static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
     /* Close existing sound port */
     close_snd_dev();
 
+    /* Save the device IDs */
+    pjsua_var.cap_dev = param->base.rec_id;
+    pjsua_var.play_dev = param->base.play_id;
+
     /* Notify app */
     if (pjsua_var.ua_cfg.cb.on_snd_dev_operation) {
 	(*pjsua_var.ua_cfg.cb.on_snd_dev_operation)(1);
@@ -1833,10 +1855,6 @@ static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
 	goto on_error;
     }
 
-    /* Save the device IDs */
-    pjsua_var.cap_dev = param->base.rec_id;
-    pjsua_var.play_dev = param->base.play_id;
-
     /* Update sound device name. */
     {
 	pjmedia_aud_dev_info rec_info;
@@ -1990,8 +2008,8 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev2(pjsua_snd_dev_param *snd_param)
     }
     
     /* Null-sound */
-    if (snd_param->capture_dev == NULL_SND_DEV_ID && 
-	snd_param->playback_dev == NULL_SND_DEV_ID) 
+    if (snd_param->capture_dev == PJSUA_SND_NULL_DEV && 
+	snd_param->playback_dev == PJSUA_SND_NULL_DEV) 
     {
 	PJSUA_UNLOCK();
 	status = pjsua_set_null_snd_dev();
@@ -2110,6 +2128,9 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
     /* Close existing sound device */
     close_snd_dev();
 
+    pjsua_var.cap_dev = PJSUA_SND_NULL_DEV;
+    pjsua_var.play_dev = PJSUA_SND_NULL_DEV;
+
     /* Notify app */
     if (pjsua_var.ua_cfg.cb.on_snd_dev_operation) {
 	(*pjsua_var.ua_cfg.cb.on_snd_dev_operation)(1);
@@ -2142,9 +2163,6 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
     status = pjmedia_master_port_start(pjsua_var.null_snd);
     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
-    pjsua_var.cap_dev = NULL_SND_DEV_ID;
-    pjsua_var.play_dev = NULL_SND_DEV_ID;
-
     pjsua_var.no_snd = PJ_FALSE;
     pjsua_var.snd_is_on = PJ_TRUE;
 
@@ -2165,6 +2183,8 @@ PJ_DEF(pjmedia_port*) pjsua_set_no_snd_dev(void)
     /* Close existing sound device */
     close_snd_dev();
     pjsua_var.no_snd = PJ_TRUE;
+    pjsua_var.cap_dev = PJSUA_SND_NO_DEV;
+    pjsua_var.play_dev = PJSUA_SND_NO_DEV;
 
     PJSUA_UNLOCK();
 
diff --git a/pjsip/src/pjsua2/endpoint.cpp b/pjsip/src/pjsua2/endpoint.cpp
index b796840..34189c2 100644
--- a/pjsip/src/pjsua2/endpoint.cpp
+++ b/pjsip/src/pjsua2/endpoint.cpp
@@ -1,4 +1,4 @@
-/* $Id: endpoint.cpp 5649 2017-09-15 05:32:08Z riza $ */
+/* $Id: endpoint.cpp 5676 2017-10-24 07:31:39Z ming $ */
 /* 
  * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
  *
@@ -973,6 +973,24 @@ void Endpoint::on_buddy_state(pjsua_buddy_id buddy_id)
     buddy->onBuddyState();
 }
 
+void Endpoint::on_buddy_evsub_state(pjsua_buddy_id buddy_id,
+				    pjsip_evsub *sub,
+				    pjsip_event *event)
+{
+    PJ_UNUSED_ARG(sub);
+
+    Buddy *buddy = (Buddy*)pjsua_buddy_get_user_data(buddy_id);
+    if (!buddy || !buddy->isValid()) {
+	/* Ignored */
+	return;
+    }
+
+    OnBuddyEvSubStateParam prm;
+    prm.e.fromPj(*event);
+
+    buddy->onBuddyEvSubState(prm);
+}
+
 // Call callbacks
 void Endpoint::on_call_state(pjsua_call_id call_id, pjsip_event *e)
 {
@@ -1052,10 +1070,8 @@ void Endpoint::on_call_sdp_created(pjsua_call_id call_id,
     }
 }
 
-void Endpoint::on_stream_created(pjsua_call_id call_id,
-                                 pjmedia_stream *strm,
-                                 unsigned stream_idx,
-                                 pjmedia_port **p_port)
+void Endpoint::on_stream_created2(pjsua_call_id call_id,
+				  pjsua_on_stream_created_param *param)
 {
     Call *call = Call::lookup(call_id);
     if (!call) {
@@ -1063,14 +1079,15 @@ void Endpoint::on_stream_created(pjsua_call_id call_id,
     }
     
     OnStreamCreatedParam prm;
-    prm.stream = strm;
-    prm.streamIdx = stream_idx;
-    prm.pPort = (void *)*p_port;
+    prm.stream = param->stream;
+    prm.streamIdx = param->stream_idx;
+    prm.destroyPort = param->destroy_port;
+    prm.pPort = (MediaPort)param->port;
     
     call->onStreamCreated(prm);
     
-    if (prm.pPort != (void *)*p_port)
-        *p_port = (pjmedia_port *)prm.pPort;
+    param->destroy_port = prm.destroyPort;
+    param->port = (pjmedia_port *)prm.pPort;
 }
 
 void Endpoint::on_stream_destroyed(pjsua_call_id call_id,
@@ -1530,6 +1547,7 @@ void Endpoint::libInit(const EpConfig &prmEpConfig) throw(Error)
     ua_cfg.cb.on_typing2	= &Endpoint::on_typing2;
     ua_cfg.cb.on_mwi_info	= &Endpoint::on_mwi_info;
     ua_cfg.cb.on_buddy_state	= &Endpoint::on_buddy_state;
+    ua_cfg.cb.on_buddy_evsub_state = &Endpoint::on_buddy_evsub_state;
     ua_cfg.cb.on_acc_find_for_incoming  = &Endpoint::on_acc_find_for_incoming;
     ua_cfg.cb.on_ip_change_progress	= &Endpoint::on_ip_change_progress;
 
@@ -1538,7 +1556,7 @@ void Endpoint::libInit(const EpConfig &prmEpConfig) throw(Error)
     ua_cfg.cb.on_call_tsx_state         = &Endpoint::on_call_tsx_state;
     ua_cfg.cb.on_call_media_state       = &Endpoint::on_call_media_state;
     ua_cfg.cb.on_call_sdp_created       = &Endpoint::on_call_sdp_created;
-    ua_cfg.cb.on_stream_created         = &Endpoint::on_stream_created;
+    ua_cfg.cb.on_stream_created2        = &Endpoint::on_stream_created2;
     ua_cfg.cb.on_stream_destroyed       = &Endpoint::on_stream_destroyed;
     ua_cfg.cb.on_dtmf_digit             = &Endpoint::on_dtmf_digit;
     ua_cfg.cb.on_call_transfer_request2 = &Endpoint::on_call_transfer_request2;
diff --git a/pjsip/src/pjsua2/siptypes.cpp b/pjsip/src/pjsua2/siptypes.cpp
index 6cbba43..6fb0003 100644
--- a/pjsip/src/pjsua2/siptypes.cpp
+++ b/pjsip/src/pjsua2/siptypes.cpp
@@ -1,4 +1,4 @@
-/* $Id: siptypes.cpp 5207 2015-12-08 11:25:45Z ming $ */
+/* $Id: siptypes.cpp 5669 2017-10-03 09:35:36Z riza $ */
 /*
  * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
  *
@@ -363,16 +363,36 @@ pjsip_media_type SipMediaType::toPj() const
 
 void SipHeader::fromPj(const pjsip_hdr *hdr) throw(Error)
 {
-    char buf[256];
-
-    int len = pjsip_hdr_print_on((void*)hdr, buf, sizeof(buf)-1);
-    if (len <= 0)
+    char *buf = NULL;
+    int len = 0;
+    unsigned buf_size = 256>>1;
+
+    /* Print header to a 256 bytes buffer first.
+     * If buffer is not sufficient, try 512, 1024, soon
+     * until > PJSIP_MAX_PKT_LEN
+     */
+    do {
+        buf_size <<= 1;
+	buf = (char*)malloc(buf_size);
+	if (!buf)
+	    PJSUA2_RAISE_ERROR(PJ_ENOMEM);
+
+	len = pjsip_hdr_print_on((void*)hdr, buf, buf_size-1);
+        if (len < 0)
+            free(buf);
+
+    } while ((buf_size < PJSIP_MAX_PKT_LEN) && (len < 0));
+    
+    if (len < 0)
 	PJSUA2_RAISE_ERROR(PJ_ETOOSMALL);
+
     buf[len] = '\0';
 
     char *pos = strchr(buf, ':');
-    if (!pos)
+    if (!pos) {
+	free(buf);
 	PJSUA2_RAISE_ERROR(PJSIP_EINVALIDHDR);
+    }
 
     // Trim white space after header name
     char *end_name = pos;
@@ -384,6 +404,7 @@ void SipHeader::fromPj(const pjsip_hdr *hdr) throw(Error)
 
     hName = string(buf, end_name);
     hValue = string(start_val);
+    free(buf);
 }
 
 pjsip_generic_string_hdr &SipHeader::toPj() const
diff --git a/pjsip/src/test/regc_test.c b/pjsip/src/test/regc_test.c
index 54056a5..ef8657c 100644
--- a/pjsip/src/test/regc_test.c
+++ b/pjsip/src/test/regc_test.c
@@ -1,4 +1,4 @@
-/* $Id: regc_test.c 5535 2017-01-19 10:31:38Z riza $ */
+/* $Id: regc_test.c 5678 2017-11-01 04:55:29Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -64,7 +64,7 @@ static pj_status_t mod_send_on_tx_request(pjsip_tx_data *tdata)
 	return PJ_ECANCELLED;
     else
 	return PJ_SUCCESS;
-};
+}
 
 
 /************************************************************************/
@@ -525,7 +525,7 @@ static int refresh_error(const pj_str_t *registrar_uri,
     }
 
     return PJ_SUCCESS;
-};
+}
 
 
 /* Send error on refresh */
@@ -700,7 +700,7 @@ on_return:
     if (tdata) pjsip_tx_data_dec_ref(tdata);
     pjsip_regc_destroy(regc);
     return ret;
-};
+}
 
 
 /* send error on authentication */
@@ -731,7 +731,7 @@ static int auth_send_error(const pj_str_t *registrar_uri,
     send_mod.count_before_reject = 0xFFFF;
 
     return ret;
-};
+}
 
 
 
diff --git a/tests/pjsua/tools/Makefile b/tests/pjsua/tools/Makefile
index 1c5ac59..35ebbfc 100644
--- a/tests/pjsua/tools/Makefile
+++ b/tests/pjsua/tools/Makefile
@@ -7,7 +7,7 @@ CC      = $(APP_CC)
 LDFLAGS = $(APP_LDFLAGS)
 LDLIBS  = $(APP_LDLIBS)
 CFLAGS  = $(APP_CFLAGS)
-CPPFLAGS= ${CFLAGS}
+CPPFLAGS= $(APP_CXXFLAGS)
 
 # If your application is in a file named myapp.cpp or myapp.c
 # # this is the line you will need to build the binary.
diff --git a/version.mak b/version.mak
index 01e6531..ffdc6de 100644
--- a/version.mak
+++ b/version.mak
@@ -1,7 +1,7 @@
 # Don't change the "export PJ_VERSION_xxx" style, they are parsed by setup.py
 export PJ_VERSION_MAJOR  := 2
 export PJ_VERSION_MINOR  := 7
-export PJ_VERSION_REV    :=
+export PJ_VERSION_REV    := 1
 export PJ_VERSION_SUFFIX :=
 
 export PJ_VERSION := $(PJ_VERSION_MAJOR).$(PJ_VERSION_MINOR)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/pjproject.git



More information about the Pkg-voip-commits mailing list