[Asterisk-code-review] build-system: Allow building with static pjproject (asterisk[master])

George Joseph asteriskteam at digium.com
Thu Feb 4 18:07:18 CST 2016


George Joseph has uploaded a new change for review.

  https://gerrit.asterisk.org/2200

Change subject: build-system: Allow building with static pjproject
......................................................................

build-system: Allow building with static pjproject

Background here:
http://lists.digium.com/pipermail/asterisk-dev/2016-January/075266.html

To facilitate testing and provide a transition period, the default behavior is
still to dynamically link to the system-installed shared pjproject libraries.

Static link:

New ./configure option:

--enable-static-pjproject
	If --with-pjproject=PATH was specified, it is assumed that PATH
	points to the pjproject source directory.  If --with-pjproject
	was specified without PATH or not specified at all, PATH is
	assumed to be ./third_party/pjproject/source. Regardless, the
	directory must contain a fully built source tree.

To build...

The default make target will...

* Download an official tarball from pjsip.org for the version specified in
  third_party/verisons.mak.
* Unpack it into the 'source' directory.
* Apply any patches located in the 'patches' directory.
* Run 'configure' with the options defined in 'makeopts'.
* Run 'make dep' to build all the dependencies.
* Run 'make'.

When that's done, change back to the Asterisk top directory and run
'./configure --enable-static-pjproject <your normal options>'

Implementation Notes:

The third_party/pjproject directory was created and makefiles were added
that download, configure and build pjproject.  None of the pjproject source
is checked in of course.

configure.ac was modified to process the new option and perform appropriate
checks.

libasteriskpj.so was created and now exposes all pjproject APIs.  It is
created and used just like libasteriskssl.  The build grabs the symbols from
the libpj*.a files, creates the .exports file and links it.  If
HAVE_PJPROJECT_STATIC is not defined, it doesn't get built and ast_pj_init
is a no-op.

Modules should continue to depend on pjproject if they use pjproject APIs
directly.  They should not care about the implementation.  No changes to any
res_pjsip modules were made.

Change-Id: Ia7a60c28c2e9ba9537c5570f933c1ebcb20a3103
---
M .gitignore
M configure
M configure.ac
M include/asterisk/_private.h
M include/asterisk/autoconfig.h.in
M main/.gitignore
M main/Makefile
M main/asterisk.c
A main/libasteriskpj.c
M makeopts.in
A third_party/Makefile
A third_party/pjproject/.gitignore
A third_party/pjproject/Makefile
A third_party/pjproject/apply_patches
A third_party/pjproject/patches/0000-config_site.patch
A third_party/pjproject/patches/0001-2.4.5-fix-for-tls-async-ops.patch
A third_party/pjproject/patches/0002-no_third_party.patch
A third_party/versions.mak
18 files changed, 674 insertions(+), 73 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/00/2200/1

diff --git a/.gitignore b/.gitignore
index 0281e10..0665ae7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@
 *.moduleinfo
 *.makeopts
 *.makedeps
+*.tmp
 .lastclean
 aclocal.m4
 autom4te.cache
diff --git a/configure b/configure
index fc76131..6d3ec60 100755
--- a/configure
+++ b/configure
@@ -909,6 +909,10 @@
 PORTAUDIO_DIR
 PORTAUDIO_INCLUDE
 PORTAUDIO_LIB
+PBX_POPT
+POPT_DIR
+POPT_INCLUDE
+POPT_LIB
 PBX_PJSIP_EXTERNAL_RESOLVER
 PJSIP_EXTERNAL_RESOLVER_DIR
 PJSIP_EXTERNAL_RESOLVER_INCLUDE
@@ -929,10 +933,7 @@
 PJ_TRANSACTION_GRP_LOCK_DIR
 PJ_TRANSACTION_GRP_LOCK_INCLUDE
 PJ_TRANSACTION_GRP_LOCK_LIB
-PBX_POPT
-POPT_DIR
-POPT_INCLUDE
-POPT_LIB
+PJPROJECT_STATIC
 PBX_PJPROJECT
 PJPROJECT_DIR
 PJPROJECT_INCLUDE
@@ -1352,6 +1353,7 @@
 with_oss
 with_postgres
 with_pjproject
+enable_static_pjproject
 with_popt
 with_portaudio
 with_pri
@@ -2028,6 +2030,8 @@
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --enable-dev-mode       Turn on developer mode
   --enable-coverage       Turn on code coverage tracking (for gcov)
+  --enable-static-pjproject
+                          Link to static pjproject libraries
   --disable-xmldoc        Explicitly disable XML documentation
   --disable-largefile     omit support for large files
   --enable-internal-poll  Use Asterisk's poll implementation
@@ -10405,6 +10409,7 @@
 
 
 
+
     PJPROJECT_DESCRIP="PJPROJECT"
     PJPROJECT_OPTION="pjproject"
     PBX_PJPROJECT=0
@@ -10436,37 +10441,27 @@
 
 
 
+PJPROJECT_STATIC=no
 
-    POPT_DESCRIP="popt"
-    POPT_OPTION="popt"
-    PBX_POPT=0
 
-# Check whether --with-popt was given.
-if test "${with_popt+set}" = set; then :
-  withval=$with_popt;
-	case ${withval} in
-	n|no)
-	USE_POPT=no
-	# -1 is a magic value used by menuselect to know that the package
-	# was disabled, other than 'not found'
-	PBX_POPT=-1
-	;;
-	y|ye|yes)
-	ac_mandatory_list="${ac_mandatory_list} POPT"
-	;;
-	*)
-	POPT_DIR="${withval}"
-	ac_mandatory_list="${ac_mandatory_list} POPT"
-	;;
+# Check whether --enable-static-pjproject was given.
+if test "${enable_static_pjproject+set}" = set; then :
+  enableval=$enable_static_pjproject; case "${enableval}" in
+	      n|no) PJPROJECT_STATIC=no ;;
+	      *) PJPROJECT_STATIC=yes ;;
 	esac
-
 fi
 
 
 
-
-
-
+if test "$PJPROJECT_STATIC" = "yes" ; then
+   if test "${ac_mandatory_list#*PJPROJECT*}" = "$ac_mandatory_list" ; then
+      ac_mandatory_list="$ac_mandatory_list PJPROJECT"
+   fi
+   if test "x$PJPROJECT_DIR" = "x" ; then
+      PJPROJECT_DIR="${PWD}/third_party/pjproject/source"
+   fi
+fi
 
 
 PJ_TRANSACTION_GRP_LOCK_DESCRIP="PJSIP Transaction Group Lock Support"
@@ -10522,6 +10517,39 @@
 PJSIP_EXTERNAL_RESOLVER_DIR=${PJPROJECT_DIR}
 
 PBX_PJSIP_EXTERNAL_RESOLVER=0
+
+
+
+
+
+
+
+
+    POPT_DESCRIP="popt"
+    POPT_OPTION="popt"
+    PBX_POPT=0
+
+# Check whether --with-popt was given.
+if test "${with_popt+set}" = set; then :
+  withval=$with_popt;
+	case ${withval} in
+	n|no)
+	USE_POPT=no
+	# -1 is a magic value used by menuselect to know that the package
+	# was disabled, other than 'not found'
+	PBX_POPT=-1
+	;;
+	y|ye|yes)
+	ac_mandatory_list="${ac_mandatory_list} POPT"
+	;;
+	*)
+	POPT_DIR="${withval}"
+	ac_mandatory_list="${ac_mandatory_list} POPT"
+	;;
+	esac
+
+fi
+
 
 
 
