diff --git a/CHANGES b/CHANGES index 91e170ffbb..aaaf3f5d1a 100644 --- 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. diff --git a/Makefile b/Makefile index a07a3299b1..7528f83749 100644 --- 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 diff --git a/configure b/configure index 2c0f99d4f3..3967cec633 100755 --- 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 @@ -10446,37 +10451,28 @@ fi +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" - ;; + +# 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 + +_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 + +_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 + +_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 + +_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 + +_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 + +_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" @@ -24739,10 +25006,10 @@ fi -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 diff --git a/configure.ac b/configure.ac index 1ca5eb3dbb..12cc8d276c 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) +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_LIBS], [$PJPROJECT_CFLAGS]) + 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_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}" + 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_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], [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]) diff --git a/include/asterisk/_private.h b/include/asterisk/_private.h index 7963f3121a..a4a4f1bea4 100644 --- a/include/asterisk/_private.h +++ b/include/asterisk/_private.h @@ -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 */ diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in index 6ed96ccb5f..43f86b0884 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,26 +580,25 @@ /* 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. */ diff --git a/main/.gitignore b/main/.gitignore index 3ff4656798..cb90a5e3b2 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 b25fb450ac..50fdc5739e 100644 --- a/main/Makefile +++ b/main/Makefile @@ -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 diff --git a/main/asterisk.c b/main/asterisk.c index ca560cdb27..da804e1963 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -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 index 0000000000..aed0ec8b14 --- /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 + * George Joseph + * + * 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 + */ + +/*** MODULEINFO + core + ***/ + +#include "asterisk.h" + +ASTERISK_REGISTER_FILE() + +#ifdef HAVE_PJPROJECT +#include +#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; +} diff --git a/makeopts.in b/makeopts.in index f606acee0e..6baef1b466 100644 --- a/makeopts.in +++ b/makeopts.in @@ -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 index 0000000000..0aca21e06a --- /dev/null +++ b/third-party/Makefile @@ -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 index 0000000000..ac4189ac4d --- /dev/null +++ b/third-party/Makefile.rules @@ -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 index 0000000000..5079deeb35 --- /dev/null +++ b/third-party/pjproject/.gitignore @@ -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 index 0000000000..310095159c --- /dev/null +++ b/third-party/pjproject/Makefile @@ -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 index 0000000000..d6e4be00be --- /dev/null +++ b/third-party/pjproject/Makefile.rules @@ -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 index 0000000000..1b72d14b02 --- /dev/null +++ b/third-party/pjproject/apply_patches @@ -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 index 0000000000..3351527ebb --- /dev/null +++ b/third-party/pjproject/configure.m4 @@ -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 index 0000000000..33fc8ea4ec --- /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 + #include + #include ++#include + #include + + /* +@@ -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, +- ¶m->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 index 0000000000..9873abf0e6 --- /dev/null +++ b/third-party/pjproject/patches/0001-Bump-tcp-tls-and-transaction-log-levels-from-1-to-3.patch @@ -0,0 +1,70 @@ +From a147b72df1ec150c1d733e882225db86142fb339 Mon Sep 17 00:00:00 2001 +From: George Joseph +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 index 0000000000..36b6c651f1 --- /dev/null +++ b/third-party/pjproject/patches/0001-ioqueue-Enable-epoll-in-aconfigure.ac.patch @@ -0,0 +1,80 @@ +From b5c0bc905911f75e08987e6833075481fe16dab2 Mon Sep 17 00:00:00 2001 +From: George Joseph +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 index 0000000000..001912cfe3 --- /dev/null +++ b/third-party/pjproject/patches/0001-sip_transport-Search-for-transport-even-if-listener-.patch @@ -0,0 +1,114 @@ +From 552194179eb6deae8326eb0fef446e69240ea41b Mon Sep 17 00:00:00 2001 +From: George Joseph +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 index 0000000000..544c1e85ec --- /dev/null +++ b/third-party/pjproject/patches/config_site.h @@ -0,0 +1,34 @@ +/* + * Asterisk config_site.h + */ + +#include + +#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 index 0000000000..31579d19cc --- /dev/null +++ b/third-party/pjproject/patches/user.mak @@ -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 index 0000000000..7b8b59c538 --- /dev/null +++ b/third-party/versions.mak @@ -0,0 +1,2 @@ + +PJPROJECT_VERSION = 2.4.5