Merge "build-system: Allow building with static pjproject"
authorzuul <zuul@gerrit.asterisk.org>
Thu, 3 Mar 2016 17:30:41 +0000 (11:30 -0600)
committerGerrit Code Review <gerrit2@gerrit.digium.api>
Thu, 3 Mar 2016 17:30:42 +0000 (11:30 -0600)
25 files changed:
CHANGES
Makefile
configure
configure.ac
include/asterisk/_private.h
include/asterisk/autoconfig.h.in
main/.gitignore
main/Makefile
main/asterisk.c
main/libasteriskpj.c [new file with mode: 0644]
makeopts.in
third-party/Makefile [new file with mode: 0644]
third-party/Makefile.rules [new file with mode: 0644]
third-party/pjproject/.gitignore [new file with mode: 0644]
third-party/pjproject/Makefile [new file with mode: 0644]
third-party/pjproject/Makefile.rules [new file with mode: 0644]
third-party/pjproject/apply_patches [new file with mode: 0755]
third-party/pjproject/configure.m4 [new file with mode: 0644]
third-party/pjproject/patches/0001-2.4.5-fix-for-tls-async-ops.patch [new file with mode: 0644]
third-party/pjproject/patches/0001-Bump-tcp-tls-and-transaction-log-levels-from-1-to-3.patch [new file with mode: 0644]
third-party/pjproject/patches/0001-ioqueue-Enable-epoll-in-aconfigure.ac.patch [new file with mode: 0644]
third-party/pjproject/patches/0001-sip_transport-Search-for-transport-even-if-listener-.patch [new file with mode: 0644]
third-party/pjproject/patches/config_site.h [new file with mode: 0644]
third-party/pjproject/patches/user.mak [new file with mode: 0644]
third-party/versions.mak [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 78a464f..7c04285 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -221,6 +221,24 @@ res_pjsip_config_wizard
    will export all the pjsip objects it created to the console or a file
    suitable for reuse in a pjsip.conf file.
 
+Build System
+------------------
+ * To help insure that Asterisk is compiled and run with the same known
+   version of pjproject, a new option (--with-pjproject-bundled) has been
+   added to ./configure.  When specified, the version of pjproject specified
+   in third-party/versions.mak will be downloaded and configured.  When you
+   make Asterisk, the build process will also automatically build pjproject
+   and Asterisk will be statically linked to it.  Once a particular version
+   of pjproject is configured and built, it won't be configured or built
+   again unless you run a 'make distclean'.
+
+   To facilitate testing, when 'make install' is run, the pjsua and pjsystest
+   utilities and the pjproject python bindings will be installed in
+   ASTDATADIR/third-party/pjproject.
+
+   The default behavior remains building with the shared pjproject
+   installation, if any.
+
 app_confbridge
 ------------------
  * Added CONFBRIDGE_INFO(muted,) for querying the muted conference state.
index a07a329..7528f83 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -249,7 +249,7 @@ endif
 
 _ASTCFLAGS+=$(OPTIONS)
 
-MOD_SUBDIRS:=channels pbx apps codecs formats cdr cel bridges funcs tests main res addons $(LOCAL_MOD_SUBDIRS)
+MOD_SUBDIRS:=third-party channels pbx apps codecs formats cdr cel bridges funcs tests main res addons $(LOCAL_MOD_SUBDIRS)
 OTHER_SUBDIRS:=utils agi contrib
 SUBDIRS:=$(OTHER_SUBDIRS) $(MOD_SUBDIRS)
 SUBDIRS_INSTALL:=$(SUBDIRS:%=%-install)
@@ -377,8 +377,10 @@ ifeq ($(findstring $(OSARCH), mingw32 cygwin ),)
     # directories containing them must be completed before the main Asterisk
     # binary can be built.
     # If MENUSELECT_EMBED is empty, we don't need this and allow 'main' to be
-    # be built without building all dependencies first.
+    # be built with only third_party first.
 main: $(filter-out main,$(MOD_SUBDIRS))
+  else
+main: third-party
   endif
 else
     # Windows: we need to build main (i.e. the asterisk dll) first,
@@ -568,7 +570,8 @@ INSTALLDIRS="$(ASTLIBDIR)" "$(ASTMODDIR)" "$(ASTSBINDIR)" "$(ASTETCDIR)" "$(ASTV
        "$(ASTDATADIR)/documentation/thirdparty" "$(ASTDATADIR)/firmware" \
        "$(ASTDATADIR)/firmware/iax" "$(ASTDATADIR)/images" "$(ASTDATADIR)/keys" \
        "$(ASTDATADIR)/phoneprov" "$(ASTDATADIR)/rest-api" "$(ASTDATADIR)/static-http" \
-       "$(ASTDATADIR)/sounds" "$(ASTDATADIR)/moh" "$(ASTMANDIR)/man8" "$(AGI_DIR)" "$(ASTDBDIR)"
+       "$(ASTDATADIR)/sounds" "$(ASTDATADIR)/moh" "$(ASTMANDIR)/man8" "$(AGI_DIR)" "$(ASTDBDIR)" \
+       "$(ASTDATADIR)/third-party"
 
 installdirs:
        @for i in $(INSTALLDIRS); do \
@@ -611,7 +614,7 @@ ifeq ($(HAVE_DAHDI),1)
 endif
 
 $(SUBDIRS_INSTALL):
-       +@DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" $(SUBMAKE) -C $(@:-install=) install
+       +@DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" ASTDATADIR="$(ASTDATADIR)" $(SUBMAKE) -C $(@:-install=) install
 
 NEWMODS:=$(foreach d,$(MOD_SUBDIRS),$(notdir $(wildcard $(d)/*.so)))
 OLDMODS=$(filter-out $(NEWMODS) $(notdir $(DESTDIR)$(ASTMODDIR)),$(notdir $(wildcard $(DESTDIR)$(ASTMODDIR)/*.so)))
@@ -889,7 +892,7 @@ sounds:
        @[ -f "$(DESTDIR)$(ASTDBDIR)/astdb.sqlite3" ] || [ ! -f "$(DESTDIR)$(ASTDBDIR)/astdb" ] || [ ! -f menuselect.makeopts ] || grep -q MENUSELECT_UTILS=.*astdb2sqlite3 menuselect.makeopts || (sed -i.orig -e's/MENUSELECT_UTILS=\(.*\)/MENUSELECT_UTILS=\1 astdb2sqlite3/' menuselect.makeopts && echo "Updating menuselect.makeopts to include astdb2sqlite3" && echo "Original version backed up to menuselect.makeopts.orig")
 
 $(SUBDIRS_UNINSTALL):
-       +@$(SUBMAKE) -C $(@:-uninstall=) uninstall
+       +@DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" ASTDATADIR="$(ASTDATADIR)" $(SUBMAKE) -C $(@:-uninstall=) uninstall
 
 main-binuninstall:
        +@DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" ASTLIBDIR="$(ASTLIBDIR)" $(SUBMAKE) -C main binuninstall
index 2c0f99d..3967cec 100755 (executable)
--- a/configure
+++ b/configure
@@ -915,6 +915,10 @@ PBX_PORTAUDIO
 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
@@ -939,10 +943,7 @@ PBX_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
 PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_DIR
 PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_INCLUDE
 PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_LIB
-PBX_POPT
-POPT_DIR
-POPT_INCLUDE
-POPT_LIB
+PJPROJECT_BUNDLED
 PBX_PJPROJECT
 PJPROJECT_DIR
 PJPROJECT_INCLUDE
@@ -1362,6 +1363,7 @@ with_osptk
 with_oss
 with_postgres
 with_pjproject
+with_pjproject_bundled
 with_popt
 with_portaudio
 with_pri
@@ -2101,6 +2103,8 @@ Optional Packages:
   --with-oss=PATH         use Open Sound System files in PATH
   --with-postgres=PATH    use PostgreSQL files in PATH
   --with-pjproject=PATH   use PJPROJECT files in PATH
+  --with-pjproject-bundled
+                          Use bundled pjproject libraries
   --with-popt=PATH        use popt files in PATH
   --with-portaudio=PATH   use PortAudio files in PATH
   --with-pri=PATH         use ISDN PRI files in PATH
@@ -10415,6 +10419,7 @@ fi
 
 
 
+
     PJPROJECT_DESCRIP="PJPROJECT"
     PJPROJECT_OPTION="pjproject"
     PBX_PJPROJECT=0
 
 
 
+PJPROJECT_BUNDLED=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"
-       ;;
-       esac
 
+# Check whether --with-pjproject-bundled was given.
+if test "${with_pjproject_bundled+set}" = set; then :
+  withval=$with_pjproject_bundled; case "${enableval}" in
+             n|no) PJPROJECT_BUNDLED=no ;;
+             *) PJPROJECT_BUNDLED=yes ;;
+       esac
 fi
 
 
 
+if test "$PJPROJECT_BUNDLED" = "yes" -a "${ac_mandatory_list#*PJPROJECT*}" != "$ac_mandatory_list" ; then
+   as_fn_error $? "--with-pjproject and --with-pjproject-bundled can't both be specified" "$LINENO" 5
+fi
 
-
-
+if test "$PJPROJECT_BUNDLED" = "yes" ; then
+   ac_mandatory_list="$ac_mandatory_list PJPROJECT"
+   PJPROJECT_DIR="${ac_top_build_prefix}third-party/pjproject"
+fi
 
 
 PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_DESCRIP="PJSIP Dialog Create UAS with Incremented Lock"
@@ -10551,6 +10547,39 @@ 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
+
+
+
+
+
+
+
+
     PORTAUDIO_DESCRIP="PortAudio"
     PORTAUDIO_OPTION="portaudio"
     PBX_PORTAUDIO=0
@@ -24441,6 +24470,244 @@ $as_echo "$as_me: *** including --without-postgres" >&6;}
    fi
 fi
 
+if test "$USE_PJPROJECT" != "no" ; then
+   if test "$PJPROJECT_BUNDLED" = "yes" ; then
+
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for embedded pjproject (may have to download)" >&5
+$as_echo_n "checking for embedded pjproject (may have to download)... " >&6; }
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: configuring" >&5
+$as_echo "configuring" >&6; }
+       make --quiet --no-print-directory -C $PJPROJECT_DIR configure
+       if test $? -ne 0 ; then
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+               { $as_echo "$as_me:${as_lineno-$LINENO}: Unable to configure $PJPROJECT_DIR" >&5
+$as_echo "$as_me: Unable to configure $PJPROJECT_DIR" >&6;}
+               as_fn_error $? "Run \"make -C $PJPROJECT_DIR NOISY_BUILD=yes configure\" to see error details." "$LINENO" 5
+       fi
+
+       PJPROJECT_INCLUDE=$(make --quiet --no-print-directory -C $PJPROJECT_DIR echo_cflags)
+       PJPROJECT_CFLAGS="$PJPROJECT_INCLUDE"
+       PBX_PJPROJECT=1
+       PJPROJECT_BUNDLED=yes
+
+$as_echo "#define HAVE_PJPROJECT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJPROJECT_BUNDLED 1" >>confdefs.h
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for embedded pjproject" >&5
+$as_echo_n "checking for embedded pjproject... " >&6; }
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+       PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_INCLUDE="$PJPROJECT_INCLUDE"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pjsip_dlg_create_uas_and_inc_lock declared in pjsip.h" >&5
+$as_echo_n "checking for pjsip_dlg_create_uas_and_inc_lock declared in pjsip.h... " >&6; }
+
+       saved_cpp="$CPPFLAGS"
+       CPPFLAGS="$PJPROJECT_INCLUDE"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pjsip.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pjsip_dlg_create_uas_and_inc_lock" >/dev/null 2>&1; then :
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+               PBX_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK=1
+
+$as_echo "#define HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK 1" >>confdefs.h
+
+
+else
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f conftest*
+
+
+       CPPGLAGS="$saved_cpp"
+       PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_INCLUDE="$PJPROJECT_INCLUDE"
+
+
+       PJ_TRANSACTION_GRP_LOCK_INCLUDE="$PJPROJECT_INCLUDE"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pjsip_tsx_create_uac2 declared in pjsip.h" >&5
+$as_echo_n "checking for pjsip_tsx_create_uac2 declared in pjsip.h... " >&6; }
+
+       saved_cpp="$CPPFLAGS"
+       CPPFLAGS="$PJPROJECT_INCLUDE"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pjsip.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pjsip_tsx_create_uac2" >/dev/null 2>&1; then :
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+               PBX_PJ_TRANSACTION_GRP_LOCK=1
+
+$as_echo "#define HAVE_PJ_TRANSACTION_GRP_LOCK 1" >>confdefs.h
+
+
+else
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f conftest*
+
+
+       CPPGLAGS="$saved_cpp"
+       PJ_TRANSACTION_GRP_LOCK_INCLUDE="$PJPROJECT_INCLUDE"
+
+
+       PJSIP_REPLACE_MEDIA_STREAM_INCLUDE="$PJPROJECT_INCLUDE"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE declared in pjmedia.h" >&5
+$as_echo_n "checking for PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE declared in pjmedia.h... " >&6; }
+
+       saved_cpp="$CPPFLAGS"
+       CPPFLAGS="$PJPROJECT_INCLUDE"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pjmedia.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE" >/dev/null 2>&1; then :
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+               PBX_PJSIP_REPLACE_MEDIA_STREAM=1
+
+$as_echo "#define HAVE_PJSIP_REPLACE_MEDIA_STREAM 1" >>confdefs.h
+
+
+else
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f conftest*
+
+
+       CPPGLAGS="$saved_cpp"
+       PJSIP_REPLACE_MEDIA_STREAM_INCLUDE="$PJPROJECT_INCLUDE"
+
+
+       PJSIP_GET_DEST_INFO_INCLUDE="$PJPROJECT_INCLUDE"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pjsip_get_dest_info declared in pjsip.h" >&5
+$as_echo_n "checking for pjsip_get_dest_info declared in pjsip.h... " >&6; }
+
+       saved_cpp="$CPPFLAGS"
+       CPPFLAGS="$PJPROJECT_INCLUDE"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pjsip.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pjsip_get_dest_info" >/dev/null 2>&1; then :
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+               PBX_PJSIP_GET_DEST_INFO=1
+
+$as_echo "#define HAVE_PJSIP_GET_DEST_INFO 1" >>confdefs.h
+
+
+else
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f conftest*
+
+
+       CPPGLAGS="$saved_cpp"
+       PJSIP_GET_DEST_INFO_INCLUDE="$PJPROJECT_INCLUDE"
+
+
+       PJ_SSL_CERT_LOAD_FROM_FILES2_INCLUDE="$PJPROJECT_INCLUDE"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pj_ssl_cert_load_from_files2 declared in pjlib.h" >&5
+$as_echo_n "checking for pj_ssl_cert_load_from_files2 declared in pjlib.h... " >&6; }
+
+       saved_cpp="$CPPFLAGS"
+       CPPFLAGS="$PJPROJECT_INCLUDE"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pjlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pj_ssl_cert_load_from_files2" >/dev/null 2>&1; then :
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+               PBX_PJ_SSL_CERT_LOAD_FROM_FILES2=1
+
+$as_echo "#define HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2 1" >>confdefs.h
+
+
+else
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f conftest*
+
+
+       CPPGLAGS="$saved_cpp"
+       PJ_SSL_CERT_LOAD_FROM_FILES2_INCLUDE="$PJPROJECT_INCLUDE"
+
+
+       PJSIP_EXTERNAL_RESOLVER_INCLUDE="$PJPROJECT_INCLUDE"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pjsip_endpt_set_ext_resolver declared in pjsip.h" >&5
+$as_echo_n "checking for pjsip_endpt_set_ext_resolver declared in pjsip.h... " >&6; }
+
+       saved_cpp="$CPPFLAGS"
+       CPPFLAGS="$PJPROJECT_INCLUDE"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pjsip.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pjsip_endpt_set_ext_resolver" >/dev/null 2>&1; then :
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+               PBX_PJSIP_EXTERNAL_RESOLVER=1
+
+$as_echo "#define HAVE_PJSIP_EXTERNAL_RESOLVER 1" >>confdefs.h
+
+
+else
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f conftest*
+
+
+       CPPGLAGS="$saved_cpp"
+       PJSIP_EXTERNAL_RESOLVER_INCLUDE="$PJPROJECT_INCLUDE"
+
+
+   else
 
    if test "x${PBX_PJPROJECT}" != "x1" -a "${USE_PJPROJECT}" != "no"; then
 
@@ -24658,7 +24925,7 @@ 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="-lpjsip ${pbxlibdir} $PJPROJECT_LIB $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -24700,7 +24967,7 @@ fi
 
    # 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} -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"
 
 
 
-saved_cppflags="${CPPFLAGS}"
-saved_libs="${LIBS}"
-CPPFLAGS="${CPPFLAGS} ${PJPROJECT_CFLAGS}"
-LIBS="${LIBS} ${PJPROJECT_LIBS}"
+      saved_cppflags="${CPPFLAGS}"
+      saved_libs="${LIBS}"
+      CPPFLAGS="${CPPFLAGS} ${PJPROJECT_CFLAGS}"
+      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
@@ -24788,8 +25055,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
        CPPFLAGS="${saved_cppflags}"
     fi
 
-LIBS="${saved_libs}"
-CPPFLAGS="${saved_cppflags}"
+      LIBS="${saved_libs}"
+      CPPFLAGS="${saved_cppflags}"
 
 
 if test "x${PBX_PJSIP_GET_DEST_INFO}" != "x1" -a "${USE_PJSIP_GET_DEST_INFO}" != "no"; then
@@ -24815,7 +25082,7 @@ 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="-lpjsip ${pbxlibdir} $PJPROJECT_LIB $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -24857,7 +25124,7 @@ fi
 
    # 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} -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"
@@ -24906,7 +25173,7 @@ if test "x${PBX_PJ_SSL_CERT_LOAD_FROM_FILES2}" != "x1" -a "${USE_PJ_SSL_CERT_LOA
          pbxlibdir="-L${PJ_SSL_CERT_LOAD_FROM_FILES2_DIR}"
       fi
    fi
-   pbxfuncname="pj_ssl_cert_load_from_files2"
+   pbxfuncname="pjsip/include/pjsip/sip_util.h"
    if test "x${pbxfuncname}" = "x" ; then   # empty lib, assume only headers
       AST_PJ_SSL_CERT_LOAD_FROM_FILES2_FOUND=yes
    else
@@ -24919,7 +25186,7 @@ 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="-lpj ${pbxlibdir} $PJPROJECT_LIB $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -24961,7 +25228,7 @@ fi
 
    # 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} -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"
@@ -25103,6 +25370,8 @@ _ACEOF
 fi
 
 
+   fi
+fi
 
 
 if test "x${PBX_POPT}" != "x1" -a "${USE_POPT}" != "no"; then
index 1ca5eb3..12cc8d2 100644 (file)
@@ -453,14 +453,37 @@ AST_EXT_LIB_SETUP([OPUS], [Opus], [opus])
 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_BUNDLED=no
+AH_TEMPLATE(m4_bpatsubst([[HAVE_PJPROJECT_BUNDLED]], [(.*)]), [Define to 1 when using the bundled pjproject.])
+
+AC_ARG_WITH([pjproject-bundled],
+       [AS_HELP_STRING([--with-pjproject-bundled],
+               [Use bundled pjproject libraries])],
+       [case "${enableval}" in
+             n|no) PJPROJECT_BUNDLED=no ;;
+             *) PJPROJECT_BUNDLED=yes ;;
+       esac])
+AC_SUBST(PJPROJECT_BUNDLED)
+
+if test "$PJPROJECT_BUNDLED" = "yes" -a "${ac_mandatory_list#*PJPROJECT*}" != "$ac_mandatory_list" ; then
+   AC_MSG_ERROR(--with-pjproject and --with-pjproject-bundled can't both be specified)
+fi
+
+if test "$PJPROJECT_BUNDLED" = "yes" ; then
+   ac_mandatory_list="$ac_mandatory_list PJPROJECT"
+   PJPROJECT_DIR="${ac_top_build_prefix}third-party/pjproject"
+fi
+
 AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_DLG_CREATE_UAS_AND_INC_LOCK], [PJSIP Dialog Create UAS with Incremented Lock], [PJPROJECT], [pjsip])
 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])
@@ -2152,22 +2175,29 @@ if test "${PG_CONFIG}" != No; then
    fi
 fi
 
-AST_PKG_CONFIG_CHECK([PJPROJECT], [libpjproject])
-
-AST_EXT_LIB_CHECK([PJSIP_DLG_CREATE_UAS_AND_INC_LOCK], [pjsip], [pjsip_dlg_create_uas_and_inc_lock], [pjsip.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
-AST_EXT_LIB_CHECK([PJ_TRANSACTION_GRP_LOCK], [pjsip], [pjsip_tsx_create_uac2], [pjsip.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
-
-saved_cppflags="${CPPFLAGS}"
-saved_libs="${LIBS}"
-CPPFLAGS="${CPPFLAGS} ${PJPROJECT_CFLAGS}"
-LIBS="${LIBS} ${PJPROJECT_LIBS}"
-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])
+if test "$USE_PJPROJECT" != "no" ; then
+   if test "$PJPROJECT_BUNDLED" = "yes" ; then
+       AC_CONFIG_MACRO_DIR(third-party/pjproject)
+       PJPROJECT_CONFIGURE([$PJPROJECT_DIR])
+   else
+      AST_PKG_CONFIG_CHECK([PJPROJECT], [libpjproject])
+
+      AST_EXT_LIB_CHECK([PJSIP_DLG_CREATE_UAS_AND_INC_LOCK], [pjsip], [pjsip_dlg_create_uas_and_inc_lock], [pjsip.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
+      AST_EXT_LIB_CHECK([PJ_TRANSACTION_GRP_LOCK], [pjsip], [pjsip_tsx_create_uac2], [pjsip.h], [$PJPROJECT_LIB], [$PJPROJECT_CFLAGS])
+
+      saved_cppflags="${CPPFLAGS}"
+      saved_libs="${LIBS}"
+      CPPFLAGS="${CPPFLAGS} ${PJPROJECT_CFLAGS}"
+      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_LIB], [$PJPROJECT_CFLAGS])
+      AST_EXT_LIB_CHECK([PJ_SSL_CERT_LOAD_FROM_FILES2], [pj], [pjsip/include/pjsip/sip_util.h], [pjlib.h], [$PJPROJECT_LIB], [$PJPROJECT_CFLAGS])
+      AST_EXT_LIB_CHECK([PJSIP_EXTERNAL_RESOLVER], [pjsip], [pjsip_endpt_set_ext_resolver], [pjsip.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
+   fi
+fi
 
 AST_EXT_LIB_CHECK([POPT], [popt], [poptStrerror], [popt.h])
 
@@ -2331,11 +2361,11 @@ AC_CHECK_FUNC([crypt], [SYSCRYPT=true], [SYSCRYPT=""])
 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)
@@ -2343,7 +2373,7 @@ AC_SUBST(CRYPT_INCLUDE)
 
 # 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])
 
index 7963f31..a4a4f1b 100644 (file)
@@ -53,6 +53,7 @@ void ast_stun_init(void);               /*!< Provided by stun.c */
 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 */
index 6ed96cc..43f86b0 100644 (file)
 /* 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. */
 /* Define if your system has the PJPROJECT libraries. */
 #undef HAVE_PJPROJECT
 
-/* Define to 1 if PJPROJECT has the PJSIP Dialog Create UAS with Incremented
-   Lock feature. */
+/* Define if your system has PJPROJECT_BUNDLED */
+#undef HAVE_PJPROJECT_BUNDLED
+
+/* Define if your system has pjsip_dlg_create_uas_and_inc_lock declared. */
 #undef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
 
-/* Define to 1 if PJPROJECT has the PJSIP External Resolver Support feature.
-   */
+/* Define if your system has pjsip_endpt_set_ext_resolver declared. */
 #undef HAVE_PJSIP_EXTERNAL_RESOLVER
 
-/* Define to 1 if PJPROJECT has the pjsip_get_dest_info support feature. */
+/* Define if your system has pjsip_get_dest_info declared. */
 #undef HAVE_PJSIP_GET_DEST_INFO
 
 /* Define if your system has the PJSIP_REPLACE_MEDIA_STREAM headers. */
 #undef HAVE_PJSIP_REPLACE_MEDIA_STREAM
 
-/* Define to 1 if PJPROJECT has the pj_ssl_cert_load_from_files2 support
-   feature. */
+/* Define if your system has pj_ssl_cert_load_from_files2 declared. */
 #undef HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2
 
-/* Define to 1 if PJPROJECT has the PJSIP Transaction Group Lock Support
-   feature. */
+/* Define if your system has pjsip_tsx_create_uac2 declared. */
 #undef HAVE_PJ_TRANSACTION_GRP_LOCK
 
 /* Define to 1 if your system defines IP_PKTINFO. */
index 3ff4656..cb90a5e 100644 (file)
@@ -1,4 +1,6 @@
 asterisk
 libasteriskssl.so.1
 libasteriskssl.dylib
+libasteriskpj.so.2
+libasteriskpj.dylib
 version.c
index b25fb45..50fdc57 100644 (file)
@@ -22,6 +22,9 @@ SRC:=$(wildcard *.c) ast_expr2.c ast_expr2f.c
 ifeq ($(AST_ASTERISKSSL),yes)
 SRC:=$(filter-out libasteriskssl.c,$(SRC))
 endif
+ifeq ($(PJPROJECT_BUNDLED),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))
 
@@ -201,7 +204,7 @@ ASTSSL_LDLIBS=-L. -lasteriskssl
 ifeq ($(findstring darwin,$(OSARCH)),) # not Darwin
 ASTSSL_LIB:=libasteriskssl.so
 
-$(ASTSSL_LIB).$(ASTSSL_SO_VERSION): _ASTLDFLAGS+=-Wl,-soname=$(ASTSSL_LIB).$(ASTSSL_SO_VERSION)
+$(ASTSSL_LIB).$(ASTSSL_SO_VERSION): _ASTLDFLAGS+=-Wl,-soname=$(ASTSSL_LIB)
 $(ASTSSL_LIB).$(ASTSSL_SO_VERSION): _ASTCFLAGS+=-fPIC -DAST_MODULE=\"asteriskssl\" -DAST_NOT_MODULE
 $(ASTSSL_LIB).$(ASTSSL_SO_VERSION): LIBS+=$(ASTSSL_LIBS)
 ifeq ($(GNU_LD),1)
@@ -219,12 +222,14 @@ ifeq ($(GNU_LD),1)
 endif
        $(ECHO_PREFIX) echo "   [LD] $^ -> $@"
        $(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(CC_LDFLAGS_SO) $^ $(CC_LIBS)
-ifneq ($(LDCONFIG),)
-       $(LDCONFIG) $(LDCONFIG_FLAGS) .
-endif
 
 $(ASTSSL_LIB): $(ASTSSL_LIB).$(ASTSSL_SO_VERSION)
-       $(LN) -sf $< $@
+       $(ECHO_PREFIX) echo "   [LN] $< -> $@"
+ifneq ($(LDCONFIG),)
+       $(CMD_PREFIX) $(LDCONFIG) $(LDCONFIG_FLAGS) . 2>/dev/null
+else
+       $(CMD_PREFIX) $(LN) -sf $< $@
+endif
 
 else # Darwin
 ASTSSL_LIB:=libasteriskssl.dylib
@@ -244,12 +249,92 @@ endif
 
 endif
 
+libasteriskpj.o: _ASTCFLAGS+=$(PJPROJECT_INCLUDE)
+
+ifeq ($(PJPROJECT_BUNDLED),yes)
+
+ASTPJ_SO_VERSION=2
+ASTPJ_LDLIBS=-L. -lasteriskpj
+
+-include $(ASTTOPDIR)/$(PJPROJECT_DIR)/build.mak
+
+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.exports: $(ASTTOPDIR)/$(PJPROJECT_DIR)/pjproject.symbols
+       $(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)&;/" $(ASTTOPDIR)/$(PJPROJECT_DIR)/pjproject.symbols >> 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) $(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)
+
+$(ASTPJ_LIB): $(ASTPJ_LIB).$(ASTPJ_SO_VERSION)
+       $(ECHO_PREFIX) echo "   [LN] $< -> $@"
+ifneq ($(LDCONFIG),)
+       $(CMD_PREFIX) $(LDCONFIG) $(LDCONFIG_FLAGS) . 2>/dev/null
+else
+       $(CMD_PREFIX) $(LN) -sf $< $@
+endif
+
+else # Darwin
+ASTPJ_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 +351,29 @@ ifeq ($(findstring darwin,$(OSARCH)),) # not Darwin
 else # Darwin
        $(INSTALL) -m 755 $(ASTSSL_LIB) "$(DESTDIR)$(ASTLIBDIR)/"
 endif
+endif
+ifeq ($(PJPROJECT_BUNDLED),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 +383,12 @@ clean::
 ifeq ($(AST_ASTERISKSSL),yes)
        rm -f $(ASTSSL_LIB) $(ASTSSL_LIB).*
 endif
-       rm -f asterisk.exports libasteriskssl.exports
+       rm -f libasteriskpj.o
+       rm -f libasteriskpj.so* libasteriskpj.dynlib
+       rm -f .libasteriskpj*
+
+       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
index ca560cd..da804e1 100644 (file)
@@ -4478,6 +4478,11 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou
                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 (file)
index 0000000..aed0ec8
--- /dev/null
@@ -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@digium.com>
+ * George Joseph <george.joseph@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@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_BUNDLED
+       pj_init();
+#endif
+       return 0;
+}
index f606ace..6baef1b 100644 (file)
@@ -229,8 +229,10 @@ OSS_LIB=@OSS_LIB@ @FFMPEG_LIB@ @SDL_LIB@ @SDL_IMAGE_LIB@ @X11_LIB@
 PGSQL_INCLUDE=@PGSQL_INCLUDE@
 PGSQL_LIB=@PGSQL_LIB@
 
+PJPROJECT_BUNDLED=@PJPROJECT_BUNDLED@
 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 (file)
index 0000000..0aca21e
--- /dev/null
@@ -0,0 +1,21 @@
+
+include Makefile.rules
+
+TP_SUBDIRS := pjproject
+# Sub directories that contain special install/uninstall targets must be explicitly listed
+# to prevent accidentally running the package's default install target.
+TP_INSTALL_SUBDIRS := pjproject
+
+.PHONY: all dist-clean distclean install clean moduleinfo makeopts uninstall __embed_libs __embed_ldscript __embed_ldflags $(TP_SUBDIRS)
+
+override MAKECMDGOALS?=all
+
+MAKECMDGOALS:=$(subst dist-clean,distclean,$(MAKECMDGOALS))
+MAKECMDGOALS:=$(subst tpclean,clean,$(MAKECMDGOALS))
+
+all distclean dist-clean install tpclean : $(TP_SUBDIRS)
+install uninstall: $(TP_INSTALL_SUBDIRS)
+
+$(TP_SUBDIRS):
+       +$(CMD_PREFIX) $(SUBMAKE) -C $@ $(MAKECMDGOALS)
+
diff --git a/third-party/Makefile.rules b/third-party/Makefile.rules
new file mode 100644 (file)
index 0000000..ac4189a
--- /dev/null
@@ -0,0 +1,37 @@
+
+ifeq ($(NOISY_BUILD),)
+       SUBMAKE?=$(MAKE) --quiet --no-print-directory
+    ECHO_PREFIX?=@
+    CMD_PREFIX?=@
+    QUIET_CONFIGURE=-q
+    REALLY_QUIET=&>/dev/null
+else
+       SUBMAKE?=$(MAKE)
+    ECHO_PREFIX?=@\#
+    CMD_PREFIX?=
+    QUIET_CONFIGURE=
+    REALLY_QUIET=
+endif
+
+DOWNLOAD :=
+DOWNLOAD != which wget 2>/dev/null
+DOWNLOAD:=$(if $(DOWNLOAD),$(DOWNLOAD) -O- ,)
+
+ifeq ($(DOWNLOAD),)
+DOWNLOAD != which curl 2>/dev/null
+DOWNLOAD:=$(if $(DOWNLOAD), $(DOWNLOAD) -L ,)
+endif
+
+ifeq ($(DOWNLOAD),)
+DOWNLOAD := echo "No download program available" ; exit 1;
+endif
+
+export SUBMAKE
+export ECHO_PREFIX
+export CMD_PREFIX
+export QUIET_CONFIGURE
+export REALLY_QUIET
+export ASTTOPDIR
+export ASTSBINDIR
+export DESTDIR
+export ASTDATADIR
diff --git a/third-party/pjproject/.gitignore b/third-party/pjproject/.gitignore
new file mode 100644 (file)
index 0000000..5079dee
--- /dev/null
@@ -0,0 +1,4 @@
+source/
+**.bz2
+build.mak
+pjproject.symbols
diff --git a/third-party/pjproject/Makefile b/third-party/pjproject/Makefile
new file mode 100644 (file)
index 0000000..3100951
--- /dev/null
@@ -0,0 +1,110 @@
+.SUFFIXES:
+.PHONY: _all all _install install clean distclean echo_cflags configure
+
+ifeq ($(MAKECMDGOALS),install)
+include ../../makeopts
+else
+-include ../../makeopts
+endif
+
+include ../versions.mak
+include ../Makefile.rules
+include Makefile.rules
+
+ECHO_PREFIX := $(ECHO_PREFIX) echo '[pjproject] '
+
+ifeq ($(MAKECMDGOALS),echo_cflags)
+-include build.mak
+ECHO_PREFIX=@\#
+endif
+
+ifneq ($(PJPROJECT_BUNDLED),yes)
+all install:
+       @echo '[pjproject] Not enabled'
+else
+
+ifneq ($(findstring clean,$(MAKECMDGOALS)),clean)
+include build.mak
+endif
+
+all: _all
+install: _install
+endif
+
+ifndef $(TMPDIR)
+ifneq ($(wildcard /tmp),)
+TMPDIR=/tmp
+else
+TMPDIR=.
+endif
+endif
+
+$(TMPDIR)/pjproject-$(PJPROJECT_VERSION).tar.bz2 : ../versions.mak
+       $(ECHO_PREFIX) Downloading $@ with $(DOWNLOAD)
+       $(CMD_PREFIX) $(DOWNLOAD) $(PJPROJECT_URL)/$(@F) > $@
+
+source/user.mak source/pjlib/include/pj/config_site.h: $(TMPDIR)/pjproject-$(PJPROJECT_VERSION).tar.bz2 patches/config_site.h patches/user.mak 
+       $(ECHO_PREFIX) Unpacking $<
+       -@rm -rf source &>/dev/null
+       -@mkdir source &>/dev/null
+       $(CMD_PREFIX) tar --strip-components=1 -C source -xjf $<
+       $(ECHO_PREFIX) Applying patches and custom files
+       $(CMD_PREFIX) ./apply_patches $(QUIET_CONFIGURE) ./patches ./source
+       $(CMD_PREFIX) cp -f ./patches/config_site.h ./source/pjlib/include/pj/
+       $(CMD_PREFIX) cp -f ./patches/user.mak ./source/
+
+build.mak: source/pjlib/include/pj/config_site.h source/user.mak Makefile.rules
+       $(ECHO_PREFIX) Configuring with $(PJPROJECT_CONFIG_OPTS)
+       $(CMD_PREFIX) (cd source ; autoconf aconfigure.ac > aconfigure && ./aconfigure $(QUIET_CONFIGURE) $(PJPROJECT_CONFIG_OPTS))
+       @sed -r -e "/prefix|export PJ_SHARED_LIBRARIES|MACHINE_NAME|OS_NAME|HOST_NAME|CC_NAME|CROSS_COMPILE|LINUX_POLL/d" source/build.mak > build.mak
+
+configure: build.mak
+
+echo_cflags: build.mak
+       @echo $(PJ_CFLAGS)
+
+source/pjlib/build/.pjlib-$(TARGET_NAME).depend: build.mak
+       $(ECHO_PREFIX) "Making dependencies"
+       +$(CMD_PREFIX) $(SUBMAKE) -C source dep
+
+source/pjlib/lib/libpj-$(TARGET_NAME).a: source/pjlib/build/.pjlib-$(TARGET_NAME).depend
+       $(ECHO_PREFIX) Compiling libs
+       +$(CMD_PREFIX) $(SUBMAKE) -C source lib $(REALLY_QUIET)
+
+pjproject.symbols: source/pjlib/lib/libpj-$(TARGET_NAME).a
+       $(ECHO_PREFIX) Generating symbols
+       $(CMD_PREFIX) nm -Pog $(PJ_LIB_FILES) | sed -n -r -e "s/.+: ([pP][jJ][^ ]+) .+/\1/gp" | sort -u > pjproject.symbols
+
+source/pjsip-apps/bin/pjsua-$(TARGET_NAME): source/pjlib/lib/libpj-$(TARGET_NAME).a
+       $(ECHO_PREFIX) Compiling apps
+       $(CMD_PREFIX) $(SUBMAKE) -C source/pjsip-apps/build pjsua pjsystest $(REALLY_QUIET)
+
+source/pjsip-apps/src/python/build/_pjsua.so: source/pjlib/lib/libpj-$(TARGET_NAME).a
+       $(ECHO_PREFIX) Compiling python bindings
+       $(CMD_PREFIX) (cd source/pjsip-apps/src/python ; python setup.py build --build-platlib=./build $(REALLY_QUIET))
+
+_all: pjproject.symbols source/pjsip-apps/bin/pjsua-$(TARGET_NAME) source/pjsip-apps/src/python/build/_pjsua.so
+
+_install: _all
+       $(ECHO_PREFIX) Installing apps and python bindings
+       @if [ ! -d "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject" ]; then \
+               $(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject"; \
+       fi;
+       $(CMD_PREFIX) $(INSTALL) -m 755 source/pjsip-apps/bin/pjsua-$(TARGET_NAME) "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject/pjsua"
+       $(CMD_PREFIX) $(INSTALL) -m 755 source/pjsip-apps/bin/pjsystest-$(TARGET_NAME) "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject/pjsystest"
+       $(CMD_PREFIX) $(INSTALL) -m 755 source/pjsip-apps/src/python/build/_pjsua.so "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject/"
+       $(CMD_PREFIX) $(INSTALL) -m 644 source/pjsip-apps/src/python/build/pjsua.py "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject/"
+
+uninstall:
+       $(ECHO_PREFIX) Uninstalling apps and python bindings
+       $(CMD_PREFIX) rm -rf "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject"
+
+clean:
+       $(ECHO_PREFIX) Cleaning
+       -$(CMD_PREFIX) test -d source && ($(SUBMAKE) -C source clean ; find source -name *.a -delete ; rm -rf source/pjsip-apps/src/python/build) || :
+       -$(CMD_PREFIX) rm -rf pjproject.symbols
+
+distclean:
+       $(ECHO_PREFIX) Distcleaning
+       -$(CMD_PREFIX) rm -rf source pjproject.symbols pjproject-*.tar.bz2 build.mak
+
diff --git a/third-party/pjproject/Makefile.rules b/third-party/pjproject/Makefile.rules
new file mode 100644 (file)
index 0000000..d6e4be0
--- /dev/null
@@ -0,0 +1,7 @@
+PJPROJECT_URL = http://www.pjsip.org/release/$(PJPROJECT_VERSION)
+
+# Even though we're not installing pjproject, we're setting prefix to /opt/pjproject to be safe
+PJPROJECT_CONFIG_OPTS = --prefix=/opt/pjproject --with-external-speex --with-external-gsm --with-external-srtp \
+       --with-external-pa --disable-video --disable-v4l2 --disable-sound --disable-resample \
+       --disable-opencore-amr --disable-ilbc-codec --without-libyuv --disable-g7221-codec \
+       --enable-epoll
diff --git a/third-party/pjproject/apply_patches b/third-party/pjproject/apply_patches
new file mode 100755 (executable)
index 0000000..1b72d14
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+if [ "$1" = "-q" ] ; then
+       quiet=1
+       shift
+fi
+
+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" >&2
+       exit 1
+fi
+
+if [ ! -d "$sourcedir" ] ; then
+       echo "$sourcedir is not a directory"  >&2
+       exit 1
+fi
+
+if [ ! "$(ls -A $patchdir/*.patch 2>/dev/null)" ] ; then
+       echo "No patches in $patchdir"  >&2
+       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 >&2" ; exit 1) || exit 1
+done
+
+for patchfile in "$patchdir"/*.patch ; do
+       [ -z $quiet ] && echo "Applying patch $(basename $patchfile)"
+       patch -d "$sourcedir" -p1 -s -i "$patchfile" || exit 1
+done
+
+exit 0
+
diff --git a/third-party/pjproject/configure.m4 b/third-party/pjproject/configure.m4
new file mode 100644 (file)
index 0000000..3351527
--- /dev/null
@@ -0,0 +1,46 @@
+AC_DEFUN([PJPROJECT_SYMBOL_CHECK],
+[
+       $1_INCLUDE="$PJPROJECT_INCLUDE"
+    AC_MSG_CHECKING([for $2 declared in $3])
+
+       saved_cpp="$CPPFLAGS"
+       CPPFLAGS="$PJPROJECT_INCLUDE"
+       AC_EGREP_HEADER($2, $3, [
+               AC_MSG_RESULT(yes)
+               PBX_$1=1
+               AC_DEFINE([HAVE_$1], 1, [Define if your system has $2 declared.])
+       ], [
+               AC_MSG_RESULT(no)
+       ])
+
+       CPPGLAGS="$saved_cpp"
+       $1_INCLUDE="$PJPROJECT_INCLUDE"
+])
+
+AC_DEFUN([PJPROJECT_CONFIGURE],
+[
+       AC_MSG_CHECKING(for embedded pjproject (may have to download))
+       AC_MSG_RESULT(configuring)
+       make --quiet --no-print-directory -C $1 configure
+       if test $? -ne 0 ; then
+               AC_MSG_RESULT(failed)
+               AC_MSG_NOTICE(Unable to configure $1)
+               AC_MSG_ERROR(Run "make -C $1 NOISY_BUILD=yes configure" to see error details.)
+       fi
+
+       PJPROJECT_INCLUDE=$(make --quiet --no-print-directory -C $1 echo_cflags)
+       PJPROJECT_CFLAGS="$PJPROJECT_INCLUDE"
+       PBX_PJPROJECT=1
+       PJPROJECT_BUNDLED=yes
+       AC_DEFINE([HAVE_PJPROJECT], 1, [Define if your system has PJPROJECT])
+       AC_DEFINE([HAVE_PJPROJECT_BUNDLED], 1, [Define if your system has PJPROJECT_BUNDLED])
+       AC_MSG_CHECKING(for embedded pjproject)
+       AC_MSG_RESULT(yes)
+
+       PJPROJECT_SYMBOL_CHECK([PJSIP_DLG_CREATE_UAS_AND_INC_LOCK], [pjsip_dlg_create_uas_and_inc_lock], [pjsip.h])
+       PJPROJECT_SYMBOL_CHECK([PJ_TRANSACTION_GRP_LOCK], [pjsip_tsx_create_uac2], [pjsip.h])
+       PJPROJECT_SYMBOL_CHECK([PJSIP_REPLACE_MEDIA_STREAM], [PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE], [pjmedia.h])
+       PJPROJECT_SYMBOL_CHECK([PJSIP_GET_DEST_INFO], [pjsip_get_dest_info], [pjsip.h])
+       PJPROJECT_SYMBOL_CHECK([PJ_SSL_CERT_LOAD_FROM_FILES2], [pj_ssl_cert_load_from_files2], [pjlib.h])
+       PJPROJECT_SYMBOL_CHECK([PJSIP_EXTERNAL_RESOLVER], [pjsip_endpt_set_ext_resolver], [pjsip.h])
+])
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 (file)
index 0000000..33fc8ea
--- /dev/null
@@ -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/0001-Bump-tcp-tls-and-transaction-log-levels-from-1-to-3.patch b/third-party/pjproject/patches/0001-Bump-tcp-tls-and-transaction-log-levels-from-1-to-3.patch
new file mode 100644 (file)
index 0000000..9873abf
--- /dev/null
@@ -0,0 +1,70 @@
+From a147b72df1ec150c1d733e882225db86142fb339 Mon Sep 17 00:00:00 2001
+From: George Joseph <george.joseph@fairview5.com>
+Date: Sun, 21 Feb 2016 10:01:53 -0700
+Subject: [PATCH] Bump tcp/tls and transaction log levels from 1 to 3
+
+sip_transport_tcp, sip_transport_tls and sip_transaction are printing messages
+at log level 1 or 2 for things that are transient, recoverable, possibly
+expected, or are handled with return codes. A good example of this is if we're
+trying to send an OPTIONS message to a TCP client that has disappeared.  Both
+sip_transport_tcp and sip_transaction are printing "connection refused"
+messages because the remote client isn't listening.  This is generally expected
+behavior and it should be up to the app caller to determine if an error message
+is warranted.
+---
+ pjsip/src/pjsip/sip_transaction.c   | 4 ++--
+ pjsip/src/pjsip/sip_transport_tcp.c | 2 +-
+ pjsip/src/pjsip/sip_transport_tls.c | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
+index 46bd971..1b4fdb7 100644
+--- a/pjsip/src/pjsip/sip_transaction.c
++++ b/pjsip/src/pjsip/sip_transaction.c
+@@ -1898,7 +1898,7 @@ static void send_msg_callback( pjsip_send_state *send_state,
+           err =pj_strerror((pj_status_t)-sent, errmsg, sizeof(errmsg));
+-          PJ_LOG(2,(tsx->obj_name,
++          PJ_LOG(3,(tsx->obj_name,
+                     "Failed to send %s! err=%d (%s)",
+                     pjsip_tx_data_get_info(send_state->tdata), -sent,
+                     errmsg));
+@@ -1938,7 +1938,7 @@ static void send_msg_callback( pjsip_send_state *send_state,
+           }
+       } else {
+-          PJ_PERROR(2,(tsx->obj_name, (pj_status_t)-sent,
++          PJ_PERROR(3,(tsx->obj_name, (pj_status_t)-sent,
+                        "Temporary failure in sending %s, "
+                        "will try next server",
+                        pjsip_tx_data_get_info(send_state->tdata)));
+diff --git a/pjsip/src/pjsip/sip_transport_tcp.c b/pjsip/src/pjsip/sip_transport_tcp.c
+index 222cb13..1bbb324 100644
+--- a/pjsip/src/pjsip/sip_transport_tcp.c
++++ b/pjsip/src/pjsip/sip_transport_tcp.c
+@@ -164,7 +164,7 @@ static void tcp_perror(const char *sender, const char *title,
+     pj_strerror(status, errmsg, sizeof(errmsg));
+-    PJ_LOG(1,(sender, "%s: %s [code=%d]", title, errmsg, status));
++    PJ_LOG(3,(sender, "%s: %s [code=%d]", title, errmsg, status));
+ }
+diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
+index 617d7f5..a83ac32 100644
+--- a/pjsip/src/pjsip/sip_transport_tls.c
++++ b/pjsip/src/pjsip/sip_transport_tls.c
+@@ -170,7 +170,7 @@ static void tls_perror(const char *sender, const char *title,
+     pj_strerror(status, errmsg, sizeof(errmsg));
+-    PJ_LOG(1,(sender, "%s: %s [code=%d]", title, errmsg, status));
++    PJ_LOG(3,(sender, "%s: %s [code=%d]", title, errmsg, status));
+ }
+-- 
+2.5.0
+
diff --git a/third-party/pjproject/patches/0001-ioqueue-Enable-epoll-in-aconfigure.ac.patch b/third-party/pjproject/patches/0001-ioqueue-Enable-epoll-in-aconfigure.ac.patch
new file mode 100644 (file)
index 0000000..36b6c65
--- /dev/null
@@ -0,0 +1,80 @@
+From b5c0bc905911f75e08987e6833075481fe16dab2 Mon Sep 17 00:00:00 2001
+From: George Joseph <george.joseph@fairview5.com>
+Date: Mon, 22 Feb 2016 13:05:59 -0700
+Subject: [PATCH] ioqueue:  Enable epoll in aconfigure.ac
+
+Although the --enable-epoll option was being accepted, the result
+was always forced to select.  This patch updates aconfigure.ac
+to properly set the value of ac_linux_poll if --enable-epoll is
+specified.
+---
+ README.txt                           |  1 +
+ aconfigure                           | 11 +++++++----
+ aconfigure.ac                        |  7 +++++--
+ pjlib/include/pj/compat/os_auto.h.in |  3 +++
+ 4 files changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/README.txt b/README.txt
+index bc45da8..48415fd 100644
+--- a/README.txt
++++ b/README.txt
+@@ -463,6 +463,7 @@ Using Default Settings
+    $ ./configure --help
+    ...
+    Optional Features:
++   --enable-epoll           Use epoll on Linux instead of select
+    --disable-floating-point   Disable floating point where possible
+    --disable-sound            Exclude sound (i.e. use null sound)
+    --disable-small-filter     Exclude small filter in resampling
+diff --git a/aconfigure.ac b/aconfigure.ac
+index 2f71abb..3e88124 100644
+--- a/aconfigure.ac
++++ b/aconfigure.ac
+@@ -410,6 +410,7 @@ dnl ######################
+ dnl # ioqueue selection
+ dnl # 
+ AC_SUBST(ac_os_objs)
++AC_SUBST(ac_linux_poll)
+ AC_MSG_CHECKING([ioqueue backend])
+ AC_ARG_ENABLE(epoll,
+             AC_HELP_STRING([--enable-epoll],
+@@ -417,10 +418,13 @@ AC_ARG_ENABLE(epoll,
+             [
+               ac_os_objs=ioqueue_epoll.o
+               AC_MSG_RESULT([/dev/epoll])
++              AC_DEFINE(PJ_HAS_LINUX_EPOLL,1)
++              ac_linux_poll=epoll
+             ],
+             [
+               ac_os_objs=ioqueue_select.o
+-              AC_MSG_RESULT([select()]) 
++              AC_MSG_RESULT([select()])
++              ac_linux_poll=select
+             ])
+ AC_SUBST(ac_shared_libraries)
+@@ -1879,7 +1883,6 @@ esac
+ AC_SUBST(target)
+-AC_SUBST(ac_linux_poll,select)
+ AC_SUBST(ac_host,unix)
+ AC_SUBST(ac_main_obj)
+ case $target in
+diff --git a/pjlib/include/pj/compat/os_auto.h.in b/pjlib/include/pj/compat/os_auto.h.in
+index 77980d3..c8e73b2 100644
+--- a/pjlib/include/pj/compat/os_auto.h.in
++++ b/pjlib/include/pj/compat/os_auto.h.in
+@@ -128,6 +128,9 @@
+  */
+ #undef PJ_SELECT_NEEDS_NFDS
++/* Was Linux epoll support enabled */
++#undef PJ_HAS_LINUX_EPOLL
++
+ /* Is errno a good way to retrieve OS errors?
+  */
+ #undef PJ_HAS_ERRNO_VAR
+-- 
+2.5.0
+
diff --git a/third-party/pjproject/patches/0001-sip_transport-Search-for-transport-even-if-listener-.patch b/third-party/pjproject/patches/0001-sip_transport-Search-for-transport-even-if-listener-.patch
new file mode 100644 (file)
index 0000000..001912c
--- /dev/null
@@ -0,0 +1,114 @@
+From 552194179eb6deae8326eb0fef446e69240ea41b Mon Sep 17 00:00:00 2001
+From: George Joseph <george.joseph@fairview5.com>
+Date: Fri, 19 Feb 2016 17:05:53 -0700
+Subject: [PATCH] sip_transport:  Search for transport even if listener was
+ specified.
+
+If a listener was specified when calling pjsip_tpmgr_acquire_transport2,
+a new transport was always created instead of using an existing one.  This
+caused several issues mostly related to the remote end not expecting a new
+connection.  I.E.  A TCP client who registered to a server is not going to
+be listening for connections coming back from the server and refuses the
+connection.
+
+Now when pjsip_tpmgr_acquire_transport2 is called with a listener, the
+registry is still searched for an existing transport and the listener
+is used as a factory only if no existing transport can be found.
+---
+ pjsip/src/pjsip/sip_transport.c | 68 ++++++++++++++++++++---------------------
+ 1 file changed, 34 insertions(+), 34 deletions(-)
+
+diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
+index 0410324..620b9c0 100644
+--- a/pjsip/src/pjsip/sip_transport.c
++++ b/pjsip/src/pjsip/sip_transport.c
+@@ -1999,29 +1999,11 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+       TRACE_((THIS_FILE, "Transport %s acquired", seltp->obj_name));
+       return PJ_SUCCESS;
+-
+-
+-    } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
+-             sel->u.listener)
+-    {
+-      /* Application has requested that a specific listener is to
+-       * be used. In this case, skip transport hash table lookup.
+-       */
+-
+-      /* Verify that the listener type matches the destination type */
+-      if (sel->u.listener->type != type) {
+-          pj_lock_release(mgr->lock);
+-          return PJSIP_ETPNOTSUITABLE;
+-      }
+-
+-      /* We'll use this listener to create transport */
+-      factory = sel->u.listener;
+-
+     } else {
+       /*
+        * This is the "normal" flow, where application doesn't specify
+-       * specific transport/listener to be used to send message to.
++       * specific transport to be used to send message to.
+        * In this case, lookup the transport from the hash table.
+        */
+       pjsip_transport_key key;
+@@ -2081,22 +2063,40 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+           return PJ_SUCCESS;
+       }
+-      /*
+-       * Transport not found!
+-       * Find factory that can create such transport.
+-       */
+-      factory = mgr->factory_list.next;
+-      while (factory != &mgr->factory_list) {
+-          if (factory->type == type)
+-              break;
+-          factory = factory->next;
+-      }
++      if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
++              sel->u.listener)
++              {
++              /* Application has requested that a specific listener is to
++               * be used.
++               */
++
++              /* Verify that the listener type matches the destination type */
++              if (sel->u.listener->type != type) {
++                      pj_lock_release(mgr->lock);
++                      return PJSIP_ETPNOTSUITABLE;
++              }
+-      if (factory == &mgr->factory_list) {
+-          /* No factory can create the transport! */
+-          pj_lock_release(mgr->lock);
+-          TRACE_((THIS_FILE, "No suitable factory was found either"));
+-          return PJSIP_EUNSUPTRANSPORT;
++              /* We'll use this listener to create transport */
++              factory = sel->u.listener;
++
++      } else {
++              /*
++               * Transport not found!
++               * Find factory that can create such transport.
++               */
++              factory = mgr->factory_list.next;
++              while (factory != &mgr->factory_list) {
++                      if (factory->type == type)
++                              break;
++                      factory = factory->next;
++              }
++
++              if (factory == &mgr->factory_list) {
++                      /* No factory can create the transport! */
++                      pj_lock_release(mgr->lock);
++                      TRACE_((THIS_FILE, "No suitable factory was found either"));
++                      return PJSIP_EUNSUPTRANSPORT;
++              }
+       }
+     }
+-- 
+2.5.0
+
diff --git a/third-party/pjproject/patches/config_site.h b/third-party/pjproject/patches/config_site.h
new file mode 100644 (file)
index 0000000..544c1e8
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Asterisk config_site.h
+ */
+
+#include <sys/select.h>
+
+#define PJ_HAS_IPV6 1
+#define NDEBUG 1
+#define PJ_MAX_HOSTNAME (256)
+#define PJSIP_MAX_URL_SIZE (512)
+#ifdef PJ_HAS_LINUX_EPOLL
+#define PJ_IOQUEUE_MAX_HANDLES (5000)
+#else
+#define PJ_IOQUEUE_MAX_HANDLES (FD_SETSIZE)
+#endif
+#define PJ_IOQUEUE_HAS_SAFE_UNREG 1
+#define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL (16)
+
+#define PJ_SCANNER_USE_BITWISE 0
+#define PJ_OS_HAS_CHECK_STACK  0
+#define PJ_LOG_MAX_LEVEL               3
+#define PJ_ENABLE_EXTRA_CHECK  0
+#define PJSIP_MAX_TSX_COUNT            ((64*1024)-1)
+#define PJSIP_MAX_DIALOG_COUNT ((64*1024)-1)
+#define PJSIP_UDP_SO_SNDBUF_SIZE       (512*1024)
+#define PJSIP_UDP_SO_RCVBUF_SIZE       (512*1024)
+#define PJ_DEBUG                       0
+#define PJSIP_SAFE_MODULE              0
+#define PJ_HAS_STRICMP_ALNUM           0
+#define PJ_HASH_USE_OWN_TOLOWER                1
+#define PJSIP_UNESCAPE_IN_PLACE                1
+
+#undef PJ_TODO
+#define PJ_TODO(x)
diff --git a/third-party/pjproject/patches/user.mak b/third-party/pjproject/patches/user.mak
new file mode 100644 (file)
index 0000000..31579d1
--- /dev/null
@@ -0,0 +1,2 @@
+
+CFLAGS += -fPIC -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-label -Wno-unused-function -Wno-strict-aliasing
diff --git a/third-party/versions.mak b/third-party/versions.mak
new file mode 100644 (file)
index 0000000..7b8b59c
--- /dev/null
@@ -0,0 +1,2 @@
+
+PJPROJECT_VERSION = 2.4.5