@@ -24291,6 +24319,25 @@
    fi
 fi
 
+if test "$USE_PJPROJECT" != "no" ; then
+if test "$PJPROJECT_STATIC" = "yes" ; then
+   if test -e "$PJPROJECT_DIR/build.mak" ; then
+      PJPROJECT_INCLUDE=`make -f /dev/null --eval="include $PJPROJECT_DIR/build.mak" --eval='$(info $(PJ_CFLAGS))' --eval='all:' -q -s`
+      PJPROJECT_LIB=`make -f /dev/null --eval="include $PJPROJECT_DIR/build.mak" --eval='$(info $(APP_LDFLAGS) $(APP_LDLIBS))' --eval='all:' -q -s`
+      PBX_PJPROJECT=1
+
+$as_echo "#define HAVE_PJPROJECT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJPROJECT_STATIC 1" >>confdefs.h
+
+# dummy shared libraries because AST_EXT_LIB_CHECK needs something
+      temp_lpjsip="m"
+      temp_lpj="m"
+   else
+      PBX_PJPROJECT=0
+   fi
+else
 
    if test "x${PBX_PJPROJECT}" != "x1" -a "${USE_PJPROJECT}" != "no"; then
 
@@ -24379,6 +24426,9 @@
 fi
    fi
 
+   temp_lpjsip="pjsip"
+   temp_lpj="pj"
+fi
 
 
 if test "x${PBX_PJ_TRANSACTION_GRP_LOCK}" != "x1" -a "${USE_PJ_TRANSACTION_GRP_LOCK}" != "no"; then
@@ -24396,15 +24446,15 @@
       AST_PJ_TRANSACTION_GRP_LOCK_FOUND=yes
    else
       ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
