summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES18
-rw-r--r--apps/app_confbridge.c15
-rw-r--r--apps/app_followme.c17
-rw-r--r--apps/confbridge/conf_config_parser.c19
-rw-r--r--apps/confbridge/include/confbridge.h1
-rw-r--r--configs/basic-pbx/asterisk.conf25
-rw-r--r--configs/samples/confbridge.conf.sample2
-rw-r--r--configs/samples/hep.conf.sample4
-rwxr-xr-xconfigure115
-rw-r--r--configure.ac8
-rw-r--r--contrib/ast-db-manage/config/versions/837aa67461fb_ps_contacts_add_authenticate_qualify.py32
-rw-r--r--include/asterisk/autoconfig.h.in3
-rw-r--r--include/asterisk/res_hep.h14
-rw-r--r--main/config_options.c2
-rw-r--r--main/file.c24
-rw-r--r--main/stasis_endpoints.c7
-rw-r--r--main/strings.c6
-rw-r--r--makeopts.in3
-rw-r--r--res/ari/resource_bridges.c2
-rw-r--r--res/ari/resource_channels.c2
-rw-r--r--res/res_ari.c3
-rw-r--r--res/res_fax.c46
-rw-r--r--res/res_hep.c37
-rw-r--r--res/res_hep.exports.in1
-rw-r--r--res/res_hep_pjsip.c9
-rw-r--r--res/res_hep_rtcp.c33
-rw-r--r--res/res_pjsip.c7
-rw-r--r--res/res_pjsip/config_transport.c4
-rw-r--r--res/res_pjsip/location.c1
-rw-r--r--res/res_pjsip/pjsip_distributor.c2
-rw-r--r--res/res_pjsip/pjsip_options.c64
-rw-r--r--res/res_pjsip_authenticator_digest.c7
-rw-r--r--res/res_pjsip_endpoint_identifier_ip.c2
-rw-r--r--res/res_pjsip_endpoint_identifier_user.c2
-rw-r--r--res/res_pjsip_outbound_registration.c2
-rw-r--r--res/res_pjsip_registrar.c2
-rw-r--r--res/res_sorcery_astdb.c3
-rw-r--r--third-party/pjproject/Makefile20
-rw-r--r--third-party/pjproject/Makefile.rules2
39 files changed, 470 insertions, 96 deletions
diff --git a/CHANGES b/CHANGES
index 63b814c21..5b3864953 100644
--- a/CHANGES
+++ b/CHANGES
@@ -26,6 +26,24 @@ res_pjsip
into the "reg_server" field in the ps_contacts table to facilitate
multi-server setups.
+res_hep
+------------------
+ * Added a new option, 'uuid_type', that sets the preferred source of the Homer
+ correlation UUID. The valid options are:
+ - call-id: Use the PJSIP SIP Call-ID header value
+ - channel: Use the Asterisk channel name
+ The default value is 'call-id'. In the event that a HEP module cannot find a
+ valid value using the specified 'uuid_type', the module may fallback to a
+ more readily available source for the correlation UUID.
+
+app_confbridge
+------------------
+ * Added a bridge profile option called regcontext that allows you to
+ dynamically register the conference bridge name as an extension into
+ the specified context. This allows tracking down conferences on multi-
+ server installations via alternate means (DUNDI for example). By default
+ this feature is not used.
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 13.8.0 to Asterisk 13.9.0 ------------
------------------------------------------------------------------------------
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index 55b7b1240..991b3a307 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -1253,9 +1253,17 @@ void conf_handle_second_active(struct confbridge_conference *conference)
void conf_ended(struct confbridge_conference *conference)
{
+ struct pbx_find_info q = { .stacklen = 0 };
+
/* Called with a reference to conference */
ao2_unlink(conference_bridges, conference);
send_conf_end_event(conference);
+ if (!ast_strlen_zero(conference->b_profile.regcontext) &&
+ pbx_find_extension(NULL, NULL, &q, conference->b_profile.regcontext,
+ conference->name, 1, NULL, "", E_MATCH)) {
+ ast_context_remove_extension(conference->b_profile.regcontext,
+ conference->name, 1, NULL);
+ }
ao2_lock(conference);
conf_stop_record(conference);
ao2_unlock(conference);
@@ -1360,6 +1368,13 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen
}
send_conf_start_event(conference);
+
+ if (!ast_strlen_zero(conference->b_profile.regcontext)) {
+ if (!ast_exists_extension(NULL, conference->b_profile.regcontext, conference->name, 1, NULL)) {
+ ast_add_extension(conference->b_profile.regcontext, 1, conference->name, 1, NULL, NULL, "Noop", NULL, NULL, "ConfBridge");
+ }
+ }
+
ast_debug(1, "Created conference '%s' and linked to container.\n", conference_name);
}
diff --git a/apps/app_followme.c b/apps/app_followme.c
index e5a5ee3c5..af6bb1039 100644
--- a/apps/app_followme.c
+++ b/apps/app_followme.c
@@ -66,6 +66,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/stasis_channels.h"
#include "asterisk/max_forwards.h"
+#define REC_FORMAT "sln"
+
/*** DOCUMENTATION
<application name="FollowMe" language="en_US">
<synopsis>
@@ -1421,7 +1423,7 @@ static int app_exec(struct ast_channel *chan, const char *data)
snprintf(targs->namerecloc, sizeof(targs->namerecloc), "%s/followme.%s",
ast_config_AST_SPOOL_DIR, ast_channel_uniqueid(chan));
- if (ast_play_and_record(chan, "vm-rec-name", targs->namerecloc, 5, "sln", &duration,
+ if (ast_play_and_record(chan, "vm-rec-name", targs->namerecloc, 5, REC_FORMAT, &duration,
NULL, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE), 0, NULL) < 0) {
goto outrun;
}
@@ -1522,7 +1524,18 @@ outrun:
ast_free(nm);
}
if (!ast_strlen_zero(targs->namerecloc)) {
- unlink(targs->namerecloc);
+ int ret;
+ char fn[PATH_MAX];
+
+ snprintf(fn, sizeof(fn), "%s.%s", targs->namerecloc,
+ REC_FORMAT);
+ ret = unlink(fn);
+ if (ret != 0) {
+ ast_log(LOG_NOTICE, "Failed to delete recorded name file %s: %d (%s)\n",
+ fn, errno, strerror(errno));
+ } else {
+ ast_debug(2, "deleted recorded prompt %s.\n", fn);
+ }
}
ast_free((char *) targs->predial_callee);
ast_party_connected_line_free(&targs->connected_in);
diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c
index b8b1e2a9c..f5bb7eb57 100644
--- a/apps/confbridge/conf_config_parser.c
+++ b/apps/confbridge/conf_config_parser.c
@@ -317,6 +317,22 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
on a conference.
</para></description>
</configOption>
+ <configOption name="regcontext">
+ <synopsis>The name of the context into which to register the name of the conference bridge as NoOP() at priority 1</synopsis>
+ <description><para>
+ When set this will cause the name of the created conference to be registered
+ into the named context at priority 1 with an operation of NoOP(). This can
+ then be used in other parts of the dialplan to test for the existence of a
+ specific conference bridge.
+ You should be aware that there are potential races between testing for the
+ existence of a bridge, and taking action upon that information, consider
+ for example two callers executing the check simultaniously, and then taking
+ special action as "first caller" into the bridge. The same for exiting,
+ directly after the check the bridge can be destroyed before the new caller
+ enters (creating a new bridge), for example, and the "first member" actions
+ could thus be missed.
+ </para></description>
+ </configOption>
<configOption name="video_mode">
<synopsis>Sets how confbridge handles video distribution to the conference participants</synopsis>
<description><para>
@@ -1563,6 +1579,8 @@ static char *handle_cli_confbridge_show_bridge_profile(struct ast_cli_entry *e,
ast_cli(a->fd,"Max Members: No Limit\n");
}
+ ast_cli(a->fd,"Registration context: %s\n", b_profile.regcontext);
+
switch (b_profile.flags
& (BRIDGE_OPT_VIDEO_SRC_LAST_MARKED | BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED
| BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER)) {
@@ -2128,6 +2146,7 @@ int conf_load_config(void)
aco_option_register(&cfg_info, "record_file_append", ACO_EXACT, bridge_types, "yes", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), BRIDGE_OPT_RECORD_FILE_APPEND);
aco_option_register(&cfg_info, "max_members", ACO_EXACT, bridge_types, "0", OPT_UINT_T, 0, FLDSET(struct bridge_profile, max_members));
aco_option_register(&cfg_info, "record_file", ACO_EXACT, bridge_types, NULL, OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, rec_file));
+ aco_option_register(&cfg_info, "regcontext", ACO_EXACT, bridge_types, NULL, OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, regcontext));
aco_option_register(&cfg_info, "language", ACO_EXACT, bridge_types, "en", OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, language));
aco_option_register_custom(&cfg_info, "^sound_", ACO_REGEX, bridge_types, NULL, sound_option_handler, 0);
/* This option should only be used with the CONFBRIDGE dialplan function */
diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h
index 8d2dffb1c..a1fa5a2b7 100644
--- a/apps/confbridge/include/confbridge.h
+++ b/apps/confbridge/include/confbridge.h
@@ -207,6 +207,7 @@ struct bridge_profile {
unsigned int internal_sample_rate; /*!< The internal sample rate of the bridge. 0 when set to auto adjust mode. */
unsigned int mix_interval; /*!< The internal mixing interval used by the bridge. When set to 0 the bridgewill use a default interval. */
struct bridge_profile_sounds *sounds;
+ char regcontext[AST_MAX_CONTEXT];
};
/*! \brief The structure that represents a conference bridge */
diff --git a/configs/basic-pbx/asterisk.conf b/configs/basic-pbx/asterisk.conf
index 576cc976b..ff66ceea7 100644
--- a/configs/basic-pbx/asterisk.conf
+++ b/configs/basic-pbx/asterisk.conf
@@ -1,26 +1,13 @@
-[directories]
-astetcdir => /etc/asterisk
-astmoddir => /usr/lib/asterisk/modules
-astvarlibdir => /var/lib/asterisk
-astdbdir => /var/lib/asterisk
-astkeydir => /var/lib/asterisk
-astdatadir => /var/lib/asterisk
-astagidir => /var/lib/asterisk/agi-bin
-astspooldir => /var/spool/asterisk
-astrundir => /var/run/asterisk
-astlogdir => /var/log/asterisk
-astsbindir => /usr/sbin
-
[options]
; If we want to start Asterisk with a default verbosity for the verbose
-; or debug logger channel types, then we use these settings.
+; or debug logger channel types, then we use these settings (by default
+; they are disabled).
;verbose = 5
-;debug = 5
+;debug = 2
; User and group to run asterisk as. NOTE: This will require changes to
; directory and device permissions.
-;runuser = asterisk ; The user to run as.
-;rungroup = asterisk ; The group to run as.
+;runuser = asterisk ; The user to run as. The default is root.
+;rungroup = asterisk ; The group to run as. The default is root
-defaultlanguage = en
-documentation_language = en_US
+;defaultlanguage = es
diff --git a/configs/samples/confbridge.conf.sample b/configs/samples/confbridge.conf.sample
index d0bdd6fd9..49208c31b 100644
--- a/configs/samples/confbridge.conf.sample
+++ b/configs/samples/confbridge.conf.sample
@@ -211,6 +211,8 @@ type=bridge
;language=en ; Set the language used for announcements to the conference.
; Default is en (English).
+;regcontext=conferences ; The name of the context into which to register conference names as extensions.
+
; All sounds in the conference are customizable using the bridge profile options below.
; Simply state the option followed by the filename or full path of the filename after
; the option. Example: sound_had_joined=conf-hasjoin This will play the conf-hasjoin
diff --git a/configs/samples/hep.conf.sample b/configs/samples/hep.conf.sample
index 40b17aa0e..6e409d151 100644
--- a/configs/samples/hep.conf.sample
+++ b/configs/samples/hep.conf.sample
@@ -13,4 +13,8 @@ capture_password = foo ; If specified, the authorization passsword
capture_id = 1234 ; A unique integer identifier for this
; server. This ID will be embedded sent
; with each packet from this server.
+uuid_type = call-id ; Specify the preferred source for the Homer
+ ; correlation UUID. Valid options are:
+ ; - 'call-id' for the PJSIP SIP Call-ID
+ ; - 'channel' for the Asterisk channel name
diff --git a/configure b/configure
index 6e305bcda..ff34770a1 100755
--- a/configure
+++ b/configure
@@ -663,6 +663,10 @@ PWLIB_LIBDIR
PWLIB_INCDIR
PWLIBDIR
PTLIB_CONFIG
+PYTHONDEV_LIBS
+PYTHONDEV_CFLAGS
+PYTHONDEV_INCLUDE
+PYTHONDEV_LIB
PJPROJECT_LIBS
PJPROJECT_CFLAGS
PG_CONFIG
@@ -1416,6 +1420,8 @@ LIBEDIT_CFLAGS
LIBEDIT_LIBS
PJPROJECT_CFLAGS
PJPROJECT_LIBS
+PYTHONDEV_CFLAGS
+PYTHONDEV_LIBS
GMIME_CFLAGS
GMIME_LIBS
GTK2_CFLAGS
@@ -2158,6 +2164,10 @@ Some influential environment variables:
C compiler flags for PJPROJECT, overriding pkg-config
PJPROJECT_LIBS
linker flags for PJPROJECT, overriding pkg-config
+ PYTHONDEV_CFLAGS
+ C compiler flags for PYTHONDEV, overriding pkg-config
+ PYTHONDEV_LIBS
+ linker flags for PYTHONDEV, overriding pkg-config
GMIME_CFLAGS
C compiler flags for GMIME, overriding pkg-config
GMIME_LIBS linker flags for GMIME, overriding pkg-config
@@ -13602,7 +13612,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -13648,7 +13658,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -13672,7 +13682,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -13717,7 +13727,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -13741,7 +13751,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -17604,7 +17614,7 @@ if ac_fn_c_try_compile "$LINENO"; then :
$as_echo "yes" >&6; }
AST_LEAK_SANITIZER=1
else
- AST_LEAK_SANITIZER=
+ AST_LEAK_SANITIZER=0
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
@@ -17636,7 +17646,7 @@ if ac_fn_c_try_compile "$LINENO"; then :
$as_echo "yes" >&6; }
AST_UNDEFINED_SANITIZER=1
else
- AST_UNDEFINED_SANITIZER=
+ AST_UNDEFINED_SANITIZER=0
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
@@ -25172,6 +25182,97 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
+
+
+ if test "x${PBX_PYTHONDEV}" != "x1" -a "${USE_PYTHONDEV}" != "no"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PYTHONDEV" >&5
+$as_echo_n "checking for PYTHONDEV... " >&6; }
+
+if test -n "$PYTHONDEV_CFLAGS"; then
+ pkg_cv_PYTHONDEV_CFLAGS="$PYTHONDEV_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"python\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "python") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PYTHONDEV_CFLAGS=`$PKG_CONFIG --cflags "python" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$PYTHONDEV_LIBS"; then
+ pkg_cv_PYTHONDEV_LIBS="$PYTHONDEV_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"python\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "python") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PYTHONDEV_LIBS=`$PKG_CONFIG --libs "python" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ PYTHONDEV_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "python" 2>&1`
+ else
+ PYTHONDEV_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "python" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$PYTHONDEV_PKG_ERRORS" >&5
+
+
+ PBX_PYTHONDEV=0
+
+
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ PBX_PYTHONDEV=0
+
+
+else
+ PYTHONDEV_CFLAGS=$pkg_cv_PYTHONDEV_CFLAGS
+ PYTHONDEV_LIBS=$pkg_cv_PYTHONDEV_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ PBX_PYTHONDEV=1
+ PYTHONDEV_INCLUDE="$PYTHONDEV_CFLAGS"
+ PYTHONDEV_LIB="$PYTHONDEV_LIBS"
+
+$as_echo "#define HAVE_PYTHONDEV 1" >>confdefs.h
+
+
+fi
+ fi
+
+
+
if test "x${PBX_POPT}" != "x1" -a "${USE_POPT}" != "no"; then
pbxlibdir=""
# if --with-POPT=DIR has been specified, use it.
diff --git a/configure.ac b/configure.ac
index 7571f7fd5..f2e42ba1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1116,7 +1116,7 @@ AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([], [int x = 1;])],
AC_MSG_RESULT(yes)
[AST_LEAK_SANITIZER=1],
- [AST_LEAK_SANITIZER=]
+ [AST_LEAK_SANITIZER=0]
AC_MSG_RESULT(no)
)
CFLAGS="${saved_sanitize_CFLAGS}"
@@ -1132,7 +1132,7 @@ AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([], [int x = 1;])],
AC_MSG_RESULT(yes)
[AST_UNDEFINED_SANITIZER=1],
- [AST_UNDEFINED_SANITIZER=]
+ [AST_UNDEFINED_SANITIZER=0]
AC_MSG_RESULT(no)
)
CFLAGS="${saved_sanitize_CFLAGS}"
@@ -2197,6 +2197,10 @@ if test "$USE_PJPROJECT" != "no" ; then
fi
fi
+AC_SUBST([PYTHONDEV_LIB])
+AC_SUBST([PYTHONDEV_INCLUDE])
+AST_PKG_CONFIG_CHECK([PYTHONDEV], [python])
+
AST_EXT_LIB_CHECK([POPT], [popt], [poptStrerror], [popt.h])
AST_EXT_LIB_CHECK([PORTAUDIO], [portaudio], [Pa_GetDeviceCount], [portaudio.h])
diff --git a/contrib/ast-db-manage/config/versions/837aa67461fb_ps_contacts_add_authenticate_qualify.py b/contrib/ast-db-manage/config/versions/837aa67461fb_ps_contacts_add_authenticate_qualify.py
new file mode 100644
index 000000000..76faf394c
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/837aa67461fb_ps_contacts_add_authenticate_qualify.py
@@ -0,0 +1,32 @@
+"""ps_contacts add authenticate_qualify
+
+Revision ID: 6be31516058d
+Revises: 81b01a191a46
+Create Date: 2016-05-03 14:57:12.538179
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '6be31516058d'
+down_revision = '81b01a191a46'
+
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.dialects.postgresql import ENUM
+
+YESNO_NAME = 'yesno_values'
+YESNO_VALUES = ['yes', 'no']
+
+def upgrade():
+ ############################# Enums ##############################
+
+ # yesno_values have already been created, so use postgres enum object
+ # type to get around "already created" issue - works okay with mysql
+ yesno_values = ENUM(*YESNO_VALUES, name=YESNO_NAME, create_type=False)
+
+ op.add_column('ps_contacts', sa.Column('authenticate_qualify', yesno_values))
+
+
+def downgrade():
+ op.drop_column('ps_contacts', 'authenticate_qualify')
+
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index 80780986a..a01131cc3 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -731,6 +731,9 @@
/* Define if your system has the PWLib libraries. */
#undef HAVE_PWLIB
+/* Define if your system has the PYTHONDEV libraries. */
+#undef HAVE_PYTHONDEV
+
/* Define to 1 if you have the Radius Client library. */
#undef HAVE_RADIUS
diff --git a/include/asterisk/res_hep.h b/include/asterisk/res_hep.h
index 8839fd60a..bd0129eea 100644
--- a/include/asterisk/res_hep.h
+++ b/include/asterisk/res_hep.h
@@ -49,6 +49,11 @@ enum hepv3_capture_type {
HEPV3_CAPTURE_TYPE_IAX = 0x10,
};
+enum hep_uuid_type {
+ HEP_UUID_TYPE_CALL_ID = 0,
+ HEP_UUID_TYPE_CHANNEL,
+};
+
/*! \brief HEPv3 Capture Info */
struct hepv3_capture_info {
/*! The source address of the packet */
@@ -104,6 +109,15 @@ struct hepv3_capture_info *hepv3_create_capture_info(const void *payload, size_t
*/
int hepv3_send_packet(struct hepv3_capture_info *capture_info);
+/*!
+ * \brief Get the preferred UUID type
+ *
+ * \since 13.10.0
+ *
+ * \retval The type of UUID the packet should use
+ */
+enum hep_uuid_type hepv3_get_uuid_type(void);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
diff --git a/main/config_options.c b/main/config_options.c
index db99a441d..c8988c984 100644
--- a/main/config_options.c
+++ b/main/config_options.c
@@ -198,8 +198,8 @@ static int link_option_to_types(struct aco_info *info, struct aco_type **types,
#ifdef AST_DEVMODE
opt->doc_unavailable = 1;
#endif
-#endif
}
+#endif
}
/* The container(s) should hold the only ref to opt */
ao2_ref(opt, -1);
diff --git a/main/file.c b/main/file.c
index 7ce021340..1c51177c2 100644
--- a/main/file.c
+++ b/main/file.c
@@ -799,7 +799,7 @@ struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *fil
/* As above, but for video. But here we don't have translators
* so we must enforce a format.
*/
- struct ast_format_cap *tmp_cap;
+ struct ast_format_cap *nativeformats, *tmp_cap;
char *buf;
int buflen;
int i, fd;
@@ -810,16 +810,23 @@ struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *fil
buflen = strlen(preflang) + strlen(filename) + 4;
buf = ast_alloca(buflen);
+ ast_channel_lock(chan);
+ nativeformats = ao2_bump(ast_channel_nativeformats(chan));
+ ast_channel_unlock(chan);
+
/* is the channel capable of video without translation ?*/
- if (!ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_MEDIA_TYPE_VIDEO)) {
+ if (!ast_format_cap_has_type(nativeformats, AST_MEDIA_TYPE_VIDEO)) {
+ ao2_cleanup(nativeformats);
return NULL;
}
if (!(tmp_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
+ ao2_cleanup(nativeformats);
return NULL;
}
/* Video is supported, so see what video formats exist for this file */
if (!fileexists_core(filename, NULL, preflang, buf, buflen, tmp_cap)) {
ao2_ref(tmp_cap, -1);
+ ao2_cleanup(nativeformats);
return NULL;
}
@@ -828,7 +835,7 @@ struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *fil
struct ast_format *format = ast_format_cap_get_format(tmp_cap, i);
if ((ast_format_get_type(format) != AST_MEDIA_TYPE_VIDEO) ||
- !ast_format_cap_iscompatible(ast_channel_nativeformats(chan), tmp_cap)) {
+ !ast_format_cap_iscompatible(nativeformats, tmp_cap)) {
ao2_ref(format, -1);
continue;
}
@@ -837,12 +844,14 @@ struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *fil
if (fd >= 0) {
ao2_ref(format, -1);
ao2_ref(tmp_cap, -1);
+ ao2_cleanup(nativeformats);
return ast_channel_vstream(chan);
}
ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
ao2_ref(format, -1);
}
ao2_ref(tmp_cap, -1);
+ ao2_cleanup(nativeformats);
return NULL;
}
@@ -1097,8 +1106,10 @@ int ast_streamfile(struct ast_channel *chan, const char *filename, const char *p
fs = ast_openstream(chan, filename, preflang);
if (!fs) {
struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
+ ast_channel_lock(chan);
ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n",
filename, ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf), strerror(errno));
+ ast_channel_unlock(chan);
return -1;
}
@@ -1133,7 +1144,12 @@ int ast_streamfile(struct ast_channel *chan, const char *filename, const char *p
res = ast_playstream(fs);
if (!res && vfs)
res = ast_playstream(vfs);
- ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", ast_channel_name(chan), filename, ast_format_get_name(ast_channel_writeformat(chan)), preflang ? preflang : "default");
+
+ if (VERBOSITY_ATLEAST(3)) {
+ ast_channel_lock(chan);
+ ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", ast_channel_name(chan), filename, ast_format_get_name(ast_channel_writeformat(chan)), preflang ? preflang : "default");
+ ast_channel_unlock(chan);
+ }
return res;
}
diff --git a/main/stasis_endpoints.c b/main/stasis_endpoints.c
index fbca2ad9b..a91cd9f6b 100644
--- a/main/stasis_endpoints.c
+++ b/main/stasis_endpoints.c
@@ -86,6 +86,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<enum name="Reachable"/>
<enum name="Created"/>
<enum name="Removed"/>
+ <enum name="Updated"/>
</enumlist>
</parameter>
<parameter name="AOR">
@@ -97,6 +98,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<parameter name="RoundtripUsec">
<para>The RTT measured during the last qualify.</para>
</parameter>
+ <parameter name="UserAgent">
+ <para>Content of the User-Agent header in REGISTER request</para>
+ </parameter>
+ <parameter name="RegExpire">
+ <para>Absolute time that this contact is no longer valid after</para>
+ </parameter>
</syntax>
</managerEventInstance>
</managerEvent>
diff --git a/main/strings.c b/main/strings.c
index 9e885ebc3..db78a6cd2 100644
--- a/main/strings.c
+++ b/main/strings.c
@@ -234,8 +234,8 @@ int ast_strings_match(const char *left, const char *op, const char *right)
{
char *internal_op = (char *)op;
char *internal_right = (char *)right;
- float left_num;
- float right_num;
+ double left_num;
+ double right_num;
int scan_numeric = 0;
if (!(left && right)) {
@@ -297,7 +297,7 @@ regex:
}
equals:
- scan_numeric = (sscanf(left, "%f", &left_num) && sscanf(internal_right, "%f", &right_num));
+ scan_numeric = (sscanf(left, "%lf", &left_num) && sscanf(internal_right, "%lf", &right_num));
if (internal_op[0] == '=') {
if (ast_strlen_zero(left) && ast_strlen_zero(internal_right)) {
diff --git a/makeopts.in b/makeopts.in
index bfc965de4..9fa49bc04 100644
--- a/makeopts.in
+++ b/makeopts.in
@@ -243,6 +243,9 @@ PORTAUDIO_LIB=@PORTAUDIO_LIB@
PRI_INCLUDE=@PRI_INCLUDE@
PRI_LIB=@PRI_LIB@
+PYTHONDEV_INCLUDE=@PYTHONDEV_INCLUDE@
+PYTHONDEV_LIB=@PYTHONDEV_LIB@
+
RESAMPLE_INCLUDE=@RESAMPLE_INCLUDE@
RESAMPLE_LIB=@RESAMPLE_LIB@
diff --git a/res/ari/resource_bridges.c b/res/ari/resource_bridges.c
index a37b83146..a86f3129c 100644
--- a/res/ari/resource_bridges.c
+++ b/res/ari/resource_bridges.c
@@ -381,7 +381,7 @@ static int ari_bridges_play_helper(const char *args_media,
return -1;
}
- if (ast_asprintf(playback_url, "/playback/%s",
+ if (ast_asprintf(playback_url, "/playbacks/%s",
stasis_app_playback_get_id(playback)) == -1) {
playback_url = NULL;
ast_ari_response_alloc_failed(response);
diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c
index f722802d8..9e2db9de6 100644
--- a/res/ari/resource_channels.c
+++ b/res/ari/resource_channels.c
@@ -524,7 +524,7 @@ static void ari_channels_handle_play(
return;
}
- if (ast_asprintf(&playback_url, "/playback/%s",
+ if (ast_asprintf(&playback_url, "/playbacks/%s",
stasis_app_playback_get_id(playback)) == -1) {
playback_url = NULL;
ast_ari_response_error(
diff --git a/res/res_ari.c b/res/res_ari.c
index f39db16cd..4a0a22d79 100644
--- a/res/res_ari.c
+++ b/res/res_ari.c
@@ -304,10 +304,11 @@ void ast_ari_response_alloc_failed(struct ast_ari_response *response)
void ast_ari_response_created(struct ast_ari_response *response,
const char *url, struct ast_json *message)
{
+ RAII_VAR(struct stasis_rest_handlers *, root, get_root_handler(), ao2_cleanup);
response->message = message;
response->response_code = 201;
response->response_text = "Created";
- ast_str_append(&response->headers, 0, "Location: %s\r\n", url);
+ ast_str_append(&response->headers, 0, "Location: /%s%s\r\n", root->path_segment, url);
}
static void add_allow_header(struct stasis_rest_handlers *handler,
diff --git a/res/res_fax.c b/res/res_fax.c
index 2fa64bc0f..6282b13d7 100644
--- a/res/res_fax.c
+++ b/res/res_fax.c
@@ -626,6 +626,8 @@ static const struct ast_datastore_info fax_datastore = {
static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_details *details);
static int fax_detect_attach(struct ast_channel *chan, int timeout, int flags);
static struct ast_fax_session_details *find_or_create_details(struct ast_channel *chan);
+static struct ast_fax_session *fax_v21_session_new (struct ast_channel *chan);
+
/*! \brief Copies fax detection and gateway framehooks during masquerades
*
@@ -2835,6 +2837,23 @@ static void destroy_gateway(void *data)
ao2_cleanup(gateway->peer_write_format);
}
+static struct ast_fax_session *fax_v21_session_new (struct ast_channel *chan) {
+ struct ast_fax_session_details *v21_details;
+ struct ast_fax_session *v21_session;
+
+ if (!chan || !(v21_details = session_details_new())) {
+ return NULL;
+ }
+
+ v21_details->caps = AST_FAX_TECH_V21_DETECT;
+ if (!(v21_session = fax_session_new(v21_details, chan, NULL, NULL))) {
+ ao2_ref(v21_details, -1);
+ return NULL;
+ }
+
+ return v21_session;
+}
+
/*! \brief Create a new fax gateway object.
* \param chan the channel the gateway object will be attached to
* \param details the fax session details
@@ -2843,30 +2862,16 @@ static void destroy_gateway(void *data)
static struct fax_gateway *fax_gateway_new(struct ast_channel *chan, struct ast_fax_session_details *details)
{
struct fax_gateway *gateway = ao2_alloc(sizeof(*gateway), destroy_gateway);
- struct ast_fax_session_details *v21_details;
if (!gateway) {
return NULL;
}
- if (!(v21_details = session_details_new())) {
+ if (!(gateway->chan_v21_session = fax_v21_session_new(chan))) {
+ ast_log(LOG_ERROR, "Can't create V21 session on chan %s for T.38 gateway session\n", ast_channel_name(chan));
ao2_ref(gateway, -1);
return NULL;
}
- v21_details->caps = AST_FAX_TECH_V21_DETECT;
- if (!(gateway->chan_v21_session = fax_session_new(v21_details, chan, NULL, NULL))) {
- ao2_ref(v21_details, -1);
- ao2_ref(gateway, -1);
- return NULL;
- }
-
- if (!(gateway->peer_v21_session = fax_session_new(v21_details, chan, NULL, NULL))) {
- ao2_ref(v21_details, -1);
- ao2_ref(gateway, -1);
- return NULL;
- }
- ao2_ref(v21_details, -1);
-
gateway->framehook = -1;
details->caps = AST_FAX_TECH_GATEWAY;
@@ -3360,6 +3365,11 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct
ast_channel_unlock(peer);
gateway->bridged = 1;
+ if (!(gateway->peer_v21_session = fax_v21_session_new(peer))) {
+ ast_log(LOG_ERROR, "Can't create V21 session on chan %s for T.38 gateway session\n", ast_channel_name(peer));
+ ast_framehook_detach(chan, gateway->framehook);
+ return f;
+ }
}
if (gateway->bridged && !ast_tvzero(gateway->timeout_start)) {
@@ -3486,6 +3496,10 @@ static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_d
.disable_inheritance = 1, /* Masquerade inheritance is handled through the datastore fixup */
};
+ if (global_fax_debug) {
+ details->option.debug = AST_FAX_OPTFLAG_TRUE;
+ }
+
ast_string_field_set(details, result, "SUCCESS");
ast_string_field_set(details, resultstr, "gateway operation started successfully");
ast_string_field_set(details, error, "NO_ERROR");
diff --git a/res/res_hep.c b/res/res_hep.c
index 69a8ab391..723b27df8 100644
--- a/res/res_hep.c
+++ b/res/res_hep.c
@@ -60,6 +60,15 @@
</enumlist>
</description>
</configOption>
+ <configOption name="uuid_type" default="call-id">
+ <synopsis>The preferred type of UUID to pass to Homer.</synopsis>
+ <description>
+ <enumlist>
+ <enum name="call-id"><para>Use the PJSIP Call-Id</para></enum>
+ <enum name="channel"><para>Use the Asterisk channel name</para></enum>
+ </enumlist>
+ </description>
+ </configOption>
<configOption name="capture_address" default="192.168.1.1:9061">
<synopsis>The address and port of the Homer server to send packets to.</synopsis>
</configOption>
@@ -231,6 +240,7 @@ struct hep_generic {
struct hepv3_global_config {
unsigned int enabled; /*!< Whether or not sending is enabled */
unsigned int capture_id; /*!< Capture ID for this agent */
+ enum hep_uuid_type uuid_type; /*!< The preferred type of the UUID */
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(capture_address); /*!< Address to send to */
AST_STRING_FIELD(capture_password); /*!< Password for Homer server */
@@ -329,6 +339,25 @@ static void *module_config_alloc(void)
return config;
}
+/*! \brief Handler for the uuid_type attribute */
+static int uuid_type_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+ struct hepv3_global_config *global_config = obj;
+
+ if (strcasecmp(var->name, "uuid_type")) {
+ return -1;
+ }
+
+ if (!strcasecmp(var->value, "channel")) {
+ global_config->uuid_type = HEP_UUID_TYPE_CHANNEL;
+ } else if (!strcasecmp(var->value, "call-id")) {
+ global_config->uuid_type = HEP_UUID_TYPE_CALL_ID;
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
/*! \brief HEPv3 run-time data destructor */
static void hepv3_data_dtor(void *obj)
{
@@ -376,6 +405,13 @@ static void capture_info_dtor(void *obj)
ast_free(info->payload);
}
+enum hep_uuid_type hepv3_get_uuid_type(void)
+{
+ RAII_VAR(struct module_config *, config, ao2_global_obj_ref(global_config), ao2_cleanup);
+
+ return config->general->uuid_type;
+}
+
struct hepv3_capture_info *hepv3_create_capture_info(const void *payload, size_t len)
{
struct hepv3_capture_info *info;
@@ -607,6 +643,7 @@ static int load_module(void)
aco_option_register(&cfg_info, "capture_address", ACO_EXACT, global_options, DEFAULT_HEP_SERVER, OPT_STRINGFIELD_T, 0, STRFLDSET(struct hepv3_global_config, capture_address));
aco_option_register(&cfg_info, "capture_password", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct hepv3_global_config, capture_password));
aco_option_register(&cfg_info, "capture_id", ACO_EXACT, global_options, "0", OPT_UINT_T, 0, STRFLDSET(struct hepv3_global_config, capture_id));
+ aco_option_register_custom(&cfg_info, "uuid_type", ACO_EXACT, global_options, "call-id", uuid_type_handler, 0);
if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
goto error;
diff --git a/res/res_hep.exports.in b/res/res_hep.exports.in
index d09d3f409..df0f2b4f7 100644
--- a/res/res_hep.exports.in
+++ b/res/res_hep.exports.in
@@ -2,6 +2,7 @@
global:
LINKER_SYMBOL_PREFIX*hepv3_send_packet;
LINKER_SYMBOL_PREFIX*hepv3_create_capture_info;
+ LINKER_SYMBOL_PREFIX*hepv3_get_uuid_type;
local:
*;
};
diff --git a/res/res_hep_pjsip.c b/res/res_hep_pjsip.c
index b5cf0b81e..caffd2563 100644
--- a/res/res_hep_pjsip.c
+++ b/res/res_hep_pjsip.c
@@ -51,13 +51,18 @@ static char *assign_uuid(const pj_str_t *call_id, const pj_str_t *local_tag, con
RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
pjsip_dialog *dlg;
char *uuid = NULL;
+ enum hep_uuid_type uuid_type = hepv3_get_uuid_type();
- if ((dlg = pjsip_ua_find_dialog(call_id, local_tag, remote_tag, PJ_FALSE))
+ if ((uuid_type == HEP_UUID_TYPE_CHANNEL)
+ && (dlg = pjsip_ua_find_dialog(call_id, local_tag, remote_tag, PJ_FALSE))
&& (session = ast_sip_dialog_get_session(dlg))
&& (session->channel)) {
uuid = ast_strdup(ast_channel_name(session->channel));
- } else {
+ }
+
+ /* If we couldn't get the channel or we never wanted it, default to the call-id */
+ if (!uuid) {
uuid = ast_malloc(pj_strlen(call_id) + 1);
if (uuid) {
diff --git a/res/res_hep_rtcp.c b/res/res_hep_rtcp.c
index 787512bbf..49a92539f 100644
--- a/res/res_hep_rtcp.c
+++ b/res/res_hep_rtcp.c
@@ -36,6 +36,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/res_hep.h"
#include "asterisk/module.h"
#include "asterisk/netsock2.h"
+#include "asterisk/channel.h"
+#include "asterisk/pbx.h"
#include "asterisk/stasis.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/json.h"
@@ -43,6 +45,35 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
static struct stasis_subscription *stasis_rtp_subscription;
+static char *assign_uuid(struct ast_json *json_channel)
+{
+ const char *channel_name = ast_json_string_get(ast_json_object_get(json_channel, "name"));
+ enum hep_uuid_type uuid_type = hepv3_get_uuid_type();
+ char *uuid = NULL;
+
+ if (!channel_name) {
+ return NULL;
+ }
+
+ if (uuid_type == HEP_UUID_TYPE_CALL_ID && ast_begins_with(channel_name, "PJSIP")) {
+ struct ast_channel *chan = ast_channel_get_by_name(channel_name);
+ char buf[128];
+
+ if (chan && !ast_func_read(chan, "CHANNEL(pjsip,call-id)", buf, sizeof(buf))) {
+ uuid = ast_strdup(buf);
+ }
+
+ ast_channel_cleanup(chan);
+ }
+
+ /* If we couldn't get the call-id or didn't want it, just use the channel name */
+ if (!uuid) {
+ uuid = ast_strdup(channel_name);
+ }
+
+ return uuid;
+}
+
static void rtcp_message_handler(struct stasis_message *message)
{
@@ -94,7 +125,7 @@ static void rtcp_message_handler(struct stasis_message *message)
ast_sockaddr_parse(&capture_info->src_addr, ast_json_string_get(from), PARSE_PORT_REQUIRE);
ast_sockaddr_parse(&capture_info->dst_addr, ast_json_string_get(to), PARSE_PORT_REQUIRE);
- capture_info->uuid = ast_strdup(ast_json_string_get(ast_json_object_get(json_channel, "name")));
+ capture_info->uuid = assign_uuid(json_channel);
if (!capture_info->uuid) {
ao2_ref(capture_info, -1);
return;
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index ae7155b6b..61d26302d 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -1092,6 +1092,13 @@
If <literal>0</literal> no timeout. Time in fractional seconds.
</para></description>
</configOption>
+ <configOption name="authenticate_qualify" default="no">
+ <synopsis>Authenticates a qualify request if needed</synopsis>
+ <description><para>
+ If true and a qualify request receives a challenge or authenticate response
+ authentication is attempted before declaring the contact available.
+ </para></description>
+ </configOption>
<configOption name="outbound_proxy">
<synopsis>Outbound proxy used when sending OPTIONS request</synopsis>
<description><para>
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index d2c087487..3a5afb6bc 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -378,6 +378,10 @@ static struct ast_sip_transport_state *find_or_create_temporary_state(struct ast
new_state->type = transport->type;
pjsip_tls_setting_default(&new_state->tls);
+#ifdef HAVE_PJSIP_TLS_TRANSPORT_PROTO
+ /* proto must be forced to 0 to enable all protocols otherwise only TLS will work */
+ new_state->tls.proto = 0;
+#endif
new_state->tls.ciphers = new_state->ciphers;
ao2_ref(new_state, +1);
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c
index db1d0794b..ef06456a7 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -1121,6 +1121,7 @@ int ast_sip_initialize_sorcery_location(void)
ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
PARSE_IN_RANGE, FLDSET(struct ast_sip_contact, qualify_frequency), 0, 86400);
ast_sorcery_object_field_register(sorcery, "contact", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_contact, qualify_timeout));
+ ast_sorcery_object_field_register(sorcery, "contact", "authenticate_qualify", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_contact, authenticate_qualify));
ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy));
ast_sorcery_object_field_register(sorcery, "contact", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, user_agent));
ast_sorcery_object_field_register(sorcery, "contact", "reg_server", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, reg_server));
diff --git a/res/res_pjsip/pjsip_distributor.c b/res/res_pjsip/pjsip_distributor.c
index cbe955728..b7da81433 100644
--- a/res/res_pjsip/pjsip_distributor.c
+++ b/res/res_pjsip/pjsip_distributor.c
@@ -391,7 +391,7 @@ static void log_unidentified_request(pjsip_rx_data *rdata, unsigned int count, u
" after %u tries in %.3f ms\n",
from_buf, rdata->pkt_info.src_name, rdata->pkt_info.src_port, callid_buf, count, period / 1000.0);
} else {
- ast_log(LOG_NOTICE, "Request from '%s' failed for '%s:%d' (callid: %s) - No matching endpoint found",
+ ast_log(LOG_NOTICE, "Request from '%s' failed for '%s:%d' (callid: %s) - No matching endpoint found\n",
from_buf, rdata->pkt_info.src_name, rdata->pkt_info.src_port, callid_buf);
}
}
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index f832e6f78..b9339f60b 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -1036,17 +1036,11 @@ int ast_sip_initialize_sorcery_qualify(void)
return 0;
}
-static int qualify_and_schedule_cb(void *obj, void *arg, int flags)
+static void qualify_and_schedule_contact(struct ast_sip_contact *contact)
{
- struct ast_sip_contact *contact = obj;
- struct ast_sip_aor *aor = arg;
int initial_interval;
int max_time = ast_sip_get_max_initial_qualify_time();
- contact->qualify_frequency = aor->qualify_frequency;
- contact->qualify_timeout = aor->qualify_timeout;
- contact->authenticate_qualify = aor->authenticate_qualify;
-
/* Delay initial qualification by a random fraction of the specified interval */
if (max_time && max_time < contact->qualify_frequency) {
initial_interval = max_time;
@@ -1062,26 +1056,47 @@ static int qualify_and_schedule_cb(void *obj, void *arg, int flags)
} else {
update_contact_status(contact, UNKNOWN);
}
+}
+
+static int qualify_and_schedule_cb_with_aor(void *obj, void *arg, int flags)
+{
+ struct ast_sip_contact *contact = obj;
+ struct ast_sip_aor *aor = arg;
+
+ contact->qualify_frequency = aor->qualify_frequency;
+ contact->qualify_timeout = aor->qualify_timeout;
+ contact->authenticate_qualify = aor->authenticate_qualify;
+
+ qualify_and_schedule_contact(contact);
+
+ return 0;
+}
+
+static int qualify_and_schedule_cb_without_aor(void *obj, void *arg, int flags)
+{
+ qualify_and_schedule_contact((struct ast_sip_contact *) obj);
return 0;
}
/*!
* \internal
- * \brief Qualify and schedule an endpoint's contacts
+ * \brief Qualify and schedule an aor's contacts
*
- * \details For the given endpoint retrieve its list of aors, qualify all
- * contacts, and schedule for checks if configured.
+ * \details For the given aor check if it has permanent contacts,
+ * qualify all contacts and schedule for checks if configured.
*/
static int qualify_and_schedule_all_cb(void *obj, void *arg, int flags)
{
struct ast_sip_aor *aor = obj;
struct ao2_container *contacts;
- contacts = ast_sip_location_retrieve_aor_contacts(aor);
- if (contacts) {
- ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb, aor);
- ao2_ref(contacts, -1);
+ if (aor->permanent_contacts) {
+ contacts = ast_sip_location_retrieve_aor_contacts(aor);
+ if (contacts) {
+ ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_with_aor, aor);
+ ao2_ref(contacts, -1);
+ }
}
return 0;
@@ -1104,6 +1119,7 @@ static void qualify_and_schedule_all(void)
{
struct ast_variable *var = ast_variable_new("qualify_frequency >", "0", "");
struct ao2_container *aors;
+ struct ao2_container *contacts;
if (!var) {
return;
@@ -1111,16 +1127,22 @@ static void qualify_and_schedule_all(void)
aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
"aor", AST_RETRIEVE_FLAG_MULTIPLE, var);
- ast_variables_destroy(var);
-
ao2_callback(sched_qualifies, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, unschedule_all_cb, NULL);
- if (!aors) {
- return;
+ if (aors) {
+ ao2_callback(aors, OBJ_NODATA, qualify_and_schedule_all_cb, NULL);
+ ao2_ref(aors, -1);
}
- ao2_callback(aors, OBJ_NODATA, qualify_and_schedule_all_cb, NULL);
- ao2_ref(aors, -1);
+ contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
+ "contact", AST_RETRIEVE_FLAG_MULTIPLE, var);
+ if (contacts) {
+ ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_without_aor, NULL);
+ ao2_ref(contacts, -1);
+ }
+
+ ast_variables_destroy(var);
+
}
static int format_contact_status(void *obj, void *arg, int flags)
@@ -1186,7 +1208,7 @@ static void aor_observer_modified(const void *obj)
contacts = ast_sip_location_retrieve_aor_contacts(aor);
if (contacts) {
- ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb, aor);
+ ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_with_aor, aor);
ao2_ref(contacts, -1);
}
}
diff --git a/res/res_pjsip_authenticator_digest.c b/res/res_pjsip_authenticator_digest.c
index ff46fd884..59e9738fd 100644
--- a/res/res_pjsip_authenticator_digest.c
+++ b/res/res_pjsip_authenticator_digest.c
@@ -206,9 +206,12 @@ static int build_nonce(struct ast_str **nonce, const char *timestamp, const pjsi
RAII_VAR(char *, eid, ao2_global_obj_ref(entity_id), ao2_cleanup);
char hash[33];
+ /*
+ * Note you may be tempted to think why not include the port. The reason
+ * is that when using TCP the port can potentially differ from before.
+ */
ast_str_append(&str, 0, "%s", timestamp);
ast_str_append(&str, 0, ":%s", rdata->pkt_info.src_name);
- ast_str_append(&str, 0, ":%d", rdata->pkt_info.src_port);
ast_str_append(&str, 0, ":%s", eid);
ast_str_append(&str, 0, ":%s", realm);
ast_md5_hash(hash, ast_str_buffer(str));
@@ -509,5 +512,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP authentication
.load = load_module,
.unload = unload_module,
.reload = reload_module,
- .load_pri = AST_MODPRI_CHANNEL_DEPEND,
+ .load_pri = AST_MODPRI_CHANNEL_DEPEND - 5,
);
diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c
index 7f4858af0..b1ffd2cc3 100644
--- a/res/res_pjsip_endpoint_identifier_ip.c
+++ b/res/res_pjsip_endpoint_identifier_ip.c
@@ -515,5 +515,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP IP endpoint ide
.load = load_module,
.reload = reload_module,
.unload = unload_module,
- .load_pri = AST_MODPRI_APP_DEPEND,
+ .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4,
);
diff --git a/res/res_pjsip_endpoint_identifier_user.c b/res/res_pjsip_endpoint_identifier_user.c
index dea5f4ae7..e018abd61 100644
--- a/res/res_pjsip_endpoint_identifier_user.c
+++ b/res/res_pjsip_endpoint_identifier_user.c
@@ -201,5 +201,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP username endpoi
.support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.unload = unload_module,
- .load_pri = AST_MODPRI_APP_DEPEND,
+ .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4,
);
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 8a40cce23..1ae3522d8 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -1096,7 +1096,7 @@ static int sip_dialog_create_contact(pj_pool_t *pool, pj_str_t *contact, const c
contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE,
"<%s:%s@%s%.*s%s:%d%s%s%s%s>",
- (pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) ? "sips" : "sip",
+ ((pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) && PJSIP_URI_SCHEME_IS_SIPS(uri)) ? "sips" : "sip",
user,
(type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
(int)local_addr.slen,
diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c
index 9aeefae29..a8144fc05 100644
--- a/res/res_pjsip_registrar.c
+++ b/res/res_pjsip_registrar.c
@@ -957,5 +957,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Suppo
.support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.unload = unload_module,
- .load_pri = AST_MODPRI_APP_DEPEND,
+ .load_pri = AST_MODPRI_CHANNEL_DEPEND - 3,
);
diff --git a/res/res_sorcery_astdb.c b/res/res_sorcery_astdb.c
index e5de9f7bb..c6b5a1b33 100644
--- a/res/res_sorcery_astdb.c
+++ b/res/res_sorcery_astdb.c
@@ -97,7 +97,6 @@ static void *sorcery_astdb_retrieve_fields_common(const struct ast_sorcery *sorc
const char *key = entry->key + strlen(family) + 2;
RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
struct ast_json_error error;
- RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
RAII_VAR(struct ast_variable *, existing, NULL, ast_variables_destroy);
void *object = NULL;
@@ -113,7 +112,7 @@ static void *sorcery_astdb_retrieve_fields_common(const struct ast_sorcery *sorc
}
if (!(object = ast_sorcery_alloc(sorcery, type, key)) ||
- ast_sorcery_objectset_apply(sorcery, object, objset)) {
+ ast_sorcery_objectset_apply(sorcery, object, existing)) {
ao2_cleanup(object);
return NULL;
}
diff --git a/third-party/pjproject/Makefile b/third-party/pjproject/Makefile
index 7fa3902ba..7349db62f 100644
--- a/third-party/pjproject/Makefile
+++ b/third-party/pjproject/Makefile
@@ -45,6 +45,13 @@ ifeq ($(SPECIAL_TARGETS),)
CF := $(filter-out -I%,$(CF))
export CFLAGS += $(CF)
export LDFLAGS += $(CC_LDFLAGS)
+ TARGETS := pjproject.symbols
+ ifeq ($(findstring TEST_FRAMEWORK,$(MENUSELECT_CFLAGS)),TEST_FRAMEWORK)
+ TARGETS += source/pjsip-apps/bin/pjsua-$(TARGET_NAME)
+ ifneq ($(PYTHONDEV_LIB),)
+ TARGETS += source/pjsip-apps/src/python/build/_pjsua.so
+ endif
+ endif
else
all install:
endif
@@ -95,12 +102,10 @@ source/pjlib/build/.pjlib-$(TARGET_NAME).depend: build.mak
$(ECHO_PREFIX) "Making dependencies"
+$(CMD_PREFIX) $(SUBMAKE) -C source dep
-
menuselect: ../../menuselect.makeopts ../../makeopts
-$(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
-
source/pjlib/lib/libpj-$(TARGET_NAME).a: menuselect source/pjlib/build/.pjlib-$(TARGET_NAME).depend
$(ECHO_PREFIX) Compiling libs
+$(CMD_PREFIX) $(SUBMAKE) -C source lib $(REALLY_QUIET)
@@ -117,17 +122,22 @@ source/pjsip-apps/src/python/build/_pjsua.so: source/pjlib/lib/libpj-$(TARGET_NA
$(ECHO_PREFIX) Compiling python bindings
$(CMD_PREFIX) (cd source/pjsip-apps/src/python ; MAKE=$(MAKE) 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
+_all: $(TARGETS)
_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;
+ifneq ($(findstring source/pjsip-apps/bin/pjsua-$(TARGET_NAME),$(TARGETS)),)
+ $(ECHO_PREFIX) Installing apps
$(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"
+endif
+ifneq ($(findstring source/pjsip-apps/src/python/build/_pjsua.so,$(TARGETS)),)
+ $(ECHO_PREFIX) Installing python bindings
$(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/"
+endif
uninstall:
$(ECHO_PREFIX) Uninstalling apps and python bindings
@@ -135,7 +145,7 @@ uninstall:
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) test -d source && ($(SUBMAKE) -C source clean ; find source -name *.a -delete ; rm -rf source/pjsip-apps/src/python/build ; rm -rf source/pjsip-apps/bin/* ) || :
-$(CMD_PREFIX) rm -rf pjproject.symbols
distclean:
diff --git a/third-party/pjproject/Makefile.rules b/third-party/pjproject/Makefile.rules
index 6b51c2f2a..d2e7d25a4 100644
--- a/third-party/pjproject/Makefile.rules
+++ b/third-party/pjproject/Makefile.rules
@@ -3,7 +3,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 --disable-speex-codec --disable-speex-aec \
--disable-gsm-codec --disable-video --disable-v4l2 --disable-sound --disable-opencore-amr \
- --disable-ilbc-codec --without-libyuv --disable-g7221-codec
+ --disable-ilbc-codec --without-libyuv --disable-g7221-codec --disable-resample
ifeq ($(shell uname -s),Linux)
PJPROJECT_CONFIG_OPTS += --enable-epoll