diff options
42 files changed, 740 insertions, 157 deletions
@@ -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. @@ -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 @@ -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" ] } } |