-      CFLAGS="${CFLAGS} $PJPROJECT_CFLAGS"
-      as_ac_Lib=`$as_echo "ac_cv_lib_pjsip_${pbxfuncname}" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpjsip" >&5
-$as_echo_n "checking for ${pbxfuncname} in -lpjsip... " >&6; }
+      CFLAGS="${CFLAGS} $PJPROJECT_INCLUDE"
+      as_ac_Lib=`$as_echo "ac_cv_lib_$temp_lpjsip''_${pbxfuncname}" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -l$temp_lpjsip" >&5
+$as_echo_n "checking for ${pbxfuncname} in -l$temp_lpjsip... " >&6; }
 if eval \${$as_ac_Lib+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpjsip ${pbxlibdir} $PJPROJECT_LIBS $LIBS"
+LIBS="-l$temp_lpjsip ${pbxlibdir} $PJPROJECT_LIB $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -24446,12 +24496,12 @@
 
    # now check for the header.
    if test "${AST_PJ_TRANSACTION_GRP_LOCK_FOUND}" = "yes"; then
-      PJ_TRANSACTION_GRP_LOCK_LIB="${pbxlibdir} -lpjsip $PJPROJECT_LIBS"
+      PJ_TRANSACTION_GRP_LOCK_LIB="${pbxlibdir} -l$temp_lpjsip $PJPROJECT_LIB"
       # if --with-PJ_TRANSACTION_GRP_LOCK=DIR has been specified, use it.
       if test "x${PJ_TRANSACTION_GRP_LOCK_DIR}" != "x"; then
          PJ_TRANSACTION_GRP_LOCK_INCLUDE="-I${PJ_TRANSACTION_GRP_LOCK_DIR}/include"
       fi
-      PJ_TRANSACTION_GRP_LOCK_INCLUDE="${PJ_TRANSACTION_GRP_LOCK_INCLUDE} $PJPROJECT_CFLAGS"
+      PJ_TRANSACTION_GRP_LOCK_INCLUDE="${PJ_TRANSACTION_GRP_LOCK_INCLUDE} $PJPROJECT_INCLUDE"
       if test "xpjsip.h" = "x" ; then	# no header, assume found
          PJ_TRANSACTION_GRP_LOCK_HEADER_FOUND="1"
       else				# check for the header
@@ -24487,8 +24537,8 @@
 
 saved_cppflags="${CPPFLAGS}"
 saved_libs="${LIBS}"
-CPPFLAGS="${CPPFLAGS} ${PJPROJECT_CFLAGS}"
-LIBS="${LIBS} ${PJPROJECT_LIBS}"
+CPPFLAGS="${CPPFLAGS} ${PJPROJECT_INCLUDE}"
+LIBS="${LIBS} ${PJPROJECT_LIB}"
 
     if test "x${PBX_PJSIP_REPLACE_MEDIA_STREAM}" != "x1" -a "${USE_PJSIP_REPLACE_MEDIA_STREAM}" != "no"; then
         if test "x" != "x"; then
@@ -24553,15 +24603,15 @@
       AST_PJSIP_GET_DEST_INFO_FOUND=yes
    else
       ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
-      CFLAGS="${CFLAGS} $PJPROJECT_CFLAGS"
-      as_ac_Lib=`$as_echo "ac_cv_lib_pjsip_${pbxfuncname}" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpjsip" >&5
-$as_echo_n "checking for ${pbxfuncname} in -lpjsip... " >&6; }
+      CFLAGS="${CFLAGS} $PJPROJECT_INCLUDE"
+      as_ac_Lib=`$as_echo "ac_cv_lib_$temp_lpjsip''_${pbxfuncname}" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -l$temp_lpjsip" >&5
+$as_echo_n "checking for ${pbxfuncname} in -l$temp_lpjsip... " >&6; }
 if eval \${$as_ac_Lib+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpjsip ${pbxlibdir} $PJPROJECT_LIBS $LIBS"
+LIBS="-l$temp_lpjsip ${pbxlibdir} $PJPROJECT_LIB $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -24603,12 +24653,12 @@
 
    # now check for the header.
    if test "${AST_PJSIP_GET_DEST_INFO_FOUND}" = "yes"; then
-      PJSIP_GET_DEST_INFO_LIB="${pbxlibdir} -lpjsip $PJPROJECT_LIBS"
+      PJSIP_GET_DEST_INFO_LIB="${pbxlibdir} -l$temp_lpjsip $PJPROJECT_LIB"
       # if --with-PJSIP_GET_DEST_INFO=DIR has been specified, use it.
       if test "x${PJSIP_GET_DEST_INFO_DIR}" != "x"; then
          PJSIP_GET_DEST_INFO_INCLUDE="-I${PJSIP_GET_DEST_INFO_DIR}/include"
       fi
-      PJSIP_GET_DEST_INFO_INCLUDE="${PJSIP_GET_DEST_INFO_INCLUDE} $PJPROJECT_CFLAGS"
+      PJSIP_GET_DEST_INFO_INCLUDE="${PJSIP_GET_DEST_INFO_INCLUDE} $PJPROJECT_INCLUDE"
       if test "xpjsip.h" = "x" ; then	# no header, assume found
          PJSIP_GET_DEST_INFO_HEADER_FOUND="1"
       else				# check for the header
@@ -24657,15 +24707,15 @@
       AST_PJ_SSL_CERT_LOAD_FROM_FILES2_FOUND=yes
    else
       ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
-      CFLAGS="${CFLAGS} $PJPROJECT_CFLAGS"
-      as_ac_Lib=`$as_echo "ac_cv_lib_pj_${pbxfuncname}" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpj" >&5
-$as_echo_n "checking for ${pbxfuncname} in -lpj... " >&6; }
+      CFLAGS="${CFLAGS} $PJPROJECT_INCLUDE"
+      as_ac_Lib=`$as_echo "ac_cv_lib_$temp_lpj''_${pbxfuncname}" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -l$temp_lpj" >&5
+$as_echo_n "checking for ${pbxfuncname} in -l$temp_lpj... " >&6; }
 if eval \${$as_ac_Lib+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpj ${pbxlibdir} $PJPROJECT_LIBS $LIBS"
+LIBS="-l$temp_lpj ${pbxlibdir} $PJPROJECT_LIB $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -24707,12 +24757,12 @@
 
    # now check for the header.
    if test "${AST_PJ_SSL_CERT_LOAD_FROM_FILES2_FOUND}" = "yes"; then
-      PJ_SSL_CERT_LOAD_FROM_FILES2_LIB="${pbxlibdir} -lpj $PJPROJECT_LIBS"
+      PJ_SSL_CERT_LOAD_FROM_FILES2_LIB="${pbxlibdir} -l$temp_lpj $PJPROJECT_LIB"
       # if --with-PJ_SSL_CERT_LOAD_FROM_FILES2=DIR has been specified, use it.
       if test "x${PJ_SSL_CERT_LOAD_FROM_FILES2_DIR}" != "x"; then
          PJ_SSL_CERT_LOAD_FROM_FILES2_INCLUDE="-I${PJ_SSL_CERT_LOAD_FROM_FILES2_DIR}/include"
       fi
-      PJ_SSL_CERT_LOAD_FROM_FILES2_INCLUDE="${PJ_SSL_CERT_LOAD_FROM_FILES2_INCLUDE} $PJPROJECT_CFLAGS"
+      PJ_SSL_CERT_LOAD_FROM_FILES2_INCLUDE="${PJ_SSL_CERT_LOAD_FROM_FILES2_INCLUDE} $PJPROJECT_INCLUDE"
       if test "xpjlib.h" = "x" ; then	# no header, assume found
          PJ_SSL_CERT_LOAD_FROM_FILES2_HEADER_FOUND="1"
       else				# check for the header
@@ -24762,14 +24812,14 @@
    else
       ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
       CFLAGS="${CFLAGS} $PJPROJECT_CFLAGS"
-      as_ac_Lib=`$as_echo "ac_cv_lib_pjsip_${pbxfuncname}" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpjsip" >&5
-$as_echo_n "checking for ${pbxfuncname} in -lpjsip... " >&6; }
+      as_ac_Lib=`$as_echo "ac_cv_lib_$temp_lpjsip''_${pbxfuncname}" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -l$temp_lpjsip" >&5
+$as_echo_n "checking for ${pbxfuncname} in -l$temp_lpjsip... " >&6; }
 if eval \${$as_ac_Lib+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpjsip ${pbxlibdir} $PJPROJECT_LIBS $LIBS"
+LIBS="-l$temp_lpjsip ${pbxlibdir} $PJPROJECT_LIBS $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -24811,7 +24861,7 @@
 
    # now check for the header.
    if test "${AST_PJSIP_EXTERNAL_RESOLVER_FOUND}" = "yes"; then
-      PJSIP_EXTERNAL_RESOLVER_LIB="${pbxlibdir} -lpjsip $PJPROJECT_LIBS"
+      PJSIP_EXTERNAL_RESOLVER_LIB="${pbxlibdir} -l$temp_lpjsip $PJPROJECT_LIBS"
       # if --with-PJSIP_EXTERNAL_RESOLVER=DIR has been specified, use it.
       if test "x${PJSIP_EXTERNAL_RESOLVER_DIR}" != "x"; then
          PJSIP_EXTERNAL_RESOLVER_INCLUDE="-I${PJSIP_EXTERNAL_RESOLVER_DIR}/include"
@@ -24850,6 +24900,11 @@
 
 
 
+if test "$PJPROJECT_STATIC" = "yes" ; then
+   PJPROJECT_LIB=""
+fi
+fi
+
 
 if test "x${PBX_POPT}" != "x1" -a "${USE_POPT}" != "no"; then
    pbxlibdir=""
diff --git a/configure.ac b/configure.ac
index e7b7e57..a85e633 100644
--- a/configure.ac
+++ b/configure.ac
@@ -453,13 +453,36 @@
 AST_EXT_LIB_SETUP([OSPTK], [OSP Toolkit], [osptk])
 AST_EXT_LIB_SETUP([OSS], [Open Sound System], [oss])
 AST_EXT_LIB_SETUP([PGSQL], [PostgreSQL], [postgres])
+
 AST_EXT_LIB_SETUP([PJPROJECT], [PJPROJECT], [pjproject])
-AST_EXT_LIB_SETUP([POPT], [popt], [popt])
+PJPROJECT_STATIC=no
+AH_TEMPLATE(m4_bpatsubst([[HAVE_PJPROJECT_STATIC]], [(.*)]), [Define to 1 if you use the pjproject static libraries.])
+
+AC_ARG_ENABLE([static-pjproject],
+	[AS_HELP_STRING([--enable-static-pjproject],
+		[Link to static pjproject libraries])],
+	[case "${enableval}" in
+	      n|no) PJPROJECT_STATIC=no ;;
+	      *) PJPROJECT_STATIC=yes ;;
+	esac])
+AC_SUBST(PJPROJECT_STATIC)
+
+if test "$PJPROJECT_STATIC" = "yes" ; then
+   if test "${ac_mandatory_list#*PJPROJECT*}" = "$ac_mandatory_list" ; then
+      ac_mandatory_list="$ac_mandatory_list PJPROJECT"
+   fi
+   if test "x$PJPROJECT_DIR" = "x" ; then
+      PJPROJECT_DIR="${PWD}/third_party/pjproject/source"
+   fi
+fi
+
 AST_EXT_LIB_SETUP_OPTIONAL([PJ_TRANSACTION_GRP_LOCK], [PJSIP Transaction Group Lock Support], [PJPROJECT], [pjsip])
 AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_REPLACE_MEDIA_STREAM], [PJSIP Media Stream Replacement Support], [PJPROJECT], [pjsip])
 AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_GET_DEST_INFO], [pjsip_get_dest_info support], [PJPROJECT], [pjsip])
 AST_EXT_LIB_SETUP_OPTIONAL([PJ_SSL_CERT_LOAD_FROM_FILES2], [pj_ssl_cert_load_from_files2 support], [PJPROJECT], [pjsip])
 AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_EXTERNAL_RESOLVER], [PJSIP External Resolver Support], [PJPROJECT], [pjsip])
