diff options
-rw-r--r-- | CHANGES | 12 | ||||
-rw-r--r-- | apps/app_queue.c | 3 | ||||
-rw-r--r-- | apps/confbridge/conf_config_parser.c | 8 | ||||
-rw-r--r-- | apps/confbridge/include/confbridge.h | 1 | ||||
-rw-r--r-- | channels/chan_rtp.c | 2 | ||||
-rw-r--r-- | channels/chan_sip.c | 12 | ||||
-rw-r--r-- | configs/samples/rtp.conf.sample | 12 | ||||
-rw-r--r-- | main/cdr.c | 19 | ||||
-rw-r--r-- | main/cli.c | 14 | ||||
-rw-r--r-- | menuselect/aclocal.m4 | 281 | ||||
-rwxr-xr-x | menuselect/configure | 197 | ||||
-rw-r--r-- | menuselect/configure.ac | 9 | ||||
-rw-r--r-- | res/ari/ari_model_validators.c | 351 | ||||
-rw-r--r-- | res/ari/ari_model_validators.h | 39 | ||||
-rw-r--r-- | res/res_rtp_asterisk.c | 87 | ||||
-rw-r--r-- | res/stasis/app.c | 7 | ||||
-rw-r--r-- | rest-api/api-docs/events.json | 5 | ||||
-rw-r--r-- | tests/test_res_stasis.c | 6 | ||||
-rw-r--r-- | third-party/pjproject/patches/0005-Re-1969-Fix-crash-on-using-an-already-destroyed-SSL-.patch | 164 |
19 files changed, 1156 insertions, 73 deletions
@@ -97,6 +97,11 @@ res_pjsip Note: The caller-id and redirecting number strings obtained from incoming SIP URI user fields are now always truncated at the first semicolon. +res_rtp_asterisk +------------------ + * An option, ice_blacklist, has been added which allows certain subnets to be + excluded from local ICE candidates. + app_confbridge ------------------ * Some sounds played into the bridge are played asynchronously. This, for @@ -109,6 +114,13 @@ app_dial when another channel answers the call. The default of ANSWERED_ELSEWHERE is unchanged. +res_ari +------------------ + * ARI events will all now include a new field in the root of the JSON message, + 'asterisk_id'. This will be the unique ID for the Asterisk system + transmitting the event. The value can be overridden using the 'entityid' + setting in asterisk.conf. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 13 to Asterisk 14 -------------------- ------------------------------------------------------------------------------ diff --git a/apps/app_queue.c b/apps/app_queue.c index bf5f95446..51741d374 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -2671,6 +2671,9 @@ static void init_queue(struct call_queue *q) q->retry = DEFAULT_RETRY; q->timeout = DEFAULT_TIMEOUT; q->maxlen = 0; + + ast_string_field_set(q, context, ""); + q->announcefrequency = 0; q->minannouncefrequency = DEFAULT_MIN_ANNOUNCE_FREQUENCY; q->announceholdtime = 1; diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c index 69d6f69ea..6f8510552 100644 --- a/apps/confbridge/conf_config_parser.c +++ b/apps/confbridge/conf_config_parser.c @@ -284,6 +284,13 @@ ASTERISK_REGISTER_FILE() or 80. </para></description> </configOption> + <configOption name="binaural_active"> + <synopsis>If true binaural conferencing with stereo audio is active</synopsis> + <description><para> + Activates binaural mixing for a conference bridge. + Binaural features are disabled by default. + </para></description> + </configOption> <configOption name="record_conference"> <synopsis>Record the conference starting with the first active user's entrance and ending with the last active user's exit</synopsis> <description><para> @@ -2172,6 +2179,7 @@ int conf_load_config(void) aco_option_register(&cfg_info, "jitterbuffer", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), USER_OPT_JITTERBUFFER); /* "auto" will fail to parse as a uint, but we use PARSE_DEFAULT to set the value to 0 in that case, which is the value that auto resolves to */ aco_option_register(&cfg_info, "internal_sample_rate", ACO_EXACT, bridge_types, "0", OPT_UINT_T, PARSE_DEFAULT, FLDSET(struct bridge_profile, internal_sample_rate), 0); + aco_option_register(&cfg_info, "binaural_active", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), BRIDGE_OPT_BINAURAL_ACTIVE); aco_option_register_custom(&cfg_info, "mixing_interval", ACO_EXACT, bridge_types, "20", mix_interval_handler, 0); aco_option_register(&cfg_info, "record_conference", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), BRIDGE_OPT_RECORD_CONFERENCE); aco_option_register_custom(&cfg_info, "video_mode", ACO_EXACT, bridge_types, NULL, video_mode_handler, 0); diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h index 93cac3a72..f91f2dc89 100644 --- a/apps/confbridge/include/confbridge.h +++ b/apps/confbridge/include/confbridge.h @@ -71,6 +71,7 @@ enum bridge_profile_flags { BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER = (1 << 3), /*!< Set if conference set the video feed to follow the loudest talker. */ BRIDGE_OPT_RECORD_FILE_APPEND = (1 << 4), /*!< Set if the record file should be appended to between start/stops. */ BRIDGE_OPT_RECORD_FILE_TIMESTAMP = (1 << 5), /*< Set if the record file should have a timestamp appended */ + BRIDGE_OPT_BINAURAL_ACTIVE = (1 << 6), /*< Set if binaural convolution is activated */ }; enum conf_menu_action_id { diff --git a/channels/chan_rtp.c b/channels/chan_rtp.c index 0fe66bd20..f1f4f05b9 100644 --- a/channels/chan_rtp.c +++ b/channels/chan_rtp.c @@ -314,7 +314,7 @@ static struct ast_channel *unicast_rtp_request(const char *type, struct ast_form } engine_name = S_COR(ast_test_flag(&opts, OPT_RTP_ENGINE), - opt_args[OPT_ARG_RTP_ENGINE], NULL); + opt_args[OPT_ARG_RTP_ENGINE], "asterisk"); ast_ouraddrfor(&address, &local_address); instance = ast_rtp_instance_new(engine_name, NULL, &local_address, NULL); diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 47b90d724..40ef6409a 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -8153,12 +8153,17 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit We also check for vrtp. If it's not there, we are not allowed do any video anyway. */ if (i->vrtp) { - if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT)) + if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS)) needvideo = 1; else if (ast_format_cap_count(i->prefcaps)) needvideo = ast_format_cap_has_type(i->prefcaps, AST_MEDIA_TYPE_VIDEO); /* Outbound call */ else needvideo = ast_format_cap_has_type(i->jointcaps, AST_MEDIA_TYPE_VIDEO); /* Inbound call */ + + if (!needvideo) { + ast_rtp_instance_destroy(i->vrtp); + i->vrtp = NULL; + } } if (i->trtp) { @@ -30472,9 +30477,10 @@ static struct ast_channel *sip_request_call(const char *type, struct ast_format_ if (p->relatedpeer) { if (!ast_strlen_zero(p->relatedpeer->fullcontact) && !p->natdetected && - (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT) && !ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT))) { + ((ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT) && !ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || + (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA) && !ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP)))) { /* We need to make an attempt to determine if a peer is behind NAT - if the peer has the auto_force_rport flag set. */ + if the peer has the flags auto_force_rport or auto_comedia set. */ struct ast_sockaddr tmpaddr; __set_address_from_contact(p->relatedpeer->fullcontact, &tmpaddr, 0); diff --git a/configs/samples/rtp.conf.sample b/configs/samples/rtp.conf.sample index 2ef5dd28a..fdd1d530e 100644 --- a/configs/samples/rtp.conf.sample +++ b/configs/samples/rtp.conf.sample @@ -59,6 +59,18 @@ rtpend=20000 ; Password used to authenticate with TURN relay server. ; turnpassword= ; +; Subnets to exclude from ICE host, srflx and relay discovery. This is useful +; to optimize the ICE process where a system has multiple host address ranges +; and/or physical interfaces and certain of them are not expected to be used +; for RTP. For example, VPNs and local interconnections may not be suitable or +; necessary for ICE. Multiple subnets may be listed. If left unconfigured, +; all discovered host addresses are used. +; +; e.g. ice_blacklist = 192.168.1.0/255.255.255.0 +; ice_blacklist = 10.32.77.0/255.255.255.0 +; +; ice_blacklist = +; [ice_host_candidates] ; ; When Asterisk is behind a static one-to-one NAT and ICE is in use, ICE will diff --git a/main/cdr.c b/main/cdr.c index e2f9b764c..baa17b967 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -698,6 +698,7 @@ struct cdr_object { ); struct cdr_object *next; /*!< The next CDR object in the chain */ struct cdr_object *last; /*!< The last CDR object in the chain */ + int is_root; /*!< True if this is the first CDR in the chain */ }; /*! @@ -853,7 +854,22 @@ static void cdr_object_dtor(void *obj) } ast_string_field_free_memory(cdr); - ao2_cleanup(cdr->next); + /* CDR destruction used to work by calling ao2_cleanup(next) and + * allowing the chain to destroy itself neatly. Unfortunately, for + * really long chains, this can result in a stack overflow. So now + * when the root CDR is destroyed, it is responsible for unreffing + * all CDRs in the chain + */ + if (cdr->is_root) { + struct cdr_object *curr = cdr->next; + struct cdr_object *next; + + while (curr) { + next = curr->next; + ao2_cleanup(curr); + curr = next; + } + } } /*! @@ -2100,6 +2116,7 @@ static void handle_channel_cache_message(void *data, struct stasis_subscription if (!cdr) { return; } + cdr->is_root = 1; ao2_link(active_cdrs_by_channel, cdr); } diff --git a/main/cli.c b/main/cli.c index 8af20b61b..3ba743d75 100644 --- a/main/cli.c +++ b/main/cli.c @@ -449,19 +449,11 @@ static char *handle_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args case CLI_INIT: e->command = "core set debug"; e->usage = -#if !defined(LOW_MEMORY) "Usage: core set debug [atleast] <level> [module]\n" -#else - "Usage: core set debug [atleast] <level>\n" -#endif " core set debug off\n" "\n" -#if !defined(LOW_MEMORY) " Sets level of debug messages to be displayed or\n" " sets a module name to display debug messages from.\n" -#else - " Sets level of debug messages to be displayed.\n" -#endif " 0 or off means no messages should be displayed.\n" " Equivalent to -d[d[...]] on startup\n"; return NULL; @@ -489,13 +481,9 @@ static char *handle_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) { return ast_strdup("atleast"); } -#if !defined(LOW_MEMORY) } else if ((a->pos == 4 && !atleast && strcasecmp(argv3, "off") && strcasecmp(argv3, "channel")) || (a->pos == 5 && atleast)) { - const char *pos = S_OR(a->argv[a->pos], ""); - - return ast_complete_source_filename(pos, a->n); -#endif + return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0); } return NULL; } diff --git a/menuselect/aclocal.m4 b/menuselect/aclocal.m4 index 8b547156d..e67774c06 100644 --- a/menuselect/aclocal.m4 +++ b/menuselect/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.14.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -12,8 +12,285 @@ # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29) +dnl +dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR + m4_include([../autoconf/ast_check_gnu_make.m4]) m4_include([../autoconf/ast_ext_lib.m4]) m4_include([../autoconf/ast_ext_tool_check.m4]) m4_include([../autoconf/ast_gcc_attribute.m4]) +m4_include([../autoconf/ast_pkgconfig.m4]) m4_include([../autoconf/ast_prog_sed.m4]) diff --git a/menuselect/configure b/menuselect/configure index 648091e5f..4235ea0a4 100755 --- a/menuselect/configure +++ b/menuselect/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac Revision: 418850 . +# From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69. # @@ -628,7 +628,11 @@ LIBOBJS GTK2_LIB GTK2_INCLUDE PBX_GTK2 -PKGCONFIG +GTK2_LIBS +GTK2_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG CONFIG_LIBXML2 SED PBX_LIBXML2 @@ -725,7 +729,12 @@ CFLAGS LDFLAGS LIBS CPPFLAGS -CPP' +CPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +GTK2_CFLAGS +GTK2_LIBS' # Initialize some variables set by options. @@ -1356,6 +1365,13 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + GTK2_CFLAGS C compiler flags for GTK2, overriding pkg-config + GTK2_LIBS linker flags for GTK2, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -4752,26 +4768,35 @@ if test "${PBX_LIBXML2}" != 1; then as_fn_error $? "Could not find required 'Libxml2' development package" "$LINENO" 5 fi -PBX_GTK2=0 -if test -n "$ac_tool_prefix"; then + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PKGCONFIG+:} false; then : +if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$PKGCONFIG"; then - ac_cv_prog_PKGCONFIG="$PKGCONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_PKGCONFIG="${ac_tool_prefix}pkg-config" + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4779,12 +4804,13 @@ done done IFS=$as_save_IFS + ;; +esac fi -fi -PKGCONFIG=$ac_cv_prog_PKGCONFIG -if test -n "$PKGCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 -$as_echo "$PKGCONFIG" >&6; } +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -4792,26 +4818,28 @@ fi fi -if test -z "$ac_cv_prog_PKGCONFIG"; then - ac_ct_PKGCONFIG=$PKGCONFIG +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_PKGCONFIG+:} false; then : +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$ac_ct_PKGCONFIG"; then - ac_cv_prog_ac_ct_PKGCONFIG="$ac_ct_PKGCONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_PKGCONFIG="pkg-config" + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4819,19 +4847,20 @@ done done IFS=$as_save_IFS + ;; +esac fi -fi -ac_ct_PKGCONFIG=$ac_cv_prog_ac_ct_PKGCONFIG -if test -n "$ac_ct_PKGCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKGCONFIG" >&5 -$as_echo "$ac_ct_PKGCONFIG" >&6; } +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - if test "x$ac_ct_PKGCONFIG" = x; then - PKGCONFIG="No" + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) @@ -4839,20 +4868,114 @@ yes:) $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac - PKGCONFIG=$ac_ct_PKGCONFIG + PKG_CONFIG=$ac_pt_PKG_CONFIG fi else - PKGCONFIG="$ac_cv_prog_PKGCONFIG" + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi fi -if test ! "x${PKGCONFIG}" = xNo; then - GTK2_INCLUDE=$(${PKGCONFIG} gtk+-2.0 --cflags 2>/dev/null) - GTK2_LIB=$(${PKGCONFIG} gtk+-2.0 --libs) - PBX_GTK2=1 + if test "x${PBX_GTK2}" != "x1" -a "${USE_GTK2}" != "no"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK2" >&5 +$as_echo_n "checking for GTK2... " >&6; } + +if test -n "$GTK2_CFLAGS"; then + pkg_cv_GTK2_CFLAGS="$GTK2_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gtk+-2.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GTK2_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GTK2_LIBS"; then + pkg_cv_GTK2_LIBS="$GTK2_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gtk+-2.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GTK2_LIBS=`$PKG_CONFIG --libs "gtk+-2.0" 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 + GTK2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0" 2>&1` + else + GTK2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GTK2_PKG_ERRORS" >&5 + + + PBX_GTK2=0 + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + PBX_GTK2=0 + + +else + GTK2_CFLAGS=$pkg_cv_GTK2_CFLAGS + GTK2_LIBS=$pkg_cv_GTK2_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + PBX_GTK2=1 + GTK2_INCLUDE="$GTK2_CFLAGS" + GTK2_LIB="$GTK2_LIBS" $as_echo "#define HAVE_GTK2 1" >>confdefs.h + fi + fi + diff --git a/menuselect/configure.ac b/menuselect/configure.ac index 5989f5cd3..29c43cb50 100644 --- a/menuselect/configure.ac +++ b/menuselect/configure.ac @@ -134,14 +134,7 @@ if test "${PBX_LIBXML2}" != 1; then AC_MSG_ERROR([Could not find required 'Libxml2' development package]) fi -PBX_GTK2=0 -AC_CHECK_TOOL(PKGCONFIG, pkg-config, No) -if test ! "x${PKGCONFIG}" = xNo; then - GTK2_INCLUDE=$(${PKGCONFIG} gtk+-2.0 --cflags 2>/dev/null) - GTK2_LIB=$(${PKGCONFIG} gtk+-2.0 --libs) - PBX_GTK2=1 - AC_DEFINE([HAVE_GTK2], 1, [Define if your system has the GTK2 libraries.]) -fi +AST_PKG_CONFIG_CHECK([GTK2], [gtk+-2.0]) AC_SUBST(PBX_GTK2) AC_SUBST(GTK2_INCLUDE) AC_SUBST(GTK2_LIB) diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c index 8f05db035..633a94c1b 100644 --- a/res/ari/ari_model_validators.c +++ b/res/ari/ari_model_validators.c @@ -1941,6 +1941,15 @@ int ast_ari_validate_application_replaced(struct ast_json *json) int has_application = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ApplicationReplaced field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -2009,6 +2018,15 @@ int ast_ari_validate_bridge_attended_transfer(struct ast_json *json) int has_transferer_second_leg = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeAttendedTransfer field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -2251,6 +2269,15 @@ int ast_ari_validate_bridge_blind_transfer(struct ast_json *json) int has_result = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeBlindTransfer field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -2417,6 +2444,15 @@ int ast_ari_validate_bridge_created(struct ast_json *json) int has_bridge = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeCreated field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -2496,6 +2532,15 @@ int ast_ari_validate_bridge_destroyed(struct ast_json *json) int has_bridge = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeDestroyed field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -2576,6 +2621,15 @@ int ast_ari_validate_bridge_merged(struct ast_json *json) int has_bridge_from = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeMerged field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -2672,6 +2726,15 @@ int ast_ari_validate_channel_caller_id(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCallerId field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -2781,6 +2844,15 @@ int ast_ari_validate_channel_connected_line(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelConnectedLine field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -2860,6 +2932,15 @@ int ast_ari_validate_channel_created(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCreated field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -2941,6 +3022,15 @@ int ast_ari_validate_channel_destroyed(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3052,6 +3142,15 @@ int ast_ari_validate_channel_dialplan(struct ast_json *json) int has_dialplan_app_data = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDialplan field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3163,6 +3262,15 @@ int ast_ari_validate_channel_dtmf_received(struct ast_json *json) int has_duration_ms = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3272,6 +3380,15 @@ int ast_ari_validate_channel_entered_bridge(struct ast_json *json) int has_bridge = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelEnteredBridge field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3360,6 +3477,15 @@ int ast_ari_validate_channel_hangup_request(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3457,6 +3583,15 @@ int ast_ari_validate_channel_hold(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelHold field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3546,6 +3681,15 @@ int ast_ari_validate_channel_left_bridge(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3640,6 +3784,15 @@ int ast_ari_validate_channel_state_change(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelStateChange field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3720,6 +3873,15 @@ int ast_ari_validate_channel_talking_finished(struct ast_json *json) int has_duration = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelTalkingFinished field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3814,6 +3976,15 @@ int ast_ari_validate_channel_talking_started(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelTalkingStarted field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3893,6 +4064,15 @@ int ast_ari_validate_channel_unhold(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelUnhold field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -3973,6 +4153,15 @@ int ast_ari_validate_channel_userevent(struct ast_json *json) int has_userevent = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelUserevent field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -4095,6 +4284,15 @@ int ast_ari_validate_channel_varset(struct ast_json *json) int has_variable = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelVarset field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -4278,6 +4476,15 @@ int ast_ari_validate_contact_status_change(struct ast_json *json) int has_endpoint = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ContactStatusChange field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -4372,6 +4579,15 @@ int ast_ari_validate_device_state_changed(struct ast_json *json) int has_device_state = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI DeviceStateChanged field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -4452,6 +4668,15 @@ int ast_ari_validate_dial(struct ast_json *json) int has_peer = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Dial field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -4582,6 +4807,15 @@ int ast_ari_validate_endpoint_state_change(struct ast_json *json) int has_endpoint = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI EndpointStateChange field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -4784,6 +5018,15 @@ int ast_ari_validate_event(struct ast_json *json) } for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Event field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -4976,6 +5219,15 @@ int ast_ari_validate_message(struct ast_json *json) } for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Message field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5015,6 +5267,15 @@ int ast_ari_validate_missing_params(struct ast_json *json) int has_params = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI MissingParams field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5146,6 +5407,15 @@ int ast_ari_validate_peer_status_change(struct ast_json *json) int has_peer = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PeerStatusChange field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5240,6 +5510,15 @@ int ast_ari_validate_playback_continuing(struct ast_json *json) int has_playback = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackContinuing field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5319,6 +5598,15 @@ int ast_ari_validate_playback_finished(struct ast_json *json) int has_playback = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackFinished field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5398,6 +5686,15 @@ int ast_ari_validate_playback_started(struct ast_json *json) int has_playback = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackStarted field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5477,6 +5774,15 @@ int ast_ari_validate_recording_failed(struct ast_json *json) int has_recording = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI RecordingFailed field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5556,6 +5862,15 @@ int ast_ari_validate_recording_finished(struct ast_json *json) int has_recording = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI RecordingFinished field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5635,6 +5950,15 @@ int ast_ari_validate_recording_started(struct ast_json *json) int has_recording = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI RecordingStarted field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5714,6 +6038,15 @@ int ast_ari_validate_stasis_end(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisEnd field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5794,6 +6127,15 @@ int ast_ari_validate_stasis_start(struct ast_json *json) int has_channel = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisStart field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; @@ -5898,6 +6240,15 @@ int ast_ari_validate_text_message_received(struct ast_json *json) int has_message = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI TextMessageReceived field asterisk_id failed validation\n"); + res = 0; + } + } else if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_type = 1; diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h index 2634528ba..0b08ce85e 100644 --- a/res/ari/ari_model_validators.h +++ b/res/ari/ari_model_validators.h @@ -1486,10 +1486,12 @@ ari_validator ast_ari_validate_application_fn(void); * - new_messages: int (required) * - old_messages: int (required) * ApplicationReplaced + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * BridgeAttendedTransfer + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1510,6 +1512,7 @@ ari_validator ast_ari_validate_application_fn(void); * - transferer_second_leg: Channel (required) * - transferer_second_leg_bridge: Bridge * BridgeBlindTransfer + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1522,22 +1525,26 @@ ari_validator ast_ari_validate_application_fn(void); * - result: string (required) * - transferee: Channel * BridgeCreated + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - bridge: Bridge (required) * BridgeDestroyed + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - bridge: Bridge (required) * BridgeMerged + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - bridge: Bridge (required) * - bridge_from: Bridge (required) * ChannelCallerId + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1545,16 +1552,19 @@ ari_validator ast_ari_validate_application_fn(void); * - caller_presentation_txt: string (required) * - channel: Channel (required) * ChannelConnectedLine + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - channel: Channel (required) * ChannelCreated + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - channel: Channel (required) * ChannelDestroyed + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1562,6 +1572,7 @@ ari_validator ast_ari_validate_application_fn(void); * - cause_txt: string (required) * - channel: Channel (required) * ChannelDialplan + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1569,6 +1580,7 @@ ari_validator ast_ari_validate_application_fn(void); * - dialplan_app: string (required) * - dialplan_app_data: string (required) * ChannelDtmfReceived + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1576,12 +1588,14 @@ ari_validator ast_ari_validate_application_fn(void); * - digit: string (required) * - duration_ms: int (required) * ChannelEnteredBridge + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - bridge: Bridge (required) * - channel: Channel * ChannelHangupRequest + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1589,39 +1603,46 @@ ari_validator ast_ari_validate_application_fn(void); * - channel: Channel (required) * - soft: boolean * ChannelHold + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - channel: Channel (required) * - musicclass: string * ChannelLeftBridge + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - bridge: Bridge (required) * - channel: Channel (required) * ChannelStateChange + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - channel: Channel (required) * ChannelTalkingFinished + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - channel: Channel (required) * - duration: int (required) * ChannelTalkingStarted + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - channel: Channel (required) * ChannelUnhold + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - channel: Channel (required) * ChannelUserevent + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1631,6 +1652,7 @@ ari_validator ast_ari_validate_application_fn(void); * - eventname: string (required) * - userevent: object (required) * ChannelVarset + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1643,17 +1665,20 @@ ari_validator ast_ari_validate_application_fn(void); * - roundtrip_usec: string * - uri: string (required) * ContactStatusChange + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - contact_info: ContactInfo (required) * - endpoint: Endpoint (required) * DeviceStateChanged + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - device_state: DeviceState (required) * Dial + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1664,17 +1689,21 @@ ari_validator ast_ari_validate_application_fn(void); * - forwarded: Channel * - peer: Channel (required) * EndpointStateChange + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - endpoint: Endpoint (required) * Event + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * Message + * - asterisk_id: string * - type: string (required) * MissingParams + * - asterisk_id: string * - type: string (required) * - params: List[string] (required) * Peer @@ -1684,47 +1713,56 @@ ari_validator ast_ari_validate_application_fn(void); * - port: string * - time: string * PeerStatusChange + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - endpoint: Endpoint (required) * - peer: Peer (required) * PlaybackContinuing + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - playback: Playback (required) * PlaybackFinished + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - playback: Playback (required) * PlaybackStarted + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - playback: Playback (required) * RecordingFailed + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - recording: LiveRecording (required) * RecordingFinished + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - recording: LiveRecording (required) * RecordingStarted + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - recording: LiveRecording (required) * StasisEnd + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date * - channel: Channel (required) * StasisStart + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date @@ -1732,6 +1770,7 @@ ari_validator ast_ari_validate_application_fn(void); * - channel: Channel (required) * - replace_channel: Channel * TextMessageReceived + * - asterisk_id: string * - type: string (required) * - application: string (required) * - timestamp: Date diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index 520fd7602..4bf625260 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -51,6 +51,7 @@ ASTERISK_REGISTER_FILE() #include <pjlib.h> #include <pjlib-util.h> #include <pjnath.h> +#include <ifaddrs.h> #endif #include "asterisk/stun.h" @@ -145,6 +146,9 @@ static pj_str_t turnaddr; static int turnport = DEFAULT_TURN_PORT; static pj_str_t turnusername; static pj_str_t turnpassword; +static struct ast_ha *ice_blacklist = NULL; /*!< Blacklisted ICE networks */ +static ast_rwlock_t ice_blacklist_lock = AST_RWLOCK_INIT_VALUE; + /*! \brief Pool factory used by pjlib to allocate memory. */ static pj_caching_pool cachingpool; @@ -2446,11 +2450,38 @@ static int rtp_learning_rtp_seq_update(struct rtp_learning_info *info, uint16_t } #ifdef HAVE_PJPROJECT +/*! + * \internal + * \brief Checks an address against the ICE blacklist + * \note If there is no ice_blacklist list, always returns 0 + * + * \param address The address to consider + * \retval 0 if address is not ICE blacklisted + * \retval 1 if address is ICE blacklisted + */ +static int rtp_address_is_ice_blacklisted(const pj_sockaddr_t *address) +{ + char buf[PJ_INET6_ADDRSTRLEN]; + struct ast_sockaddr saddr; + int result = 1; + + ast_sockaddr_parse(&saddr, pj_sockaddr_print(address, buf, sizeof(buf), 0), 0); + + ast_rwlock_rdlock(&ice_blacklist_lock); + if (!ice_blacklist || (ast_apply_ha(ice_blacklist, &saddr) == AST_SENSE_ALLOW)) { + result = 0; + } + ast_rwlock_unlock(&ice_blacklist_lock); + + return result; +} + static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *addr, int port, int component, int transport) { pj_sockaddr address[16]; unsigned int count = PJ_ARRAY_SIZE(address), pos = 0; + int basepos = -1; /* Add all the local interface IP addresses */ if (ast_sockaddr_is_ipv4(addr)) { @@ -2464,9 +2495,18 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct host_candidate_overrides_apply(count, address); for (pos = 0; pos < count; pos++) { - pj_sockaddr_set_port(&address[pos], port); - ast_rtp_ice_add_cand(rtp, component, transport, PJ_ICE_CAND_TYPE_HOST, 65535, &address[pos], &address[pos], NULL, + if (!rtp_address_is_ice_blacklisted(&address[pos])) { + if (basepos == -1) { + basepos = pos; + } + pj_sockaddr_set_port(&address[pos], port); + ast_rtp_ice_add_cand(rtp, component, transport, PJ_ICE_CAND_TYPE_HOST, 65535, &address[pos], &address[pos], NULL, pj_sockaddr_get_len(&address[pos])); + } + } + if (basepos == -1) { + /* start with first address unless excluded above */ + basepos = 0; } /* If configured to use a STUN server to get our external mapped address do so */ @@ -2475,15 +2515,27 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct if (!ast_stun_request(component == AST_RTP_ICE_COMPONENT_RTCP ? rtp->rtcp->s : rtp->s, &stunaddr, NULL, &answer)) { pj_sockaddr base; + pj_sockaddr ext; pj_str_t mapped = pj_str(ast_strdupa(ast_inet_ntoa(answer.sin_addr))); + int srflx = 1; /* Use the first local host candidate as the base */ - pj_sockaddr_cp(&base, &address[0]); + pj_sockaddr_cp(&base, &address[basepos]); + + pj_sockaddr_init(pj_AF_INET(), &ext, &mapped, ntohs(answer.sin_port)); - pj_sockaddr_init(pj_AF_INET(), &address[0], &mapped, ntohs(answer.sin_port)); + /* If the returned address is the same as one of our host candidates, don't send the srflx */ + for (pos = 0; pos < count; pos++) { + if ((pj_sockaddr_cmp(&address[pos], &ext) == 0) && !rtp_address_is_ice_blacklisted(&address[pos])) { + srflx = 0; + break; + } + } - ast_rtp_ice_add_cand(rtp, component, transport, PJ_ICE_CAND_TYPE_SRFLX, 65535, &address[0], &base, - &base, pj_sockaddr_get_len(&address[0])); + if (srflx) { + ast_rtp_ice_add_cand(rtp, component, transport, PJ_ICE_CAND_TYPE_SRFLX, 65535, &ext, &base, + &base, pj_sockaddr_get_len(&ext)); + } } } @@ -5393,6 +5445,10 @@ static int rtp_reload(int reload) turnusername = pj_str(NULL); turnpassword = pj_str(NULL); host_candidate_overrides_clear(); + ast_rwlock_wrlock(&ice_blacklist_lock); + ast_free_ha(ice_blacklist); + ice_blacklist = NULL; + ast_rwlock_unlock(&ice_blacklist_lock); #endif if (cfg) { @@ -5502,6 +5558,25 @@ static int rtp_reload(int reload) AST_RWLIST_INSERT_TAIL(&host_candidates, candidate, next); } AST_RWLIST_UNLOCK(&host_candidates); + + /* Read ICE blacklist configuration lines */ + ast_rwlock_wrlock(&ice_blacklist_lock); + for (var = ast_variable_browse(cfg, "general"); var; var = var->next) { + if (!strcasecmp(var->name, "ice_blacklist")) { + struct ast_ha *na; + int ha_error = 0; + if (!(na = ast_append_ha("d", var->value, ice_blacklist, &ha_error))) { + ast_log(LOG_WARNING, "Invalid ice_blacklist value: %s\n", var->value); + } else { + ice_blacklist = na; + } + if (ha_error) { + ast_log(LOG_ERROR, "Bad ice_blacklist configuration value line %d : %s\n", var->lineno, var->value); + } + } + } + ast_rwlock_unlock(&ice_blacklist_lock); + #endif ast_config_destroy(cfg); } diff --git a/res/stasis/app.c b/res/stasis/app.c index fb313df99..8bd1bc05a 100644 --- a/res/stasis/app.c +++ b/res/stasis/app.c @@ -929,8 +929,15 @@ struct stasis_topic *ast_app_get_topic(struct stasis_app *app) void app_send(struct stasis_app *app, struct ast_json *message) { stasis_app_cb handler; + char eid[20]; RAII_VAR(void *, data, NULL, ao2_cleanup); + if (ast_json_object_set(message, "asterisk_id", ast_json_string_create( + ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) { + ast_log(AST_LOG_WARNING, "Failed to append EID to outgoing event %s\n", + ast_json_string_get(ast_json_object_get(message, "type"))); + } + /* Copy off mutable state with lock held */ { SCOPED_AO2LOCK(lock, app); diff --git a/rest-api/api-docs/events.json b/rest-api/api-docs/events.json index ca2616101..4ef1d21a4 100644 --- a/rest-api/api-docs/events.json +++ b/rest-api/api-docs/events.json @@ -110,6 +110,11 @@ "type": "string", "required": true, "description": "Indicates the type of this message." + }, + "asterisk_id": { + "type": "string", + "required": false, + "description": "The unique ID for the Asterisk instance that raised this event." } }, "subTypes": [ diff --git a/tests/test_res_stasis.c b/tests/test_res_stasis.c index 4e28d44c6..459890373 100644 --- a/tests/test_res_stasis.c +++ b/tests/test_res_stasis.c @@ -138,6 +138,7 @@ AST_TEST_DEFINE(app_replaced) RAII_VAR(struct ast_json *, expected_message1, NULL, ast_json_unref); RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); RAII_VAR(struct ast_json *, expected_message2, NULL, ast_json_unref); + char eid[20]; int res; switch (cmd) { @@ -158,9 +159,10 @@ AST_TEST_DEFINE(app_replaced) stasis_app_register(app_name, test_handler, app_data1); stasis_app_register(app_name, test_handler, app_data2); - expected_message1 = ast_json_pack("[{s: s, s: s}]", + expected_message1 = ast_json_pack("[{s: s, s: s, s: s}]", "type", "ApplicationReplaced", - "application", app_name); + "application", app_name, + "asterisk_id", ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)); message = ast_json_pack("{ s: o }", "test-message", ast_json_null()); expected_message2 = ast_json_pack("[o]", ast_json_ref(message)); diff --git a/third-party/pjproject/patches/0005-Re-1969-Fix-crash-on-using-an-already-destroyed-SSL-.patch b/third-party/pjproject/patches/0005-Re-1969-Fix-crash-on-using-an-already-destroyed-SSL-.patch new file mode 100644 index 000000000..551e61ab6 --- /dev/null +++ b/third-party/pjproject/patches/0005-Re-1969-Fix-crash-on-using-an-already-destroyed-SSL-.patch @@ -0,0 +1,164 @@ +From 9e67e0d5c3fdc747530a956038b374fca4748b76 Mon Sep 17 00:00:00 2001 +From: riza <riza@localhost> +Date: Thu, 13 Oct 2016 09:02:50 +0000 +Subject: [PATCH 1/4] Re #1969: Fix crash on using an already destroyed SSL + socket. + +--- + pjlib/src/pj/ssl_sock_ossl.c | 66 ++++++++++++++++++++++++++++---------------- + 1 file changed, 42 insertions(+), 24 deletions(-) + +diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c +index fa0db2d..ceab67a 100644 +--- a/pjlib/src/pj/ssl_sock_ossl.c ++++ b/pjlib/src/pj/ssl_sock_ossl.c +@@ -822,7 +822,10 @@ static void close_sockets(pj_ssl_sock_t *ssock) + pj_lock_acquire(ssock->write_mutex); + asock = ssock->asock; + if (asock) { +- ssock->asock = NULL; ++ // Don't set ssock->asock to NULL, as it may trigger assertion in ++ // send operation. This should be safe as active socket will simply ++ // return PJ_EINVALIDOP on any operation if it is already closed. ++ //ssock->asock = NULL; + ssock->sock = PJ_INVALID_SOCKET; + } + sock = ssock->sock; +@@ -841,9 +844,9 @@ static void close_sockets(pj_ssl_sock_t *ssock) + /* Reset SSL socket state */ + static void reset_ssl_sock_state(pj_ssl_sock_t *ssock) + { ++ pj_lock_acquire(ssock->write_mutex); + ssock->ssl_state = SSL_STATE_NULL; +- +- destroy_ssl(ssock); ++ pj_lock_release(ssock->write_mutex); + + close_sockets(ssock); + +@@ -1612,6 +1615,21 @@ static pj_status_t do_handshake(pj_ssl_sock_t *ssock) + return PJ_EPENDING; + } + ++static void ssl_on_destroy(void *arg) ++{ ++ pj_pool_t *pool = NULL; ++ pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)arg; ++ ++ destroy_ssl(ssock); ++ ++ pj_lock_destroy(ssock->write_mutex); ++ ++ pool = ssock->pool; ++ ssock->pool = NULL; ++ if (pool) ++ pj_pool_release(pool); ++} ++ + + /* + ******************************************************************* +@@ -1830,7 +1848,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock, + + /* Create new SSL socket instance */ + status = pj_ssl_sock_create(ssock_parent->pool, +- &ssock_parent->newsock_param, &ssock); ++ &ssock_parent->newsock_param, &ssock); + if (status != PJ_SUCCESS) + goto on_return; + +@@ -1906,12 +1924,10 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock, + if (status != PJ_SUCCESS) + goto on_return; + +- /* Temporarily add ref the group lock until active socket creation, +- * to make sure that group lock is destroyed if the active socket +- * creation fails. +- */ + pj_grp_lock_add_ref(glock); + asock_cfg.grp_lock = ssock->param.grp_lock = glock; ++ pj_grp_lock_add_handler(ssock->param.grp_lock, ssock->pool, ssock, ++ ssl_on_destroy); + } + + pj_bzero(&asock_cb, sizeof(asock_cb)); +@@ -1927,11 +1943,6 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock, + ssock, + &ssock->asock); + +- /* This will destroy the group lock if active socket creation fails */ +- if (asock_cfg.grp_lock) { +- pj_grp_lock_dec_ref(asock_cfg.grp_lock); +- } +- + if (status != PJ_SUCCESS) + goto on_return; + +@@ -2251,17 +2262,26 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool, + /* Create secure socket mutex */ + status = pj_lock_create_recursive_mutex(pool, pool->obj_name, + &ssock->write_mutex); +- if (status != PJ_SUCCESS) ++ if (status != PJ_SUCCESS) { ++ pj_pool_release(pool); + return status; ++ } + + /* Init secure socket param */ + pj_ssl_sock_param_copy(pool, &ssock->param, param); ++ ++ if (ssock->param.grp_lock) { ++ pj_grp_lock_add_ref(ssock->param.grp_lock); ++ pj_grp_lock_add_handler(ssock->param.grp_lock, pool, ssock, ++ ssl_on_destroy); ++ } ++ + ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3; + if (!ssock->param.timer_heap) { + PJ_LOG(3,(ssock->pool->obj_name, "Warning: timer heap is not " + "available. It is recommended to supply one to avoid " +- "a race condition if more than one worker threads " +- "are used.")); ++ "a race condition if more than one worker threads " ++ "are used.")); + } + + /* Finally */ +@@ -2277,8 +2297,6 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool, + */ + PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock) + { +- pj_pool_t *pool; +- + PJ_ASSERT_RETURN(ssock, PJ_EINVAL); + + if (!ssock->pool) +@@ -2290,12 +2308,11 @@ PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock) + } + + reset_ssl_sock_state(ssock); +- pj_lock_destroy(ssock->write_mutex); +- +- pool = ssock->pool; +- ssock->pool = NULL; +- if (pool) +- pj_pool_release(pool); ++ if (ssock->param.grp_lock) { ++ pj_grp_lock_dec_ref(ssock->param.grp_lock); ++ } else { ++ ssl_on_destroy(ssock); ++ } + + return PJ_SUCCESS; + } +@@ -2782,6 +2799,7 @@ pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock, + + /* Start accepting */ + pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param); ++ ssock->newsock_param.grp_lock = NULL; + status = pj_activesock_start_accept(ssock->asock, pool); + if (status != PJ_SUCCESS) + goto on_error; +-- +2.7.4 + |