summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES18
-rw-r--r--Makefile7
-rw-r--r--Makefile.moddir_rules12
-rw-r--r--apps/app_dial.c5
-rwxr-xr-xbuild_tools/download_externals180
-rwxr-xr-xbuild_tools/list_valid_installed_externals55
-rwxr-xr-xbuild_tools/make_version4
-rw-r--r--build_tools/menuselect-deps.in2
-rw-r--r--channels/chan_sip.c14
-rw-r--r--codecs/codecs.xml25
-rw-r--r--configs/samples/alsa.conf.sample4
-rw-r--r--configs/samples/ccss.conf.sample16
-rw-r--r--configs/samples/chan_dahdi.conf.sample4
-rw-r--r--configs/samples/console.conf.sample4
-rw-r--r--configs/samples/mgcp.conf.sample6
-rw-r--r--configs/samples/minivm.conf.sample14
-rw-r--r--configs/samples/misdn.conf.sample4
-rw-r--r--configs/samples/oss.conf.sample4
-rw-r--r--configs/samples/queues.conf.sample4
-rw-r--r--configs/samples/res_snmp.conf.sample2
-rw-r--r--configs/samples/sip.conf.sample44
-rw-r--r--configs/samples/skinny.conf.sample20
-rw-r--r--configs/samples/unistim.conf.sample4
-rw-r--r--configs/samples/vpb.conf.sample2
-rwxr-xr-xconfigure86
-rw-r--r--configure.ac16
-rwxr-xr-xcontrib/scripts/sip_to_pjsip/sip_to_pjsip.py7
-rw-r--r--include/asterisk/astobj2.h27
-rw-r--r--include/asterisk/named_locks.h10
-rw-r--r--include/asterisk/sorcery.h20
-rw-r--r--main/astobj2.c75
-rw-r--r--main/format_cap.c2
-rw-r--r--main/named_locks.c83
-rw-r--r--main/sorcery.c19
-rw-r--r--makeopts.in2
-rw-r--r--res/ari/resource_channels.c2
-rw-r--r--res/res.xml6
-rw-r--r--res/res_pjsip/config_global.c17
-rw-r--r--res/res_pjsip/location.c36
-rw-r--r--res/res_pjsip/pjsip_configuration.c4
-rw-r--r--res/res_pjsip_registrar.c28
-rw-r--r--rest-api/api-docs/channels.json3
42 files changed, 740 insertions, 157 deletions
diff --git a/CHANGES b/CHANGES
index 5857165c8..39e70cea5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,11 +12,29 @@
--- Functionality changes from Asterisk 14 to Asterisk 15 --------------------
------------------------------------------------------------------------------
+chan_sip
+------------------
+ * If an offer is received with optional SRTP (a media stream with RTP/AVP but
+ which contains a crypto line) chan_sip will now accept it and enable SRTP.
+ If you would like to do optional SRTP on outbound you will need to create
+ a dialplan that dials with it enabled initially and if it fails fall back to
+ without.
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 14.0.0 to Asterisk 14.1.0 ----------
------------------------------------------------------------------------------
+Build System
+------------------
+ * The res_digium_phone, codec_g729a, codec_silk, codec_siren7 and
+ codec_siren14 binary modules hosted at downloads.digium.com can now be
+ automatically downloaded and installed during the Asterisk install
+ process. If selected in menuselect, when 'make install' is run, the
+ script will check the downloads site for a new version and download
+ and install it if needed. The '--with-externals-cache' option to
+ ./configure can be used to specify a location to cache the latest
+ tarballs so they don't have to be re-downloaded for every install.
+
app_voicemail
------------------
* Added "tps_queue_high" and "tps_queue_low" options.
diff --git a/Makefile b/Makefile
index bf8f0f89a..992e1d301 100644
--- a/Makefile
+++ b/Makefile
@@ -618,9 +618,10 @@ $(SUBDIRS_INSTALL):
NEWMODS:=$(foreach d,$(MOD_SUBDIRS),$(notdir $(wildcard $(d)/*.so)))
OLDMODS=$(filter-out $(NEWMODS) $(notdir $(DESTDIR)$(ASTMODDIR)),$(notdir $(wildcard $(DESTDIR)$(ASTMODDIR)/*.so)))
+BADMODS=$(strip $(filter-out $(shell ./build_tools/list_valid_installed_externals),$(OLDMODS)))
oldmodcheck:
- @if [ -n "$(OLDMODS)" ]; then \
+ @if [ -n "$(BADMODS)" ]; then \
echo " WARNING WARNING WARNING" ;\
echo "" ;\
echo " Your Asterisk modules directory, located at" ;\
@@ -630,7 +631,7 @@ oldmodcheck:
echo " modules are compatible with this version before" ;\
echo " attempting to run Asterisk." ;\
echo "" ;\
- for f in $(OLDMODS); do \
+ for f in $(BADMODS); do \
echo " $$f" ;\
done ;\
echo "" ;\
@@ -980,7 +981,7 @@ menuselect/nmenuselect: menuselect/makeopts .lastclean
menuselect/makeopts: makeopts .lastclean
+$(MAKE_MENUSELECT) makeopts
-menuselect-tree: $(foreach dir,$(filter-out main,$(MOD_SUBDIRS)),$(wildcard $(dir)/*.c) $(wildcard $(dir)/*.cc)) build_tools/cflags.xml build_tools/cflags-devmode.xml sounds/sounds.xml build_tools/embed_modules.xml utils/utils.xml agi/agi.xml configure makeopts
+menuselect-tree: $(foreach dir,$(filter-out main,$(MOD_SUBDIRS)),$(wildcard $(dir)/*.c) $(wildcard $(dir)/*.cc) $(wildcard $(dir)/*.xml)) build_tools/cflags.xml build_tools/cflags-devmode.xml sounds/sounds.xml build_tools/embed_modules.xml utils/utils.xml agi/agi.xml configure makeopts
@echo "Generating input for menuselect ..."
@echo "<?xml version=\"1.0\"?>" > $@
@echo >> $@
diff --git a/Makefile.moddir_rules b/Makefile.moddir_rules
index 9b5f3f13a..95e62788f 100644
--- a/Makefile.moddir_rules
+++ b/Makefile.moddir_rules
@@ -146,6 +146,18 @@ clean::
install:: all
@echo "Installing modules from `basename $(CURDIR)`..."
@for x in $(LOADABLE_MODS:%=%.so); do $(INSTALL) -m 755 $$x "$(DESTDIR)$(ASTMODDIR)" ; done
+ifneq ($(findstring :,$(XMLSTARLET)$(BASH)),:)
+ @if [ -f .moduleinfo ] ; then \
+ declare -A DISABLED_MODS ;\
+ for x in $(MENUSELECT_$(MENUSELECT_CATEGORY)) ; do DISABLED_MODS[$${x}]=1 ; done ;\
+ EXTERNAL_MODS=$$(xmlstarlet sel -t -m "/category/member[support_level = 'external']" -v "@name" -n .moduleinfo) ;\
+ for x in $${EXTERNAL_MODS} ; do \
+ if [ -z "$${DISABLED_MODS[$${x}]}" ] ; then \
+ $(ASTTOPDIR)/build_tools/download_externals $${x} ;\
+ fi ;\
+ done ;\
+ fi
+endif
uninstall::
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 48193b5a0..c427faf6e 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -1919,9 +1919,10 @@ static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
break;
case '5':
- /* XXX should we set status to DENY ? */
- if (ast_test_flag64(opts, OPT_PRIVACY))
+ if (ast_test_flag64(opts, OPT_PRIVACY)) {
+ ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
break;
+ }
/* if not privacy, then 5 is the same as "default" case */
default: /* bad input or -1 if failure to start autoservice */
/* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
diff --git a/build_tools/download_externals b/build_tools/download_externals
new file mode 100755
index 000000000..8d5872df7
--- /dev/null
+++ b/build_tools/download_externals
@@ -0,0 +1,180 @@
+#!/usr/bin/env bash
+
+if [[ ( ${BASH_VERSINFO[0]} == 4 && ${BASH_VERSINFO[1]} > 1 ) || ${BASH_VERSINFO[0]} > 4 ]] ; then
+ shopt -s compat41
+fi
+set -e
+
+ASTTOPDIR=${ASTTOPDIR:-.}
+
+module_name=$1
+
+if [[ -z ${module_name} ]] ; then
+ echo "You must supply a module name."
+ exit 64
+fi
+
+tmpdir=$(mktemp -d)
+if [[ -z "${tmpdir}" ]] ; then
+ echo "${module_name}: Unable to create temporary directory."
+ exit 1
+fi
+trap "rm -rf ${tmpdir}" EXIT
+
+sed -r -e "s/^([^ =]+)\s*=\s*(.*)$/\1=\"\2\"/g" ${ASTTOPDIR}/makeopts >${tmpdir}/makeopts
+source ${tmpdir}/makeopts
+if [[ -z "${ASTMODDIR}" ]] ; then
+ echo "${module_name}: Unable to parse ${ASTTOPDIR}/makeopts."
+ exit 1
+fi
+
+XMLSTARLET=${XMLSTARLET:-xmlstarlet}
+if [[ "${XMLSTARLET}" = ":" ]] ; then
+ echo "${module_name}: The externals downloader requires xmlstarlet to be installed."
+ exit 1
+fi
+
+cache_dir="${EXTERNALS_CACHE_DIR}"
+if [[ -z ${cache_dir} ]] ; then
+ cache_dir=${tmpdir}
+fi
+
+version=$(${ASTTOPDIR}/build_tools/make_version ${ASTTOPDIR})
+if [[ ! ${version} =~ ^(GIT-)?([^.-]+)[.-].* ]] ; then
+ echo "${module_name}: Couldn't parse version ${version}"
+ exit 1
+fi
+major_version=${BASH_REMATCH[2]}
+
+if [[ "${major_version}" == "master" ]] ; then
+ echo "${module_name}: External module downloading is not available in the 'master' git branch. Please disable in menuselect and download manually."
+ exit 1
+fi
+
+major_version=${major_version}.0
+
+if [[ "${HOST_CPU}" = "x86_64" ]] ; then
+ host_bits=64
+else
+ host_bits=32
+fi
+
+remote_url=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${module_name}']/member_data/downloader/@remote_url" ${ASTTOPDIR}/menuselect-tree || :)
+if [[ -n "${remote_url}" ]] ; then
+ remote_url="${remote_url}/asterisk-${major_version}/x86-${host_bits}"
+else
+ directory_name=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${module_name}']/member_data/downloader/@directory_name" ${ASTTOPDIR}/menuselect-tree || :)
+ remote_url="http://downloads.digium.com/pub/telephony/${directory_name:-${module_name}}/asterisk-${major_version}/x86-${host_bits}"
+fi
+
+version_convert() {
+ local v=${1##*_}
+ if [[ ${v} =~ ([0-9]+)[.]([0-9]+)[.]([0-9]+) ]] ; then
+ v=$(( ${BASH_REMATCH[1]}<<18 | ${BASH_REMATCH[2]}<<9 | ${BASH_REMATCH[3]} ))
+ fi
+ echo ${v}
+}
+
+${WGET} -q -O ${tmpdir}/manifest.xml ${remote_url}/manifest.xml || {
+ echo "${module_name}: Unable to fetch ${remote_url}/manifest.xml"
+ exit 1
+}
+
+rpv=$(${XMLSTARLET} sel -t -v "/package/@version" ${tmpdir}/manifest.xml)
+rpvi=$(version_convert ${rpv})
+echo "${module_name}: Remote package version ${rpv} (${rpvi})"
+
+module_dir=${module_name}-${rpv}-x86_${host_bits}
+tarball=${module_dir}.tar.gz
+export need_install=0
+
+if [[ -f ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml ]] ; then
+ package_arch=$(${XMLSTARLET} sel -t -v "/package/@arch" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
+ ipv=$(${XMLSTARLET} sel -t -v "/package/@version" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
+ ipvi=$(version_convert ${ipv})
+ ip_major=${ipv%_*}
+ echo "${module_name}: Installed package version ${ipv} (${ipvi})"
+ if [[ "${ip_major}" != "${major_version}" || "${package_arch}" != "x86_${host_bits}" ]] ; then
+ echo "${module_name}: The installed package is not for this version of Asterisk. Reinstalling."
+ need_install=1
+ elif [[ ${rpvi} > ${ipvi} ]] ; then
+ echo "${module_name}: A newer package is available"
+ need_install=1
+ else
+ sums=$(${XMLSTARLET} sel -t -m "//file" -v "@md5sum" -n ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
+ for sum in ${sums} ; do
+ install_path=$(${XMLSTARLET} sel -t -v "//file[@md5sum = '${sum}']/@install_path" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml )
+ f=${DESTDIR}$(eval echo ${install_path})
+ if [[ ! -f ${f} ]] ; then
+ echo Not found: ${f}
+ need_install=1
+ else
+ cs=$(md5sum ${f} | cut -b1-32)
+ if [[ "${cs}" != "${sum}" ]] ; then
+ echo Checksum mismatch: ${f}
+ need_install=1
+ fi
+ fi
+ done
+ fi
+else
+ need_install=1
+fi
+
+if [[ ${need_install} == 1 ]] ; then
+ if [[ ( -n "${ipvi}" ) && ${ipvi} > ${rpvi} ]] ; then
+ echo "${module_name}: Installed package is newer than that available for download."
+ exit 0
+ fi
+else
+ echo "${module_name} is up to date."
+ exit 0;
+fi
+
+need_download=1
+if [[ -f ${cache_dir}/${module_name}.manifest.xml ]] ; then
+ cpv=$(${XMLSTARLET} sel -t -v "/package/@version" ${cache_dir}/${module_name}.manifest.xml)
+ cpvi=$(version_convert ${cpv})
+ echo "${module_name}: Cached package version ${cpv} (${cpvi})"
+ if [[ ${cpvi} == ${rpvi} && ( -f ${cache_dir}/${tarball} ) ]] ; then
+ echo "${module_name}: Cached version is available."
+ need_download=0
+ fi
+fi
+
+if [[ ${need_download} = 1 ]] ; then
+ echo "${module_name}: Downloading ${remote_url}/${tarball}"
+ ${WGET} -q -O ${cache_dir}/${tarball} ${remote_url}/${tarball} || {
+ echo "${module_name}: Unable to fetch ${remote_url}/${tarball}"
+ exit 1
+ }
+ cp ${tmpdir}/manifest.xml ${cache_dir}/${module_name}.manifest.xml
+fi
+
+tar -xzf ${cache_dir}/${tarball} -C ${cache_dir}
+trap "rm -rf ${cache_dir}/${module_dir} ; rm -rf ${tmpdir}" EXIT
+
+echo "${module_name}: Installing."
+
+if [[ $EUID == 0 ]] ; then
+ install_params="--group=0 --owner=0"
+fi
+
+names=$(${XMLSTARLET} sel -t -m "//file" -v "@name" -n ${cache_dir}/${module_dir}/manifest.xml)
+for name in ${names} ; do
+ source_path=${cache_dir}/${module_dir}/${name}
+ install_path=$(${XMLSTARLET} sel -t -v "//file[@name = '${name}']/@install_path" ${cache_dir}/${module_dir}/manifest.xml)
+ install_path=${DESTDIR}$(eval echo ${install_path})
+ executable=$(${XMLSTARLET} sel -t -v "//file[@name = '${name}']/@executable" ${cache_dir}/${module_dir}/manifest.xml || :)
+ if [[ "${executable}" = "yes" ]] ; then
+ mode=0755
+ else
+ mode=0644
+ fi
+
+ ${INSTALL} -Dp ${install_params} --mode=${mode} ${source_path} ${install_path}
+
+done
+${INSTALL} -Dp ${install_params} --mode=0644 ${cache_dir}/${module_dir}/manifest.xml ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml
+
+echo "${module_name}: Installed."
diff --git a/build_tools/list_valid_installed_externals b/build_tools/list_valid_installed_externals
new file mode 100755
index 000000000..12aff3f95
--- /dev/null
+++ b/build_tools/list_valid_installed_externals
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+
+if [[ ( ${BASH_VERSINFO[0]} == 4 && ${BASH_VERSINFO[1]} > 1 ) || ${BASH_VERSINFO[0]} > 4 ]] ; then
+ shopt -s compat41
+fi
+set -e
+
+ASTTOPDIR=${ASTTOPDIR:-.}
+
+tmpdir=$(mktemp -d)
+if [[ -z "${tmpdir}" ]] ; then
+ echo "${module_name}: Unable to create temporary directory."
+ exit 1
+fi
+trap "rm -rf ${tmpdir}" EXIT
+
+sed -r -e "s/^([^ =]+)\s*=\s*(.*)$/\1=\"\2\"/g" ${ASTTOPDIR}/makeopts >${tmpdir}/makeopts
+source ${tmpdir}/makeopts
+if [[ -z "${ASTMODDIR}" ]] ; then
+ echo "${module_name}: Unable to parse ${ASTTOPDIR}/makeopts."
+ exit 1
+fi
+
+XMLSTARLET=${XMLSTARLET:-xmlstarlet}
+if [[ "${XMLSTARLET}" = ":" ]] ; then
+ echo "${module_name}: The externals downloader requires xmlstarlet to be installed."
+ exit 1
+fi
+
+version=$(${ASTTOPDIR}/build_tools/make_version ${ASTTOPDIR})
+if [[ ! ${version} =~ ^(GIT-)?([^.-]+)[.-].* ]] ; then
+ echo "${module_name}: Couldn't parse version ${version}"
+ exit 1
+fi
+major_version=${BASH_REMATCH[2]}.0
+
+if [[ "${HOST_CPU}" = "x86_64" ]] ; then
+ host_bits=64
+else
+ host_bits=32
+fi
+
+names=""
+for manifest in ${DESTDIR}${ASTMODDIR}/*.manifest.xml ; do
+ if [ ! -f "$manifest" ] ; then
+ break
+ fi
+ package_version=$(${XMLSTARLET} sel -t -v "/package/@version" ${manifest})
+ package_major_version=${package_version%_*}
+ package_arch=$(${XMLSTARLET} sel -t -v "/package/@arch" ${manifest})
+ if [[ "$package_major_version" = "$major_version" && "${package_arch}" = "x86_${host_bits}" ]] ; then
+ names+=$(${XMLSTARLET} sel -t -m "//file[@executable = 'yes']" -v "concat(@name, ' ')" ${manifest})
+ fi
+done
+echo $names
diff --git a/build_tools/make_version b/build_tools/make_version
index fd14a550a..3e0f4a0b0 100755
--- a/build_tools/make_version
+++ b/build_tools/make_version
@@ -89,11 +89,13 @@ elif [ -d ${1}/.git ]; then
if [ -z ${GIT} ]; then
GIT="git"
fi
-
+
if ! command -v ${GIT} >/dev/null 2>&1; then
echo "UNKNOWN__and_probably_unsupported"
exit 1
fi
+ cd ${1}
+
# If the first log commit messages indicates that this is checked into
# subversion, we'll just use the SVN- form of the revision.
MODIFIED=""
diff --git a/build_tools/menuselect-deps.in b/build_tools/menuselect-deps.in
index a04440955..9b077680e 100644
--- a/build_tools/menuselect-deps.in
+++ b/build_tools/menuselect-deps.in
@@ -31,6 +31,8 @@ KQUEUE=@PBX_KQUEUE@
LDAP=@PBX_LDAP@
LIBEDIT=@PBX_LIBEDIT@
LIBXML2=@PBX_LIBXML2@
+XMLSTARLET=@PBX_XMLSTARLET@
+BASH=@PBX_BASH@
LTDL=@PBX_LTDL@
LUA=@PBX_LUA@
MISDN=@PBX_MISDN@
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 6250731bd..1d70e8975 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1479,7 +1479,8 @@ static int handle_response_register(struct sip_pvt *p, int resp, const char *res
static void handle_response(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno);
/*------ SRTP Support -------- */
-static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp, const char *a);
+static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp,
+ const char *a);
/*------ T38 Support --------- */
static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
@@ -10612,6 +10613,10 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
} else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) {
processed_crypto = TRUE;
processed = TRUE;
+ if (secure_audio == FALSE) {
+ ast_log(AST_LOG_NOTICE, "Processed audio crypto attribute without SAVP specified; accepting anyway\n");
+ secure_audio = TRUE;
+ }
} else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) {
processed = TRUE;
}
@@ -10629,6 +10634,10 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
} else if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) {
processed_crypto = TRUE;
processed = TRUE;
+ if (secure_video == FALSE) {
+ ast_log(AST_LOG_NOTICE, "Processed video crypto attribute without SAVP specified; accepting anyway\n");
+ secure_video = TRUE;
+ }
} else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) {
processed = TRUE;
}
@@ -33750,7 +33759,8 @@ static void sip_send_all_mwi_subscriptions(void)
ao2_iterator_destroy(&iter);
}
-static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp, const char *a)
+static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp,
+ const char *a)
{
struct ast_rtp_engine_dtls *dtls;
diff --git a/codecs/codecs.xml b/codecs/codecs.xml
new file mode 100644
index 000000000..ac3c6e638
--- /dev/null
+++ b/codecs/codecs.xml
@@ -0,0 +1,25 @@
+<member name="codec_silk" displayname="Download the SILK codec from Digium. See http://downloads.digium.com/pub/telephony/codec_silk/README.">
+ <support_level>external</support_level>
+ <depend>xmlstarlet</depend>
+ <depend>bash</depend>
+ <defaultenabled>no</defaultenabled>
+</member>
+<member name="codec_siren7" displayname="Download the Siren7 codec from Digium. See http://downloads.digium.com/pub/telephony/codec_siren7/README.">
+ <support_level>external</support_level>
+ <depend>xmlstarlet</depend>
+ <depend>bash</depend>
+ <defaultenabled>no</defaultenabled>
+</member>
+<member name="codec_siren14" displayname="Download the Siren14 codec from Digium. See http://downloads.digium.com/pub/telephony/codec_siren14/README.">
+ <support_level>external</support_level>
+ <depend>xmlstarlet</depend>
+ <depend>bash</depend>
+ <defaultenabled>no</defaultenabled>
+</member>
+<member name="codec_g729a" displayname="Download the g729a codec from Digium. A license must be purchased for this codec. See http://downloads.digium.com/pub/telephony/codec_g729/README.">
+ <support_level>external</support_level>
+ <depend>xmlstarlet</depend>
+ <depend>bash</depend>
+ <defaultenabled>no</defaultenabled>
+ <member_data><downloader directory_name="codec_g729"/></member_data>
+</member>
diff --git a/configs/samples/alsa.conf.sample b/configs/samples/alsa.conf.sample
index ced5b4485..23aac4e10 100644
--- a/configs/samples/alsa.conf.sample
+++ b/configs/samples/alsa.conf.sample
@@ -46,7 +46,7 @@ extension=s
; systems where there will be no return audio path, such as overhead pagers.
;noaudiocapture=true
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
; ALSA channel. Defaults to "no". An enabled jitterbuffer will
; be used only if the sending side can create and the receiving
@@ -74,5 +74,5 @@ extension=s
; network normally has low jitter, but occasionally has spikes.
; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
diff --git a/configs/samples/ccss.conf.sample b/configs/samples/ccss.conf.sample
index 21b0b0668..7b3fe7d23 100644
--- a/configs/samples/ccss.conf.sample
+++ b/configs/samples/ccss.conf.sample
@@ -64,9 +64,9 @@
; PLEASE READ THIS!!!
;===========================================
;
-;---------------------------------------------------------------------
+; --------------------------------------------------------------------
; Timers
-;---------------------------------------------------------------------
+; --------------------------------------------------------------------
;There are three configurable timers for all types of CC: the
;cc_offer_timer, the ccbs_available_timer, and the ccnr_available_timer.
;In addition, when using a generic agent, there is a fourth timer,
@@ -98,9 +98,9 @@
; only affects operation when using a generic agent.
;
;cc_recall_timer = 20
-;---------------------------------------------------------------------
+; --------------------------------------------------------------------
; Policies
-;---------------------------------------------------------------------
+; --------------------------------------------------------------------
; Policy settings tell Asterisk how to behave and what sort of
; resources to allocate in order to facilitate CC. There are two
; settings to control the actions Asterisk will take.
@@ -153,9 +153,9 @@
;cc_monitor_policy=never
;
;
-;---------------------------------------------------------------------
+; --------------------------------------------------------------------
; Limits
-;---------------------------------------------------------------------
+; --------------------------------------------------------------------
;
; The use of CC requires Asterisk to potentially use more memory than
; some administrators would like. As such, it is a good idea to limit
@@ -175,9 +175,9 @@
;
;cc_max_monitors = 5
;
-;---------------------------------------------------------------------
+; --------------------------------------------------------------------
; Other
-;---------------------------------------------------------------------
+; --------------------------------------------------------------------
;
; When using a generic CC agent, the caller who requested CC will be
; called back when a called party becomes available. When the caller
diff --git a/configs/samples/chan_dahdi.conf.sample b/configs/samples/chan_dahdi.conf.sample
index a0c729c11..e70a2a138 100644
--- a/configs/samples/chan_dahdi.conf.sample
+++ b/configs/samples/chan_dahdi.conf.sample
@@ -1220,7 +1220,7 @@ pickupgroup=1
;
;jitterbuffers=4
;
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
; DAHDI channel. Defaults to "no". An enabled jitterbuffer will
; be used only if the sending side can create and the receiving
@@ -1248,7 +1248,7 @@ pickupgroup=1
; network normally has low jitter, but occasionally has spikes.
; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
;
; You can define your own custom ring cadences here. You can define up to 8
; pairs. If the silence is negative, it indicates where the caller ID spill is
diff --git a/configs/samples/console.conf.sample b/configs/samples/console.conf.sample
index 606254eee..aad306ed5 100644
--- a/configs/samples/console.conf.sample
+++ b/configs/samples/console.conf.sample
@@ -44,7 +44,7 @@
;
;mohinterpret=default
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
; Console channel. Defaults to "no". An enabled jitterbuffer will
; be used only if the sending side can create and the receiving
@@ -72,7 +72,7 @@
; network normally has low jitter, but occasionally has spikes.
; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
;
diff --git a/configs/samples/mgcp.conf.sample b/configs/samples/mgcp.conf.sample
index 7c725bc3d..f4bc0dbf2 100644
--- a/configs/samples/mgcp.conf.sample
+++ b/configs/samples/mgcp.conf.sample
@@ -11,12 +11,12 @@
;cos=3 ; Sets 802.1p priority for signaling packets.
;cos_audio=5 ; Sets 802.1p priority for RTP audio packets.
-;---------------------- DIGIT TIMEOUTS ----------------------------
+; --------------------- DIGIT TIMEOUTS ----------------------------
firstdigittimeout = 30000 ; default 16000 = 16s
gendigittimeout = 10000 ; default 8000 = 8s
matchdigittimeout = 5000 ; defaults 3000 = 3s
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
; MGCP channel. Defaults to "no". An enabled jitterbuffer will
; be used only if the sending side can create and the receiving
@@ -48,7 +48,7 @@ matchdigittimeout = 5000 ; defaults 3000 = 3s
; network normally has low jitter, but occasionally has spikes.
; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
;[dlinkgw]
;host = 192.168.0.64
diff --git a/configs/samples/minivm.conf.sample b/configs/samples/minivm.conf.sample
index 55a39c869..2df3449d1 100644
--- a/configs/samples/minivm.conf.sample
+++ b/configs/samples/minivm.conf.sample
@@ -12,7 +12,7 @@
; this configuration file or realtime. The idea is to build voicemail as building blocks so that
; a complete and adaptive voicemail system can be built in the dialplan
;
-;------------------------------ Variables to use in subject, from and message body ------------------
+; ----------------------------- Variables to use in subject, from and message body ------------------
; Change the from, body and/or subject, variables:
; MVM_NAME, MVM_DUR, MVM_MSGNUM, VM_MAILBOX, MVM_CALLERID, MVM_CIDNUM,
; MVM_CIDNAME, MVM_DATE
@@ -24,7 +24,7 @@
; Note: The emailbody config row can only be up to 512 characters due to a
; limitation in the Asterisk configuration subsystem.
; To create longer mails, use the templatefile option when creating the template
-;----------------------------------------------------------------------------------------------------
+; ---------------------------------------------------------------------------------------------------
[general]
; Default format for storing and sending voicemail
@@ -64,7 +64,7 @@ silencethreshold=128
; This is used both for e-mail and pager messages
;mailcmd=/usr/sbin/sendmail -t
;
-;--------------Default e-mail message template (used if no templates are used) ------
+; -------------Default e-mail message template (used if no templates are used) ------
;fromstring=The Asterisk PBX
;
@@ -82,7 +82,7 @@ emaildateformat=%A, %B %d, %Y at %r
; 24h date format
;emaildateformat=%A, %d %B %Y at %H:%M:%S
;
-;--------------Default pager message template (used if no templates are used) ------
+; -------------Default pager message template (used if no templates are used) ------
; You can also change the Pager From: string, the pager body and/or subject.
; The above defined variables also can be used here
;pagerfromstring=The Asterisk PBX
@@ -90,7 +90,7 @@ emaildateformat=%A, %B %d, %Y at %r
;pagerbody=New ${MVM_DUR} long msg in box ${MVM_MAILBOX}\nfrom ${MVM_CALLERID}, on ${MVM_DATE}
;
;
-;--------------Timezone definitions (used in voicemail accounts) -------------------
+; -------------Timezone definitions (used in voicemail accounts) -------------------
;
; Users may be located in different timezones, or may have different
; message announcements for their introductory message when they enter
@@ -133,7 +133,7 @@ central=America/Chicago|'vm-received' Q 'digits/at' IMp
central24=America/Chicago|'vm-received' q 'digits/at' H N 'hours'
military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p'
-;----------------------- Message body templates---------------------
+; ---------------------- Message body templates---------------------
; [template-name] ; "template-" is a verbatim marker
; fromaddress = Your Friendly Asterisk Server
; fromemail = asteriskvm@digium.com
@@ -187,7 +187,7 @@ dateformat=%A, %B %d, %Y at %r
;subject = Dear old chap, you've got an electronic communique
;charset=ascii
-;----------------------- Mailbox accounts --------------------------
+; ---------------------- Mailbox accounts --------------------------
;Template for mailbox definition - all options
;
; [username@domain] ; Has to be unique within domain (MWM_USERNAME, MWM_DOMAIN)
diff --git a/configs/samples/misdn.conf.sample b/configs/samples/misdn.conf.sample
index ac54dbc5a..ca27c03bd 100644
--- a/configs/samples/misdn.conf.sample
+++ b/configs/samples/misdn.conf.sample
@@ -109,7 +109,7 @@ crypt_prefix=**
;
crypt_keys=test,muh
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
; SIP channel. Defaults to "no". An enabled jitterbuffer will
; be used only if the sending side can create and the receiving
@@ -140,7 +140,7 @@ crypt_keys=test,muh
; network normally has low jitter, but occasionally has spikes.
; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
; users sections:
;
diff --git a/configs/samples/oss.conf.sample b/configs/samples/oss.conf.sample
index c3781a2a2..ee169209f 100644
--- a/configs/samples/oss.conf.sample
+++ b/configs/samples/oss.conf.sample
@@ -46,7 +46,7 @@
; queuesize = 10 ; frames in device driver
; frags = 8 ; argument to SETFRAGMENT
- ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+ ; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
; OSS channel. Defaults to "no". An enabled jitterbuffer will
; be used only if the sending side can create and the receiving
@@ -74,7 +74,7 @@
; network normally has low jitter, but occasionally has spikes.
; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
- ;-----------------------------------------------------------------------------------
+ ; ----------------------------------------------------------------------------------
; below is an entry for a second console channel
; [card1]
diff --git a/configs/samples/queues.conf.sample b/configs/samples/queues.conf.sample
index 85cf9e40f..8a9c88402 100644
--- a/configs/samples/queues.conf.sample
+++ b/configs/samples/queues.conf.sample
@@ -129,7 +129,7 @@ monitor-type = MixMonitor
;
;penaltymemberslimit = 5
;
-;----------------------QUEUE TIMING OPTIONS------------------------------------
+; ---------------------QUEUE TIMING OPTIONS------------------------------------
; A Queue has two different "timeout" values associated with it. One is the
; timeout parameter configured in queues.conf. This timeout specifies the
; amount of time to try ringing a member's phone before considering the
@@ -181,7 +181,7 @@ monitor-type = MixMonitor
;retry = 5
;timeoutpriority = app|conf
;
-;-----------------------END QUEUE TIMING OPTIONS---------------------------------
+; ----------------------END QUEUE TIMING OPTIONS---------------------------------
; Weight of queue - when compared to other queues, higher weights get
; first shot at available channels when the same channel is included in
; more than one queue.
diff --git a/configs/samples/res_snmp.conf.sample b/configs/samples/res_snmp.conf.sample
index a6e40c8e2..7f3734910 100644
--- a/configs/samples/res_snmp.conf.sample
+++ b/configs/samples/res_snmp.conf.sample
@@ -1,6 +1,6 @@
;
; Configuration file for res_snmp
-;---------------------------------
+; --------------------------------
;
; Res_snmp can run as a subagent or standalone SNMP agent. The standalone snmp
; agent is based on net-snmp and will read a configuration file called
diff --git a/configs/samples/sip.conf.sample b/configs/samples/sip.conf.sample
index da176b4d6..916e2d671 100644
--- a/configs/samples/sip.conf.sample
+++ b/configs/samples/sip.conf.sample
@@ -15,7 +15,7 @@
; - context - Which set of services you offer various users
;
; SIP dial strings
-;-----------------------------------------------------------
+; ----------------------------------------------------------
; In the dialplan (extensions.conf) you can use several
; syntaxes for dialing SIP devices.
; SIP/devicename
@@ -87,7 +87,7 @@
; sip reload Reload configuration file
; sip show settings Show the current channel configuration
;
-;------- Naming devices ------------------------------------------------------
+; ------ Naming devices ------------------------------------------------------
;
; When naming devices, make sure you understand how Asterisk matches calls
; that come in.
@@ -111,7 +111,7 @@
; not needed at all. Check below. In later releases, it's renamed
; to "defaultuser" which is a better name, since it is used in
; combination with the "defaultip" setting.
-;-----------------------------------------------------------------------------
+; ----------------------------------------------------------------------------
; ** Old configuration options **
; The "call-limit" configuation option is considered old is replaced
@@ -573,7 +573,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; are not purged during SIP reloads.
;
-;------------------------ TLS settings ------------------------------------------------------------
+; ----------------------- TLS settings ------------------------------------------------------------
;tlscertfile=</path/to/certificate.pem> ; Certificate chain (*.pem format only) to use for TLS connections
; The certificates must be sorted starting with the subject's certificate
; and followed by intermediate CA certificates if applicable. If the
@@ -622,7 +622,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; Your distribution might have changed that list
; further.
;
-;--------------------------- SIP timers ----------------------------------------------------
+; -------------------------- SIP timers ----------------------------------------------------
; These timers are used primarily in INVITE transactions.
; The default for Timer T1 is 500 ms or the measured run-trip time between
; Asterisk and the device if you have qualify=yes for the device.
@@ -636,7 +636,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; in this amount of time, the call will autocongest
; Defaults to 64*timert1
-;--------------------------- RTP timers ----------------------------------------------------
+; -------------------------- RTP timers ----------------------------------------------------
; These timers are currently used for both audio and video streams. The RTP timeouts
; are only applied to the audio channel.
; The settings are settable in the global section as well as per device
@@ -652,7 +652,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;rtpkeepalive=<secs> ; Send keepalives in the RTP stream to keep NAT open
; (default is off - zero)
-;--------------------------- SIP Session-Timers (RFC 4028)------------------------------------
+; -------------------------- SIP Session-Timers (RFC 4028)------------------------------------
; SIP Session-Timers provide an end-to-end keep-alive mechanism for active SIP sessions.
; This mechanism can detect and reclaim SIP channels that do not terminate through normal
; signaling procedures. Session-Timers can be configured globally or at a user/peer level.
@@ -681,7 +681,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;session-minse=90
;session-refresher=uac
;
-;--------------------------- SIP DEBUGGING ---------------------------------------------------
+; -------------------------- SIP DEBUGGING ---------------------------------------------------
;sipdebug = yes ; Turn on SIP debugging by default, from
; the moment the channel loads this configuration.
; NOTE: You cannot use the CLI to turn it off. You'll
@@ -692,7 +692,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; SIP history is output to the DEBUG logging channel
-;--------------------------- STATUS NOTIFICATIONS (SUBSCRIPTIONS) ----------------------------
+; -------------------------- STATUS NOTIFICATIONS (SUBSCRIPTIONS) ----------------------------
; You can subscribe to the status of extensions with a "hint" priority
; (See extensions.conf.sample for examples)
; chan_sip support two major formats for notifications: dialog-info and SIMPLE
@@ -741,7 +741,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;callcounter = yes ; Enable call counters on devices. This can be set per
; device too.
-;----------------------------------------- T.38 FAX SUPPORT ----------------------------------
+; ---------------------------------------- T.38 FAX SUPPORT ----------------------------------
;
; This setting is available in the [general] section as well as in device configurations.
; Setting this to yes enables T.38 FAX (UDPTL) on SIP calls; it defaults to off.
@@ -774,7 +774,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; faxdetect = cng ; Enables only CNG detection
; faxdetect = t38 ; Enables only T.38 detection
;
-;----------------------------------------- OUTBOUND SIP REGISTRATIONS ------------------------
+; ---------------------------------------- OUTBOUND SIP REGISTRATIONS ------------------------
; Asterisk can register as a SIP user agent to a SIP proxy (provider)
; Format for the register statement is:
; register => [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry]
@@ -851,7 +851,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; 401 responses and continue retrying according to normal
; retry rules.
-;----------------------------------------- OUTBOUND MWI SUBSCRIPTIONS -------------------------
+; ---------------------------------------- OUTBOUND MWI SUBSCRIPTIONS -------------------------
; Asterisk can subscribe to receive the MWI from another SIP server and store it locally for retrieval
; by other phones. At this time, you can only subscribe using UDP as the transport.
; Format for the mwi register statement is:
@@ -866,7 +866,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; MWI received will be stored in the 1234 mailbox of the SIP_Remote context.
; It can be used by other phones by following the below:
; mailbox=1234@SIP_Remote
-;----------------------------------------- NAT SUPPORT ------------------------
+; ---------------------------------------- NAT SUPPORT ------------------------
;
; WARNING: SIP operation behind a NAT is tricky and you really need
; to read and understand well the following section.
@@ -1008,7 +1008,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;
; icesupport = yes
-;----------------------------------- MEDIA HANDLING --------------------------------
+; ---------------------------------- MEDIA HANDLING --------------------------------
; By default, Asterisk tries to re-invite media streams to an optimal path. If there's
; no reason for Asterisk to stay in the media path, the media will be redirected.
; This does not really work well in the case where Asterisk is outside and the
@@ -1090,7 +1090,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; option may be specified at the global or peer scope.
;force_avp=yes ; Force 'RTP/AVP', 'RTP/AVPF', 'RTP/SAVP', and 'RTP/SAVPF' to be used for
; media streams when appropriate, even if a DTLS stream is present.
-;----------------------------------------- REALTIME SUPPORT ------------------------
+; ---------------------------------------- REALTIME SUPPORT ------------------------
; For additional information on ARA, the Asterisk Realtime Architecture,
; please read https://wiki.asterisk.org/wiki/display/AST/Realtime+Database+Configuration
;
@@ -1128,7 +1128,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; is still in memory (due to caching or other reasons), the
; information will not be removed from realtime storage
-;----------------------------------------- SIP DOMAIN SUPPORT ------------------------
+; ---------------------------------------- SIP DOMAIN SUPPORT ------------------------
; Incoming INVITE and REFER messages can be matched against a list of 'allowed'
; domains, each of which can direct the call to a specific context if desired.
; By default, all domains are accepted and sent to the default context or the
@@ -1167,13 +1167,13 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; destinations which do not have a prior
; account relationship with your server.
-;------------------------------ Advice of Charge CONFIGURATION --------------------------
+; ----------------------------- Advice of Charge CONFIGURATION --------------------------
; snom_aoc_enabled = yes; ; This options turns on and off support for sending AOC-D and
; AOC-E to snom endpoints. This option can be used both in the
; peer and global scope. The default for this option is off.
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
; SIP channel. Defaults to "no". An enabled jitterbuffer will
; be used only if the sending side can create and the receiving
@@ -1205,7 +1205,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
[authentication]
; Global credentials for outbound calls, i.e. when a proxy challenges your
@@ -1224,7 +1224,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; You may also add auth= statements to [peer] definitions
; Peer auth= override all other authentication settings if we match on realm
-;------------------------------------------------------------------------------
+; -----------------------------------------------------------------------------
; DEVICE CONFIGURATION
;
; SIP entities have a 'type' which determines their roles within Asterisk.
@@ -1351,7 +1351,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; ; from the peer's configuration.
;
-;------------------------------------------------------------------------------
+; -----------------------------------------------------------------------------
; DTLS-SRTP CONFIGURATION
;
; DTLS-SRTP support is available if the underlying RTP engine in use supports it.
@@ -1409,7 +1409,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;port=80 ; The port number we want to connect to on the remote side
; Also used as "defaultport" in combination with "defaultip" settings
-;--- sample definition for a provider
+; -- sample definition for a provider
;[provider1]
;type=peer
;host=sip.provider1.com
diff --git a/configs/samples/skinny.conf.sample b/configs/samples/skinny.conf.sample
index be88dc230..2bf06fbc8 100644
--- a/configs/samples/skinny.conf.sample
+++ b/configs/samples/skinny.conf.sample
@@ -54,7 +54,7 @@ keepalive=120
;cos_audio=5 ; Sets 802.1p priority for RTP audio packets.
;cos_video=4 ; Sets 802.1p priority for RTP video packets.
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
;jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
; skinny channel. Defaults to "no". An enabled jitterbuffer will
; be used only if the sending side can create and the receiving
@@ -79,10 +79,10 @@ keepalive=120
; Defaults to fixed.
;jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
[lines]
-;----------------------------------- LINES SECTION --------------------------------
+; ---------------------------------- LINES SECTION --------------------------------
; Options set under [lines] apply to all lines unless explicitly set for a particular
; device. The options that can be set under lines are specified in GENERAL LINE OPTIONS.
; These options can also be set for each individual device as well as those under SPECIFIC
@@ -95,15 +95,15 @@ keepalive=120
; Where options are common to both lines and devices, the results typically take that of
; the least permission. ie if a no is set for either line or device, the call will not be
; able to use that permission
-;-------------------------------- GENERAL LINE OPTIONS -----------------------------
+; ------------------------------- GENERAL LINE OPTIONS -----------------------------
;earlyrtp=1 ; whether audio signalling should be provided by asterisk
; ; (earlyrtp=1) or device generated (earlyrtp=0). default=yes
;transfer=1 ; whether the device is allowed to transfer. default=yes
;context=default ; context to use for this line.
;callfwdtimeout=20000 ; ms before cfwd_noans occurs (default 20 secs)
-;------------------------------- SPECIFIC LINE OPTIONS -----------------------------
+; ------------------------------ SPECIFIC LINE OPTIONS -----------------------------
;setvar= ; allows for the setting of chanvars.
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
;[100]
;nat=yes
@@ -149,7 +149,7 @@ keepalive=120
[devices]
-;---------------------------------- DEVICES SECTION -------------------------------
+; --------------------------------- DEVICES SECTION -------------------------------
; Options set under [devices] apply to all devices unless explicitly set for a particular
; device. The options that can be set under devices are specified in GENERAL DEVICE OPTIONS.
; These options can also be set for each individual device as well as those under SPECIFIC
@@ -162,16 +162,16 @@ keepalive=120
; Where options are common to both lines and devices, the results typically take that of
; the least permission. ie if a no is set for either line or device, the call will not be
; able to use that permission
-;------------------------------- GENERAL DEVICE OPTIONS ----------------------------
+; ------------------------------ GENERAL DEVICE OPTIONS ----------------------------
;earlyrtp=1 ; whether audio signalling should be provided by asterisk
; ; (earlyrtp=1) or device generated (earlyrtp=0). default=yes
;transfer=1 ; whether the device is allowed to transfer. default=yes
-;------------------------------ SPECIFIC DEVICE OPTIONS ----------------------------
+; ----------------------------- SPECIFIC DEVICE OPTIONS ----------------------------
;device="SEPxxxxxxxxxxxx ; id of the device. Must be set.
;version=P002G204 ; firmware version to be loaded. If this version is different
; ; to the one on the device, the device will try to load this
; ; version from the tftp server. Set to device firmware version.
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
; Typical config for 12SP+
;[florian]
diff --git a/configs/samples/unistim.conf.sample b/configs/samples/unistim.conf.sample
index c33426b0c..a09642796 100644
--- a/configs/samples/unistim.conf.sample
+++ b/configs/samples/unistim.conf.sample
@@ -17,7 +17,7 @@ port=5000 ; UDP port
;autoprovisioning=no ; Allow undeclared phones to register an extension. See README for important
; informations. no (default), yes, tn.
;mohsuggest=default
-;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of a
; SIP channel. Defaults to "no". An enabled jitterbuffer will
; be used only if the sending side can create and the receiving
@@ -41,7 +41,7 @@ port=5000 ; UDP port
; variable size, actually the new jb of IAX2). Defaults to fixed.
; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
-;-----------------------------------------------------------------------------------
+; ----------------------------------------------------------------------------------
;[black] ; name of the device
diff --git a/configs/samples/vpb.conf.sample b/configs/samples/vpb.conf.sample
index fecb3ec59..bdc89dff5 100644
--- a/configs/samples/vpb.conf.sample
+++ b/configs/samples/vpb.conf.sample
@@ -199,7 +199,7 @@ grunttimeout=3600
;
mode=immediate
-;-------------------------------------------------------------------------
+; ------------------------------------------------------------------------
; Channel definitions
;
; Each channel inherits the settings specified above, unless the are
diff --git a/configure b/configure
index 886ef6f9f..51f062328 100755
--- a/configure
+++ b/configure
@@ -822,6 +822,7 @@ PBX_SPANDSP
SPANDSP_DIR
SPANDSP_INCLUDE
SPANDSP_LIB
+EXTERNALS_CACHE_DIR
SOUNDS_CACHE_DIR
PBX_SDL_IMAGE
SDL_IMAGE_DIR
@@ -1206,6 +1207,8 @@ PTHREAD_CC
ax_pthread_config
MD5
SOXMIX
+PBX_BASH
+PBX_XMLSTARLET
PBX_FLEX
PBX_BISON
OPENSSL
@@ -1215,6 +1218,7 @@ DOWNLOAD
FETCH
ALEMBIC
GIT
+BASH
XMLSTARLET
XMLLINT
KPATHSEA
@@ -1402,6 +1406,7 @@ with_resample
with_sdl
with_SDL_image
with_sounds_cache
+with_externals_cache
with_spandsp
with_ss7
with_speex
@@ -2148,6 +2153,8 @@ Optional Packages:
--with-SDL_image=PATH use Sdl Image files in PATH
--with-sounds-cache=PATH
use cached sound tarfiles in PATH
+ --with-externals-cache=PATH
+ use cached external module tarfiles in PATH
--with-spandsp=PATH use SPANDSP files in PATH
--with-ss7=PATH use ISDN SS7 files in PATH
--with-speex=PATH use Speex files in PATH
@@ -7493,6 +7500,47 @@ $as_echo "no" >&6; }
fi
+# Extract the first word of "bash", so it can be a program name with args.
+set dummy bash; 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_path_BASH+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $BASH in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_BASH="$BASH" # 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_path_BASH="$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
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_BASH" && ac_cv_path_BASH=":"
+ ;;
+esac
+fi
+BASH=$ac_cv_path_BASH
+if test -n "$BASH"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BASH" >&5
+$as_echo "$BASH" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
# Extract the first word of "git", so it can be a program name with args.
set dummy git; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -7800,6 +7848,20 @@ else
fi
+if test "x${XMLSTARLET}" = "x:" ; then
+ PBX_XMLSTARLET=0
+else
+ PBX_XMLSTARLET=1
+fi
+
+
+if test "x${BASH}" = "x:" ; then
+ PBX_BASH=0
+else
+ PBX_BASH=1
+fi
+
+
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}soxmix", so it can be a program name with args.
set dummy ${ac_tool_prefix}soxmix; ac_word=$2
@@ -11542,6 +11604,30 @@ fi
+
+# Check whether --with-externals-cache was given.
+if test "${with_externals_cache+set}" = set; then :
+ withval=$with_externals_cache;
+ case ${withval} in
+ n|no)
+ unset EXTERNALS_CACHE_DIR
+ ;;
+ *)
+ if test "x${withval}" = "x"; then
+ :
+ else
+ EXTERNALS_CACHE_DIR="${withval}"
+ fi
+ ;;
+ esac
+
+else
+ :
+fi
+
+
+
+
SPANDSP_DESCRIP="SPANDSP"
SPANDSP_OPTION="spandsp"
PBX_SPANDSP=0
diff --git a/configure.ac b/configure.ac
index 7fd702fee..e7fc21c66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -281,6 +281,7 @@ AC_PATH_PROG([CATDVI], [catdvi], :)
AC_PATH_PROG([KPATHSEA], [kpsewhich], :)
AC_PATH_PROG([XMLLINT], [xmllint], :)
AC_PATH_PROG([XMLSTARLET], [xmlstarlet], :)
+AC_PATH_PROG([BASH], [bash], :)
AC_PATH_PROG([GIT], [git], :)
AC_PATH_PROG([ALEMBIC], [alembic], :)
if test "${WGET}" != ":" ; then
@@ -340,6 +341,20 @@ else
fi
AC_SUBST(PBX_FLEX)
+if test "x${XMLSTARLET}" = "x:" ; then
+ PBX_XMLSTARLET=0
+else
+ PBX_XMLSTARLET=1
+fi
+AC_SUBST(PBX_XMLSTARLET)
+
+if test "x${BASH}" = "x:" ; then
+ PBX_BASH=0
+else
+ PBX_BASH=1
+fi
+AC_SUBST(PBX_BASH)
+
AC_CHECK_TOOL([SOXMIX], [soxmix], [:])
if test "${SOXMIX}" != ":" ; then
AC_DEFINE([HAVE_SOXMIX], 1, [Define to 1 if your system has soxmix application.])
@@ -522,6 +537,7 @@ AST_EXT_LIB_SETUP([RESAMPLE], [LIBRESAMPLE], [resample])
AST_EXT_LIB_SETUP([SDL], [Sdl], [sdl])
AST_EXT_LIB_SETUP([SDL_IMAGE], [Sdl Image], [SDL_image])
AST_OPTION_ONLY([sounds-cache], [SOUNDS_CACHE_DIR], [cached sound tarfiles], [])
+AST_OPTION_ONLY([externals-cache], [EXTERNALS_CACHE_DIR], [cached external module tarfiles], [])
AST_EXT_LIB_SETUP([SPANDSP], [SPANDSP], [spandsp])
AST_EXT_LIB_SETUP([SS7], [ISDN SS7], [ss7])
AST_EXT_LIB_SETUP([SPEEX], [Speex], [speex])
diff --git a/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py b/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
index 1a0d6a480..4da31cb59 100755
--- a/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
+++ b/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
@@ -17,7 +17,7 @@ PREFIX = 'pjsip_'
def section_by_type(section, pjsip, type):
"""Finds a section based upon the given type, adding it if not found."""
def __find_dict(mdicts, key, val):
- """Given a list of mult-dicts, return the multi-dict that contains
+ """Given a list of multi-dicts, return the multi-dict that contains
the given key/value pair."""
def found(d):
@@ -395,6 +395,7 @@ peer_map = [
['session-minse', set_value('timers_min_se')],
['session-expires', set_value('timers_sess_expires')],
# identify_by ?
+ ['canreinvite', set_direct_media], # direct_media alias
['directmedia', set_direct_media], # direct_media
# direct_media_method
# directed_media_glare_mitigation
@@ -1020,7 +1021,7 @@ class Registration:
if self.outbound_proxy:
set_value('outboundproxy', self.outbound_proxy, section, pjsip,
- nmapped, 'registartion')
+ nmapped, 'registration')
def map_registrations(sip, pjsip, nmapped):
@@ -1181,7 +1182,7 @@ def cli_options():
"""
global PREFIX
usage = "usage: %prog [options] [input-file [output-file]]\n\n" \
- "Converts the chan_sip configuration input-file to the chan_pjsip output-file.\n"\
+ "Converts the chan_sip configuration input-file to the chan_pjsip output-file.\n" \
"The input-file defaults to 'sip.conf'.\n" \
"The output-file defaults to 'pjsip.conf'."
parser = optparse.OptionParser(usage=usage)
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index 0472c1b37..28ae73e87 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -368,6 +368,13 @@ enum ao2_alloc_opts {
AO2_ALLOC_OPT_LOCK_NOLOCK = (2 << 0),
/*! The ao2 object locking option field mask. */
AO2_ALLOC_OPT_LOCK_MASK = (3 << 0),
+ /*!
+ * \internal The ao2 object uses a separate object for locking.
+ *
+ * \note This option is used internally by ao2_alloc_with_lockobj and
+ * should never be passed directly to ao2_alloc.
+ */
+ AO2_ALLOC_OPT_LOCK_OBJ = AO2_ALLOC_OPT_LOCK_MASK,
};
/*!
@@ -408,6 +415,26 @@ void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned in
/*! @} */
+/*!
+ * \since 14.1.0
+ * \brief Allocate and initialize an object with separate locking.
+ *
+ * \param data_size The sizeof() of the user-defined structure.
+ * \param destructor_fn The destructor function (can be NULL)
+ * \param lockobj A separate ao2 object that will provide locking.
+ * \param debug_msg An ao2 object debug tracing message.
+ * \return A pointer to user-data.
+ *
+ * \see \ref ao2_alloc for additional details.
+ *
+ * \note lockobj must be a valid AO2 object.
+ */
+#define ao2_alloc_with_lockobj(data_size, destructor_fn, lockobj, tag) \
+ __ao2_alloc_with_lockobj((data_size), (destructor_fn), (lockobj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+void *__ao2_alloc_with_lockobj(size_t data_size, ao2_destructor_fn destructor_fn, void *lockobj,
+ const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
+
/*! \brief
* Reference/unreference an object and return the old refcount.
*
diff --git a/include/asterisk/named_locks.h b/include/asterisk/named_locks.h
index 0fe07d992..1959841d0 100644
--- a/include/asterisk/named_locks.h
+++ b/include/asterisk/named_locks.h
@@ -48,7 +48,7 @@
* To use a named lock:
* Call ast_named_lock_get with the appropriate keyspace and key.
* Use the standard ao2 lock/unlock functions as needed.
- * Call ast_named_lock_put when you're finished with it.
+ * Call ao2_cleanup when you're finished with it.
*/
/*!
@@ -66,9 +66,6 @@ struct ast_named_lock;
struct ast_named_lock *__ast_named_lock_get(const char *filename, int lineno, const char *func,
enum ast_named_lock_type lock_type, const char *keyspace, const char *key);
-int __ast_named_lock_put(const char *filename, int lineno, const char *func,
- struct ast_named_lock *lock);
-
/*!
* \brief Geta named lock handle
* \since 13.9.0
@@ -92,11 +89,8 @@ int __ast_named_lock_put(const char *filename, int lineno, const char *func,
* \since 13.9.0
*
* \param lock The pointer to the ast_named_lock structure returned by ast_named_lock_get
- * \retval 0 Success
- * \retval -1 Failure
*/
-#define ast_named_lock_put(lock) \
- __ast_named_lock_put(__FILE__, __LINE__, __PRETTY_FUNCTION__, lock)
+#define ast_named_lock_put(lock) ao2_cleanup(lock)
/*!
* @}
diff --git a/include/asterisk/sorcery.h b/include/asterisk/sorcery.h
index 23219ec41..896633816 100644
--- a/include/asterisk/sorcery.h
+++ b/include/asterisk/sorcery.h
@@ -988,10 +988,30 @@ int ast_sorcery_changeset_create(const struct ast_variable *original, const stru
*
* \retval non-NULL success
* \retval NULL failure
+ *
+ * \note The returned object does not support AO2 locking.
*/
void *ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor);
/*!
+ * \since 14.1.0
+ * \brief Allocate a generic sorcery capable object with locking.
+ *
+ * \details Sorcery objects may be replaced with new allocations during reloads.
+ * If locking is required on sorcery objects it must be shared between the old
+ * object and the new one. lockobj can be any AO2 object with locking enabled,
+ * but in most cases named locks should be used to provide stable locking.
+ *
+ * \param size Size of the object
+ * \param destructor Optional destructor function
+ * \param lockobj An AO2 object that will provide locking.
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+void *ast_sorcery_lockable_alloc(size_t size, ao2_destructor_fn destructor, void *lockobj);
+
+/*!
* \brief Allocate an object
*
* \param sorcery Pointer to a sorcery structure
diff --git a/main/astobj2.c b/main/astobj2.c
index 5c92f263f..604e6a1ae 100644
--- a/main/astobj2.c
+++ b/main/astobj2.c
@@ -108,6 +108,17 @@ struct astobj2_rwlock {
void *user_data[0];
};
+struct ao2_lockobj_priv {
+ void *lock;
+};
+
+/* AstObj2 with locking provided by a separate object. */
+struct astobj2_lockobj {
+ struct ao2_lockobj_priv lockobj;
+ struct __priv_data priv_data;
+ void *user_data[0];
+};
+
#ifdef AO2_DEBUG
struct ao2_stats ao2;
#endif
@@ -118,6 +129,9 @@ struct ao2_stats ao2;
#define INTERNAL_OBJ_RWLOCK(user_data) \
((struct astobj2_rwlock *) (((char *) (user_data)) - sizeof(struct astobj2_rwlock)))
+#define INTERNAL_OBJ_LOCKOBJ(user_data) \
+ ((struct astobj2_lockobj *) (((char *) (user_data)) - sizeof(struct astobj2_lockobj)))
+
#define INTERNAL_OBJ(user_data) \
(struct astobj2 *) ((char *) user_data - sizeof(struct astobj2))
@@ -187,6 +201,7 @@ int __ao2_lock(void *user_data, enum ao2_lock_req lock_how, const char *file, co
struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func);
struct astobj2_lock *obj_mutex;
struct astobj2_rwlock *obj_rwlock;
+ struct astobj2_lockobj *obj_lockobj;
int res = 0;
if (obj == NULL) {
@@ -231,6 +246,10 @@ int __ao2_lock(void *user_data, enum ao2_lock_req lock_how, const char *file, co
case AO2_ALLOC_OPT_LOCK_NOLOCK:
/* The ao2 object has no lock. */
break;
+ case AO2_ALLOC_OPT_LOCK_OBJ:
+ obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data);
+ res = __ao2_lock(obj_lockobj->lockobj.lock, lock_how, file, func, line, var);
+ break;
default:
ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
user_data);
@@ -245,6 +264,7 @@ int __ao2_unlock(void *user_data, const char *file, const char *func, int line,
struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func);
struct astobj2_lock *obj_mutex;
struct astobj2_rwlock *obj_rwlock;
+ struct astobj2_lockobj *obj_lockobj;
int res = 0;
int current_value;
@@ -281,6 +301,10 @@ int __ao2_unlock(void *user_data, const char *file, const char *func, int line,
case AO2_ALLOC_OPT_LOCK_NOLOCK:
/* The ao2 object has no lock. */
break;
+ case AO2_ALLOC_OPT_LOCK_OBJ:
+ obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data);
+ res = __ao2_unlock(obj_lockobj->lockobj.lock, file, func, line, var);
+ break;
default:
ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
user_data);
@@ -295,6 +319,7 @@ int __ao2_trylock(void *user_data, enum ao2_lock_req lock_how, const char *file,
struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func);
struct astobj2_lock *obj_mutex;
struct astobj2_rwlock *obj_rwlock;
+ struct astobj2_lockobj *obj_lockobj;
int res = 0;
if (obj == NULL) {
@@ -339,6 +364,10 @@ int __ao2_trylock(void *user_data, enum ao2_lock_req lock_how, const char *file,
case AO2_ALLOC_OPT_LOCK_NOLOCK:
/* The ao2 object has no lock. */
return 0;
+ case AO2_ALLOC_OPT_LOCK_OBJ:
+ obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data);
+ res = __ao2_trylock(obj_lockobj->lockobj.lock, lock_how, file, func, line, var);
+ break;
default:
ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
user_data);
@@ -370,6 +399,7 @@ enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int
{
struct astobj2 *obj = INTERNAL_OBJ(user_data);
struct astobj2_rwlock *obj_rwlock;
+ struct astobj2_lockobj *obj_lockobj;
enum ao2_lock_req orig_lock;
switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) {
@@ -400,6 +430,10 @@ enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int
break;
}
break;
+ case AO2_ALLOC_OPT_LOCK_OBJ:
+ obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data);
+ orig_lock = __adjust_lock(obj_lockobj->lockobj.lock, lock_how, keep_stronger);
+ break;
default:
ast_log(LOG_ERROR, "Invalid lock option on ao2 object %p\n", user_data);
/* Fall through */
@@ -441,6 +475,7 @@ int __ao2_ref(void *user_data, int delta,
struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func);
struct astobj2_lock *obj_mutex;
struct astobj2_rwlock *obj_rwlock;
+ struct astobj2_lockobj *obj_lockobj;
int current_value;
int ret;
void *weakproxy = NULL;
@@ -552,6 +587,12 @@ int __ao2_ref(void *user_data, int delta,
case AO2_ALLOC_OPT_LOCK_NOLOCK:
ast_free(obj);
break;
+ case AO2_ALLOC_OPT_LOCK_OBJ:
+ obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data);
+ ao2_t_ref(obj_lockobj->lockobj.lock, -1, "release lockobj");
+
+ ast_free(obj_lockobj);
+ break;
default:
ast_log(__LOG_ERROR, file, line, func,
"Invalid lock option on ao2 object %p\n", user_data);
@@ -581,13 +622,14 @@ void __ao2_cleanup(void *obj)
}
}
-void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options,
- const char *tag, const char *file, int line, const char *func)
+static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options,
+ void *lockobj, const char *tag, const char *file, int line, const char *func)
{
/* allocation */
struct astobj2 *obj;
struct astobj2_lock *obj_mutex;
struct astobj2_rwlock *obj_rwlock;
+ struct astobj2_lockobj *obj_lockobj;
switch (options & AO2_ALLOC_OPT_LOCK_MASK) {
case AO2_ALLOC_OPT_LOCK_MUTEX:
@@ -614,6 +656,22 @@ void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned in
return NULL;
}
break;
+ case AO2_ALLOC_OPT_LOCK_OBJ:
+ lockobj = ao2_t_bump(lockobj, "set lockobj");
+ if (!lockobj) {
+ ast_log(__LOG_ERROR, file, line, func, "AO2_ALLOC_OPT_LOCK_OBJ requires a non-NULL lockobj.\n");
+ return NULL;
+ }
+
+ obj_lockobj = __ast_calloc(1, sizeof(*obj_lockobj) + data_size, file, line, func);
+ if (obj_lockobj == NULL) {
+ ao2_t_ref(lockobj, -1, "release lockobj for failed alloc");
+ return NULL;
+ }
+
+ obj_lockobj->lockobj.lock = lockobj;
+ obj = (struct astobj2 *) &obj_lockobj->priv_data;
+ break;
default:
/* Invalid option value. */
ast_log(__LOG_DEBUG, file, line, func, "Invalid lock option requested\n");
@@ -643,6 +701,19 @@ void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned in
return EXTERNAL_OBJ(obj);
}
+void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options,
+ const char *tag, const char *file, int line, const char *func)
+{
+ return internal_ao2_alloc(data_size, destructor_fn, options, NULL, tag, file, line, func);
+}
+
+void *__ao2_alloc_with_lockobj(size_t data_size, ao2_destructor_fn destructor_fn, void *lockobj,
+ const char *tag, const char *file, int line, const char *func)
+{
+ return internal_ao2_alloc(data_size, destructor_fn, AO2_ALLOC_OPT_LOCK_OBJ, lockobj,
+ tag, file, line, func);
+}
+
unsigned int ao2_options_get(void *obj)
{
struct astobj2 *orig_obj;
diff --git a/main/format_cap.c b/main/format_cap.c
index 2b3e6cd5f..013b7bea1 100644
--- a/main/format_cap.c
+++ b/main/format_cap.c
@@ -703,7 +703,7 @@ const char *ast_format_cap_get_names(struct ast_format_cap *cap, struct ast_str
ast_str_set(buf, 0, "(");
- if (!AST_VECTOR_SIZE(&cap->preference_order)) {
+ if (!cap || !AST_VECTOR_SIZE(&cap->preference_order)) {
ast_str_append(buf, 0, "nothing)");
return ast_str_buffer(*buf);
}
diff --git a/main/named_locks.c b/main/named_locks.c
index 596048388..c71f3b579 100644
--- a/main/named_locks.c
+++ b/main/named_locks.c
@@ -35,13 +35,17 @@ ASTERISK_REGISTER_FILE()
struct ao2_container *named_locks;
#define NAMED_LOCKS_BUCKETS 101
-struct ast_named_lock {
+struct named_lock_proxy {
+ AO2_WEAKPROXY();
char key[0];
};
+struct ast_named_lock {
+};
+
static int named_locks_hash(const void *obj, const int flags)
{
- const struct ast_named_lock *lock = obj;
+ const struct named_lock_proxy *lock = obj;
switch (flags & OBJ_SEARCH_MASK) {
case OBJ_SEARCH_KEY:
@@ -57,8 +61,8 @@ static int named_locks_hash(const void *obj, const int flags)
static int named_locks_cmp(void *obj_left, void *obj_right, int flags)
{
- const struct ast_named_lock *object_left = obj_left;
- const struct ast_named_lock *object_right = obj_right;
+ const struct named_lock_proxy *object_left = obj_left;
+ const struct named_lock_proxy *object_right = obj_right;
const char *right_key = obj_right;
int cmp;
@@ -98,45 +102,72 @@ int ast_named_locks_init(void)
return 0;
}
+static void named_lock_proxy_cb(void *weakproxy, void *data)
+{
+ ao2_unlink(named_locks, weakproxy);
+}
+
struct ast_named_lock *__ast_named_lock_get(const char *filename, int lineno, const char *func,
enum ast_named_lock_type lock_type, const char *keyspace, const char *key)
{
+ struct named_lock_proxy *proxy = NULL;
struct ast_named_lock *lock = NULL;
- int concat_key_buff_len = strlen(keyspace) + strlen(key) + 2;
- char *concat_key = ast_alloca(concat_key_buff_len);
+ int keylen = strlen(keyspace) + strlen(key) + 2;
+ char *concat_key = ast_alloca(keylen);
sprintf(concat_key, "%s-%s", keyspace, key); /* Safe */
ao2_lock(named_locks);
- lock = ao2_find(named_locks, concat_key, OBJ_SEARCH_KEY | OBJ_NOLOCK);
- if (lock) {
+ proxy = ao2_find(named_locks, concat_key, OBJ_SEARCH_KEY | OBJ_NOLOCK);
+ if (proxy) {
ao2_unlock(named_locks);
- ast_assert((ao2_options_get(lock) & AO2_ALLOC_OPT_LOCK_MASK) == lock_type);
- return lock;
- }
+ lock = __ao2_weakproxy_get_object(proxy, 0, __PRETTY_FUNCTION__, filename, lineno, func);
+
+ if (lock) {
+ /* We have an existing lock and it's not being destroyed. */
+ ao2_ref(proxy, -1);
+ ast_assert((ao2_options_get(lock) & AO2_ALLOC_OPT_LOCK_MASK) == lock_type);
+
+ return lock;
+ }
- lock = ao2_alloc_options(sizeof(*lock) + concat_key_buff_len, NULL, lock_type);
- if (lock) {
- strcpy(lock->key, concat_key); /* Safe */
- ao2_link_flags(named_locks, lock, OBJ_NOLOCK);
+ /* the old proxy is being destroyed, clean list before creating/adding new one */
+ ao2_lock(named_locks);
+ ao2_unlink_flags(named_locks, proxy, OBJ_NOLOCK);
+ ao2_ref(proxy, -1);
}
- ao2_unlock(named_locks);
- return lock;
-}
+ proxy = ao2_t_weakproxy_alloc(sizeof(*proxy) + keylen, NULL, concat_key);
+ if (!proxy) {
+ goto failure_cleanup;
+ }
-int __ast_named_lock_put(const char *filename, int lineno, const char *func,
- struct ast_named_lock *lock)
-{
+ lock = __ao2_alloc(sizeof(*lock) + keylen, NULL, lock_type, concat_key, filename, lineno, func);
if (!lock) {
- return -1;
+ goto failure_cleanup;
}
- ao2_lock(named_locks);
- if (ao2_ref(lock, -1) == 2) {
- ao2_unlink_flags(named_locks, lock, OBJ_NOLOCK);
+ /* We have exclusive access to proxy and lock, no need for locking here. */
+ if (ao2_weakproxy_set_object(proxy, lock, OBJ_NOLOCK)) {
+ goto failure_cleanup;
}
+
+ if (ao2_weakproxy_subscribe(proxy, named_lock_proxy_cb, NULL, OBJ_NOLOCK)) {
+ goto failure_cleanup;
+ }
+
+ strcpy(proxy->key, concat_key); /* Safe */
+ ao2_link_flags(named_locks, proxy, OBJ_NOLOCK);
ao2_unlock(named_locks);
+ ao2_t_ref(proxy, -1, "Release allocation reference");
- return 0;
+ return lock;
+
+failure_cleanup:
+ ao2_unlock(named_locks);
+
+ ao2_cleanup(proxy);
+ ao2_cleanup(lock);
+
+ return NULL;
}
diff --git a/main/sorcery.c b/main/sorcery.c
index 55ee830b7..9f8c35c3b 100644
--- a/main/sorcery.c
+++ b/main/sorcery.c
@@ -1736,9 +1736,26 @@ static void sorcery_object_destructor(void *object)
ast_free(details->object->id);
}
+void *ast_sorcery_lockable_alloc(size_t size, ao2_destructor_fn destructor, void *lockobj)
+{
+ void *object = ao2_alloc_with_lockobj(size + sizeof(struct ast_sorcery_object),
+ sorcery_object_destructor, lockobj, "");
+ struct ast_sorcery_object_details *details = object;
+
+ if (!object) {
+ return NULL;
+ }
+
+ details->object = object + size;
+ details->object->destructor = destructor;
+
+ return object;
+}
+
void *ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
{
- void *object = ao2_alloc_options(size + sizeof(struct ast_sorcery_object), sorcery_object_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK);
+ void *object = ao2_alloc_options(size + sizeof(struct ast_sorcery_object),
+ sorcery_object_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK);
struct ast_sorcery_object_details *details = object;
if (!object) {
diff --git a/makeopts.in b/makeopts.in
index f0b0d0ef5..86b7f9d99 100644
--- a/makeopts.in
+++ b/makeopts.in
@@ -28,11 +28,13 @@ WGET=@WGET@
FETCH=@FETCH@
DOWNLOAD=@DOWNLOAD@
SOUNDS_CACHE_DIR=@SOUNDS_CACHE_DIR@
+EXTERNALS_CACHE_DIR=@EXTERNALS_CACHE_DIR@
RUBBER=@RUBBER@
CATDVI=@CATDVI@
KPATHSEA=@KPATHSEA@
XMLLINT=@XMLLINT@
XMLSTARLET=@XMLSTARLET@
+BASH=@BASH@
MD5=@MD5@
SHA1SUM=@SHA1SUM@
OPENSSL=@OPENSSL@
diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c
index 35b757267..8d3292129 100644
--- a/res/ari/resource_channels.c
+++ b/res/ari/resource_channels.c
@@ -886,6 +886,8 @@ void ast_ari_channels_hangup(struct ast_variable *headers,
cause = AST_CAUSE_CONGESTION;
} else if (!strcmp(args->reason, "no_answer")) {
cause = AST_CAUSE_NOANSWER;
+ } else if(!strcmp(args->reason, "answered_elsewhere")) {
+ cause = AST_CAUSE_ANSWERED_ELSEWHERE;
} else {
ast_ari_response_error(
response, 400, "Invalid Reason",
diff --git a/res/res.xml b/res/res.xml
new file mode 100644
index 000000000..e9cb5f962
--- /dev/null
+++ b/res/res.xml
@@ -0,0 +1,6 @@
+<member name="res_digium_phone" displayname="Download the Digium Phone Module for Asterisk. See http://downloads.digium.com/pub/telephony/res_digium_phone/README.">
+ <support_level>external</support_level>
+ <depend>xmlstarlet</depend>
+ <depend>bash</depend>
+ <defaultenabled>no</defaultenabled>
+</member>
diff --git a/res/res_pjsip/config_global.c b/res/res_pjsip/config_global.c
index 1d0c11c35..281630ae4 100644
--- a/res/res_pjsip/config_global.c
+++ b/res/res_pjsip/config_global.c
@@ -76,21 +76,21 @@ struct global_config {
/*! Realm to use in challenges before an endpoint is identified */
AST_STRING_FIELD(default_realm);
);
- /* Value to put in Max-Forwards header */
+ /*! Value to put in Max-Forwards header */
unsigned int max_forwards;
- /* The interval at which to send keep alive messages to active connection-oriented transports */
+ /*! The interval at which to send keep alive messages to active connection-oriented transports */
unsigned int keep_alive_interval;
- /* The maximum time for all contacts to be qualified at startup */
+ /*! The maximum time for all contacts to be qualified at startup */
unsigned int max_initial_qualify_time;
- /* The interval at which to check for expired contacts */
+ /*! The interval at which to check for expired contacts */
unsigned int contact_expiration_check_interval;
/*! Nonzero to disable multi domain support */
unsigned int disable_multi_domain;
- /* The maximum number of unidentified requests per source IP address before a security event is logged */
+ /*! The maximum number of unidentified requests per source IP address before a security event is logged */
unsigned int unidentified_request_count;
- /* The period during which unidentified requests are accumulated */
+ /*! The period during which unidentified requests are accumulated */
unsigned int unidentified_request_period;
- /* Interval at which expired unidentifed requests will be pruned */
+ /*! Interval at which expired unidentifed requests will be pruned */
unsigned int unidentified_request_prune_interval;
struct {
/*! Taskprocessor high water alert trigger level */
@@ -510,7 +510,8 @@ int ast_sip_initialize_sorcery_global(void)
ast_sorcery_object_field_register(sorcery, "global", "contact_expiration_check_interval",
__stringify(DEFAULT_CONTACT_EXPIRATION_CHECK_INTERVAL),
OPT_UINT_T, 0, FLDSET(struct global_config, contact_expiration_check_interval));
- ast_sorcery_object_field_register(sorcery, "global", "disable_multi_domain", "no",
+ ast_sorcery_object_field_register(sorcery, "global", "disable_multi_domain",
+ DEFAULT_DISABLE_MULTI_DOMAIN ? "yes" : "no",
OPT_BOOL_T, 1, FLDSET(struct global_config, disable_multi_domain));
ast_sorcery_object_field_register(sorcery, "global", "unidentified_request_count",
__stringify(DEFAULT_UNIDENTIFIED_REQUEST_COUNT),
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c
index 0ab69ec5b..5abfcabad 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -49,11 +49,22 @@ static void aor_destroy(void *obj)
/*! \brief Allocator for AOR */
static void *aor_alloc(const char *name)
{
- struct ast_sip_aor *aor = ast_sorcery_generic_alloc(sizeof(struct ast_sip_aor), aor_destroy);
+ void *lock;
+ struct ast_sip_aor *aor;
+
+ lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", name);
+ if (!lock) {
+ return NULL;
+ }
+
+ aor = ast_sorcery_lockable_alloc(sizeof(struct ast_sip_aor), aor_destroy, lock);
+ ao2_ref(lock, -1);
+
if (!aor) {
return NULL;
}
ast_string_field_init(aor, 128);
+
return aor;
}
@@ -206,17 +217,11 @@ struct ao2_container *ast_sip_location_retrieve_aor_contacts_nolock(const struct
struct ao2_container *ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor)
{
struct ao2_container *contacts;
- struct ast_named_lock *lock;
- lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", ast_sorcery_object_get_id(aor));
- if (!lock) {
- return NULL;
- }
-
- ao2_lock(lock);
+ /* ao2_lock / ao2_unlock do not actually write aor since it has an ao2 lockobj. */
+ ao2_lock((void*)aor);
contacts = ast_sip_location_retrieve_aor_contacts_nolock(aor);
- ao2_unlock(lock);
- ast_named_lock_put(lock);
+ ao2_unlock((void*)aor);
return contacts;
}
@@ -369,19 +374,12 @@ int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri,
struct ast_sip_endpoint *endpoint)
{
int res;
- struct ast_named_lock *lock;
-
- lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", ast_sorcery_object_get_id(aor));
- if (!lock) {
- return -1;
- }
- ao2_lock(lock);
+ ao2_lock(aor);
res = ast_sip_location_add_contact_nolock(aor, uri, expiration_time, path_info, user_agent,
via_addr, via_port, call_id,
endpoint);
- ao2_unlock(lock);
- ast_named_lock_put(lock);
+ ao2_unlock(aor);
return res;
}
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 333be7143..d8ae9e0a3 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -603,6 +603,10 @@ static int ident_handler(const struct aco_option *opt, struct ast_variable *var,
endpoint->ident_method = 0;
return -1;
}
+ if (endpoint->ident_method & method) {
+ /* We are already indentifying by this method. No need to do it again. */
+ continue;
+ }
endpoint->ident_method |= method;
AST_VECTOR_APPEND(&endpoint->ident_method_order, method);
diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c
index f99a3b84d..fd87ef7bb 100644
--- a/res/res_pjsip_registrar.c
+++ b/res/res_pjsip_registrar.c
@@ -523,25 +523,17 @@ static int register_aor(pjsip_rx_data *rdata,
{
int res;
struct ao2_container *contacts = NULL;
- struct ast_named_lock *lock;
- lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", aor_name);
- if (!lock) {
- return PJ_TRUE;
- }
-
- ao2_lock(lock);
+ ao2_lock(aor);
contacts = ast_sip_location_retrieve_aor_contacts_nolock(aor);
if (!contacts) {
- ao2_unlock(lock);
- ast_named_lock_put(lock);
+ ao2_unlock(aor);
return PJ_TRUE;
}
res = register_aor_core(rdata, endpoint, aor, aor_name, contacts);
ao2_cleanup(contacts);
- ao2_unlock(lock);
- ast_named_lock_put(lock);
+ ao2_unlock(aor);
return res;
}
@@ -563,6 +555,7 @@ static int match_aor(const char *aor_name, const char *id)
static char *find_aor_name(const char *username, const char *domain, const char *aors)
{
char *configured_aors;
+ char *aors_buf;
char *aor_name;
char *id_domain;
struct ast_sip_domain_alias *alias;
@@ -570,8 +563,10 @@ static char *find_aor_name(const char *username, const char *domain, const char
id_domain = ast_alloca(strlen(username) + strlen(domain) + 2);
sprintf(id_domain, "%s@%s", username, domain);
+ aors_buf = ast_strdupa(aors);
+
/* Look for exact match on username@domain */
- configured_aors = ast_strdupa(aors);
+ configured_aors = aors_buf;
while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
if (match_aor(aor_name, id_domain)) {
return ast_strdup(aor_name);
@@ -586,7 +581,7 @@ static char *find_aor_name(const char *username, const char *domain, const char
sprintf(id_domain, "%s@%s", username, alias->domain);
ao2_cleanup(alias);
- configured_aors = ast_strdupa(aors);
+ configured_aors = strcpy(aors_buf, aors);/* Safe */
while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
if (match_aor(aor_name, id_domain_alias)) {
return ast_strdup(aor_name);
@@ -594,8 +589,13 @@ static char *find_aor_name(const char *username, const char *domain, const char
}
}
+ if (ast_strlen_zero(username)) {
+ /* No username, no match */
+ return NULL;
+ }
+
/* Look for exact match on username only */
- configured_aors = ast_strdupa(aors);
+ configured_aors = strcpy(aors_buf, aors);/* Safe */
while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
if (match_aor(aor_name, username)) {
return ast_strdup(aor_name);
diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json
index 75feeb105..ee18bfe11 100644
--- a/rest-api/api-docs/channels.json
+++ b/rest-api/api-docs/channels.json
@@ -400,7 +400,8 @@
"normal",
"busy",
"congestion",
- "no_answer"
+ "no_answer",
+ "answered_elsewhere"
]
}
}