+
+AST_EXT_LIB_SETUP([POPT], [popt], [popt])
 AST_EXT_LIB_SETUP([PORTAUDIO], [PortAudio], [portaudio])
 AST_EXT_LIB_SETUP([PRI], [ISDN PRI], [pri])
 AST_EXT_LIB_SETUP_OPTIONAL([PRI_SETUP_ACK_INBAND], [ISDN PRI progress inband ie in SETUP ACK], [PRI], [pri])
@@ -2087,21 +2110,44 @@
    fi
 fi
 
-AST_PKG_CONFIG_CHECK([PJPROJECT], [libpjproject])
+if test "$USE_PJPROJECT" != "no" ; then
+if test "$PJPROJECT_STATIC" = "yes" ; then
+   if test -e "$PJPROJECT_DIR/build.mak" ; then
+      PJPROJECT_INCLUDE=`make -f /dev/null --eval="include $PJPROJECT_DIR/build.mak" --eval='$(info $(PJ_CFLAGS))' --eval='all:' -q -s`
+      PJPROJECT_LIB=`make -f /dev/null --eval="include $PJPROJECT_DIR/build.mak" --eval='$(info $(APP_LDFLAGS) $(APP_LDLIBS))' --eval='all:' -q -s`
+      PBX_PJPROJECT=1
+      AC_DEFINE([HAVE_PJPROJECT], 1, [Define if your system has the pjproject libraries.])
+      AC_DEFINE([HAVE_PJPROJECT_STATIC], 1, [Define if your system has the pjproject static libraries.])
+# dummy shared libraries because AST_EXT_LIB_CHECK needs something
+      temp_lpjsip="m"
+      temp_lpj="m"
+   else
+      PBX_PJPROJECT=0
+   fi
+else
+   AST_PKG_CONFIG_CHECK([PJPROJECT], [libpjproject])
+   temp_lpjsip="pjsip"
+   temp_lpj="pj"
+fi
 
-AST_EXT_LIB_CHECK([PJ_TRANSACTION_GRP_LOCK], [pjsip], [pjsip_tsx_create_uac2], [pjsip.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
+AST_EXT_LIB_CHECK([PJ_TRANSACTION_GRP_LOCK], [$temp_lpjsip], [pjsip_tsx_create_uac2], [pjsip.h], [$PJPROJECT_LIB], [$PJPROJECT_INCLUDE])
 
 saved_cppflags="${CPPFLAGS}"
 saved_libs="${LIBS}"
-CPPFLAGS="${CPPFLAGS} ${PJPROJECT_CFLAGS}"
-LIBS="${LIBS} ${PJPROJECT_LIBS}"
+CPPFLAGS="${CPPFLAGS} ${PJPROJECT_INCLUDE}"
+LIBS="${LIBS} ${PJPROJECT_LIB}"
 AST_C_COMPILE_CHECK([PJSIP_REPLACE_MEDIA_STREAM], [pjmedia_mod_offer_flag flag = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE], [pjmedia.h])
 LIBS="${saved_libs}"
 CPPFLAGS="${saved_cppflags}"
 
-AST_EXT_LIB_CHECK([PJSIP_GET_DEST_INFO], [pjsip], [pjsip_get_dest_info], [pjsip.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
-AST_EXT_LIB_CHECK([PJ_SSL_CERT_LOAD_FROM_FILES2], [pj], [pj_ssl_cert_load_from_files2], [pjlib.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
-AST_EXT_LIB_CHECK([PJSIP_EXTERNAL_RESOLVER], [pjsip], [pjsip_endpt_set_ext_resolver], [pjsip.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
+AST_EXT_LIB_CHECK([PJSIP_GET_DEST_INFO], [$temp_lpjsip], [pjsip_get_dest_info], [pjsip.h], [$PJPROJECT_LIB], [$PJPROJECT_INCLUDE])
+AST_EXT_LIB_CHECK([PJ_SSL_CERT_LOAD_FROM_FILES2], [$temp_lpj], [pj_ssl_cert_load_from_files2], [pjlib.h], [$PJPROJECT_LIB], [$PJPROJECT_INCLUDE])
+AST_EXT_LIB_CHECK([PJSIP_EXTERNAL_RESOLVER], [$temp_lpjsip], [pjsip_endpt_set_ext_resolver], [pjsip.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
+
+if test "$PJPROJECT_STATIC" = "yes" ; then
+   PJPROJECT_LIB=""
+fi
+fi
 
 AST_EXT_LIB_CHECK([POPT], [popt], [poptStrerror], [popt.h])
 
@@ -2265,11 +2311,11 @@
 if test "x$LIBCRYPT_LIB" != "x" ; then
     CRYPT_LIB="$LIBCRYPT_LIB"
     CRYPT_INCLUDE="$LIBCRYPT_INCLUDE"
-    AC_DEFINE([HAVE_CRYPT], [1], [Define to 1 if you have the `crypt' function.])
+    AC_DEFINE([HAVE_CRYPT], [1], [Define to 1 if you have the 'crypt' function.])
 elif test "x$SYSCRYPT" != "x" ; then
     CRYPT_LIB=""
     CRYPT_INCLUDE=""
-    AC_DEFINE([HAVE_CRYPT], [1], [Define to 1 if you have the `crypt' function.])
+    AC_DEFINE([HAVE_CRYPT], [1], [Define to 1 if you have the 'crypt' function.])
 fi
 
 AC_SUBST(CRYPT_LIB)
@@ -2277,7 +2323,7 @@
 
 # Find crypt_r support
 AC_CHECK_LIB([crypt], [crypt_r],
-    [AC_DEFINE([HAVE_CRYPT_R], [1], [Define to 1 if you have the `crypt_r' function.])])
+    [AC_DEFINE([HAVE_CRYPT_R], [1], [Define to 1 if you have the 'crypt_r' function.])])
 
 AST_EXT_LIB_CHECK([CRYPTO], [crypto], [AES_encrypt], [openssl/aes.h])
 
diff --git a/include/asterisk/_private.h b/include/asterisk/_private.h
index 7963f31..a4a4f1b 100644
--- a/include/asterisk/_private.h
+++ b/include/asterisk/_private.h
@@ -53,6 +53,7 @@
 int ast_cel_engine_init(void);		/*!< Provided by cel.c */
 int ast_cel_engine_reload(void);	/*!< Provided by cel.c */
 int ast_ssl_init(void);                 /*!< Provided by ssl.c */
+int ast_pj_init(void);                 /*!< Provided by libasteriskpj.c */
 int ast_test_init(void);            /*!< Provided by test.c */
 int ast_msg_init(void);             /*!< Provided by message.c */
 void ast_msg_shutdown(void);        /*!< Provided by message.c */
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index d86ba4a..cd8e6fe 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -154,13 +154,13 @@
 /* Define to 1 if you have the `cosl' function. */
 #undef HAVE_COSL
 
-/* Define to 1 if you have the `crypt' function. */
+/* Define to 1 if you have the 'crypt' function. */
 #undef HAVE_CRYPT
 
 /* Define to 1 if you have the OpenSSL Cryptography library. */
 #undef HAVE_CRYPTO
 
-/* Define to 1 if you have the `crypt_r' function. */
+/* Define to 1 if you have the 'crypt_r' function. */
 #undef HAVE_CRYPT_R
 
 /* Define to 1 if you have a functional curl library. */
@@ -580,6 +580,9 @@
 /* Define if your system has the PJPROJECT libraries. */
 #undef HAVE_PJPROJECT
 
+/* Define if your system has the pjproject static libraries. */
+#undef HAVE_PJPROJECT_STATIC
+
 /* Define to 1 if PJPROJECT has the PJSIP External Resolver Support feature.
    */
 #undef HAVE_PJSIP_EXTERNAL_RESOLVER
diff --git a/main/.gitignore b/main/.gitignore
index 3ff4656..cb90a5e 100644
--- a/main/.gitignore
+++ b/main/.gitignore
@@ -1,4 +1,6 @@
 asterisk
 libasteriskssl.so.1
 libasteriskssl.dylib
+libasteriskpj.so.2
+libasteriskpj.dylib
 version.c
diff --git a/main/Makefile b/main/Makefile
index b25fb45..fc40fdc 100644
--- a/main/Makefile
+++ b/main/Makefile
@@ -22,6 +22,9 @@
 ifeq ($(AST_ASTERISKSSL),yes)
 SRC:=$(filter-out libasteriskssl.c,$(SRC))
 endif
+ifeq ($(PJPROJECT_STATIC),yes)
+SRC:=$(filter-out libasteriskpj.c,$(SRC))
+endif
 OBJSFILTER=fskmodem_int.o fskmodem_float.o cygload.o buildinfo.o
 OBJS=$(filter-out $(OBJSFILTER),$(SRC:.c=.o))
 
@@ -244,12 +247,96 @@
 
 endif
 
+libasteriskpj.o: _ASTCFLAGS+=$(PJPROJECT_INCLUDE)
+
+ifeq ($(PJPROJECT_STATIC),yes)
+
+ASTPJ_SO_VERSION=2
+ASTPJ_LDLIBS=-L. -lasteriskpj
+
+.libasteriskpj.stripped_build.tmp: $(PJPROJECT_DIR)/build.mak
+	@sed -r -e "/prefix|export PJ_SHARED_LIBRARIES|MACHINE_NAME|OS_NAME|HOST_NAME|CC_NAME|CROSS_COMPILE|LINUX_POLL/d" $(PJPROJECT_DIR)/build.mak > .libasteriskpj.stripped_build.tmp
+
+-include .libasteriskpj.stripped_build.tmp
+
+PJPROJECT_LDLIBS := \
+-Wl,--whole-archive \
+$(PJSUA_LIB_LDLIB) \
+$(PJSIP_UA_LDLIB) \
+$(PJSIP_SIMPLE_LDLIB) \
+$(PJSIP_LDLIB) \
+$(PJNATH_LDLIB) \
+$(PJMEDIA_CODEC_LDLIB) \
+$(PJMEDIA_VIDEODEV_LDLIB) \
+$(PJMEDIA_AUDIODEV_LDLIB) \
+$(PJMEDIA_LDLIB) \
+$(PJLIB_UTIL_LDLIB) \
+$(PJLIB_LDLIB) \
+-Wl,--no-whole-archive \
+$(APP_THIRD_PARTY_LIBS) \
+$(APP_THIRD_PARTY_EXT)
+
+ifeq ($(findstring darwin,$(OSARCH)),) # not Darwin
+ASTPJ_LIB:=libasteriskpj.so
+
+.libasteriskpj.symbols.tmp: $(PJSIP_LDLIB) .libasteriskpj.stripped_build.tmp
+	@find $(PJPROJECT_DIR) -type f -name *.a -exec nm -Pog '{}' ';' | sed -n -r -e "s/.+: ([pP][jJ][^ ]+) .+/\1/gp" | sort -u > .libasteriskpj.symbols.tmp
+
+libasteriskpj.exports: .libasteriskpj.symbols.tmp
+	$(ECHO_PREFIX) echo "   [GENERATE] libasteriskpj.exports"
+ifeq ($(GNU_LD),1)
+	$(CMD_PREFIX) echo -e "{\n\tglobal:" > libasteriskpj.exports
+	$(CMD_PREFIX) sed -r -e "s/.*/\t\t$(LINKER_SYMBOL_PREFIX)&;/" .libasteriskpj.symbols.tmp >> libasteriskpj.exports
+	$(CMD_PREFIX) echo -e "\t\t$(LINKER_SYMBOL_PREFIX)ast_pj_init;\n" >> libasteriskpj.exports
+	$(CMD_PREFIX) echo -e "\tlocal:\n\t\t*;\n};" >> libasteriskpj.exports
+endif
+
+$(ASTPJ_LIB).$(ASTPJ_SO_VERSION): _ASTLDFLAGS+=-Wl,-soname=$(ASTPJ_LIB).$(ASTPJ_SO_VERSION) $(PJ_LDFLAGS)
+$(ASTPJ_LIB).$(ASTPJ_SO_VERSION): _ASTCFLAGS+=-fPIC -DAST_MODULE=\"asteriskpj\" $(PJ_CFLAGS)
+$(ASTPJ_LIB).$(ASTPJ_SO_VERSION): LIBS+=$(PJPROJECT_LDLIBS) -lssl -lcrypto -luuid -lm -lrt -lpthread
+ifeq ($(GNU_LD),1)
+    $(ASTPJ_LIB).$(ASTPJ_SO_VERSION): SO_SUPPRESS_SYMBOLS=-Wl,--version-script,libasteriskpj.exports,--warn-common
+endif
+$(ASTPJ_LIB).$(ASTPJ_SO_VERSION): SOLINK=$(DYLINK)
+
+# These rules are duplicated from $(ASTTOPDIR)/Makefile.rules because the library name
+# being built does not match the "%.so" pattern; there are also additional steps
+# required to build a proper shared library (as opposed to the 'loadable module'
+# type that are built by the standard rules)
+$(ASTPJ_LIB).$(ASTPJ_SO_VERSION): libasteriskpj.o | libasteriskpj.exports
+	$(ECHO_PREFIX) echo "   [LD] $^ -> $@"
+	$(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(CC_LDFLAGS_SO) $^ $(CC_LIBS)
+ifneq ($(LDCONFIG),)
+	$(LDCONFIG) $(LDCONFIG_FLAGS) .
+endif
+
+$(ASTPJ_LIB): $(ASTPJ_LIB).$(ASTPJ_SO_VERSION)
+	$(LN) -sf $< $@
+
+else # Darwin
+ASTSSL_LIB:=libasteriskpj.dylib
+
+# -install_name allows library to be found if installed somewhere other than
+# /lib or /usr/lib
+$(ASTPJ_LIB): _ASTLDFLAGS+=-dynamiclib -install_name $(ASTLIBDIR)/$(ASTPJ_LIB) $(PJ_LDFLAGS)
+$(ASTPJ_LIB): _ASTCFLAGS+=-fPIC -DAST_MODULE=\"asteriskpj\" $(PJ_CFLAGS)
+$(ASTPJ_LIB): LIBS+=$(PJPROJECT_LIBS)  -lssl -lcrypto -luuid -lm -lrt -lpthread
+$(ASTPJ_LIB): SOLINK=$(DYLINK)
+
+# Special rules for building a shared library (not a dynamically loadable module)
+$(ASTPJ_LIB): libasteriskpj.o
+	$(ECHO_PREFIX) echo "   [LD] $^ -> $@"
+	$(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(CC_LDFLAGS_SO) $^ $(CC_LIBS)
+endif
+
+endif
+
 tcptls.o: _ASTCFLAGS+=$(OPENSSL_INCLUDE)
 
-$(MAIN_TGT): $(OBJS) $(ASTSSL_LIB) $(LIBEDIT_OBJ) $(AST_EMBED_LDSCRIPTS)
+$(MAIN_TGT): $(OBJS) $(ASTSSL_LIB) $(ASTPJ_LIB) $(LIBEDIT_OBJ) $(AST_EMBED_LDSCRIPTS)
 	@$(CC) -c -o buildinfo.o $(_ASTCFLAGS) buildinfo.c $(ASTCFLAGS)
 	$(ECHO_PREFIX) echo "   [LD] $(OBJS) $(LIBEDIT_OBJ) $(AST_EMBED_LDSCRIPTS) -> $@"
-	$(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(OBJS) $(ASTSSL_LDLIBS) $(LIBEDIT_OBJ) $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(GMIMELDFLAGS) $(LIBEDIT_LIB)
+	$(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(OBJS) $(ASTSSL_LDLIBS) $(ASTPJ_LDLIBS) $(LIBEDIT_OBJ) $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(GMIMELDFLAGS) $(LIBEDIT_LIB)
 
 ifeq ($(GNU_LD),1)
 $(MAIN_TGT): asterisk.exports
@@ -266,16 +353,29 @@
 else # Darwin
 	$(INSTALL) -m 755 $(ASTSSL_LIB) "$(DESTDIR)$(ASTLIBDIR)/"
 endif
+endif
+ifeq ($(PJPROJECT_STATIC),yes)
+ifeq ($(findstring darwin,$(OSARCH)),) # not Darwin
+	$(INSTALL) -m 755 $(ASTPJ_LIB).$(ASTPJ_SO_VERSION) "$(DESTDIR)$(ASTLIBDIR)/"
+	$(LN) -sf $(ASTPJ_LIB).$(ASTPJ_SO_VERSION) "$(DESTDIR)$(ASTLIBDIR)/$(ASTPJ_LIB)"
+else # Darwin
+	$(INSTALL) -m 755 $(ASTPJ_LIB) "$(DESTDIR)$(ASTLIBDIR)/"
+endif
+endif
 ifneq ($(LDCONFIG),)
 	$(LDCONFIG) $(LDCONFIG_FLAGS) "$(DESTDIR)$(ASTLIBDIR)/"
-endif
 endif
 	$(LN) -sf asterisk "$(DESTDIR)$(ASTSBINDIR)/rasterisk"
 
 binuninstall:
 	rm -f "$(DESTDIR)$(ASTSBINDIR)/$(MAIN_TGT)"
 	rm -f "$(DESTDIR)$(ASTSBINDIR)/rasterisk"
+ifneq ($(ASTSSL_LIB).$(ASTSSL_SO_VERSION),.)
 	rm -f "$(DESTDIR)$(ASTLIBDIR)/$(ASTSSL_LIB).$(ASTSSL_SO_VERSION)"
+endif
+ifneq ($(ASTPJ_LIB).$(ASTPJ_SO_VERSION),.)
+	rm -f "$(DESTDIR)$(ASTLIBDIR)/$(ASTPJ_LIB).$(ASTPJ_SO_VERSION)"
+endif
 ifneq ($(LDCONFIG),)
 	$(LDCONFIG) $(LDCONFIG_FLAGS) "$(DESTDIR)$(ASTLIBDIR)/"
 endif
@@ -285,7 +385,12 @@
 ifeq ($(AST_ASTERISKSSL),yes)
 	rm -f $(ASTSSL_LIB) $(ASTSSL_LIB).*
 endif
-	rm -f asterisk.exports libasteriskssl.exports
+	rm -f libasteriskpj.o
+ifeq ($(PJPROJECT_STATIC),yes)
+	rm -f $(ASTPJ_LIB) $(ASTPJ_LIB).*
+endif
+	rm -f asterisk.exports libasteriskssl.exports libasteriskpj.exports
 	@if [ -f editline/Makefile ]; then $(MAKE) -C editline distclean ; fi
 	@$(MAKE) -C stdtime clean
 	rm -f libresample/src/*.o
+	rm -f *.tmp
diff --git a/main/asterisk.c b/main/asterisk.c
index ca560cd..da804e1 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -4478,6 +4478,11 @@
 		exit(1);
 	}
 
+	if (ast_pj_init()) {
+		printf("Failed: ast_pj_init\n%s", term_quit());
+		exit(1);
+	}
+
 	if (app_init()) {
 		printf("App core initialization failed.\n%s", term_quit());
 		exit(1);
diff --git a/main/libasteriskpj.c b/main/libasteriskpj.c
new file mode 100644
index 0000000..1a257c0
--- /dev/null
+++ b/main/libasteriskpj.c
@@ -0,0 +1,52 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2009-2012, Digium, Inc.
+ * Copyright (C) 2015, Fairview 5 Engineering, LLC
+ *
+ * Russell Bryant <russell at digium.com>
+ * George Joseph <george.joseph at fairview5.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Loader stub for static pjproject libraries
+ *
+ * \author George Joseph <george.joseph at fairview5.com>
+ */
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_REGISTER_FILE()
+
+#ifdef HAVE_PJPROJECT
+#include <pjlib.h>
+#endif
+
+#include "asterisk/_private.h" /* ast_pj_init() */
+
+/*!
+ * \internal
+ * \brief Initialize static pjproject implementation
+ */
+int ast_pj_init(void)
+{
+#ifdef HAVE_PJPROJECT_STATIC
+	pj_init();
+#endif
+	return 0;
+}
diff --git a/makeopts.in b/makeopts.in
index f606ace..8468057 100644
--- a/makeopts.in
+++ b/makeopts.in
@@ -229,8 +229,10 @@
 PGSQL_INCLUDE=@PGSQL_INCLUDE@
 PGSQL_LIB=@PGSQL_LIB@
 
+PJPROJECT_STATIC=@PJPROJECT_STATIC@
 PJPROJECT_INCLUDE=@PJPROJECT_INCLUDE@
 PJPROJECT_LIB=@PJPROJECT_LIB@
+PJPROJECT_DIR=@PJPROJECT_DIR@
 
 POPT_INCLUDE=@POPT_INCLUDE@
 POPT_LIB=@POPT_LIB@
diff --git a/third_party/Makefile b/third_party/Makefile
new file mode 100644
index 0000000..7d4d650
--- /dev/null
+++ b/third_party/Makefile
@@ -0,0 +1,8 @@
+
+SUBDIRS := $(wildcard */.)
+
+.PHONY : all $(SUBDIRS)
+all : $(SUBDIRS)
+
+$(SUBDIRS) :
+	$(MAKE) -C $@
diff --git a/third_party/pjproject/.gitignore b/third_party/pjproject/.gitignore
new file mode 100644
index 0000000..f4046d1
--- /dev/null
+++ b/third_party/pjproject/.gitignore
@@ -0,0 +1,2 @@
+source/
+**.bz2
diff --git a/third_party/pjproject/Makefile b/third_party/pjproject/Makefile
new file mode 100644
index 0000000..22e7e58
--- /dev/null
+++ b/third_party/pjproject/Makefile
@@ -0,0 +1,36 @@
+#
+# This Makefile can use some work!!
+#
+include ../versions.mak
+
+include makeopts
+
+.PHONY: all clean distclean compile configure
+
+all: compile
+
+pjproject-$(PJPROJECT_VERSION).tar.bz2 : ../versions.mak
+	@curl -L -R http://www.pjsip.org/release/$(PJPROJECT_VERSION)/pjproject-$(PJPROJECT_VERSION).tar.bz2 -o pjproject-$(PJPROJECT_VERSION).tar.bz2
+
+source/version.mak: pjproject-$(PJPROJECT_VERSION).tar.bz2
+	@echo Unpacking $<
+	@-mkdir source &>/dev/null
+	@tar --strip-components=1 -C source -xjf pjproject-$(PJPROJECT_VERSION).tar.bz2
+	@./apply_patches ./patches ./source
+	@touch source/version.mak
+
+configure source/build.mak: source/version.mak makeopts
+	@echo Configuring with $(CONFIG_OPTS) CFLAGS="$(PJPROJECT_CFLAGS)"
+	@(cd source ; ./aconfigure -q $(CONFIG_OPTS) CFLAGS="$(PJPROJECT_CFLAGS)")
+	@echo "Making dependencies"
+	@(cd source ; make dep > /dev/null)
+
+compile: source/build.mak
+	@echo Compiling
+	@$(MAKE) -C source
+
+clean:
+	@$(MAKE) -C source clean
+
+distclean:
+	- at rm -rf source
diff --git a/third_party/pjproject/apply_patches b/third_party/pjproject/apply_patches
new file mode 100755
index 0000000..6bf9617
--- /dev/null
+++ b/third_party/pjproject/apply_patches
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+patchdir=${1:?You must supply a patches directory}
+sourcedir=${2?:You must supply a source directory}
+
+patchdir=`readlink -f $patchdir`
+sourcedir=`readlink -f $sourcedir`
+
+if [ ! -d "$patchdir" ] ; then
+	echo "$patchdir is not a directory"
+	exit 1
+fi
+
+if [ ! -d "$sourcedir" ] ; then
+	echo "$sourcedir is not a directory"
+	exit 1
+fi
+
+if [ ! "$(ls -A $patchdir/*.patch 2>/dev/null)" ] ; then
+	echo "No patches in $patchdir"
+	exit 0
+fi
+
+for patchfile in $patchdir/*.patch ; do
+	patch -d $sourcedir -p1 -s -r- -f -N --dry-run -i "$patchfile" || (echo "Patchfile $(basename $patchfile) failed to apply" ; exit 1) || exit 1
+done
+
+for patchfile in "$patchdir"/*.patch ; do
+	echo "Applying patch $(basename $patchfile)"
+	patch -d "$sourcedir" -p1 -s -i "$patchfile" || exit 1
+done
+
+exit 0
+
diff --git a/third_party/pjproject/patches/0000-config_site.patch b/third_party/pjproject/patches/0000-config_site.patch
new file mode 100644
index 0000000..4360ab9
--- /dev/null
+++ b/third_party/pjproject/patches/0000-config_site.patch
@@ -0,0 +1,6 @@
+--- a/pjlib/include/pj/config_site.h	1969-12-31 17:00:00.000000000 -0700
++++ b/pjlib/include/pj/config_site.h	2016-02-04 16:17:37.252380183 -0700
+@@ -0,0 +1,3 @@
++#define PJ_HAS_IPV6 1
++#define NDEBUG 1
++
diff --git a/third_party/pjproject/patches/0001-2.4.5-fix-for-tls-async-ops.patch b/third_party/pjproject/patches/0001-2.4.5-fix-for-tls-async-ops.patch
new file mode 100644
index 0000000..33fc8ea
--- /dev/null
+++ b/third_party/pjproject/patches/0001-2.4.5-fix-for-tls-async-ops.patch
@@ -0,0 +1,224 @@
+diff --git a/pjlib/include/pj/ssl_sock.h b/pjlib/include/pj/ssl_sock.h
+index 1682bda..a69af32 100644
+--- a/pjlib/include/pj/ssl_sock.h
++++ b/pjlib/include/pj/ssl_sock.h
+@@ -864,6 +864,18 @@ PJ_DECL(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param);
+ 
+ 
+ /**
++ * Duplicate pj_ssl_sock_param.
++ *
++ * @param pool	Pool to allocate memory.
++ * @param dst	Destination parameter.
++ * @param src	Source parameter.
++ */
++PJ_DECL(void) pj_ssl_sock_param_copy(pj_pool_t *pool, 
++				     pj_ssl_sock_param *dst,
++				     const pj_ssl_sock_param *src);
++
++
++/**
+  * Create secure socket instance.
+  *
+  * @param pool		The pool for allocating secure socket instance.
+@@ -1115,6 +1127,30 @@ PJ_DECL(pj_status_t) pj_ssl_sock_start_accept(pj_ssl_sock_t *ssock,
+ 
+ 
+ /**
++ * Same as #pj_ssl_sock_start_accept(), but application can provide
++ * a secure socket parameter, which will be used to create a new secure
++ * socket reported in \a on_accept_complete() callback when there is
++ * an incoming connection.
++ *
++ * @param ssock		The secure socket.
++ * @param pool		Pool used to allocate some internal data for the
++ *			operation.
++ * @param localaddr	Local address to bind on.
++ * @param addr_len	Length of buffer containing local address.
++ * @param newsock_param	Secure socket parameter for new accepted sockets.
++ *
++ * @return		PJ_SUCCESS if the operation has been successful,
++ *			or the appropriate error code on failure.
++ */
++PJ_DECL(pj_status_t)
++pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
++			  pj_pool_t *pool,
++			  const pj_sockaddr_t *local_addr,
++			  int addr_len,
++			  const pj_ssl_sock_param *newsock_param);
++
++
++/**
+  * Starts asynchronous socket connect() operation and SSL/TLS handshaking 
+  * for this socket. Once the connection is done (either successfully or not),
+  * the \a on_connect_complete() callback will be called.
+diff --git a/pjlib/src/pj/ssl_sock_common.c b/pjlib/src/pj/ssl_sock_common.c
+index 913efee..717ab1d 100644
+--- a/pjlib/src/pj/ssl_sock_common.c
++++ b/pjlib/src/pj/ssl_sock_common.c
+@@ -19,6 +19,7 @@
+ #include <pj/ssl_sock.h>
+ #include <pj/assert.h>
+ #include <pj/errno.h>
++#include <pj/pool.h>
+ #include <pj/string.h>
+ 
+ /*
+@@ -48,6 +49,31 @@ PJ_DEF(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param)
+ }
+ 
+ 
++/*
++ * Duplicate SSL socket parameter.
++ */
++PJ_DEF(void) pj_ssl_sock_param_copy( pj_pool_t *pool, 
++				     pj_ssl_sock_param *dst,
++				     const pj_ssl_sock_param *src)
++{
++    /* Init secure socket param */
++    pj_memcpy(dst, src, sizeof(*dst));
++    if (src->ciphers_num > 0) {
++	unsigned i;
++	dst->ciphers = (pj_ssl_cipher*)
++			pj_pool_calloc(pool, src->ciphers_num, 
++				       sizeof(pj_ssl_cipher));
++	for (i = 0; i < src->ciphers_num; ++i)
++	    dst->ciphers[i] = src->ciphers[i];
++    }
++
++    if (src->server_name.slen) {
++        /* Server name must be null-terminated */
++        pj_strdup_with_null(pool, &dst->server_name, &src->server_name);
++    }
++}
++
++
+ PJ_DEF(pj_status_t) pj_ssl_cert_get_verify_status_strings(
+ 						pj_uint32_t verify_status, 
+ 						const char *error_strings[],
+diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
+index 40a5a1e..6a701b7 100644
+--- a/pjlib/src/pj/ssl_sock_ossl.c
++++ b/pjlib/src/pj/ssl_sock_ossl.c
+@@ -141,6 +141,7 @@ struct pj_ssl_sock_t
+     pj_pool_t		 *pool;
+     pj_ssl_sock_t	 *parent;
+     pj_ssl_sock_param	  param;
++    pj_ssl_sock_param	  newsock_param;
+     pj_ssl_cert_t	 *cert;
+     
+     pj_ssl_cert_info	  local_cert_info;
+@@ -1757,11 +1758,9 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
+     unsigned i;
+     pj_status_t status;
+ 
+-    PJ_UNUSED_ARG(src_addr_len);
+-
+     /* Create new SSL socket instance */
+-    status = pj_ssl_sock_create(ssock_parent->pool, &ssock_parent->param,
+-				&ssock);
++    status = pj_ssl_sock_create(ssock_parent->pool,
++    				&ssock_parent->newsock_param, &ssock);
+     if (status != PJ_SUCCESS)
+ 	goto on_return;
+ 
+@@ -2183,20 +2182,8 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
+ 	return status;
+ 
+     /* Init secure socket param */
+-    ssock->param = *param;
++    pj_ssl_sock_param_copy(pool, &ssock->param, param);
+     ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3;
+-    if (param->ciphers_num > 0) {
+-	unsigned i;
+-	ssock->param.ciphers = (pj_ssl_cipher*)
+-			       pj_pool_calloc(pool, param->ciphers_num, 
+-					      sizeof(pj_ssl_cipher));
+-	for (i = 0; i < param->ciphers_num; ++i)
+-	    ssock->param.ciphers[i] = param->ciphers[i];
+-    }
+-
+-    /* Server name must be null-terminated */
+-    pj_strdup_with_null(pool, &ssock->param.server_name, 
+-			&param->server_name);
+ 
+     /* Finally */
+     *p_ssock = ssock;
+@@ -2617,12 +2604,36 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock,
+ 					      const pj_sockaddr_t *localaddr,
+ 					      int addr_len)
+ {
++    return pj_ssl_sock_start_accept2(ssock, pool, localaddr, addr_len,
++    				     &ssock->param);
++}
++
++
++/**
++ * Same as #pj_ssl_sock_start_accept(), but application provides parameter
++ * for new accepted secure sockets.
++ */
++PJ_DEF(pj_status_t)
++pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
++			  pj_pool_t *pool,
++			  const pj_sockaddr_t *localaddr,
++			  int addr_len,
++			  const pj_ssl_sock_param *newsock_param)
++{
+     pj_activesock_cb asock_cb;
+     pj_activesock_cfg asock_cfg;
+     pj_status_t status;
+ 
+     PJ_ASSERT_RETURN(ssock && pool && localaddr && addr_len, PJ_EINVAL);
+ 
++    /* Verify new socket parameters */
++    if (newsock_param->grp_lock != ssock->param.grp_lock ||
++        newsock_param->sock_af != ssock->param.sock_af ||
++        newsock_param->sock_type != ssock->param.sock_type)
++    {
++        return PJ_EINVAL;
++    }
++
+     /* Create socket */
+     status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0, 
+ 			    &ssock->sock);
+@@ -2691,6 +2702,7 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock,
+ 	goto on_error;
+ 
+     /* Start accepting */
++    pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param);
+     status = pj_activesock_start_accept(ssock->asock, pool);
+     if (status != PJ_SUCCESS)
+ 	goto on_error;
+diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
+index a9e95fb..91d99a7 100644
+--- a/pjsip/src/pjsip/sip_transport_tls.c
++++ b/pjsip/src/pjsip/sip_transport_tls.c
+@@ -314,7 +314,7 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
+     int af, sip_ssl_method;
+     pj_uint32_t sip_ssl_proto;
+     struct tls_listener *listener;
+-    pj_ssl_sock_param ssock_param;
++    pj_ssl_sock_param ssock_param, newsock_param;
+     pj_sockaddr *listener_addr;
+     pj_bool_t has_listener;
+     pj_status_t status;
+@@ -473,9 +473,14 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
+      */
+     has_listener = PJ_FALSE;
+ 
+-    status = pj_ssl_sock_start_accept(listener->ssock, pool, 
++    pj_memcpy(&newsock_param, &ssock_param, sizeof(newsock_param));
++    newsock_param.async_cnt = 1;
++    newsock_param.cb.on_data_read = &on_data_read;
++    newsock_param.cb.on_data_sent = &on_data_sent;
++    status = pj_ssl_sock_start_accept2(listener->ssock, pool, 
+ 			  (pj_sockaddr_t*)listener_addr, 
+-			  pj_sockaddr_get_len((pj_sockaddr_t*)listener_addr));
++			  pj_sockaddr_get_len((pj_sockaddr_t*)listener_addr),
++			  &newsock_param);
+     if (status == PJ_SUCCESS || status == PJ_EPENDING) {
+ 	pj_ssl_sock_info info;
+ 	has_listener = PJ_TRUE;
+-- 
+cgit v0.11.2
+
diff --git a/third_party/pjproject/patches/0002-no_third_party.patch b/third_party/pjproject/patches/0002-no_third_party.patch
new file mode 100644
index 0000000..b671909
--- /dev/null
+++ b/third_party/pjproject/patches/0002-no_third_party.patch
@@ -0,0 +1,17 @@
+--- pjproject-2.2/third_party/build/os-linux.mak	2014-01-02 22:44:05.000000000 -0500
++++ pjproject-2.2-no_third_party/third_party/build/os-linux.mak	2014-02-28 10:56:33.998682746 -0500
+@@ -1,9 +1,9 @@
+-DIRS += gsm
++#DIRS += gsm
+-DIRS += ilbc
+-DIRS += speex
+-DIRS += portaudio
+-DIRS += g7221
+-DIRS += srtp
+-DIRS += resample
++#DIRS += ilbc
++#DIRS += speex
++#DIRS += portaudio
++#DIRS += g7221
++#DIRS += srtp
++#DIRS += resample
diff --git a/third_party/versions.mak b/third_party/versions.mak
new file mode 100644
index 0000000..7b8b59c
--- /dev/null
+++ b/third_party/versions.mak
@@ -0,0 +1,2 @@
+
+PJPROJECT_VERSION = 2.4.5

-- 
To view, visit https://gerrit.asterisk.org/2200
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia7a60c28c2e9ba9537c5570f933c1ebcb20a3103
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: George Joseph <george.joseph at fairview5.com>



More information about the asterisk-code-review mailing list