--- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-sounds-main.install +++ asterisk-1.4.21.2~dfsg/debian/asterisk-sounds-main.install @@ -0,0 +1,2 @@ +usr/share/asterisk/sounds +usr/share/asterisk/moh --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.install +++ asterisk-1.4.21.2~dfsg/debian/asterisk.install @@ -0,0 +1,4 @@ +usr/lib/asterisk +usr/sbin +usr/share/asterisk/firmware +usr/share/asterisk/keys --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.logrotate +++ asterisk-1.4.21.2~dfsg/debian/asterisk.logrotate @@ -0,0 +1,9 @@ +/var/log/asterisk/debug /var/log/asterisk/messages /var/log/asterisk/full /var/log/asterisk/*_log { + weekly + missingok + rotate 4 + sharedscripts + postrotate + /usr/sbin/invoke-rc.d asterisk logger-reload > /dev/null 2> /dev/null + endscript +} --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-dev.install +++ asterisk-1.4.21.2~dfsg/debian/asterisk-dev.install @@ -0,0 +1,2 @@ +usr/include/asterisk +../../include/asterisk.h usr/include/asterisk --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-sounds-main.lintian-overrides +++ asterisk-1.4.21.2~dfsg/debian/asterisk-sounds-main.lintian-overrides @@ -0,0 +1 @@ +asterisk-sounds-main: package-contains-empty-directory --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.postrm +++ asterisk-1.4.21.2~dfsg/debian/asterisk.postrm @@ -0,0 +1,9 @@ +#! /bin/sh -e + +if [ "$1" = purge ]; then + userdel -r asterisk 2>/dev/null || true + rm -fR /var/log/asterisk + +fi + +#DEBHELPER# --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-config.postinst +++ asterisk-1.4.21.2~dfsg/debian/asterisk-config.postinst @@ -0,0 +1,51 @@ +#! /bin/sh + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# + +case "$1" in + configure) + set +e # ignore errors temporarily + + # find conffiles under /etc/asterisk belonging to asterisk-config + # and chown them to user asterisk. + dpkg-query -W -f='${Conffiles}\n' asterisk-config 2>/dev/null | \ + sed -nr -e 's; (/etc/asterisk/.*) [0-9a-f]*;\1;p' | \ + while read conffile; do + chown asterisk: ${conffile} 2>/dev/null + done + + # handle them in the end with a glob since it's way faster + dpkg-statoverride --quiet --list '/etc/asterisk/*' | while read STAT; do + chown `echo $STAT | cut -d' ' -f 1,2,4 | sed 's/ /:/'` \ + 2>/dev/null + done + + set -e + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + --- asterisk-1.4.21.2~dfsg.orig/debian/watch +++ asterisk-1.4.21.2~dfsg/debian/watch @@ -0,0 +1,5 @@ +version=3 +opts=dversionmangle=s/\~dfsg//,downloadurlmangle=s/.*ref=// \ + http://downloads.digium.com/pub/telephony/asterisk/releases/ \ + http://www\.digium\.com/elqNow/elqRedir\.htm\?ref=http://downloads\.digium\.com/pub/telephony/asterisk/releases/asterisk-([0-9.]*)\.tar\.gz\ + debian svn-upgrade --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-config.install +++ asterisk-1.4.21.2~dfsg/debian/asterisk-config.install @@ -0,0 +1,2 @@ +etc/asterisk +../ast_config/* etc/asterisk/ --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.docs +++ asterisk-1.4.21.2~dfsg/debian/asterisk.docs @@ -0,0 +1,5 @@ +BUGS +README +CREDITS +UPGRADE.txt +CHANGES --- asterisk-1.4.21.2~dfsg.orig/debian/backports/etch.xorcom +++ asterisk-1.4.21.2~dfsg/debian/backports/etch.xorcom @@ -0,0 +1,11 @@ +#!/bin/sh +# +# Hook for extra backport changes of the xorcom buildd. +# + +# from --configure: +sed -i -e '/--with-imap/d' debian/rules +# disable patch that enables building of app_voicemail_{imap,odbc}.so +sed -i -e '/hack-multiple-app-voicemail/d' debian/patches/series + +exit 0 --- asterisk-1.4.21.2~dfsg.orig/debian/backports/etch +++ asterisk-1.4.21.2~dfsg/debian/backports/etch @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Hook for automatic backports at Buildserver.NET +# +# Target dist: Debian Etch + +# Replace libcurl4-openssl-dev with libcurl3-dev +sed -i -e 's#^\(Build-Depends:.*\)libcurl4[^\ ]*-dev[^\ ]* \(.*\)$#\1libcurl3-dev \2#' debian/control + +# Replace libsnmp-dev with libsnmp9-dev +sed -i -e 's#^\(Build-Depends:.*\)libsnmp-dev[^\ ]* \(.*\)$#\1libsnmp9-dev, \2#' debian/control + +# remove vpb-driver dependency +sed -i -e 's#^\(Build-Depends:.*\), libvpb-dev#\1#' debian/control + +# Until we can have a stable backport of the new speex, let's just use +# our existing "broken" speex 1.1.12: +sed -i -e 's#^\(Build-Depends:.*\), libspeexdsp-dev#\1#' debian/control + +# dh_lintian is new +sed -i -e '/dh_lintian/d' debian/rules +sed -i -e 's#^\(Build-Depends:.*\)debhelper (>= [0-9\.]*), \(.*\)$#\1debhelper \(>= 5\), \2#' debian/control + +# Replace libcap2-dev to libcap-dev +sed -i -e 's#^\(Build-Depends:.*\)libcap2-dev\(.*\)$#\1libcap-dev\2#' debian/control + +# Remove explicit imap support: +sed -i -e 's#^\(Build-Depends:.*\)libc-client2007b-dev, \(.*\)$#\1 \2#' debian/control + +exit 0 --- asterisk-1.4.21.2~dfsg.orig/debian/backports/feisty +++ asterisk-1.4.21.2~dfsg/debian/backports/feisty @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Hook for automatic backports at Buildserver.NET +# +# Target dist: Ubuntu Feisty + +# Replace libcurl4-openssl-dev with libcurl3-dev +sed -i -e 's#^\(Build-Depends:.*\)libcurl4[^\ ]*-dev[^\ ]* \(.*\)$#\1libcurl3-dev \2#' debian/control + +# Replace libsnmp-dev with libsnmp9-dev +sed -i -e 's#^\(Build-Depends:.*\)libsnmp-dev[^\ ]* \(.*\)$#\1libsnmp9-dev, \2#' debian/control + +# remove vpb-driver dependency +sed -i -e 's#^\(Build-Depends:.*\), libvpb-dev#\1#' debian/control + +exit 0 --- asterisk-1.4.21.2~dfsg.orig/debian/backports/edgy +++ asterisk-1.4.21.2~dfsg/debian/backports/edgy @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Hook for automatic backports at Buildserver.NET +# +# Target dist: Ubuntu Edgy + +# Replace libcurl4-openssl-dev with libcurl3-dev +sed -i -e 's#^\(Build-Depends:.*\)libcurl4[^\ ]*-dev[^\ ]* \(.*\)$#\1libcurl3-dev \2#' debian/control + +# Replace libsnmp-dev with libsnmp9-dev +sed -i -e 's#^\(Build-Depends:.*\)libsnmp-dev[^\ ]* \(.*\)$#\1libsnmp9-dev, \2#' debian/control + +# remove vpb-driver dependency +sed -i -e 's#^\(Build-Depends:.*\), libvpb-dev#\1#' debian/control + +exit 0 --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.dirs +++ asterisk-1.4.21.2~dfsg/debian/asterisk.dirs @@ -0,0 +1,21 @@ +etc/asterisk + +usr/share/asterisk +var/log/asterisk +var/spool/asterisk +var/lib/asterisk +var/run/asterisk + +usr/share/asterisk/static-http + +var/lib/asterisk/moh +var/lib/asterisk/sounds/custom +var/log/asterisk/cdr-csv +var/log/asterisk/cdr-custom +var/spool/asterisk/dictate +var/spool/asterisk/meetme +var/spool/asterisk/monitor +var/spool/asterisk/system +var/spool/asterisk/tmp +var/spool/asterisk/voicemail +var/spool/asterisk/outgoing --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-h323.install +++ asterisk-1.4.21.2~dfsg/debian/asterisk-h323.install @@ -0,0 +1 @@ +usr/lib/asterisk/modules/chan_h323.so --- asterisk-1.4.21.2~dfsg.orig/debian/ast_config/asterisk.conf +++ asterisk-1.4.21.2~dfsg/debian/ast_config/asterisk.conf @@ -0,0 +1,8 @@ +[global] +astetcdir => /etc/asterisk +astmoddir => /usr/lib/asterisk/modules +astvarlibdir => /var/lib/asterisk +astagidir => /usr/share/asterisk/agi-bin +astspooldir => /var/spool/asterisk +astrundir => /var/run/asterisk +astlogdir => /var/log/asterisk --- asterisk-1.4.21.2~dfsg.orig/debian/ast_config/modules.conf +++ asterisk-1.4.21.2~dfsg/debian/ast_config/modules.conf @@ -0,0 +1,75 @@ +; +; Asterisk configuration file +; +; Module Loader configuration file +; + +[modules] +autoload=yes +; +; Any modules that need to be loaded before the Asterisk core has been +; initialized (just after the logger has been initialized) can be loaded +; using 'preload'. This will frequently be needed if you wish to map all +; module configuration files into Realtime storage, since the Realtime +; driver will need to be loaded before the modules using those configuration +; files are initialized. +; +; An example of loading ODBC support would be: +;preload => res_odbc.so +;preload => res_config_odbc.so +; +; If you want, load the GTK console right away. +; Don't load the KDE console since +; it's not as sophisticated right now. +; +noload => pbx_gtkconsole.so +;load => pbx_gtkconsole.so +noload => pbx_kdeconsole.so +; +; Intercom application is obsoleted by +; chan_oss. Don't load it. +; +noload => app_intercom.so +; +; The 'modem' channel driver and its subdrivers are +; obsolete, don't load them. +; +noload => chan_modem.so +noload => chan_modem_aopen.so +noload => chan_modem_bestdata.so +noload => chan_modem_i4l.so +; +; Comment this out (after installing CAPI middleware and hardware +; drivers) if you have CAPI-able hardware and wish to use it in +; Asterisk. +; +noload => chan_capi.so +; +load => res_musiconhold.so +; +; Load either OSS or ALSA, not both +; By default, load OSS only (automatically) and do not load ALSA +; +noload => chan_alsa.so +;noload => chan_oss.so +; +; Disable CDR logging to SQLite by default since it writes unconditionally to +; cdr.db without a way to rotate it. +; +noload => cdr_sqlite.so +; +; These conflict with app_voicemail.so/app_directory.so and each other +; These are for IMAP and ODBC storage for Voicemail +noload => app_directory_odbc.so +noload => app_voicemail_odbc.so +noload => app_voicemail_imap.so +; +; Enable these if you want to configure Asterisk in a database +; +noload => res_config_odbc.so +noload => res_config_pgsql.so +; +; Module names listed in "global" section will have symbols globally +; exported to modules loaded after them. +; +[global] --- asterisk-1.4.21.2~dfsg.orig/debian/ast_config/manager.conf +++ asterisk-1.4.21.2~dfsg/debian/ast_config/manager.conf @@ -0,0 +1,16 @@ +; +; Asterisk Call Management support +; + +; By default asterisk will listen on localhost only. +[general] +enabled = yes +port = 5038 +bindaddr = 127.0.0.1 + +; No access is allowed by default. +; To set a password, create a file in /etc/asterisk/manager.d +; use creative permission games to allow other serivces to create their own +; files +#include "manager.d/*.conf" + --- asterisk-1.4.21.2~dfsg.orig/debian/compat +++ asterisk-1.4.21.2~dfsg/debian/compat @@ -0,0 +1 @@ +5 --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.init +++ asterisk-1.4.21.2~dfsg/debian/asterisk.init @@ -0,0 +1,242 @@ +#! /bin/sh +# +# asterisk start the asterisk PBX +# (c) Mark Purcell +# (c) Tzafrir Cohen +# (c) Faidon Liambotis + +# This package is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# Based on: +# +# skeleton example file to build /etc/init.d/ scripts. +# This file should be used to construct scripts for /etc/init.d. +# +# Written by Miquel van Smoorenburg . +# Modified for Debian GNU/Linux +# by Ian Murdock . +# +# Version: @(#)skeleton 1.9 26-Feb-2001 miquels@cistron.nl +# + +### BEGIN INIT INFO +# Provides: asterisk +# Required-Start: $local_fs zaptel +# Required-Stop: $local_fs +# Should-Start: +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Asterisk PBX +# Description: Controls the Asterisk PBX +### END INIT INFO + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +NAME=asterisk +USER=$NAME +GROUP=$USER +DAEMON=/usr/sbin/$NAME +DESC="Asterisk PBX" +PIDFILE="/var/run/asterisk/asterisk.pid" +ASTSAFE_PIDFILE="/var/run/asterisk/asterisk_safe.pid" +PIDFILE_DIR=`dirname $PIDFILE` +UMASK=007 # by default +#MAXFILES=1024 # (the system default) + +# by default: use real-time priority +PARAMS="" +CHDIR_PARM="" +AST_REALTIME="yes" +RUNASTERISK="yes" +AST_DUMPCORE="no" +AST_DUMPCORE_DIR="/var/spool/asterisk" # only used if AST_DUMPCORE != no +# core_pattern. See: http://lxr.linux.no/source/Documentation/sysctl/kernel.txt +#CORE_PATTERN= +if [ -r /etc/default/$NAME ]; then . /etc/default/$NAME; fi + +if [ "$RUNASTERISK" != "yes" ];then + echo "Asterisk not yet configured. Edit /etc/default/asterisk first." + exit 0 +fi + +if [ "$AST_REALTIME" != "no" ] +then + PARAMS="$PARAMS -p" +fi + +if [ "$AST_DUMPCORE" != "no" ] +then + PARAMS="$PARAMS -g" + if [ "$CORE_PATTERN" != '' ] + then + echo "$CORE_PATTERN" >/proc/sys/kernel/core_pattern + fi + if [ -d "$AST_DUMPCORE_DIR" ] + then + CHDIR_PARM="--chdir $AST_DUMPCORE_DIR" + fi +fi + +if [ "x$USER" = "x" ] +then + echo "Error: empty USER name" + exit 1 +fi +if [ `id -u "$USER"` = 0 ] +then + echo "Starting as root not supported." + exit 1 +fi +PARAMS="$PARAMS -U $USER" + +if [ "x$AST_DEBUG_PARAMS" = x ] +then + AST_DEBUG_PARAMS=-cvvvvvddddd +fi +if [ "$RUNASTSAFE" = "yes" ];then + # The value of WRAPPER_DAEMON in can be set in /etc/default/asterisk + WRAPPER_DAEMON=${WRAPPER_DAEMON:-/usr/sbin/safe_asterisk} + REALDAEMON="$WRAPPER_DAEMON" +else + REALDAEMON="$DAEMON" +fi + +test -x $DAEMON || exit 0 + +if [ ! -d "$PIDFILE_DIR" ];then + mkdir "$PIDFILE_DIR" + chown $USER:$GROUP "$PIDFILE_DIR" +fi + +set -e + +if [ "$UMASK" != '' ] +then + umask $UMASK +fi + +# allow changing the per-process open files limit: +if [ "$MAXFILES" != '' ] +then + ulimit -n $MAXFILES +fi + +status() { + plist=`ps ax | awk "{ if (\\$5 == \"$DAEMON\") print \\$1 }"` + if [ "$plist" = "" ]; then + echo "$DESC is stopped" + return 1 + else + echo "$DESC is running: $plist" + return 0 + fi +} + +asterisk_rx() { + if ! status >/dev/null; then return 0; fi + + # if $HOME is set, asterisk -rx writes a .asterisk_history there + ( + unset HOME + + $DAEMON -rx "$1" + ) +} + +case "$1" in + debug) + # we add too many special parameters that I don't want to skip + # accidentally. I'm afraid that skipping -U once may cause + # confusing results. I also want to maintain the user's choice + # of -p + echo "Debugging $DESC: " + $DAEMON $PARAMS $AST_DEBUG_PARAMS + exit 0 + ;; + start) + if status > /dev/null; then + echo "$DESC is already running. Use restart." + exit 0 + fi + echo -n "Starting $DESC: " + if [ "$RUNASTSAFE" != "yes" ];then + # TODO: what if we cought the wrapper just as its asterisk + # was killed? status should check for the wrapper if we're in + # "safe mode" + if status > /dev/null; then + echo "$DESC is already running. Use restart." + exit 0 + fi + start-stop-daemon --start --group $GROUP --pidfile "$PIDFILE" \ + $CHDIR_PARM \ + --exec $REALDAEMON -- $PARAMS + else + start-stop-daemon --start --group $GROUP \ + --background --make-pidfile \ + $CHDIR_PARM --pidfile "$ASTSAFE_PIDFILE" \ + --exec $REALDAEMON -- $PARAMS + fi + + + echo "$NAME." + ;; + stop) + echo -n "Stopping $DESC: $NAME" + # Try gracefully. + # this may hang in some cases. Specifically, when the asterisk + # processes is stopped. No bother to worry about cleanup: + # it will either fail or die when asterisk dies. + ( asterisk_rx 'stop now' > /dev/null 2>&1 & ) & + if [ "$RUNASTSAFE" = "yes" ];then + start-stop-daemon --stop --quiet --oknodo \ + --pidfile $ASTSAFE_PIDFILE + rm -f $ASTSAFE_PIDFILE + fi + # just making sure it's really, really dead. + # KILL is necessary just in case there's an asterisk -r in the background + start-stop-daemon --stop --quiet --oknodo --retry=0/2/TERM/2/KILL/5 --exec $DAEMON + echo "." + ;; + reload) + echo "Reloading $DESC configuration files." + asterisk_rx 'module reload' + ;; + logger-reload) + asterisk_rx 'logger reload' + ;; + extensions-reload|dialplan-reload) + echo "Reloading $DESC configuration files." + asterisk_rx 'dialplan reload' + ;; + restart-convenient) + asterisk_rx 'restart when convenient' + ;; + restart|force-reload) + $0 stop + $0 start + ;; + status) + status + exit $? + ;; + zaptel-fix) + echo "Unloading and reloading loading Asterisk and Zaptel:" + $0 stop + /etc/init.d/zaptel unload + # load modules from /etc/modules. This will break if you count on + # discover/hotplug + /etc/init.d/module-init-tools + /etc/init.d/zaptel start + $0 start + ;; + *) + N=/etc/init.d/$NAME + echo "Usage: $N {start|stop|restart|reload|status|debug|logger-reload|extensions-reload|restart-convenient|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.links +++ asterisk-1.4.21.2~dfsg/debian/asterisk.links @@ -0,0 +1,3 @@ +usr/share/man/man8/asterisk.8 usr/share/man/man8/rasterisk.8 +usr/local/share/asterisk/sounds usr/share/asterisk/sounds/custom +var/lib/asterisk/sounds/custom usr/share/asterisk/sounds/recordings --- asterisk-1.4.21.2~dfsg.orig/debian/NEWS +++ asterisk-1.4.21.2~dfsg/debian/NEWS @@ -0,0 +1,36 @@ +asterisk (1:1.4.13~dfsg-1) unstable; urgency=medium + + Since this version, ODBC and IMAP storage for Voicemail are provided. + As this could not be done as a runtime option, app_voicemail_odbc.so and + app_voicemail_imap.so are provided. However, these conflict app_voicemail.so + and each other. + If you use a modified modules.conf and you have autoload enabled, you *must* + add explicit noload entries for two of the three voicemail modules. + + -- Faidon Liambotis Mon, 03 Dec 2007 18:36:55 +0200 + +asterisk (1:1.4.2~dfsg-5) unstable; urgency=low + + There are significant configuration differences between + asterisk 1.2.x & 1.4.x, please refer to the file + /usr/share/doc/asterisk/UPGRADE.txt.gz for details. + + -- Mark Purcell Sat, 14 Apr 2007 16:44:18 +0100 + +asterisk (1:1.2.10.dfsg-1) unstable; urgency=low + + The iLBC codec library code has been removed from the Debian asterisk + package as it does not conform with the DFSG. + + -- Mark Purcell Mon, 17 Jul 2006 21:15:50 +0100 + +asterisk (1:1.0.7.dfsg.1-1) unstable; urgency=low + + The Debian version of the upstream asterisk source has had the fpm Music on Hold + removed as this music has only been licenced for use within asterisk which is + incompatible with the Debian Free Software Guildlines + . Please drop your alternative + Music on Hold into the directory /usr/share/asterisk/mohmp3/ + + -- Mark Purcell Sun, 20 Mar 2005 10:30:44 +0000 + --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.postinst +++ asterisk-1.4.21.2~dfsg/debian/asterisk.postinst @@ -0,0 +1,112 @@ +#! /bin/sh + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# + +case "$1" in + configure) + # add asterisk user + if ! getent passwd asterisk > /dev/null ; then + echo 'Adding system user for Asterisk' 1>&2 + adduser --system --group --quiet \ + --home /var/lib/asterisk \ + --no-create-home --disabled-login \ + --gecos "Asterisk PBX daemon" \ + asterisk + fi + + # add asterisk to required groups + for group in dialout audio; do + if groups asterisk | grep -w -q -v $group; then + adduser asterisk $group + fi + done + + # chown asterisk on all $dirs and their subdirectories + # do not harm the files, they should be empty on new installations + # and we don't want to mess-up anything on old installations + find /var/log/asterisk \ + /var/lib/asterisk \ + /var/run/asterisk \ + -type d | while read dir; do + if ! dpkg-statoverride --list "$dir" > /dev/null ; then + chown asterisk: $dir + fi + done + + # this is not needed for new installations but is not such a bad idea + # removing this will _break_ upgrades from versions < 1:1.4.10.1~dfsg-1 + # + # we are doing the same for subdirectories, since we are not shipping + # any and it's supposed to be user-modifiable + if ! dpkg-statoverride --list "/etc/asterisk" > /dev/null ; then + chown asterisk: /etc/asterisk + fi + + # spool holds some sensitive information (e.g. monitor, voicemail etc.) + find /var/spool/asterisk -type d | while read dir; do + if ! dpkg-statoverride --list "$dir" > /dev/null ; then + chown asterisk: $dir + chmod 750 $dir + fi + done + + # Create /usr/local directory; policy 9.1.2 + if [ ! -e /usr/local/share/asterisk/sounds ]; then + if mkdir -p /usr/local/share/asterisk/sounds 2>/dev/null ; then + chown root:staff /usr/local/share/asterisk/sounds + chmod 2775 /usr/local/share/asterisk/sounds + fi + fi + + ### this is done here in case asterisk-config was installed/upgraded first + + set +e # ignore errors temporarily + + # find the name of the package providing config; either asterisk-config + # or a package providing asterisk-config-custom + ASTERISK_CONFIG=`dpkg-query -W -f='${Package}\t${Provides}\n' | \ + sed -nr 's/(.*)\tasterisk-config-custom|(asterisk-config)(\t.*)?/\1\2/p'` + + # find conffiles under /etc/asterisk belonging to asterisk-config + # and chown them to user asterisk. + dpkg-query -W -f='${Conffiles}\n' $ASTERISK_CONFIG 2>/dev/null | \ + sed -nr -e 's; (/etc/asterisk/.*) [0-9a-f]*;\1;p' | \ + while read conffile; do + chown asterisk: $conffile 2>/dev/null + done + + # handle them in the end with a glob since it's way faster + dpkg-statoverride --quiet --list '/etc/asterisk/*' | while read STAT; do + chown `echo $STAT | cut -d' ' -f 1,2,4 | sed 's/ /:/'` \ + 2>/dev/null + done + + set -e + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + --- asterisk-1.4.21.2~dfsg.orig/debian/rules +++ asterisk-1.4.21.2~dfsg/debian/rules @@ -0,0 +1,251 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# This file is public domain software, originally written by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +export DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE)) + confflags += --build $(DEB_HOST_GNU_TYPE) +else + confflags += --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE) +endif + +export PROC := $(shell dpkg-architecture -qDEB_BUILD_GNU_CPU) + +ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS))) + BUILDFLAGS += OPTIMIZE=-O0 +else + BUILDFLAGS += OPTIMIZE=-O2 +endif +BUILDFLAGS += MAKECMDGOALS=dont-optimize + +# show full gcc arguments instead of [CC] and [LD] +BUILDFLAGS += NOISY_BUILD=yes + +# Force music files selection: +BUILDFLAGS += MENUSELECT_MOH= \ + ASTDATADIR=/usr/share/asterisk \ + ASTVARRUNDIR=/var/run/asterisk \ + + +ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) + CFLAGS += -g +endif +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) + INSTALL_PROGRAM += -s +endif + +include /usr/share/quilt/quilt.make + +DEBVERSION:=$(shell head -n 1 debian/changelog \ + | sed -e 's/^[^(]*(\([^)]*\)).*/\1/') +DEB_NOEPOCH_VERSION:=$(shell echo $(DEBVERSION) | cut -d':' -f 2) +UPVERSION:=$(shell echo $(DEBVERSION) | sed -e 's/^.*://' -e 's/-[0-9.]*$$//' -e 's/.dfsg$$//') + +FILENAME := asterisk_$(UPVERSION)~dfsg.orig.tar.gz +UPFILENAME := asterisk_$(UPVERSION).orig.tar.gz +URL := http://downloads.digium.com/pub/asterisk/releases/asterisk-$(UPVERSION).tar.gz + +# make sure we have 'fetch' . We need to have either wget or fetch +# on the system. However it is generally not a good idea to actually +# get remote tarballs at build time. So if nither wget nor fetch +# happen to be installed, the configure script will find a dummy +# fetch script that always returns an error. +FETCH_ENV = PATH=$$PATH:$(CURDIR)/debian/dummyprogs + + +check-sounds: + ( [ ! -f sounds/asterisk-moh-freeplay-wav.tar.gz ] && \ + [ ! -f sounds/fpm-calm-river.mp3 ] && \ + [ ! -f sounds/fpm-sunshine.mp3 ] && \ + [ ! -f sounds/fpm-world-mix.mp3 ] ) || \ + (echo "WARNING: non-free fpm sounds must be removed from sources before packaging." ; false ) + touch $@ + +config.status: check-sounds patch + dh_testdir + + [ -f .version.bak ] || cp -a .version .version.bak + echo $(DEB_NOEPOCH_VERSION) > .version + + if [ ! -r configure.debian_sav ]; then cp -a configure configure.debian_sav; fi + #./bootstrap.sh # also runs autoonf. TODO: currently not needed. + + chmod 755 $(CURDIR)/debian/dummyprogs/fetch + + $(FETCH_ENV) ./configure \ + --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \ + --prefix=/usr \ + --mandir=\$${prefix}/share/man \ + --infodir=\$${prefix}/share/info \ + --with-cap \ + --with-gsm \ + --with-imap=system \ + --with-pwlib=/usr/share/pwlib/include/ \ + --with-h323=/usr/share/openh323/ + + +menuselect.makeopts: config.status + $(FETCH_ENV) $(MAKE) $(BUILDFLAGS) menuselect.makeopts + sed -i -e '/^MENUSELECT_MOH=/d' menuselect.makeopts + + # some voodoo in order to get chan_h323 built, and make it in one + # build pass: + # enable chan_h323 (not enabled by default). Note that modules listed + # in MENUSELECT_CHANNEL are ones to disable: + sed -i -e '/MENUSELECT_CHANNELS=/s/chan_h323//' menuselect.makeopts + cat menuselect.makedeps + cat menuselect.makeopts + +build: build-arch build-indep + +build-arch: build-arch-stamp +build-arch-stamp: menuselect.makeopts + dh_testdir + + # Add here command to compile/build the package. + $(FETCH_ENV) $(MAKE) $(BUILDFLAGS) || true + + # Build a second time to pick up h323 :-( + $(FETCH_ENV) $(MAKE) $(BUILDFLAGS) + + + touch $@ + +build-indep: build-indep-stamp +build-indep-stamp: menuselect.makeopts + dh_testdir + + # Add here command to compile/build the arch indep package. +ifndef ASTERISK_NO_DOCS + $(FETCH_ENV) $(MAKE) progdocs +endif + touch $@ + + +clean: cleaned unpatch +# make clean breaks if we don't patch it up, hence the dependency +cleaned: patch + dh_testdir + dh_testroot + + # Add here commands to clean up after the build process. + $(MAKE) distclean + -$(RM) -rf debian/build + + if [ -r configure.debian_sav ]; then mv configure.debian_sav configure; fi + -test -d configs && chmod -x configs/*.sample + -$(RM) -f build-arch-stamp build-indep-stamp config.status check-sounds menuselect.makeopts + + [ ! -f .version.bak ] || mv .version.bak .version + + dh_clean + +install: install-arch install-indep +install-arch: build-arch + dh_testdir + dh_testroot + dh_clean -k -s + dh_installdirs -s + + $(FETCH_ENV) $(MAKE) $(BUILDFLAGS) DESTDIR=$(CURDIR)/debian/tmp install + + dh_install -s --sourcedir=debian/tmp + + $(RM) -f $(CURDIR)/debian/asterisk/usr/sbin/streamplayer + $(RM) -f $(CURDIR)/debian/asterisk/usr/sbin/stereorize + touch $@ + +install-indep: build-indep + dh_testdir + dh_testroot + dh_clean -k -i + dh_installdirs -i + + $(FETCH_ENV) $(MAKE) $(BUILDFLAGS) DESTDIR=$(CURDIR)/debian/tmp install samples + + dh_install -i --sourcedir=debian/tmp + + # create a simple config + echo "; please read doc/manager.txt" > $(CURDIR)/debian/asterisk-config/etc/asterisk/manager.d/README.conf + +# Build architecture-independent files here. +binary-indep: install-indep + dh_testdir -i + dh_testroot -i + dh_installlogrotate -i + dh_installdocs -i -XREADME.cygwin + dh_installexamples -i + dh_installcron -i + dh_installchangelogs ChangeLog -i + dh_link -i + dh_compress -i + dh_fixperms -i + # should follow dh_fixperms; asterisk configurations may contain + # sensitive information, such as passwords + chmod o-rwx $(CURDIR)/debian/asterisk-config/etc/asterisk/* + chmod o+rx $(CURDIR)/debian/asterisk-config/etc/asterisk/manager.d + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i + +# Build architecture-dependent files here. +binary-arch: install-arch + dh_testdir -a + dh_testroot -a + dh_installlogrotate -a + dh_installdocs -a + dh_installman utils/*.1 doc/*.8 contrib/scripts/*.8 + dh_installexamples -a + dh_installchangelogs ChangeLog -a + dh_installinit -a -- defaults 21 + dh_strip -a --dbg-package=asterisk-dbg + dh_link -a + dh_compress -a + dh_fixperms -a + dh_installdeb -a + rm -f debian/asterisk/usr/lib/asterisk/modules/chan_h323.so + dh_shlibdeps -a + dh_gencontrol -a + dh_md5sums -a + dh_builddeb -a + +print-version: + @@echo "Debian version: $(DEBVERSION)" + @@echo "Upstream version: $(UPVERSION)" + +TMP_TARBALL_TOP=../tarballs/asterisk-$(UPVERSION).tmp/asterisk-$(UPVERSION) +get-orig-source: + @@dh_testdir + @@[ -d ../tarballs/. ]||mkdir -p ../tarballs + @@echo Downloading $(UPFILENAME) from $(URL) ... + @@wget -nv -T10 -t3 -O ../tarballs/$(UPFILENAME) $(URL) + @@echo Repacking as DFSG-free... + @@mkdir -p ../tarballs/asterisk-$(UPVERSION).tmp/ + @@cd ../tarballs/asterisk-$(UPVERSION).tmp ; \ + tar xfz ../$(UPFILENAME) + @@rm -f $(TMP_TARBALL_TOP)/sounds/fpm-*.mp3 + @@rm -f $(TMP_TARBALL_TOP)/sounds/asterisk-moh-freeplay-wav.tar.gz + @@rm -rf $(TMP_TARBALL_TOP)/codecs/ilbc/* + # in case the tarball is not clean: + @@rm -rf $(TMP_TARBALL_TOP)/*/.makeopts + @@rm -rf $(TMP_TARBALL_TOP)/*/.*.makeopts + @@rm -rf $(TMP_TARBALL_TOP)/*/.moduleinfo + @@rm -rf $(TMP_TARBALL_TOP)/*/.*.moduleinfo + @@rm -rf $(TMP_TARBALL_TOP)/menuselect-tree + @@printf "all:\nclean:\n.PHONY: all clean\n" > \ + $(TMP_TARBALL_TOP)/codecs/ilbc/Makefile + @@rm -f $(TMP_TARBALL_TOP)/codecs/codec_ilbc.c + @@rm -rf $(TMP_TARBALL_TOP)/contrib/firmware/ + @@cd ../tarballs/asterisk-$(UPVERSION).tmp ; \ + tar cfz ../$(FILENAME) * + @@echo Cleaning up... + @@$(RM) -rf ../tarballs/asterisk-$(UPVERSION).tmp/ + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install clean patch unpatch --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-config.preinst +++ asterisk-1.4.21.2~dfsg/debian/asterisk-config.preinst @@ -0,0 +1,59 @@ +#! /bin/sh +# preinst script +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +# Remove a no-longer used conffile +rm_conffile() { + PKGNAME="$1" + CONFFILE="$2" + + if [ -e "$CONFFILE" ]; then + md5sum="`md5sum \"$CONFFILE\" | sed -e \"s/ .*//\"`" + old_md5sum="`dpkg-query -W -f='${Conffiles}' $PKGNAME | sed -n -e \"\\\\' $CONFFILE'{s/ obsolete$//;s/.* //p}\"`" + if [ "$md5sum" != "$old_md5sum" ]; then + echo "Obsolete conffile $CONFFILE has been modified by you." + echo "Saving as $CONFFILE.dpkg-bak ..." + mv -f "$CONFFILE" "$CONFFILE".dpkg-bak + else + echo "Removing obsolete conffile $CONFFILE ..." + rm -f "$CONFFILE" + fi + fi +} + +case "$1" in + install|upgrade) + # chan_modem was removed on 1.4+ + if dpkg --compare-versions "$2" lt "1:1.4.0-1~"; then + rm_conffile asterisk-config "/etc/asterisk/modem.conf" + fi + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 --- asterisk-1.4.21.2~dfsg.orig/debian/patches/h323-workaround-openh323-segfault +++ asterisk-1.4.21.2~dfsg/debian/patches/h323-workaround-openh323-segfault @@ -0,0 +1,30 @@ +Hack dynamic loader to workaround libopenh323 bug + +libopenh323 is buggy and crashes on dlclose() when the library was opened with +RTLD_LAZY (#438815). Hack around this by opening it with RTLD_NOW by matching +the module names (chan_h323.so and the external chan_oh323.so) + +This is a very crude hack needed because we are removing libopenh323 +dependencies from the asterisk binary. (h323-no-deps-on-asterisk) +Namely, it will have unexpected results if e.g. the user renames the module +for any reason. + +Should be removed when #438815 closes. + + -- Faidon Liambotis + +--- a/main/loader.c ++++ b/main/loader.c +@@ -359,6 +359,12 @@ static struct ast_module *load_dynamic_m + + strcpy(resource_being_loaded->resource, resource); + ++ /* libopenh323 is buggy and segfaults on dlclose() when opened with ++ * RTLD_LAZY. Workaround this until it gets fixed */ ++ if (!strcasecmp(resource, "chan_h323.so") || ++ !strcasecmp(resource, "chan_oh323.so")) ++ lib = dlopen(fn, RTLD_NOW | RTLD_LOCAL); ++ + if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) { + ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror()); + free(resource_being_loaded); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/astvarrundir +++ asterisk-1.4.21.2~dfsg/debian/patches/astvarrundir @@ -0,0 +1,18 @@ +Move ASTVARRUNDIR to /var/run/asterisk/ + +This is needed because we need to have write access to a directory when +dropping uid/gid. + + -- Mark Purcell + +--- a/Makefile ++++ b/Makefile +@@ -125,7 +125,7 @@ else + ASTSBINDIR=$(sbindir) + ASTSPOOLDIR=$(localstatedir)/spool/asterisk + ASTLOGDIR=$(localstatedir)/log/asterisk +- ASTVARRUNDIR=$(localstatedir)/run ++ ASTVARRUNDIR=$(localstatedir)/run/asterisk + ASTMANDIR=$(mandir) + ifneq ($(findstring BSD,$(OSARCH)),) + ASTVARLIBDIR=$(prefix)/share/asterisk --- asterisk-1.4.21.2~dfsg.orig/debian/patches/use-libpri-bristuffed +++ asterisk-1.4.21.2~dfsg/debian/patches/use-libpri-bristuffed @@ -0,0 +1,141 @@ +--- a/configure ++++ b/configure +@@ -25862,18 +25862,18 @@ fi + + + if test "${AST_PRI_FOUND}" = "yes"; then +- PRI_LIB="-lpri " ++ PRI_LIB="-lpri-bristuffed " + PRI_HEADER_FOUND="1" + if test "x${PRI_DIR}" != "x"; then + PRI_LIB="${pbxlibdir} ${PRI_LIB}" +- PRI_INCLUDE="-I${PRI_DIR}/include" ++ PRI_INCLUDE="-I${PRI_DIR}/include/bristuffed" + saved_cppflags="${CPPFLAGS}" +- CPPFLAGS="${CPPFLAGS} -I${PRI_DIR}/include" ++ CPPFLAGS="${CPPFLAGS} -I${PRI_DIR}/include/bristuffed" + if test "xlibpri.h" != "x" ; then +- as_ac_Header=`echo "ac_cv_header_${PRI_DIR}/include/libpri.h" | $as_tr_sh` ++ as_ac_Header=`echo "ac_cv_header_${PRI_DIR}/include/bristuffed/libpri.h" | $as_tr_sh` + if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then +- { echo "$as_me:$LINENO: checking for ${PRI_DIR}/include/libpri.h" >&5 +-echo $ECHO_N "checking for ${PRI_DIR}/include/libpri.h... $ECHO_C" >&6; } ++ { echo "$as_me:$LINENO: checking for ${PRI_DIR}/include/bristuffed/libpri.h" >&5 ++echo $ECHO_N "checking for ${PRI_DIR}/include/bristuffed/libpri.h... $ECHO_C" >&6; } + if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 + fi +@@ -25882,8 +25882,8 @@ ac_res=`eval echo '${'$as_ac_Header'}'` + echo "${ECHO_T}$ac_res" >&6; } + else + # Is the header compilable? +-{ echo "$as_me:$LINENO: checking ${PRI_DIR}/include/libpri.h usability" >&5 +-echo $ECHO_N "checking ${PRI_DIR}/include/libpri.h usability... $ECHO_C" >&6; } ++{ echo "$as_me:$LINENO: checking ${PRI_DIR}/include/bristuffed/libpri.h usability" >&5 ++echo $ECHO_N "checking ${PRI_DIR}/include/bristuffed/libpri.h usability... $ECHO_C" >&6; } + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ + _ACEOF +@@ -25891,7 +25891,7 @@ cat confdefs.h >>conftest.$ac_ext + cat >>conftest.$ac_ext <<_ACEOF + /* end confdefs.h. */ + $ac_includes_default +-#include <${PRI_DIR}/include/libpri.h> ++#include <${PRI_DIR}/include/bristuffed/libpri.h> + _ACEOF + rm -f conftest.$ac_objext + if { (ac_try="$ac_compile" +@@ -25923,15 +25923,15 @@ rm -f core conftest.err conftest.$ac_obj + echo "${ECHO_T}$ac_header_compiler" >&6; } + + # Is the header present? +-{ echo "$as_me:$LINENO: checking ${PRI_DIR}/include/libpri.h presence" >&5 +-echo $ECHO_N "checking ${PRI_DIR}/include/libpri.h presence... $ECHO_C" >&6; } ++{ echo "$as_me:$LINENO: checking ${PRI_DIR}/include/bristuffed/libpri.h presence" >&5 ++echo $ECHO_N "checking ${PRI_DIR}/include/bristuffed/libpri.h presence... $ECHO_C" >&6; } + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ + _ACEOF + cat confdefs.h >>conftest.$ac_ext + cat >>conftest.$ac_ext <<_ACEOF + /* end confdefs.h. */ +-#include <${PRI_DIR}/include/libpri.h> ++#include <${PRI_DIR}/include/bristuffed/libpri.h> + _ACEOF + if { (ac_try="$ac_cpp conftest.$ac_ext" + case "(($ac_try" in +@@ -25964,25 +25964,25 @@ echo "${ECHO_T}$ac_header_preproc" >&6; + # So? What about this header? + case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) +- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: accepted by the compiler, rejected by the preprocessor!" >&5 +-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: accepted by the compiler, rejected by the preprocessor!" >&2;} +- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: proceeding with the compiler's result" >&5 +-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: proceeding with the compiler's result" >&2;} ++ { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: accepted by the compiler, rejected by the preprocessor!" >&5 ++echo "$as_me: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: proceeding with the compiler's result" >&5 ++echo "$as_me: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) +- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: present but cannot be compiled" >&5 +-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: present but cannot be compiled" >&2;} +- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: check for missing prerequisite headers?" >&5 +-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: check for missing prerequisite headers?" >&2;} +- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: see the Autoconf documentation" >&5 +-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: see the Autoconf documentation" >&2;} +- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: section \"Present But Cannot Be Compiled\"" >&5 +-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: section \"Present But Cannot Be Compiled\"" >&2;} +- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: proceeding with the preprocessor's result" >&5 +-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: proceeding with the preprocessor's result" >&2;} +- { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/libpri.h: in the future, the compiler will take precedence" >&5 +-echo "$as_me: WARNING: ${PRI_DIR}/include/libpri.h: in the future, the compiler will take precedence" >&2;} ++ { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: present but cannot be compiled" >&5 ++echo "$as_me: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: present but cannot be compiled" >&2;} ++ { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: check for missing prerequisite headers?" >&5 ++echo "$as_me: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: check for missing prerequisite headers?" >&2;} ++ { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: see the Autoconf documentation" >&5 ++echo "$as_me: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: see the Autoconf documentation" >&2;} ++ { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: section \"Present But Cannot Be Compiled\"" >&5 ++echo "$as_me: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: section \"Present But Cannot Be Compiled\"" >&2;} ++ { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: proceeding with the preprocessor's result" >&5 ++echo "$as_me: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: proceeding with the preprocessor's result" >&2;} ++ { echo "$as_me:$LINENO: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: in the future, the compiler will take precedence" >&5 ++echo "$as_me: WARNING: ${PRI_DIR}/include/bristuffed/libpri.h: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX + ## ------------------------------- ## + ## Report this to www.asterisk.org ## +@@ -25991,8 +25991,8 @@ _ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; + esac +-{ echo "$as_me:$LINENO: checking for ${PRI_DIR}/include/libpri.h" >&5 +-echo $ECHO_N "checking for ${PRI_DIR}/include/libpri.h... $ECHO_C" >&6; } ++{ echo "$as_me:$LINENO: checking for ${PRI_DIR}/include/bristuffed/libpri.h" >&5 ++echo $ECHO_N "checking for ${PRI_DIR}/include/bristuffed/libpri.h... $ECHO_C" >&6; } + if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 + else +--- a/configure.ac ++++ b/configure.ac +@@ -1232,7 +1232,7 @@ fi + + AST_EXT_LIB_CHECK([POPT], [popt], [poptStrerror], [popt.h]) + +-AST_EXT_LIB_CHECK([PRI], [pri], [pri_keypad_facility], [libpri.h]) ++AST_EXT_LIB_CHECK([PRI], [pri-bristuffed], [pri_keypad_facility], [bristuffed/libpri.h]) + + AST_EXT_LIB_CHECK([PRI_VERSION], [pri], [pri_get_version], [libpri.h]) + +--- a/channels/chan_zap.c ++++ b/channels/chan_zap.c +@@ -71,7 +71,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi + #include + + #ifdef HAVE_PRI +-#include ++#include + #endif + + #include "asterisk/lock.h" --- asterisk-1.4.21.2~dfsg.orig/debian/patches/func_devstate +++ asterisk-1.4.21.2~dfsg/debian/patches/func_devstate @@ -0,0 +1,249 @@ +Add backport of func_devname.c + +This is the DEVSTATE() dialplan function which allows retrieving any device +state in the dialplan, as well as creating custom device states that are +controllable from the dialplan. +It is similar to bristuff's app_devstate. +See http://www.asterisk.org/node/48325 for more information. + +This is a backport from the 1.6 development version. +Both the function and its backport were done by Russell Bryant of Digium. + +Russell has said that he will maintain this backport. + +Update this by doing: +svn cat http://svncommunity.digium.com/svn/russell/func_devstate-1.4/func_devstate.c + + -- Faidon Liambotis + +--- /dev/null ++++ b/funcs/func_devstate.c +@@ -0,0 +1,228 @@ ++/* ++ * Asterisk -- An open source telephony toolkit. ++ * ++ * Copyright (C) 2007, Digium, Inc. ++ * ++ * Russell Bryant ++ * ++ * See http://www.asterisk.org for more information about ++ * the Asterisk project. Please do not directly contact ++ * any of the maintainers of this project for assistance; ++ * the project provides a web site, mailing lists and IRC ++ * channels for your use. ++ * ++ * This program is free software, distributed under the terms of ++ * the GNU General Public License Version 2. See the LICENSE file ++ * at the top of the source tree. ++ */ ++ ++/*! \file ++ * ++ * \brief Manually controlled blinky lights ++ * ++ * \author Russell Bryant ++ * ++ * \ingroup functions ++ * ++ * \note Props go out to Ahrimanes in #asterisk for requesting this at 4:30 AM ++ * when I couldn't sleep. :) ++ */ ++ ++#include "asterisk.h" ++ ++ASTERISK_FILE_VERSION(__FILE__, "$Revision: 4 $") ++ ++#include ++ ++#include "asterisk/module.h" ++#include "asterisk/channel.h" ++#include "asterisk/pbx.h" ++#include "asterisk/utils.h" ++#include "asterisk/linkedlists.h" ++#include "asterisk/devicestate.h" ++#include "asterisk/cli.h" ++#include "asterisk/astdb.h" ++ ++static const char astdb_family[] = "CustomDevstate"; ++ ++static const char *ast_devstate_str(int state) ++{ ++ const char *res = "UNKNOWN"; ++ ++ switch (state) { ++ case AST_DEVICE_UNKNOWN: ++ break; ++ case AST_DEVICE_NOT_INUSE: ++ res = "NOT_INUSE"; ++ break; ++ case AST_DEVICE_INUSE: ++ res = "INUSE"; ++ break; ++ case AST_DEVICE_BUSY: ++ res = "BUSY"; ++ break; ++ case AST_DEVICE_INVALID: ++ res = "INVALID"; ++ break; ++ case AST_DEVICE_UNAVAILABLE: ++ res = "UNAVAILABLE"; ++ break; ++ case AST_DEVICE_RINGING: ++ res = "RINGING"; ++ break; ++ case AST_DEVICE_RINGINUSE: ++ res = "RINGINUSE"; ++ break; ++ case AST_DEVICE_ONHOLD: ++ res = "ONHOLD"; ++ break; ++ } ++ ++ return res; ++} ++ ++static int ast_devstate_val(const char *val) ++{ ++ if (!strcasecmp(val, "NOT_INUSE")) ++ return AST_DEVICE_NOT_INUSE; ++ else if (!strcasecmp(val, "INUSE")) ++ return AST_DEVICE_INUSE; ++ else if (!strcasecmp(val, "BUSY")) ++ return AST_DEVICE_BUSY; ++ else if (!strcasecmp(val, "INVALID")) ++ return AST_DEVICE_INVALID; ++ else if (!strcasecmp(val, "UNAVAILABLE")) ++ return AST_DEVICE_UNAVAILABLE; ++ else if (!strcasecmp(val, "RINGING")) ++ return AST_DEVICE_RINGING; ++ else if (!strcasecmp(val, "RINGINUSE")) ++ return AST_DEVICE_RINGINUSE; ++ else if (!strcasecmp(val, "ONHOLD")) ++ return AST_DEVICE_ONHOLD; ++ ++ return AST_DEVICE_UNKNOWN; ++} ++ ++static int devstate_read(struct ast_channel *chan, char *cmd, char *data, ++ char *buf, size_t len) ++{ ++ ast_copy_string(buf, ast_devstate_str(ast_device_state(data)), len); ++ ++ return 0; ++} ++ ++static int devstate_write(struct ast_channel *chan, char *function, ++ char *data, const char *value) ++{ ++ size_t len = strlen("Custom:"); ++ ++ if (strncasecmp(data, "Custom:", len)) { ++ ast_log(LOG_WARNING, "The DEVSTATE function can only be used to set 'Custom:' device state!\n"); ++ return -1; ++ } ++ data += len; ++ if (ast_strlen_zero(data)) { ++ ast_log(LOG_WARNING, "DEVSTATE function called with no custom device name!\n"); ++ return -1; ++ } ++ ++ ast_db_put(astdb_family, data, (char *) value); ++ ++ ast_device_state_changed("Custom:%s", data); ++ ++ return 0; ++} ++ ++static int custom_devstate_callback(const char *data) ++{ ++ char buf[256] = ""; ++ ++ ast_db_get(astdb_family, data, buf, sizeof(buf)); ++ ++ return ast_devstate_val(buf); ++} ++ ++static int cli_funcdevstate_list(int fd, int argc, char *argv[]) ++{ ++ struct ast_db_entry *db_entry, *db_tree; ++ ++ if (argc != 2) ++ return RESULT_SHOWUSAGE; ++ ++ ast_cli(fd, "\n" ++ "---------------------------------------------------------------------\n" ++ "--- Custom Device States --------------------------------------------\n" ++ "---------------------------------------------------------------------\n" ++ "---\n"); ++ ++ db_entry = db_tree = ast_db_gettree(astdb_family, NULL); ++ for (; db_entry; db_entry = db_entry->next) { ++ const char *dev_name = strrchr(db_entry->key, '/') + 1; ++ if (dev_name <= (const char *) 1) ++ continue; ++ ast_cli(fd, "--- name: 'custom:%s' state: '%s'\n" ++ "---\n", dev_name, db_entry->data); ++ } ++ ast_db_freetree(db_tree); ++ db_tree = NULL; ++ ++ ast_cli(fd, ++ "---------------------------------------------------------------------\n" ++ "---------------------------------------------------------------------\n" ++ "\n"); ++ ++ return RESULT_SUCCESS; ++} ++ ++static struct ast_cli_entry cli_funcdevstate[] = { ++ { { "funcdevstate", "list", }, cli_funcdevstate_list, NULL, NULL }, ++}; ++ ++static struct ast_custom_function devstate_function = { ++ .name = "DEVSTATE", ++ .synopsis = "Get or Set a device state", ++ .syntax = "DEVSTATE(device)", ++ .desc = ++ " The DEVSTATE function can be used to retrieve the device state from any\n" ++ "device state provider. For example:\n" ++ " NoOp(SIP/mypeer has state ${DEVSTATE(SIP/mypeer)})\n" ++ " NoOp(Conference number 1234 has state ${DEVSTATE(MeetMe:1234)})\n" ++ "\n" ++ " The DEVSTATE function can also be used to set custom device state from\n" ++ "the dialplan. The \"Custom:\" prefix must be used. For example:\n" ++ " Set(DEVSTATE(Custom:lamp1)=BUSY)\n" ++ " Set(DEVSTATE(Custom:lamp2)=NOT_INUSE)\n" ++ "You can subscribe to the status of a custom device state using a hint in\n" ++ "the dialplan:\n" ++ " exten => 1234,hint,Custom:lamp1\n" ++ "\n" ++ " The possible values for both uses of this function are:\n" ++ "UNKNOWN | NOT_INUSE | INUSE | BUSY | INVALID | UNAVAILABLE | RINGING\n" ++ "RINGINUSE | ONHOLD\n", ++ .read = devstate_read, ++ .write = devstate_write, ++}; ++ ++static int unload_module(void) ++{ ++ int res = 0; ++ ++ res |= ast_custom_function_unregister(&devstate_function); ++ ast_devstate_prov_del("Custom"); ++ ast_cli_unregister_multiple(cli_funcdevstate, ARRAY_LEN(cli_funcdevstate)); ++ ++ return res; ++} ++ ++static int load_module(void) ++{ ++ int res = 0; ++ ++ res |= ast_custom_function_register(&devstate_function); ++ res |= ast_devstate_prov_add("Custom", custom_devstate_callback); ++ ast_cli_register_multiple(cli_funcdevstate, ARRAY_LEN(cli_funcdevstate)); ++ ++ return res; ++} ++ ++AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Gets or sets a device state in the dialplan"); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/misdn_FOP +++ asterisk-1.4.21.2~dfsg/debian/patches/misdn_FOP @@ -0,0 +1,62 @@ +When dialing out a misdn channel, either by using a group (g:group), +or a port, asterisk creates the channel with a tmp channel number: mISDN/X-uY, +with X being (port-1)*2. Y not important. + +Port 0: temporal channel name 0. BChannels 1 and 2 +Port 1: temporal channel name 2. BChannels 3 and 4 +Port 2: temporal channel name 4. BChannels 5 and 6 + +As you can see, temporal channel for port 1 conflicts with real +channel 2 for port 0. This is not consistent. + +This patch forces temporal channels (those for which we have +not a B channel yet), to be named mISDN/tmpX-uY. + +Also, it will rename the channel using the ast_change_name() +function, which generates "rename" events, and can be followed by manager events. + +As a plus, it will make FOP work correctly with misdn channels. + +http://bugs.digium.com/view.php?id=0011142 + + -- Victor Seva + +--- a/channels/chan_misdn.c ++++ b/channels/chan_misdn.c +@@ -3334,17 +3334,19 @@ static void update_name(struct ast_chann + { + int chan_offset=0; + int tmp_port = misdn_cfg_get_next_port(0); ++ char newname[255]; + for (; tmp_port > 0; tmp_port=misdn_cfg_get_next_port(tmp_port)) { + if (tmp_port == port) break; + chan_offset+=misdn_lib_port_is_pri(tmp_port)?30:2; + } + if (c<0) c=0; + +- ast_string_field_build(tmp, name, "%s/%d-u%d", +- misdn_type, chan_offset+c, glob_channel++); +- +- chan_misdn_log(3,port," --> updating channel name to [%s]\n",tmp->name); +- ++ snprintf(newname,sizeof(newname),"%s/%d-",misdn_type,chan_offset+c); ++ if (strncmp(tmp->name,newname,strlen(newname))) { ++ snprintf(newname,sizeof(newname),"%s/%d-u%d", misdn_type, chan_offset+c, glob_channel++); ++ ast_change_name(tmp,newname); ++ chan_misdn_log(3,port," --> updating channel name to [%s]\n",tmp->name); ++ } + } + + static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, int format, int port, int c) +@@ -3364,7 +3366,10 @@ static struct ast_channel *misdn_new(str + if (callerid) + ast_callerid_parse(callerid, &cid_name, &cid_num); + +- tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); ++ if (c) ++ tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); ++ else ++ tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/tmp%d-u%d", misdn_type, chan_offset + c, glob_channel++); + + if (tmp) { + int bridging; --- asterisk-1.4.21.2~dfsg.orig/debian/patches/pubkey_jnctn +++ asterisk-1.4.21.2~dfsg/debian/patches/pubkey_jnctn @@ -0,0 +1,35 @@ +Public key for Junction Networks. From http://www.jnctn.net/jnctn.pub +at Wed, 12 Oct 2005 23:35:06 +0200 + +See also http://www.junctionnetworks.com/Asterisk-config.htm + + -- Tzafrir Cohen + +Also fix the Makefile to copy all keys on make install instead of mentioning +them explicitely. + +Forwarded as a note to #10811. + + -- Faidon Liambotis + +--- /dev/null ++++ b/keys/jnctn.pub +@@ -0,0 +1,6 @@ ++-----BEGIN PUBLIC KEY----- ++MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWaDv4190BpeL5K+Yuq5Q7+vPs ++FVrkibbIp+Io1gCQ6CGZJbR0kUZvTdf58bBdG0zqf6azFN8XPaNz9PVLDl+KgHwU ++3Ilu//eX8ph8Wu+Oxs/ymi/hzKm+Cd6aty94zYuqiegc0KdrjvU5TLQAkIQpiB6k ++CvuIm0R0XXQjj3R7LwIDAQAB ++-----END PUBLIC KEY----- +--- a/Makefile ++++ b/Makefile +@@ -469,8 +469,7 @@ bininstall: _all installdirs $(SUBDIRS_I + mkdir -p $(DESTDIR)$(ASTDATADIR)/firmware + mkdir -p $(DESTDIR)$(ASTDATADIR)/firmware/iax + mkdir -p $(DESTDIR)$(ASTMANDIR)/man8 +- $(INSTALL) -m 644 keys/iaxtel.pub $(DESTDIR)$(ASTDATADIR)/keys +- $(INSTALL) -m 644 keys/freeworlddialup.pub $(DESTDIR)$(ASTDATADIR)/keys ++ $(INSTALL) -m 644 keys/* $(DESTDIR)$(ASTDATADIR)/keys + $(INSTALL) -m 644 doc/asterisk.8 $(DESTDIR)$(ASTMANDIR)/man8 + $(INSTALL) -m 644 contrib/scripts/astgenkey.8 $(DESTDIR)$(ASTMANDIR)/man8 + $(INSTALL) -m 644 contrib/scripts/autosupport.8 $(DESTDIR)$(ASTMANDIR)/man8 --- asterisk-1.4.21.2~dfsg.orig/debian/patches/allow-tilde-destdir +++ asterisk-1.4.21.2~dfsg/debian/patches/allow-tilde-destdir @@ -0,0 +1,21 @@ +badshell is disallowing tildes (~) in the DESTDIR directory to warn people +who use a shell that doesn't expand it to $HOMEDIR. + +However, we have such a tilde in our directory (~dfsg) that isn't expanded +to $HOMEDIR nor shouldn't be. + +Should be reported upstream. + + -- Faidon Liambotis + +--- a/Makefile ++++ b/Makefile +@@ -507,7 +507,7 @@ ifneq ($(findstring ~,$(DESTDIR)),) + @exit 1 + endif + +-install: badshell datafiles bininstall ++install: datafiles bininstall + @if [ -x /usr/sbin/asterisk-post-install ]; then \ + /usr/sbin/asterisk-post-install $(DESTDIR) . ; \ + fi --- asterisk-1.4.21.2~dfsg.orig/debian/patches/silence-buildsum-warning +++ asterisk-1.4.21.2~dfsg/debian/patches/silence-buildsum-warning @@ -0,0 +1,18 @@ +Several of our modules were compiled before build sum was introduced. +Avoid annoying our users for now. We will enable this option at a later point +when most of the modules will get a compilation with the new headers. + + -- Faidon Liambotis + +--- a/main/loader.c ++++ b/main/loader.c +@@ -625,7 +625,9 @@ static unsigned int inspect_module(const + } + + if (!ast_test_flag(mod->info, AST_MODFLAG_BUILDSUM)) { ++ /* + ast_log(LOG_WARNING, "Module '%s' was not compiled against a recent version of Asterisk and may cause instability.\n", mod->resource); ++ */ + } else if (!ast_strlen_zero(mod->info->buildopt_sum) && + strcmp(buildopt_sum, mod->info->buildopt_sum)) { + ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/series +++ asterisk-1.4.21.2~dfsg/debian/patches/series @@ -0,0 +1,88 @@ +### upstream fixes +allow-tilde-destdir + +debian-banner +silence-buildsum-warning +hack-multiple-app-voicemail +astvarrundir +make-clean-fixes +safe_asterisk-config +safe_asterisk-nobg +h323-no-deps-on-asterisk +h323-workaround-openh323-segfault + +astgenkey-security +apptest_sleep + +### new features +pubkey_jnctn +func_devstate + +# for chan_vpb +vpb-handle-nocards + +# for chan_misdn (even though it's not enabled yet) +misdn_FOP + +### bristuff +bristuff/bristuff-notice + +bristuff/configurable-AST_SYSTEM_NAME + +# standalone changes/applications +# - they don't break the API +# - they don't need other API changes +bristuff/xagi +bristuff/misc-app-segfault +bristuff/misc-app-pickup +bristuff/misc-app-devstate +bristuff/misc-res-watchdog +bristuff/misc-manager-dbdel +bristuff/misc-res-esel + +# small non-API-breaking bug fixes +bristuff/chan-iax2-hangup-cause +bristuff/isdn-fixes +bristuff/app-meetme-avoid-overflows +bristuff/answer-before-say + +# app_dial adding of options +bristuff/app-dial-priority-202 +bristuff/app-dial-etc +bristuff/app-dial-R-noinband +bristuff/app-dial-c-callback + +bristuff/zapata_num_spans + +# use /usr/include/bristuffed/libpri.h - /usr/lib/libpri-bristuffed.so.1.0 +use-libpri-bristuffed +# euroISDN, BRI support +bristuff/zapata-bri+euroisdn + +bristuff/ast-send-message + +# don't split these up! +bristuff/ast_monitor_start-targetscript +bristuff/ast-device-state-CID +bristuff/uniqueid-10-channel-ops-uniqueid +bristuff/uniqueid-20-monitor +bristuff/uniqueid-30-app-chanspy +bristuff/uniqueid-40-manager + +# these depend on the uniqueid changes; the following are a set +bristuff/feature-autoanswer +bristuff/feature-holdedcalls + +#bristuff/zapata_euroisdn_holded + +# GSM support; it needs the above patch applied first, unfortunately. +bristuff/zapata-gsm + +# bridging app backported from 1.6 +# it needs the above feature patches applied first. +feature-bridge + +# bugfixes on top of everything +zap-fix-timing-source +zap-fix-deadlock +zap-fix-cause34 --- asterisk-1.4.21.2~dfsg.orig/debian/patches/hack-multiple-app-voicemail +++ asterisk-1.4.21.2~dfsg/debian/patches/hack-multiple-app-voicemail @@ -0,0 +1,60 @@ +This is a very ugly hack on upstream's Makefiles to allow building multiple +variants of app_voicemail. Three variants are created: + * app_voicemail.so: plain old filesystem storage that doesn't break existing + setups + * app_voicemail_imap.so: IMAP storage + * app_voicemail_odbc.so: ODBC storage (and app_directory_odbc.so) +All these conflict with each other and Asterisk will refuse to load them +concurrently. +They are marked noload on our default autoload configuration. + +A bug should be opened with upstream so that we can discuss the matter. + + -- Faidon Liambotis + +--- a/apps/Makefile ++++ b/apps/Makefile +@@ -18,6 +18,16 @@ ALL_C_MODS:=$(patsubst %.c,%,$(wildcard + ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard app_*.cc)) + + C_MODS:=$(filter-out $(MENUSELECT_APPS),$(ALL_C_MODS)) ++ifeq ($(findstring IMAP_STORAGE,$(MENUSELECT_OPTS_app_voicemail)),) ++C_MODS+=app_voicemail_imap ++MENUSELECT_DEPENDS_app_voicemail_imap+=IMAP_TK SSL ++MENUSELECT_DEPENDS_app_directory_imap+=IMAP_TK SSL ++endif ++ifeq ($(findstring ODBC_STORAGE,$(MENUSELECT_OPTS_app_voicemail)),) ++C_MODS+=app_voicemail_odbc app_directory_odbc ++MENUSELECT_DEPENDS_app_voicemail_odbc+=UNIXODBC LTDL ++MENUSELECT_DEPENDS_app_directory_odbc+=UNIXODBC LTDL ++endif + CC_MODS:=$(filter-out $(MENUSELECT_APPS),$(ALL_CC_MODS)) + + LOADABLE_MODS:=$(C_MODS) $(CC_MODS) +@@ -28,6 +38,8 @@ ifneq ($(findstring apps,$(MENUSELECT_EM + endif + + MENUSELECT_OPTS_app_directory:=$(MENUSELECT_OPTS_app_voicemail) ++MENUSELECT_OPTS_app_directory_imap:=$(MENUSELECT_OPTS_app_voicemail) ++MENUSELECT_OPTS_app_directory_odbc:=$(MENUSELECT_OPTS_app_voicemail) + ifneq ($(findstring ODBC_STORAGE,$(MENUSELECT_OPTS_app_voicemail)),) + MENUSELECT_DEPENDS_app_voicemail+=$(MENUSELECT_DEPENDS_ODBC_STORAGE) + MENUSELECT_DEPENDS_app_directory+=$(MENUSELECT_DEPENDS_ODBC_STORAGE) +@@ -44,4 +56,17 @@ endif + + all: _all + ++app_voicemail_%.c: ++ ln -s app_voicemail.c $@ ++ ++app_directory_%.c: ++ ln -s app_directory.c $@ ++ ++clean:: ++ rm -f app_voicemail_*.c ++ ++app_voicemail_imap.o: ASTCFLAGS+=-DIMAP_STORAGE ++app_voicemail_odbc.o: ASTCFLAGS+=-DODBC_STORAGE ++app_directory_odbc.o: ASTCFLAGS+=-DODBC_STORAGE ++ + include $(ASTTOPDIR)/Makefile.moddir_rules --- asterisk-1.4.21.2~dfsg.orig/debian/patches/feature-bridge +++ asterisk-1.4.21.2~dfsg/debian/patches/feature-bridge @@ -0,0 +1,373 @@ +Backport of asterisk 1.5/1.6 feature that Bridges together two channels already in the PBX. + + -- Jon Webster + +--- a/res/res_features.c ++++ b/res/res_features.c +@@ -230,6 +230,7 @@ struct ast_bridge_thread_obj + struct ast_bridge_config bconfig; + struct ast_channel *chan; + struct ast_channel *peer; ++ unsigned int return_to_pbx:1; + }; + + +@@ -284,11 +285,13 @@ static struct ast_channel *ast_feature_r + static void *ast_bridge_call_thread(void *data) + { + struct ast_bridge_thread_obj *tobj = data; ++ int res; + +- tobj->chan->appl = "Transferred Call"; ++ tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge"; + tobj->chan->data = tobj->peer->name; +- tobj->peer->appl = "Transferred Call"; ++ tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge"; + tobj->peer->data = tobj->chan->name; ++ + if (tobj->chan->cdr) { + ast_cdr_reset(tobj->chan->cdr, NULL); + ast_cdr_setdestchan(tobj->chan->cdr, tobj->peer->name); +@@ -299,10 +302,29 @@ static void *ast_bridge_call_thread(void + } + + ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig); +- ast_hangup(tobj->chan); +- ast_hangup(tobj->peer); +- bzero(tobj, sizeof(*tobj)); /*! \todo XXX for safety */ ++ ++ if (tobj->return_to_pbx) { ++ if (!ast_check_hangup(tobj->peer)) { ++ ast_log(LOG_VERBOSE, "putting peer %s into PBX again\n", tobj->peer->name); ++ res = ast_pbx_start(tobj->peer); ++ if (res != AST_PBX_SUCCESS) ++ ast_log(LOG_WARNING, "FAILED continuing PBX on peer %s\n", tobj->peer->name); ++ } else ++ ast_hangup(tobj->peer); ++ if (!ast_check_hangup(tobj->chan)) { ++ ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", tobj->chan->name); ++ res = ast_pbx_start(tobj->chan); ++ if (res != AST_PBX_SUCCESS) ++ ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", tobj->chan->name); ++ } else ++ ast_hangup(tobj->chan); ++ } else { ++ ast_hangup(tobj->chan); ++ ast_hangup(tobj->peer); ++ } ++ + free(tobj); ++ + return NULL; + } + +@@ -2389,6 +2411,125 @@ static int handle_showfeatures(int fd, i + return RESULT_SUCCESS; + } + ++static char mandescr_bridge[] = ++"Description: Bridge together two channels already in the PBX\n" ++"Variables: ( Headers marked with * are required )\n" ++" *Channel1: Channel to Bridge to Channel2\n" ++" *Channel2: Channel to Bridge to Channel1\n" ++" Tone: (Yes|No) Play courtesy tone to Channel 2\n" ++"\n"; ++ ++static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan) ++{ ++ ast_moh_stop(chan); ++ ast_mutex_lock(&chan->lock); ++ ast_setstate(tmpchan, chan->_state); ++ tmpchan->readformat = chan->readformat; ++ tmpchan->writeformat = chan->writeformat; ++ ast_channel_masquerade(tmpchan, chan); ++ ast_mutex_lock(&tmpchan->lock); ++ ast_do_masquerade(tmpchan); ++ /* when returning from bridge, the channel will continue at the next priority */ ++ ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1); ++ ast_mutex_unlock(&tmpchan->lock); ++ ast_mutex_unlock(&chan->lock); ++} ++ ++static int action_bridge(struct mansession *s, const struct message *m) ++{ ++ const char *channela = astman_get_header(m, "Channel1"); ++ const char *channelb = astman_get_header(m, "Channel2"); ++ const char *playtone = astman_get_header(m, "Tone"); ++ struct ast_channel *chana = NULL, *chanb = NULL; ++ struct ast_channel *tmpchana = NULL, *tmpchanb = NULL; ++ struct ast_bridge_thread_obj *tobj = NULL; ++ ++ /* make sure valid channels were specified */ ++ if (!ast_strlen_zero(channela) && !ast_strlen_zero(channelb)) { ++ chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela)); ++ chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb)); ++ if (chana) ++ ast_mutex_unlock(&chana->lock); ++ if (chanb) ++ ast_mutex_unlock(&chanb->lock); ++ ++ /* send errors if any of the channels could not be found/locked */ ++ if (!chana) { ++ char buf[256]; ++ snprintf(buf, sizeof(buf), "Channel1 does not exists: %s", channela); ++ astman_send_error(s, m, buf); ++ return 0; ++ } ++ if (!chanb) { ++ char buf[256]; ++ snprintf(buf, sizeof(buf), "Channel2 does not exists: %s", channelb); ++ astman_send_error(s, m, buf); ++ return 0; ++ } ++ } else { ++ astman_send_error(s, m, "Missing channel parameter in request"); ++ return 0; ++ } ++ ++ /* Answer the channels if needed */ ++ if (chana->_state != AST_STATE_UP) ++ ast_answer(chana); ++ if (chanb->_state != AST_STATE_UP) ++ ast_answer(chanb); ++ ++ /* create the placeholder channels and grab the other channels */ ++ if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, ++ NULL, NULL, 0, "Bridge/%s", chana->name))) { ++ astman_send_error(s, m, "Unable to create temporary channel!"); ++ return 1; ++ } ++ ++ if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, ++ NULL, NULL, 0, "Bridge/%s", chanb->name))) { ++ astman_send_error(s, m, "Unable to create temporary channels!"); ++ ast_channel_free(tmpchana); ++ return 1; ++ } ++ ++ do_bridge_masquerade(chana, tmpchana); ++ do_bridge_masquerade(chanb, tmpchanb); ++ ++ /* make the channels compatible, send error if we fail doing so */ ++ if (ast_channel_make_compatible(tmpchana, tmpchanb)) { ++ ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name); ++ astman_send_error(s, m, "Could not make channels compatible for manager bridge"); ++ ast_hangup(tmpchana); ++ ast_hangup(tmpchanb); ++ return 1; ++ } ++ ++ /* setup the bridge thread object and start the bridge */ ++ if (!(tobj = ast_calloc(1, sizeof(*tobj)))) { ++ ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno)); ++ astman_send_error(s, m, "Unable to spawn a new bridge thread"); ++ ast_hangup(tmpchana); ++ ast_hangup(tmpchanb); ++ return 1; ++ } ++ ++ tobj->chan = tmpchana; ++ tobj->peer = tmpchanb; ++ tobj->return_to_pbx = 1; ++ ++ if (ast_true(playtone)) { ++ if (!ast_strlen_zero(xfersound) && !ast_streamfile(tmpchanb, xfersound, tmpchanb->language)) { ++ if (ast_waitstream(tmpchanb, "") < 0) ++ ast_log(LOG_WARNING, "Failed to play a courtesy tone on chan %s\n", tmpchanb->name); ++ } ++ } ++ ++ ast_bridge_call_thread_launch(tobj); ++ ++ astman_send_ack(s, m, "Launched bridge thread with success"); ++ ++ return 0; ++} ++ + static char showfeatures_help[] = + "Usage: feature list\n" + " Lists currently configured features.\n"; +@@ -3216,6 +3357,154 @@ static int load_config(void) + + } + ++static char *app_bridge = "Bridge"; ++static char *bridge_synopsis = "Bridge two channels"; ++static char *bridge_descrip = ++"Usage: Bridge(channel[|options])\n" ++" Allows the ability to bridge two channels via the dialplan.\n" ++"The current channel is bridged to the specified 'channel'.\n" ++"The following options are supported:\n" ++" p - Play a courtesy tone to 'channel'.\n" ++"BRIDGERESULT dial plan variable will contain SUCCESS, FAILURE, LOOP, NONEXISTENT or INCOMPATIBLE.\n"; ++ ++enum { ++ BRIDGE_OPT_PLAYTONE = (1 << 0), ++}; ++ ++AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS ++ AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE) ++END_OPTIONS ); ++ ++static int bridge_exec(struct ast_channel *chan, void *data) ++{ ++ struct ast_module_user *u; ++ struct ast_channel *current_dest_chan, *final_dest_chan; ++ char *tmp_data = NULL; ++ struct ast_flags opts = { 0, }; ++ struct ast_bridge_config bconfig = { { 0, }, }; ++ ++ AST_DECLARE_APP_ARGS(args, ++ AST_APP_ARG(dest_chan); ++ AST_APP_ARG(options); ++ ); ++ ++ if (ast_strlen_zero(data)) { ++ ast_log(LOG_WARNING, "Bridge require at least 1 argument specifying the other end of the bridge\n"); ++ return -1; ++ } ++ ++ u = ast_module_user_add(chan); ++ ++ tmp_data = ast_strdupa(data); ++ AST_STANDARD_APP_ARGS(args, tmp_data); ++ if (!ast_strlen_zero(args.options)) ++ ast_app_parse_options(bridge_exec_options, &opts, NULL, args.options); ++ ++ /* avoid bridge with ourselves */ ++ if (!strncmp(chan->name, args.dest_chan, ++ strlen(chan->name) < strlen(args.dest_chan) ? ++ strlen(chan->name) : strlen(args.dest_chan))) { ++ ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name); ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", ++ "Response: Failed\r\n" ++ "Reason: Unable to bridge channel to itself\r\n" ++ "Channel1: %s\r\n" ++ "Channel2: %s\r\n", ++ chan->name, args.dest_chan); ++ pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP"); ++ ast_module_user_remove(u); ++ return 0; ++ } ++ ++ /* make sure we have a valid end point */ ++ if (!(current_dest_chan = ast_get_channel_by_name_prefix_locked(args.dest_chan, ++ strlen(args.dest_chan)))) { ++ ast_log(LOG_WARNING, "Bridge failed because channel %s does not exists or we " ++ "cannot get its lock\n", args.dest_chan); ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", ++ "Response: Failed\r\n" ++ "Reason: Cannot grab end point\r\n" ++ "Channel1: %s\r\n" ++ "Channel2: %s\r\n", chan->name, args.dest_chan); ++ pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT"); ++ ast_module_user_remove(u); ++ return 0; ++ } ++ ast_mutex_unlock(¤t_dest_chan->lock); ++ ++ /* answer the channel if needed */ ++ if (current_dest_chan->_state != AST_STATE_UP) ++ ast_answer(current_dest_chan); ++ ++ /* try to allocate a place holder where current_dest_chan will be placed */ ++ if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, ++ NULL, NULL, 0, "Bridge/%s", current_dest_chan->name))) { ++ ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan); ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", ++ "Response: Failed\r\n" ++ "Reason: cannot create placeholder\r\n" ++ "Channel1: %s\r\n" ++ "Channel2: %s\r\n", chan->name, args.dest_chan); ++ } ++ do_bridge_masquerade(current_dest_chan, final_dest_chan); ++ ++ /* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */ ++ /* try to make compatible, send error if we fail */ ++ if (ast_channel_make_compatible(chan, final_dest_chan) < 0) { ++ ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name); ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", ++ "Response: Failed\r\n" ++ "Reason: Could not make channels compatible for bridge\r\n" ++ "Channel1: %s\r\n" ++ "Channel2: %s\r\n", chan->name, final_dest_chan->name); ++ ast_hangup(final_dest_chan); /* may be we should return this channel to the PBX? */ ++ pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "INCOMPATIBLE"); ++ ast_module_user_remove(u); ++ return 0; ++ } ++ ++ /* Report that the bridge will be successfull */ ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", ++ "Response: Success\r\n" ++ "Channel1: %s\r\n" ++ "Channel2: %s\r\n", chan->name, final_dest_chan->name); ++ ++ /* we have 2 valid channels to bridge, now it is just a matter of setting up the bridge config and starting the bridge */ ++ if (ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE) && !ast_strlen_zero(xfersound)) { ++ if (!ast_streamfile(final_dest_chan, xfersound, final_dest_chan->language)) { ++ if (ast_waitstream(final_dest_chan, "") < 0) ++ ast_log(LOG_WARNING, "Failed to play courtesy tone on %s\n", final_dest_chan->name); ++ } ++ } ++ ++ /* do the bridge */ ++ ast_bridge_call(chan, final_dest_chan, &bconfig); ++ ++ /* the bridge has ended, set BRIDGERESULT to SUCCESS. If the other channel has not been hung up, return it to the PBX */ ++ pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS"); ++ if (!ast_check_hangup(final_dest_chan)) { ++ if (option_debug) { ++ ast_log(LOG_DEBUG, "starting new PBX in %s,%s,%d for chan %s\n", ++ final_dest_chan->context, final_dest_chan->exten, ++ final_dest_chan->priority, final_dest_chan->name); ++ } ++ ++ if (ast_pbx_start(final_dest_chan) != AST_PBX_SUCCESS) { ++ ast_log(LOG_WARNING, "FAILED continuing PBX on dest chan %s\n", final_dest_chan->name); ++ ast_hangup(final_dest_chan); ++ } else if (option_debug) ++ ast_log(LOG_DEBUG, "SUCCESS continuing PBX on chan %s\n", final_dest_chan->name); ++ } else { ++ if (option_debug) ++ ast_log(LOG_DEBUG, "hangup chan %s since the other endpoint has hung up\n", final_dest_chan->name); ++ ast_hangup(final_dest_chan); ++ } ++ ++ ast_module_user_remove(u); ++ ++ return 0; ++} ++ + static int reload(void) + { + autoanswer_reregister_extensions(); +@@ -3226,6 +3515,8 @@ static int load_module(void) + { + int res; + ++ ast_register_application(app_bridge, bridge_exec, bridge_synopsis, bridge_descrip); ++ + memset(parking_ext, 0, sizeof(parking_ext)); + memset(parking_con, 0, sizeof(parking_con)); + +@@ -3241,6 +3532,7 @@ static int load_module(void) + ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" ); + ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park, + "Park a channel", mandescr_park); ++ ast_manager_register2("Bridge", EVENT_FLAG_COMMAND, action_bridge, "Bridge two channels already in the PBX", mandescr_bridge); + } + + res |= ast_register_application(holdedcall, retrieve_call_exec, synopsis, descrip); +@@ -3261,9 +3553,11 @@ static int unload_module(void) + ast_module_user_hangup_all(); + + ast_manager_unregister("ParkedCalls"); ++ ast_manager_unregister("Bridge"); + ast_manager_unregister("Park"); + ast_cli_unregister_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry)); + ast_unregister_application(parkcall); ++ ast_unregister_application(app_bridge); + ast_unregister_application(autoanswer); + ast_unregister_application(autoanswerlogin); + ast_unregister_application(holdedcall); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/safe_asterisk-config +++ asterisk-1.4.21.2~dfsg/debian/patches/safe_asterisk-config @@ -0,0 +1,43 @@ +Use ASTSAFE_TTY and ASTSAFE_CONSOLE from /etc/default/asterisk to configure +safe_asterisk. + +Closes: #381786 + + -- Faidon Liambotis + +--- a/contrib/scripts/safe_asterisk ++++ b/contrib/scripts/safe_asterisk +@@ -1,9 +1,13 @@ + #!/bin/sh + # vim:textwidth=80:tabstop=4:shiftwidth=4:smartindent:autoindent + ++if [ -f /etc/default/asterisk ]; then ++ . /etc/default/asterisk; ++fi ++ + CLIARGS="$*" # Grab any args passed to safe_asterisk +-TTY=9 # TTY (if you want one) for Asterisk to run on +-CONSOLE=yes # Whether or not you want a console ++TTY=${ASTSAFE_TTY:-9} # TTY (if you want one) for Asterisk to run on ++CONSOLE=${ASTSAFE_CONSOLE:-yes} # Whether or not you want a console + #NOTIFY=ben@alkaloid.net # Who to notify about crashes + #EXEC=/path/to/somescript # Run this command if Asterisk crashes + MACHINE=`hostname` # To specify which machine has crashed when getting the mail +@@ -85,7 +89,7 @@ ulimit -c unlimited + # Don't fork when running "safely" + # + ASTARGS="" +-if [ "$TTY" != "" ]; then ++if [ "$TTY" != "no" ]; then + if [ -c /dev/tty${TTY} ]; then + TTY=tty${TTY} + elif [ -c /dev/vc/${TTY} ]; then +@@ -125,7 +129,7 @@ run_asterisk() + { + while :; do + +- if [ "$TTY" != "" ]; then ++ if [ "$TTY" != "no" ]; then + cd /tmp + stty sane < /dev/${TTY} + nice -n $PRIORITY ${ASTSBINDIR}/asterisk -f ${CLIARGS} ${ASTARGS} >& /dev/${TTY} < /dev/${TTY} --- asterisk-1.4.21.2~dfsg.orig/debian/patches/astgenkey-security +++ asterisk-1.4.21.2~dfsg/debian/patches/astgenkey-security @@ -0,0 +1,19 @@ +astgenkey should generate a private key that is not world-readable. + +Upstream bug: http://bugs.digium.com/view.php?id=12373 + + -- Lionel Elie Mamane + +--- a/contrib/scripts/astgenkey ++++ b/contrib/scripts/astgenkey +@@ -47,7 +47,10 @@ done + rm -f ${KEY}.key ${KEY}.pub + + echo "Generating SSL key '$KEY': " ++umask 0077 + openssl genrsa -out ${KEY}.key ${DES3} 1024 ++[ "$(id -u)" = 0 ] && chown asterisk:asterisk ${KEY}.key ++umask 0022 + openssl rsa -in ${KEY}.key -pubout -out ${KEY}.pub + + if [ -f "${KEY}.key" ] && [ -f "${KEY}.pub" ]; then --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/app-dial-c-callback +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/app-dial-c-callback @@ -0,0 +1,62 @@ +--- a/apps/app_dial.c ++++ b/apps/app_dial.c +@@ -201,7 +201,8 @@ static char *descrip = + " R - indicate ringing to the calling party when the called party indicates\n" + " ringing, pass no audio until answered.\n" + " S(x) - Hang up the call after 'x' seconds *after* the called party has\n" +-" answered the call.\n" ++" answered the call.\n" ++" c - callback initiation, ring once and hangup.\n" + " t - Allow the called party to transfer the calling party by sending the\n" + " DTMF sequence defined in features.conf.\n" + " T - Allow the calling party to transfer the called party by sending the\n" +@@ -257,6 +258,7 @@ enum { + OPT_CALLER_PARK = (1 << 26), + OPT_IGNORE_FORWARDING = (1 << 27), + OPT_NOINBAND = (1 << 28), ++ OPT_CALLBACK_INIT = (1 << 29), + } dial_exec_option_flags; + + #define DIAL_STILLGOING (1 << 30) +@@ -301,6 +303,7 @@ AST_APP_OPTIONS(dial_exec_options, { + AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY), + AST_APP_OPTION('r', OPT_RINGBACK), + AST_APP_OPTION('R', OPT_NOINBAND), ++ AST_APP_OPTION('c', OPT_CALLBACK_INIT), + AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP), + AST_APP_OPTION('t', OPT_CALLEE_TRANSFER), + AST_APP_OPTION('T', OPT_CALLER_TRANSFER), +@@ -621,14 +624,20 @@ static struct ast_channel *wait_for_answ + HANDLE_CAUSE(AST_CAUSE_CONGESTION, in); + break; + case AST_CONTROL_RINGING: +- if (option_verbose > 2) ++ if (ast_test_flag(peerflags, OPT_CALLBACK_INIT)) { ++ if (option_verbose > 2) ++ ast_verbose( VERBOSE_PREFIX_3 "%s is ringing, hanging up.\n", o->chan->name); ++ return NULL; ++ } else { ++ if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name); +- /* Setup early media if appropriate */ +- if (single && CAN_EARLY_BRIDGE(peerflags)) ++ /* Setup early media if appropriate */ ++ if (single && CAN_EARLY_BRIDGE(peerflags)) + ast_rtp_early_bridge(in, c); +- if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) { ++ if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) { + ast_indicate(in, AST_CONTROL_RINGING); + (*sentringing)++; ++ } + } + break; + case AST_CONTROL_PROGRESS: +@@ -1095,7 +1104,7 @@ static int dial_exec_full(struct ast_cha + outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"); + } + +- ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_NOINBAND); ++ ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_CALLBACK_INIT | OPT_NOINBAND); + /* loop through the list of dial destinations */ + rest = args.peers; + while ((cur = strsep(&rest, "&")) ) { --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/uniqueid-10-channel-ops-uniqueid +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/uniqueid-10-channel-ops-uniqueid @@ -0,0 +1,273 @@ +Add or convert channel operations so they can use the unique ID. + +--- a/include/asterisk/channel.h ++++ b/include/asterisk/channel.h +@@ -682,6 +682,18 @@ void ast_channel_free(struct ast_channe + */ + struct ast_channel *ast_request(const char *type, int format, void *data, int *status); + ++/*! \brief Requests a channel ++ * \param type type of channel to request ++ * \param format requested channel format (codec) ++ * \param data data to pass to the channel requester ++ * \param status status ++ * \param uniqueid uniqueid ++ * Request a channel of a given type, with data as optional information used ++ * by the low level module. Sets the channels uniqueid to 'uniqueid'. ++ * \return Returns an ast_channel on success, NULL on failure. ++ */ ++struct ast_channel *ast_request_with_uniqueid(const char *type, int format, void *data, int *status, char *uniqueid); ++ + /*! + * \brief Request a channel of a given type, with data as optional information used + * by the low level module and attempt to place a call on it +@@ -697,8 +709,12 @@ struct ast_channel *ast_request(const ch + */ + struct ast_channel *ast_request_and_dial(const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname); + ++struct ast_channel *ast_request_and_dial_uniqueid(const char *type, int format, void *data, int timeout, int *reason, int callingpres, const char *cidnum, const char *cidname, char *uniqueid); ++ + struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, struct outgoing_helper *oh); + ++struct ast_channel *__ast_request_and_dial_uniqueid(const char *type, int format, void *data, int timeout, int *reason, int callingpres, const char *cidnum, const char *cidname, struct outgoing_helper *oh, char *uniqueid); ++ + /*! \brief "Requests" a channel for sending a message + * \param type type of channel to request + * \param data data to pass to the channel requester +@@ -990,6 +1006,8 @@ struct ast_channel *ast_get_channel_by_e + /*! \brief Get next channel by exten (and optionally context) and lock it */ + struct ast_channel *ast_walk_channel_by_exten_locked(const struct ast_channel *chan, const char *exten, + const char *context); ++/*! Get channel by uniqueid (locks channel) */ ++struct ast_channel *ast_get_channel_by_uniqueid_locked(const char *uniqueid); + + /*! ! \brief Waits for a digit + * \param c channel to wait for a digit on +--- a/main/channel.c ++++ b/main/channel.c +@@ -1017,7 +1017,7 @@ void ast_channel_undefer_dtmf(struct ast + */ + static struct ast_channel *channel_find_locked(const struct ast_channel *prev, + const char *name, const int namelen, +- const char *context, const char *exten) ++ const char *context, const char *exten, const char *uniqueid) + { + const char *msg = prev ? "deadlock" : "initial deadlock"; + int retries; +@@ -1045,7 +1045,10 @@ static struct ast_channel *channel_find_ + * XXX Need a better explanation for this ... + */ + } +- if (name) { /* want match by name */ ++ if (uniqueid) { ++ if (!strcasecmp(c->uniqueid, uniqueid)) ++ break; ++ } else if (name) { /* want match by name */ + if ((!namelen && strcasecmp(c->name, name)) || + (namelen && strncasecmp(c->name, name, namelen))) + continue; /* name match failed */ +@@ -1100,39 +1103,44 @@ static struct ast_channel *channel_find_ + /*! \brief Browse channels in use */ + struct ast_channel *ast_channel_walk_locked(const struct ast_channel *prev) + { +- return channel_find_locked(prev, NULL, 0, NULL, NULL); ++ return channel_find_locked(prev, NULL, 0, NULL, NULL, NULL); + } + + /*! \brief Get channel by name and lock it */ + struct ast_channel *ast_get_channel_by_name_locked(const char *name) + { +- return channel_find_locked(NULL, name, 0, NULL, NULL); ++ return channel_find_locked(NULL, name, 0, NULL, NULL, NULL); + } + + /*! \brief Get channel by name prefix and lock it */ + struct ast_channel *ast_get_channel_by_name_prefix_locked(const char *name, const int namelen) + { +- return channel_find_locked(NULL, name, namelen, NULL, NULL); ++ return channel_find_locked(NULL, name, namelen, NULL, NULL, NULL); + } + + /*! \brief Get next channel by name prefix and lock it */ + struct ast_channel *ast_walk_channel_by_name_prefix_locked(const struct ast_channel *chan, const char *name, + const int namelen) + { +- return channel_find_locked(chan, name, namelen, NULL, NULL); ++ return channel_find_locked(chan, name, namelen, NULL, NULL, NULL); + } + + /*! \brief Get channel by exten (and optionally context) and lock it */ + struct ast_channel *ast_get_channel_by_exten_locked(const char *exten, const char *context) + { +- return channel_find_locked(NULL, NULL, 0, context, exten); ++ return channel_find_locked(NULL, NULL, 0, context, exten, NULL); + } + + /*! \brief Get next channel by exten (and optionally context) and lock it */ + struct ast_channel *ast_walk_channel_by_exten_locked(const struct ast_channel *chan, const char *exten, + const char *context) + { +- return channel_find_locked(chan, NULL, 0, context, exten); ++ return channel_find_locked(chan, NULL, 0, context, exten, NULL); ++} ++ ++struct ast_channel *ast_get_channel_by_uniqueid_locked(const char *uniqueid) ++{ ++ return channel_find_locked(NULL, NULL, 0, NULL, NULL, uniqueid); + } + + /*! \brief Wait, look for hangups and condition arg */ +@@ -2862,6 +2870,12 @@ char *ast_channel_reason2str(int reason) + + struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh) + { ++ return __ast_request_and_dial_uniqueid(type, format, data, ++ timeout, outstate, 0, cid_num, cid_name, oh, NULL); ++} ++ ++struct ast_channel *__ast_request_and_dial_uniqueid(const char *type, int format, void *data, int timeout, int *outstate, int callingpres, const char *cid_num, const char *cid_name, struct outgoing_helper *oh, char* uniqueid) ++{ + int dummy_outstate; + int cause = 0; + struct ast_channel *chan; +@@ -2873,7 +2887,7 @@ struct ast_channel *__ast_request_and_di + else + outstate = &dummy_outstate; /* make outstate always a valid pointer */ + +- chan = ast_request(type, format, data, &cause); ++ chan = ast_request_with_uniqueid(type, format, data, &cause, uniqueid); + if (!chan) { + ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); + /* compute error and return */ +@@ -2993,8 +3007,12 @@ struct ast_channel *ast_request_and_dial + { + return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL); + } ++struct ast_channel *ast_request_and_dial_uniqueid(const char *type, int format, void *data, int timeout, int *outstate, int callingpres, const char *cidnum, const char *cidname, char *uniqueid) ++{ ++ return __ast_request_and_dial_uniqueid(type, format, data, timeout, outstate, 0, cidnum, cidname, NULL, uniqueid); ++} + +-struct ast_channel *ast_request(const char *type, int format, void *data, int *cause) ++struct ast_channel *ast_request_with_uniqueid(const char *type, int format, void *data, int *cause, char *uniqueid) + { + struct chanlist *chan; + struct ast_channel *c; +@@ -3033,6 +3051,7 @@ struct ast_channel *ast_request(const ch + if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause))) + return NULL; + ++ if (uniqueid) strncpy(c->uniqueid, uniqueid, sizeof(c->uniqueid)); + /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ + return c; + } +@@ -3044,6 +3063,11 @@ struct ast_channel *ast_request(const ch + return NULL; + } + ++struct ast_channel *ast_request(const char *type, int format, void *data, int *cause) ++{ ++ return ast_request_with_uniqueid(type, format, data, cause, NULL); ++} ++ + int ast_call(struct ast_channel *chan, char *addr, int timeout) + { + /* Place an outgoing call, but don't wait any longer than timeout ms before returning. +--- a/include/asterisk/pbx.h ++++ b/include/asterisk/pbx.h +@@ -717,9 +717,17 @@ int ast_async_goto_by_name(const char *c + int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel); + + /*! Synchronously or asynchronously make an outbound call and send it to a ++ particular extension (extended version with callinpres and uniqueid) */ ++int ast_pbx_outgoing_exten_uniqueid(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, char *uniqueid); ++ ++/*! Synchronously or asynchronously make an outbound call and send it to a + particular application with given extension */ + int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel); + ++/*! Synchronously or asynchronously make an outbound call and send it to a ++ particular application with given extension (extended version with callinpres and uniqueid) */ ++int ast_pbx_outgoing_app_uniqueid(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, char *uniqueid); ++ + /*! + * \brief Evaluate a condition + * +--- a/main/pbx.c ++++ b/main/pbx.c +@@ -4992,7 +4992,7 @@ static int ast_pbx_outgoing_cdr_failed(v + return 0; /* success */ + } + +-int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel) ++int ast_pbx_outgoing_exten_uniqueid(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel, char *uniqueid) + { + struct ast_channel *chan; + struct async_stat *as; +@@ -5002,7 +5002,7 @@ int ast_pbx_outgoing_exten(const char *t + + if (sync) { + LOAD_OH(oh); +- chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); ++ chan = __ast_request_and_dial_uniqueid(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid); + if (channel) { + *channel = chan; + if (chan) +@@ -5094,7 +5094,7 @@ int ast_pbx_outgoing_exten(const char *t + res = -1; + goto outgoing_exten_cleanup; + } +- chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); ++ chan = ast_request_and_dial_uniqueid(type, format, data, timeout, reason, callingpres, cid_num, cid_name, uniqueid); + if (channel) { + *channel = chan; + if (chan) +@@ -5134,6 +5134,10 @@ outgoing_exten_cleanup: + return res; + } + ++int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel) ++{ ++ return ast_pbx_outgoing_exten_uniqueid(type, format, data, timeout, context, exten, priority, reason, sync, 0, cid_num, cid_name, vars, account, channel, NULL); ++} + struct app_tmp { + char app[256]; + char data[256]; +@@ -5158,7 +5162,7 @@ static void *ast_pbx_run_app(void *data) + return NULL; + } + +-int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) ++int ast_pbx_outgoing_app_uniqueid(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, char *uniqueid) + { + struct ast_channel *chan; + struct app_tmp *tmp; +@@ -5177,7 +5181,7 @@ int ast_pbx_outgoing_app(const char *typ + goto outgoing_app_cleanup; + } + if (sync) { +- chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); ++ chan = __ast_request_and_dial_uniqueid(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid); + if (chan) { + if (!chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ + chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ +@@ -5259,7 +5263,7 @@ int ast_pbx_outgoing_app(const char *typ + res = -1; + goto outgoing_app_cleanup; + } +- chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); ++ chan = __ast_request_and_dial_uniqueid(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid); + if (!chan) { + free(as); + res = -1; +@@ -5299,6 +5303,10 @@ outgoing_app_cleanup: + return res; + } + ++int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) ++{ ++ return ast_pbx_outgoing_app_uniqueid(type, format, data, timeout, app, appdata, reason, sync, 0, cid_num, cid_name, vars, account, locked_channel, NULL); ++} + void __ast_context_destroy(struct ast_context *con, const char *registrar) + { + struct ast_context *tmp, *tmpl=NULL; --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/uniqueid-40-manager +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/uniqueid-40-manager @@ -0,0 +1,242 @@ +--- a/main/manager.c ++++ b/main/manager.c +@@ -87,6 +87,8 @@ struct fast_originate_helper { + char idtext[AST_MAX_EXTENSION]; + char account[AST_MAX_ACCOUNT_CODE]; + int priority; ++ int callingpres; ++ char uniqueid[64]; + struct ast_variable *vars; + }; + +@@ -1419,11 +1421,20 @@ static int action_hangup(struct mansessi + { + struct ast_channel *c = NULL; + const char *name = astman_get_header(m, "Channel"); +- if (ast_strlen_zero(name)) { +- astman_send_error(s, m, "No channel specified"); ++ const char *uniqueid = astman_get_header(m, "Uniqueid"); ++ ++ if (ast_strlen_zero(name) && ast_strlen_zero(uniqueid)) { ++ astman_send_error(s, m, "No channel or uniqueid specified"); + return 0; + } +- c = ast_get_channel_by_name_locked(name); ++ ++ if (!ast_strlen_zero(uniqueid)) { ++ c = ast_get_channel_by_uniqueid_locked(uniqueid); ++ } else { ++ if (!ast_strlen_zero(name)) ++ c = ast_get_channel_by_name_locked(name); ++ } ++ + if (!c) { + astman_send_error(s, m, "No such channel"); + return 0; +@@ -1674,12 +1685,18 @@ static int action_redirect(struct manses + const char *exten = astman_get_header(m, "Exten"); + const char *context = astman_get_header(m, "Context"); + const char *priority = astman_get_header(m, "Priority"); ++ const char *uniqueid = astman_get_header(m, "Uniqueid"); ++ const char *uniqueid2 = astman_get_header(m, "ExtraUniqueid"); ++ const char *exten2 = astman_get_header(m, "ExtraExten"); ++ const char *context2 = astman_get_header(m, "ExtraContext"); ++ const char *priority2 = astman_get_header(m, "ExtraPriority"); + struct ast_channel *chan, *chan2 = NULL; + int pi = 0; ++ int pi2 = 0; + int res; + +- if (ast_strlen_zero(name)) { +- astman_send_error(s, m, "Channel not specified"); ++ if (ast_strlen_zero(name) && ast_strlen_zero(uniqueid)) { ++ astman_send_error(s, m, "Channel or Uniqueid not specified"); + return 0; + } + if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { +@@ -1688,8 +1705,18 @@ static int action_redirect(struct manses + return 0; + } + } ++ if (!ast_strlen_zero(priority2) && (sscanf(priority2, "%d", &pi2) != 1)) { ++ if ((pi = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL)) < 1) { ++ astman_send_error(s, m, "Invalid extra priority\n"); ++ return 0; ++ } ++ } + /* XXX watch out, possible deadlock!!! */ +- chan = ast_get_channel_by_name_locked(name); ++ if (!ast_strlen_zero(uniqueid)) { ++ chan = ast_get_channel_by_uniqueid_locked(uniqueid); ++ } else { ++ chan = ast_get_channel_by_name_locked(name); ++ } + if (!chan) { + char buf[BUFSIZ]; + snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); +@@ -1701,8 +1728,11 @@ static int action_redirect(struct manses + ast_channel_unlock(chan); + return 0; + } +- if (!ast_strlen_zero(name2)) ++ if (!ast_strlen_zero(uniqueid2)) { ++ chan2 = ast_get_channel_by_uniqueid_locked(uniqueid2); ++ } else if (!ast_strlen_zero(name2)) { + chan2 = ast_get_channel_by_name_locked(name2); ++ } + if (chan2 && ast_check_hangup(chan2)) { + astman_send_error(s, m, "Redirect failed, extra channel not up.\n"); + ast_channel_unlock(chan); +@@ -1711,9 +1741,9 @@ static int action_redirect(struct manses + } + res = ast_async_goto(chan, context, exten, pi); + if (!res) { +- if (!ast_strlen_zero(name2)) { ++ if ((!ast_strlen_zero(name2)) || (!ast_strlen_zero(uniqueid2))){ + if (chan2) +- res = ast_async_goto(chan2, context, exten, pi); ++ res = ast_async_goto(chan2, context2, exten2, pi2); + else + res = -1; + if (!res) +@@ -1830,15 +1860,15 @@ static void *fast_originate(void *data) + char requested_channel[AST_CHANNEL_NAME]; + + if (!ast_strlen_zero(in->app)) { +- res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, ++ res = ast_pbx_outgoing_app_uniqueid(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, in->callingpres, + S_OR(in->cid_num, NULL), + S_OR(in->cid_name, NULL), +- in->vars, in->account, &chan); ++ in->vars, in->account, &chan, in->uniqueid); + } else { +- res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, ++ res = ast_pbx_outgoing_exten_uniqueid(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, in->callingpres, + S_OR(in->cid_num, NULL), + S_OR(in->cid_name, NULL), +- in->vars, in->account, &chan); ++ in->vars, in->account, &chan, in->uniqueid); + } + + if (!chan) +@@ -1898,6 +1928,7 @@ static int action_originate(struct manse + const char *appdata = astman_get_header(m, "Data"); + const char *async = astman_get_header(m, "Async"); + const char *id = astman_get_header(m, "ActionID"); ++ const char *callingpres = astman_get_header(m, "CallingPres"); + struct ast_variable *vars = astman_get_variables(m); + char *tech, *data; + char *l = NULL, *n = NULL; +@@ -1907,6 +1938,9 @@ static int action_originate(struct manse + int reason = 0; + char tmp[256]; + char tmp2[256]; ++ char *uniqueid; ++ int cpresi = 0; ++ char idText[256] = ""; + + pthread_t th; + pthread_attr_t attr; +@@ -1924,6 +1958,10 @@ static int action_originate(struct manse + astman_send_error(s, m, "Invalid timeout\n"); + return 0; + } ++ if (!ast_strlen_zero(callingpres) && (sscanf(callingpres, "%d", &cpresi) != 1)) { ++ astman_send_error(s, m, "Invalid CallingPres\n"); ++ return 0; ++ } + ast_copy_string(tmp, name, sizeof(tmp)); + tech = tmp; + data = strchr(tmp, '/'); +@@ -1943,6 +1981,7 @@ static int action_originate(struct manse + if (ast_strlen_zero(l)) + l = NULL; + } ++ uniqueid = ast_alloc_uniqueid(); + if (ast_true(async)) { + struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); + if (!fast) { +@@ -1962,8 +2001,10 @@ static int action_originate(struct manse + ast_copy_string(fast->context, context, sizeof(fast->context)); + ast_copy_string(fast->exten, exten, sizeof(fast->exten)); + ast_copy_string(fast->account, account, sizeof(fast->account)); ++ ast_copy_string(fast->uniqueid, uniqueid, sizeof(fast->uniqueid)); + fast->timeout = to; + fast->priority = pi; ++ fast->callingpres = cpresi; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (ast_pthread_create(&th, &attr, fast_originate, fast)) { +@@ -1974,19 +2015,28 @@ static int action_originate(struct manse + pthread_attr_destroy(&attr); + } + } else if (!ast_strlen_zero(app)) { +- res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); ++ res = ast_pbx_outgoing_app_uniqueid(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, cpresi, l, n, vars, account, NULL, uniqueid); + } else { + if (exten && context && pi) +- res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); ++ res = ast_pbx_outgoing_exten_uniqueid(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, cpresi, l, n, vars, account, NULL, uniqueid); + else { + astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); + return 0; + } + } +- if (!res) +- astman_send_ack(s, m, "Originate successfully queued"); +- else ++ if (!res) { ++ if (id && !ast_strlen_zero(id)) { ++ snprintf(idText,256,"ActionID: %s\r\n",id); ++ } ++ ast_cli(s->fd, "Response: Success\r\n" ++ "%s" ++ "Message: Originate successfully queued\r\n" ++ "Uniqueid: %s\r\n" ++ "\r\n", ++ idText, uniqueid); ++ } else { + astman_send_error(s, m, "Originate failed"); ++ } + return 0; + } + +--- a/include/asterisk/channel.h ++++ b/include/asterisk/channel.h +@@ -89,6 +89,9 @@ + + #include "asterisk/abstract_jb.h" + ++/* Max length of the uniqueid */ ++#define AST_MAX_UNIQUEID 64 ++ + #include + #ifdef POLLCOMPAT + #include "asterisk/poll-compat.h" +@@ -1039,6 +1042,8 @@ int ast_waitfordigit_full(struct ast_cha + int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders); + int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders, int audiofd, int ctrlfd); + ++char *ast_alloc_uniqueid(void); ++ + /*! \brief Report DTMF on channel 0 */ + #define AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0) + /*! \brief Report DTMF on channel 1 */ +--- a/main/channel.c ++++ b/main/channel.c +@@ -706,6 +706,15 @@ static const struct ast_channel_tech nul + .description = "Null channel (should not see this)", + }; + ++/*! \brief Create a uniqueid */ ++char *ast_alloc_uniqueid(void) { ++ char *uniqueid; ++ uniqueid = malloc(64); ++ if (!uniqueid) return NULL; ++ snprintf(uniqueid, 63, "%s-%d-%li.%d", ast_config_AST_SYSTEM_NAME, ast_mainpid, (long)time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1)); ++ return uniqueid; ++} ++ + /*! \brief Create a new channel structure */ + struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt, ...) + { --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/zapata-gsm +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/zapata-gsm @@ -0,0 +1,1057 @@ +--- a/channels/chan_zap.c ++++ b/channels/chan_zap.c +@@ -77,6 +77,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi + #ifdef HAVE_PRI + #include + #endif ++#ifdef HAVE_GSMAT ++#include ++#endif + + #include "asterisk/lock.h" + #include "asterisk/channel.h" +@@ -185,6 +188,7 @@ static const char config[] = "zapata.con + #define SIG_FXOGS ZT_SIG_FXOGS + #define SIG_FXOKS ZT_SIG_FXOKS + #define SIG_PRI ZT_SIG_CLEAR ++#define SIG_GSM (0x100000 | ZT_SIG_CLEAR) + #define SIG_SF ZT_SIG_SF + #define SIG_SFWINK (0x0100000 | ZT_SIG_SF) + #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) +@@ -234,6 +238,8 @@ static int matchdigittimeout = 3000; + /*! \brief Protect the interface list (of zt_pvt's) */ + AST_MUTEX_DEFINE_STATIC(iflock); + ++static char gsm_modem_pin[20]; ++static char gsm_modem_exten[AST_MAX_EXTENSION]; + + static int ifcount = 0; + +@@ -251,6 +257,7 @@ static enum ast_bridge_result zt_bridge( + + static int zt_sendtext(struct ast_channel *c, const char *text); + ++static int zt_sendmessage(struct ast_channel *c, const char *dest, const char *text, int ispdu); + + /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */ + static inline int zt_get_event(int fd) +@@ -350,6 +357,19 @@ struct zt_pri { + int debugfd; + }; + ++#ifdef HAVE_GSMAT ++struct zt_gsm { ++ pthread_t master; ++ ast_mutex_t lock; /* Mutex */ ++ int fd; ++ int span; ++ struct gsm_modul *modul; ++ char pin[256]; ++ int available; ++ char exten[AST_MAX_EXTENSION]; /* Where to idle extra calls */ ++ struct zt_pvt *pvt; ++}; ++#endif + + static struct zt_pri pris[NUM_SPANS]; + +@@ -378,6 +398,7 @@ struct zt_pri; + #define POLARITY_REV 1 + + ++ + static struct zt_distRings drings; + + struct distRingData { +@@ -590,6 +611,9 @@ static struct zt_pvt { + int prioffset; + int logicalspan; + #endif ++#ifdef HAVE_GSMAT ++ struct zt_gsm gsm; ++#endif + int polarity; + int dsp_features; + char begindigit; +@@ -696,7 +720,7 @@ static struct zt_chan_conf zt_chan_conf_ + static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause); + static int zt_digit_begin(struct ast_channel *ast, char digit); + static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration); +-static int zt_sendtext(struct ast_channel *c, const char *text); ++static int zt_sendmessage(struct ast_channel *c, const char *dest, const char *text, int ispdu); + static int zt_call(struct ast_channel *ast, char *rdest, int timeout); + static int zt_hangup(struct ast_channel *ast); + static int zt_answer(struct ast_channel *ast); +@@ -718,6 +742,9 @@ static const struct ast_channel_tech zap + .send_digit_begin = zt_digit_begin, + .send_digit_end = zt_digit_end, + .send_text = zt_sendtext, ++#if 0 /* we (Debian) disable that addition because of ABI breakage */ ++ .send_message = zt_sendmessage, ++#endif + .call = zt_call, + .hangup = zt_hangup, + .answer = zt_answer, +@@ -1241,6 +1268,8 @@ static char *zap_sig2str(int sig) + return "GR-303 with FXOKS"; + case SIG_GR303FXSKS: + return "GR-303 with FXSKS"; ++ case SIG_GSM: ++ return "GSM"; + case 0: + return "Pseudo"; + default: +@@ -1662,7 +1691,7 @@ static inline int zt_confmute(struct zt_ + { + int x, y, res; + x = muted; +- if (p->sig == SIG_PRI) { ++ if ((p->sig == SIG_PRI) || (p->sig == SIG_GSM)) { + y = 1; + res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y); + if (res) +@@ -2077,6 +2106,25 @@ static int zt_call(struct ast_channel *a + p->dialdest[0] = '\0'; + disable_dtmf_detect(p); + break; ++ case SIG_GSM: ++#ifdef HAVE_GSMAT ++ if (p->gsm.modul) { ++ c = strchr(dest, '/'); ++ if (c) ++ c++; ++ else ++ c = dest; ++ ast_mutex_lock(&p->gsm.lock); ++ if (gsm_dial(p->gsm.modul, p->use_callingpres ? ast->cid.cid_pres : 0, c)) { ++ ast_log(LOG_WARNING, "dialing failed on channel %d\n", p->channel); ++ ast_mutex_unlock(&p->gsm.lock); ++ ast_mutex_unlock(&p->lock); ++ return -1; ++ } ++ ast_mutex_unlock(&p->gsm.lock); ++ } ++#endif ++ break; + default: + ast_log(LOG_DEBUG, "not yet implemented\n"); + ast_mutex_unlock(&p->lock); +@@ -2719,7 +2767,13 @@ static int zt_hangup(struct ast_channel + } + } + #endif +- if (p->sig && (p->sig != SIG_PRI)) ++#ifdef HAVE_GSMAT ++ if (p->gsm.modul) { ++ if (!p->alreadyhungup) ++ gsm_hangup(p->gsm.modul); ++ } ++#endif ++ if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_GSM)) + res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); + if (res < 0) { + ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); +@@ -2896,6 +2950,13 @@ static int zt_answer(struct ast_channel + zt_train_ec(p); + break; + #endif ++#ifdef HAVE_GSMAT ++ case SIG_GSM: ++ if (p->gsm.modul) { ++ gsm_answer(p->gsm.modul); ++ } ++ break; ++#endif + case 0: + ast_mutex_unlock(&p->lock); + return 0; +@@ -7278,6 +7339,10 @@ static int pri_create_spanmap(int span, + + #endif + ++#ifdef HAVE_GSMAT ++static void *gsm_dchannel(void *vgsm); ++#endif ++ + static struct zt_pvt *mkintf(int channel, const struct zt_chan_conf *conf, struct zt_pri *pri, int reloading) + { + /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ +@@ -7506,6 +7571,37 @@ static struct zt_pvt *mkintf(int channel + tmp->prioffset = 0; + } + #endif ++#ifdef HAVE_GSMAT ++ if (conf->chan.sig == SIG_GSM) { ++ struct zt_bufferinfo bi; ++ ast_mutex_init(&tmp->gsm.lock); ++ strncpy(tmp->gsm.pin, gsm_modem_pin, sizeof(tmp->gsm.pin) - 1); ++ strncpy(tmp->gsm.exten, gsm_modem_exten, sizeof(tmp->gsm.exten) - 1); ++ tmp->gsm.available = 0; ++ snprintf(fn, sizeof(fn), "%d", channel + 1); ++ /* Open non-blocking */ ++ tmp->gsm.fd = zt_open(fn); ++ bi.txbufpolicy = ZT_POLICY_IMMEDIATE; ++ bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; ++ bi.numbufs = 16; ++ bi.bufsize = 1024; ++ if (ioctl(tmp->gsm.fd, ZT_SET_BUFINFO, &bi)) { ++ ast_log(LOG_ERROR, "Unable to set buffer info on channel '%s': %s\n", fn, strerror(errno)); ++ return NULL; ++ } ++ tmp->gsm.pvt = tmp; ++ tmp->gsm.span = tmp->span; ++ tmp->gsm.modul = gsm_new(tmp->gsm.fd, 0, tmp->gsm.pin, tmp->span, tmp->channel); ++ if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, tmp->channel)) { ++ ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d: %s\n", tmp->channel, strerror(errno)); ++ destroy_zt_pvt(&tmp); ++ return NULL; ++ } ++ if (ast_pthread_create(&tmp->gsm.master, NULL, gsm_dchannel, &tmp->gsm)) { ++ zt_close(tmp->gsm.fd); ++ } ++ } ++#endif + } else { + chan_sig = tmp->sig; + memset(&p, 0, sizeof(p)); +@@ -7806,6 +7902,12 @@ static inline int available(struct zt_pv + return 1; + } + #endif ++#ifdef HAVE_GSMAT ++ if (p->gsm.modul) { ++ return gsm_available(p->gsm.modul); ++ } ++ ++#endif + if (!(p->radio || (p->oprmode < 0))) + { + if (!p->sig || (p->sig == SIG_FXSLS)) +@@ -8163,6 +8265,235 @@ next: + return tmp; + } + ++#ifdef HAVE_GSMAT ++static int zt_reset_span(int span, int sleep) { ++ int ctl; ++ int res; ++ ++ ctl = open("/dev/zap/ctl", O_RDWR); ++ if (ctl < 0) { ++ ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); ++ return -1; ++ } ++ ast_verbose(VERBOSE_PREFIX_2 "Shutting down span %d. Please wait...\n", span); ++ res = ioctl(ctl, ZT_SHUTDOWN, &span); ++ if (res) { ++ ast_log(LOG_WARNING, "error shutting down span %d\n", span); ++ return -1; ++ } ++ usleep(sleep * 1000); ++ ast_verbose(VERBOSE_PREFIX_2 "Starting up span %d. Please wait...\n", span); ++ res = ioctl(ctl, ZT_STARTUP, &span); ++ if (res) { ++ ast_log(LOG_WARNING, "error starting up span %d\n", span); ++ return -1; ++ } ++ ast_verbose(VERBOSE_PREFIX_2 "Reset of span %d completed.\n", span); ++ return 0; ++} ++ ++ ++static void handle_gsm_event(struct zt_gsm *gsm, gsm_event *e) ++{ ++ struct ast_channel *c = NULL; ++ int law = ZT_LAW_ALAW; ++ int res = 0; ++ ++ switch(e->e) { ++ case GSM_EVENT_DCHAN_UP: ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d registered to network!\n", gsm->span); ++ gsm->available = 1; ++ break; ++ case GSM_EVENT_DCHAN_DOWN: ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d unregistered from network!\n", gsm->span); ++ gsm->available = 0; ++/* ast_mutex_lock(&gsm->pvt->lock); ++ gsm->pvt->alreadyhungup = 1; ++ if (gsm->pvt->owner) { ++ gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; ++ } ++ ast_mutex_unlock(&gsm->pvt->lock); */ ++ break; ++ case GSM_EVENT_RING: ++ ast_mutex_lock(&gsm->pvt->lock); ++ if (!ast_strlen_zero(e->ring.callingnum)) { ++ strncpy(gsm->pvt->cid_num, e->ring.callingnum, sizeof(gsm->pvt->cid_num) - 1); ++ } else { ++ strncpy(gsm->pvt->cid_name, "CID withheld", sizeof(gsm->pvt->cid_name)); ++ } ++ if (!ast_strlen_zero(gsm->exten)) { ++ strncpy(gsm->pvt->exten, gsm->exten, sizeof(gsm->pvt->exten) - 1); ++ } else { ++ gsm->pvt->exten[0] = 's'; ++ gsm->pvt->exten[1] = '\0'; ++ } ++ c = zt_new(gsm->pvt, AST_STATE_RING, 1, SUB_REAL, ZT_LAW_ALAW, AST_TRANS_CAP_SPEECH); ++ if (c) { ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Ring on channel %d (from %s to %s)\n", e->ring.channel, e->ring.callingnum, gsm->exten); ++ gsm->pvt->owner = c; ++ if (ioctl(gsm->pvt->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1) ++ ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", gsm->pvt->channel, law); ++ res = zt_setlaw(gsm->pvt->subs[SUB_REAL].zfd, law); ++ res = set_actual_gain(gsm->pvt->subs[SUB_REAL].zfd, 0, gsm->pvt->rxgain, gsm->pvt->txgain, law); ++ if (res < 0) { ++ ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", gsm->pvt->channel); ++// } else { ++// ast_log(LOG_NOTICE, "tx gain %f rx gain %f law %d pvt->law %d\n", gsm->pvt->txgain, gsm->pvt->rxgain, law, gsm->pvt->law); ++ } ++ } ++ ast_mutex_unlock(&gsm->pvt->lock); ++ break; ++ case GSM_EVENT_HANGUP: ++ ast_verbose(VERBOSE_PREFIX_3 "Got hang up on channel %d\n", e->hangup.channel); ++ ast_mutex_lock(&gsm->pvt->lock); ++ gsm->pvt->alreadyhungup = 1; ++ if (gsm->pvt->owner) { ++ gsm->pvt->owner->hangupcause = e->hangup.cause; ++ gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; ++ } ++ ast_mutex_unlock(&gsm->pvt->lock); ++ break; ++ case GSM_EVENT_ERROR: ++ ast_log(LOG_WARNING, "Got error on channel\n"); ++ ast_mutex_lock(&gsm->pvt->lock); ++ gsm->pvt->alreadyhungup = 1; ++ if (gsm->pvt->owner) { ++ gsm->pvt->owner->hangupcause = e->error.cause; ++ gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; ++ } ++ ast_mutex_unlock(&gsm->pvt->lock); ++ if (e->error.hard) { ++// gsm_poweroff(gsm->modul); ++ zt_reset_span(gsm->span, 8000); ++// gsm_restart(gsm->modul, 10000); ++ } else { ++// gsm_poweroff(gsm->modul); ++ zt_reset_span(gsm->span, 8000); ++// gsm_restart(gsm->modul, 10000); ++ } ++ break; ++ case GSM_EVENT_ALERTING: ++ ast_mutex_lock(&gsm->pvt->lock); ++ gsm->pvt->subs[SUB_REAL].needringing =1; ++ ast_mutex_unlock(&gsm->pvt->lock); ++ break; ++ case GSM_EVENT_ANSWER: ++ ast_mutex_lock(&gsm->pvt->lock); ++ gsm->pvt->dialing = 0; ++ gsm->pvt->subs[SUB_REAL].needanswer =1; ++ gsm->pvt->ignoredtmf = 0; ++ ast_mutex_unlock(&gsm->pvt->lock); ++ break; ++ case GSM_EVENT_PIN_REQUIRED: ++ gsm_send_pin(gsm->modul, gsm->pin); ++ break; ++ case GSM_EVENT_SM_RECEIVED: ++ ast_verbose(VERBOSE_PREFIX_3 "SMS from %s received on span %d. (Text: %s) (PDU: %s)\n", e->sm_received.sender, gsm->span, e->sm_received.text, e->sm_received.pdu); ++ manager_event(EVENT_FLAG_CALL, "Message received", ++ "Span: %d\r\n" ++ "Sender: %s\r\n" ++ "SMSC: %s\r\n" ++ "Length: %d\r\n" ++ "Text: %s\r\n" ++ "PDU: %s\r\n", ++ gsm->span, ++ e->sm_received.sender, ++ e->sm_received.smsc, ++ e->sm_received.len, ++ e->sm_received.text, ++ e->sm_received.pdu); ++ break; ++ default: ++ ast_log(LOG_WARNING,"!! Unknown GSM event %d !!\n", e->e); ++ } ++} ++ ++static void *gsm_dchannel(void *vgsm) ++{ ++ struct zt_gsm *gsm = vgsm; ++ gsm_event *e; ++ struct timeval tv = {0,0}, *next; ++ fd_set rfds, efds; ++ int res,x; ++ ++ if (!gsm) return NULL; ++ ++ if (!gsm->modul) { ++ fprintf(stderr, "No gsm_mod\n"); ++ return NULL; ++ } ++ gsm_set_debug(gsm->modul, GSM_DEBUG_NONE); ++ for (;;) { ++ ++ /* Run the D-Channel */ ++ FD_ZERO(&rfds); ++ FD_ZERO(&efds); ++ FD_SET(gsm->fd, &rfds); ++ FD_SET(gsm->fd, &efds); ++ ++ if ((next = gsm_schedule_next(gsm->modul))) { ++ gettimeofday(&tv, NULL); ++ tv.tv_sec = next->tv_sec - tv.tv_sec; ++ tv.tv_usec = next->tv_usec - tv.tv_usec; ++ if (tv.tv_usec < 0) { ++ tv.tv_usec += 1000000; ++ tv.tv_sec -= 1; ++ } ++ if (tv.tv_sec < 0) { ++ tv.tv_sec = 0; ++ tv.tv_usec = 0; ++ } ++ } ++ res = select(gsm->fd + 1, &rfds, NULL, &efds, next ? &tv : NULL); ++ e = NULL; ++ ++ ast_mutex_lock(&gsm->lock); ++ if (!res) { ++ e = gsm_schedule_run(gsm->modul); ++ } else if (res > 0) { ++ e = gsm_check_event(gsm->modul, 1); ++ } else if (errno == ELAST) { ++ res = ioctl(gsm->fd, ZT_GETEVENT, &x); ++ printf("Got Zaptel event: %d\n", x); ++ } else if (errno != EINTR) ++ fprintf(stderr, "Error (%d) on select: %s\n", ELAST, strerror(errno)); ++ ++ if (!e) { ++ e = gsm_check_event(gsm->modul, 0); ++ } ++ ++ if (e) { ++ handle_gsm_event(gsm, e); ++ } ++ ast_mutex_unlock(&gsm->lock); ++ ++ res = ioctl(gsm->fd, ZT_GETEVENT, &x); ++ ++ if (!res && x) { ++ switch (x) { ++ case ZT_EVENT_NOALARM: ++ ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", gsm->span); ++ usleep(1000); ++ gsm_restart(gsm->modul, 10000); ++ break; ++ case ZT_EVENT_ALARM: ++ ast_log(LOG_NOTICE, "Alarm detected on span %d\n", gsm->span); ++ break; ++ default: ++ fprintf(stderr, "Got event on GSM interface: %d\n", x); ++ } ++ } ++ ++ ++ } ++ return NULL; ++} ++ ++#endif ++ + #ifdef HAVE_PRI + static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv) + { +@@ -8385,6 +8716,18 @@ static void zt_pri_error(char *s, int sp + ast_log(LOG_WARNING, "%d %s", span, s); + } + ++#ifdef HAVE_GSMAT ++static void zt_gsm_message(char *s, int channel) ++{ ++ ast_verbose("GSM %d: %s", channel, s); ++} ++ ++static void zt_gsm_error(char *s, int channel) ++{ ++ ast_log(LOG_WARNING, "GSM %d: %s", channel, s); ++} ++#endif ++ + static int pri_check_restart(struct zt_pri *pri) + { + if ((pri->nodetype != PRI_NETWORK) && (pri->nodetype != PRI_CPE)) { +@@ -10537,6 +10880,243 @@ static int app_zapInband(struct ast_chan + + #endif /* HAVE_PRI */ + ++#ifdef HAVE_GSMAT ++static int handle_zap_reset_span(int fd, int argc, char *argv[]) ++{ ++ int span; ++ int sleep = 5000; ++ if (argc < 4) ++ return RESULT_SHOWUSAGE; ++ span = atoi(argv[3]); ++ if ((span < 1) || (span > NUM_SPANS)) { ++ ast_cli(fd, "Invalid span '%s'. Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS); ++ return RESULT_SUCCESS; ++ } ++ if (zt_reset_span(span, sleep)) { ++ return RESULT_FAILURE; ++ } ++ return RESULT_SUCCESS; ++} ++ ++static int handle_gsm_debug_helper(int fd, int channel, int debug) ++{ ++/* gsm debug channel */ ++ struct zt_pvt *pvt = NULL; ++ if (channel < 1) { ++ ast_cli(fd, "Invalid channel %d. Should be a number.\n", channel); ++ return RESULT_SUCCESS; ++ } ++ pvt = iflist; ++ while (pvt) { ++ if (pvt->channel == channel) { ++ ast_mutex_lock(&pvt->lock); ++ gsm_set_debug(pvt->gsm.modul, debug); ++ ast_mutex_unlock(&pvt->lock); ++ ast_cli(fd, "%s debugging on channel %d\n", debug ? "Enabled":"Disabled", channel); ++ return RESULT_SUCCESS; ++ } ++ pvt = pvt->next; ++ } ++ ++ ast_cli(fd, "No GSM running on channel %d\n", channel); ++ return RESULT_SUCCESS; ++} ++ ++ ++ ++static int handle_gsm_debug(int fd, int argc, char *argv[]) ++{ ++/* gsm debug channel */ ++ int channel; ++ if (argc < 4) { ++ return RESULT_SHOWUSAGE; ++ } ++ channel = atoi(argv[3]); ++ return handle_gsm_debug_helper(fd, channel, GSM_DEBUG_AT); ++} ++ ++static int handle_gsm_no_debug(int fd, int argc, char *argv[]) ++{ ++/* gsm no debug channel */ ++ int channel; ++ if (argc < 5) { ++ return RESULT_SHOWUSAGE; ++ } ++ channel = atoi(argv[4]); ++ return handle_gsm_debug_helper(fd, channel, GSM_DEBUG_NONE); ++} ++ ++static char zap_reset_help[] = ++ "Usage: zap reset span \n" ++ " Reset/Restart a zaptel span\n"; ++ ++static char gsm_debug_help[] = ++ "Usage: gsm debug channel \n" ++ " Enables debugging on a given GSM channel\n"; ++ ++static char gsm_no_debug_help[] = ++ "Usage: gsm no debug channel \n" ++ " Disables debugging on a given GSM channel\n"; ++ ++static struct ast_cli_entry zap_gsm_cli[] = { ++ { { "zap", "reset", "span", NULL }, handle_zap_reset_span, ++ "Restart a zaptel span", zap_reset_help, complete_span_4 }, ++ { { "gsm", "debug", "channel", NULL }, handle_gsm_debug, ++ "Enables GSM debugging on a channel", gsm_debug_help }, ++ { { "gsm", "no", "debug", "channel", NULL }, handle_gsm_no_debug, ++ "Disables GSM debugging on a channel", gsm_no_debug_help}, ++}; ++ ++ ++ ++static char gsm_send_pdu_help[] = ++ "Usage: gsm send pdu \n" ++ " Sends a PDU on a GSM channel\n"; ++ ++ ++ ++static int handle_gsm_send_pdu(int fd, int argc, char *argv[]) ++{ ++/* gsm send sms */ ++ int channel; ++ struct zt_pvt *pvt = NULL; ++ if (argc < 5) { ++ return RESULT_SHOWUSAGE; ++ } ++ channel = atoi(argv[3]); ++ if (channel < 1) { ++ ast_cli(fd, "Invalid channel %s. Should be a number.\n", argv[3]); ++ return RESULT_SUCCESS; ++ } ++ pvt = iflist; ++ while (pvt) { ++ if (pvt->channel == channel) { ++ if (pvt->owner) { ++ ast_cli(fd, "Channel in use.\n"); ++ return RESULT_FAILURE; ++ } else { ++ ast_mutex_lock(&pvt->lock); ++ gsm_sms_send_pdu(pvt->gsm.modul, argv[4]); ++ ast_mutex_unlock(&pvt->lock); ++ return RESULT_SUCCESS; ++ } ++ } ++ pvt = pvt->next; ++ } ++ ++ return RESULT_SUCCESS; ++} ++ ++static struct ast_cli_entry gsm_send_pdu = { ++ { "gsm", "send", "pdu", NULL }, handle_gsm_send_pdu, "Sends a SM on a GSM channel", gsm_send_pdu_help, complete_span_4 }; ++ ++ ++static char gsm_send_sms_help[] = ++ "Usage: gsm send sms \n" ++ " Sends a SM on a GSM channel\n"; ++ ++ ++static int handle_gsm_send_sms(int fd, int argc, char *argv[]) ++{ ++/* gsm send sms */ ++ int channel; ++ struct zt_pvt *pvt = NULL; ++ if (argc < 6) { ++ return RESULT_SHOWUSAGE; ++ } ++ channel = atoi(argv[3]); ++ if (channel < 1) { ++ ast_cli(fd, "Invalid channel %s. Should be a number.\n", argv[3]); ++ return RESULT_SUCCESS; ++ } ++ pvt = iflist; ++ while (pvt) { ++ if (pvt->channel == channel) { ++ if (pvt->owner) { ++ ast_cli(fd, "Channel in use.\n"); ++ return RESULT_FAILURE; ++ } else { ++ ast_mutex_lock(&pvt->lock); ++ gsm_sms_send_text(pvt->gsm.modul, argv[4], argv[5]); ++ ast_mutex_unlock(&pvt->lock); ++ return RESULT_SUCCESS; ++ } ++ } ++ pvt = pvt->next; ++ } ++ ++ return RESULT_SUCCESS; ++} ++ ++static int zt_gsm_sendtext(struct ast_channel *chan, const char * dest, const char *text, int ispdu) { ++ struct zt_pvt *pvt = NULL; ++ char *c = NULL; ++ pvt = chan->tech_pvt; ++ ++ if (!pvt) return -1; ++ ++ /* parse dialstring */ ++ c = strrchr(dest, '/'); ++ if (c) ++ c++; ++ else ++ c = (char *)dest; ++ ++ ast_mutex_lock(&pvt->lock); ++ if (ispdu) { ++ gsm_sms_send_pdu(pvt->gsm.modul, (char *)text); ++ } else { ++ gsm_sms_send_text(pvt->gsm.modul, c, (char *)text); ++ } ++ ast_mutex_unlock(&pvt->lock); ++ gsm_wait(pvt->gsm.modul); ++ return 0; ++} ++ ++static struct ast_cli_entry gsm_send_sms = { ++ { "gsm", "send", "sms", NULL }, handle_gsm_send_sms, "Sends a SM on a GSM channel", gsm_send_sms_help, complete_span_4 }; ++ ++static char gsm_show_status_help[] = ++ "Usage: gsm show status >\n" ++ " Displays status information about the GSM channel.\n"; ++ ++ ++static int handle_gsm_show_status(int fd, int argc, char *argv[]) ++{ ++ int channel; ++ struct zt_pvt *pvt = NULL; ++ if (argc < 4) { ++ return RESULT_SHOWUSAGE; ++ } ++ channel = atoi(argv[3]); ++ if (channel < 1) { ++ ast_cli(fd, "Invalid channel %s. Should be a number.\n", argv[3]); ++ return RESULT_SUCCESS; ++ } ++ pvt = iflist; ++ while (pvt) { ++ if (pvt->channel == channel) { ++ if (pvt->owner) { ++ ast_cli(fd, "Channel in use.\n"); ++ return RESULT_FAILURE; ++ } else { ++ ast_mutex_lock(&pvt->lock); ++ gsm_request_status(pvt->gsm.modul); ++ ast_mutex_unlock(&pvt->lock); ++ return RESULT_SUCCESS; ++ } ++ } ++ pvt = pvt->next; ++ } ++ ++ return RESULT_SUCCESS; ++} ++ ++static struct ast_cli_entry gsm_show_status = { ++ { "gsm", "show", "status", NULL }, handle_gsm_show_status, "Displays status information about the GSM channel.", gsm_show_status_help, complete_span_4 }; ++ ++#endif /* HAVE_GSMAT */ ++ + static int app_zapEC(struct ast_channel *chan, void *data) + { + int res=-1; +@@ -11158,6 +11738,12 @@ static int __unload_module(void) + ast_unregister_application(zapCD_app); + ast_unregister_application(zapInband_app); + #endif ++#ifdef HAVE_GSMAT ++ ast_cli_unregister_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0])); ++ ast_cli_unregister(&gsm_send_sms); ++ ast_cli_unregister(&gsm_send_pdu); ++ ast_cli_unregister(&gsm_show_status); ++#endif + ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); + ast_unregister_application(zapEC_app); + ast_manager_unregister( "ZapDialOffhook" ); +@@ -11678,6 +12264,11 @@ static int process_zap(struct zt_chan_co + confp->chan.radio = 0; + confp->pri.nodetype = BRI_CPE; + #endif ++#ifdef HAVE_GSMAT ++ } else if (!strcasecmp(v->value, "gsm")) { ++ confp->chan.sig = SIG_GSM; ++ confp->chan.radio = 0; ++#endif + } else { + ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); + } +@@ -11820,6 +12411,10 @@ static int process_zap(struct zt_chan_co + ast_copy_string(confp->pri.nocid, v->value, sizeof(confp->pri.nocid)); + } else if (!strcasecmp(v->name, "withheldcid")) { + ast_copy_string(confp->pri.withheldcid, v->value, sizeof(confp->pri.withheldcid)); ++ } else if (!strcasecmp(v->name, "pin")) { ++ ast_copy_string(gsm_modem_pin, v->value, sizeof(gsm_modem_pin) - 1); ++ } else if (!strcasecmp(v->name, "exten")) { ++ ast_copy_string(gsm_modem_exten, v->value, sizeof(gsm_modem_exten) - 1); + } else if (!strcasecmp(v->name, "resetinterval")) { + if (!strcasecmp(v->value, "never")) + confp->pri.resetinterval = -1; +@@ -12175,6 +12770,10 @@ static int load_module(void) + ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec, + zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip); + #endif ++#ifdef HAVE_GSMAT ++ gsm_set_error(zt_gsm_error); ++ gsm_set_message(zt_gsm_message); ++#endif + res = setup_zap(0); + /* Make sure we can register our Zap channel type */ + if (res) +@@ -12193,6 +12792,12 @@ static int load_module(void) + #endif + ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc); + ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); ++#ifdef HAVE_GSMAT ++ ast_cli_register(&gsm_send_sms); ++ ast_cli_register(&gsm_send_pdu); ++ ast_cli_register(&gsm_show_status); ++ ast_cli_register_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0])); ++#endif + + memset(round_robin, 0, sizeof(round_robin)); + ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" ); +@@ -12206,7 +12811,66 @@ static int load_module(void) + return res; + } + +-static int zt_sendtext(struct ast_channel *c, const char *text) ++#ifdef HAVE_PRI ++static int zt_tdd_sendtext(struct ast_channel *c, const char *text); ++ ++static int zt_pri_sendtext(struct ast_channel *c, const char *text) { ++ struct zt_pvt *p = c->tech_pvt; ++ if (!p) return -1; ++ if (!p->pri) return -1; ++ if (strlen(text)) { ++ if (p->pri) { ++ if (!pri_grab(p, p->pri)) { ++ // ast_log(LOG_NOTICE, "Sending Display IE '%s'\n", text); ++ pri_information_display(p->pri->pri,p->call,(char *)text); ++ pri_rel(p->pri); ++ } else ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); ++ } ++ } ++ return 0; ++} ++#endif ++ ++static int zt_sendtext(struct ast_channel *c, const char *text) { ++ struct zt_pvt *p = c->tech_pvt; ++ if (!p) return -1; ++ if (p->sig == SIG_PRI) { ++#ifdef HAVE_PRI ++ return zt_pri_sendtext(c, text); ++#endif ++ } else if (p->sig == SIG_GSM) { ++ } else { ++ return zt_tdd_sendtext(c, text); ++ } ++ return -1; ++} ++ ++static int zt_sendmessage(struct ast_channel *c, const char *dest, const char *text, int ispdu) { ++struct zt_pvt *p = c->tech_pvt; ++ if (!p) return -1; ++ if (p->sig == SIG_PRI) { ++#ifdef HAVE_PRI ++ if (ispdu) { ++ ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP ISDN channel\n"); ++ return -1; ++ } ++ return zt_pri_sendtext(c, text); ++#endif ++ } else if (p->sig == SIG_GSM) { ++#ifdef HAVE_GSMAT ++ return zt_gsm_sendtext(c, dest, text, ispdu); ++#endif ++ } else { ++ if (ispdu) { ++ ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP channel\n"); ++ return -1; ++ } ++ return zt_tdd_sendtext(c, text); ++ } ++ return -1; ++} ++ ++static int zt_tdd_sendtext(struct ast_channel *c, const char *text) + { + #define END_SILENCE_LEN 400 + #define HEADER_MS 50 +--- a/configure.ac ++++ b/configure.ac +@@ -178,6 +178,7 @@ AST_EXT_LIB_SETUP([CAP], [POSIX 1.e capa + AST_EXT_LIB_SETUP([CURSES], [curses], [curses]) + AST_EXT_LIB_SETUP([GNUTLS], [GNU TLS support (used for iksemel only)], [gnutls]) + AST_EXT_LIB_SETUP([GSM], [GSM], [gsm], [, or 'internal']) ++AST_EXT_LIB_SETUP([GSMAT], [GSMAT], [GSM AT command signalling], [gsmat]) + AST_EXT_LIB_SETUP([IKSEMEL], [Iksemel Jabber Library], [iksemel]) + AST_EXT_LIB_SETUP([IMAP_TK], [UW IMAP Toolkit], [imap]) + AST_EXT_LIB_SETUP([ISDNNET], [ISDN4Linux Library], [isdnnet]) +--- a/configure ++++ b/configure +@@ -26600,6 +26600,188 @@ echo "$as_me: *** without explicitly spe + fi + fi + ++{ echo "$as_me:$LINENO: checking for ${GSMAT_DIR}/include/libgsmat.h" >&5 ++echo $ECHO_N "checking for ${GSMAT_DIR}/include/libgsmat.h... $ECHO_C" >&6; } ++if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ eval "$as_ac_Header=\$ac_header_preproc" ++fi ++ac_res=`eval echo '${'$as_ac_Header'}'` ++ { echo "$as_me:$LINENO: result: $ac_res" >&5 ++echo "${ECHO_T}$ac_res" >&6; } ++ ++if test `eval echo '${'$as_ac_Header'}'` = yes; then ++ GSMAT_HEADER_FOUND=1 ++else ++ GSMAT_HEADER_FOUND=0 ++fi ++ ++ ++ ++ if test "${GSMAT_HEADER_FOUND}" = "yes"; then ++ GSMAT_LIB="-lgsmat " ++ GSMAT_HEADER_FOUND="1" ++ if test "x${GSMAT_DIR}" != "x"; then ++ GSMAT_LIB="${pbxlibdir} ${GSMAT_LIB}" ++ GSMAT_INCLUDE="-I${GSMAT_DIR}/include" ++ fi ++ CPPFLAGS="${saved_cppflags}" ++ else ++ if test "xlibgsmat.h" != "x" ; then ++ if test "${ac_cv_header_libpri_h+set}" = set; then ++ { echo "$as_me:$LINENO: checking for libgsmat.h" >&5 ++echo $ECHO_N "checking for libgsmat.h... $ECHO_C" >&6; } ++if test "${ac_cv_header_libgsmat_h+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++fi ++{ echo "$as_me:$LINENO: result: $ac_cv_header_libgsmat_h" >&5 ++echo "${ECHO_T}$ac_cv_header_libgsmat_h" >&6; } ++else ++ # Is the header compilable? ++{ echo "$as_me:$LINENO: checking libgsmat.h usability" >&5 ++echo $ECHO_N "checking libgsmat.h usability... $ECHO_C" >&6; } ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++#include ++_ACEOF ++rm -f conftest.$ac_objext ++if { (ac_try="$ac_compile" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_compile") 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ++ test -z "$ac_c_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest.$ac_objext; then ++ ac_header_compiler=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_header_compiler=no ++fi ++ ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 ++echo "${ECHO_T}$ac_header_compiler" >&6; } ++ ++# Is the header present? ++{ echo "$as_me:$LINENO: checking libgsmat.h presence" >&5 ++echo $ECHO_N "checking libgsmat.h presence... $ECHO_C" >&6; } ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++_ACEOF ++if { (ac_try="$ac_cpp conftest.$ac_ext" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null && { ++ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || ++ test ! -s conftest.err ++ }; then ++ ac_header_preproc=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_header_preproc=no ++fi ++ ++rm -f conftest.err conftest.$ac_ext ++{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 ++echo "${ECHO_T}$ac_header_preproc" >&6; } ++ ++# So? What about this header? ++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in ++ yes:no: ) ++ { echo "$as_me:$LINENO: WARNING: libgsmat.h: accepted by the compiler, rejected by the preprocessor!" >&5 ++echo "$as_me: WARNING: libgsmat.h: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { echo "$as_me:$LINENO: WARNING: libgsmat.h: proceeding with the compiler's result" >&5 ++echo "$as_me: WARNING: libgsmat.h: proceeding with the compiler's result" >&2;} ++ ac_header_preproc=yes ++ ;; ++ no:yes:* ) ++ { echo "$as_me:$LINENO: WARNING: libgsmat.h: present but cannot be compiled" >&5 ++echo "$as_me: WARNING: libgsmat.h: present but cannot be compiled" >&2;} ++ { echo "$as_me:$LINENO: WARNING: libgsmat.h: check for missing prerequisite headers?" >&5 ++echo "$as_me: WARNING: libgsmat.h: check for missing prerequisite headers?" >&2;} ++ { echo "$as_me:$LINENO: WARNING: libgsmat.h: see the Autoconf documentation" >&5 ++echo "$as_me: WARNING: libgsmat.h: see the Autoconf documentation" >&2;} ++ { echo "$as_me:$LINENO: WARNING: libgsmat.h: section \"Present But Cannot Be Compiled\"" >&5 ++echo "$as_me: WARNING: libgsmat.h: section \"Present But Cannot Be Compiled\"" >&2;} ++ { echo "$as_me:$LINENO: WARNING: libgsmat.h: proceeding with the preprocessor's result" >&5 ++echo "$as_me: WARNING: libgsmat.h: proceeding with the preprocessor's result" >&2;} ++ { echo "$as_me:$LINENO: WARNING: libgsmat.h: in the future, the compiler will take precedence" >&5 ++echo "$as_me: WARNING: libgsmat.h: in the future, the compiler will take precedence" >&2;} ++ ++ ;; ++esac ++{ echo "$as_me:$LINENO: checking for libgsmat.h" >&5 ++echo $ECHO_N "checking for libgsmat.h... $ECHO_C" >&6; } ++if test "${ac_cv_header_libgsmat_h+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_header_libgsmat_h=$ac_header_preproc ++fi ++{ echo "$as_me:$LINENO: result: $ac_cv_header_libgsmat_h" >&5 ++echo "${ECHO_T}$ac_cv_header_libgsmat_h" >&6; } ++ ++fi ++ ++ ++ fi ++ fi ++ if test "x${GSMAT_HEADER_FOUND}" = "x0" ; then ++ if test -n "${GSMAT_MANDATORY}" ; ++ then ++ { echo "$as_me:$LINENO: ***" >&5 ++echo "$as_me: ***" >&6;} ++ { echo "$as_me:$LINENO: *** It appears that you do not have the GSMAT development package installed." >&5 ++echo "$as_me: *** It appears that you do not have the GSMAT development package installed." >&6;} ++ { echo "$as_me:$LINENO: *** Please install it to include ${GSMAT_DESCRIP} support, or re-run configure" >&5 ++echo "$as_me: *** Please install it to include ${GSMAT_DESCRIP} support, or re-run configure" >&6;} ++ { echo "$as_me:$LINENO: *** without explicitly specifying --with-${GSMAT_OPTION}" >&5 ++echo "$as_me: *** without explicitly specifying --with-${GSMAT_OPTION}" >&6;} ++ exit 1 ++ fi ++ GSMAT_LIB="" ++ GSMAT_INCLUDE="" ++ PBX_GSMAT=0 ++ else ++ PBX_GSMAT=1 ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_GSMAT 1 ++_ACEOF ++ ++fi + + if test "${USE_PWLIB}" != "no"; then + if test -n "${PWLIB_DIR}"; then --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/app-dial-priority-202 +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/app-dial-priority-202 @@ -0,0 +1,42 @@ +--- a/apps/app_dial.c ++++ b/apps/app_dial.c +@@ -11,6 +11,10 @@ + * the project provides a web site, mailing lists and IRC + * channels for your use. + * ++ * Copyright (C) 2004, Junghanns.NET GmbH ++ * ++ * Klaus-Peter Junghanns ++ * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. +@@ -130,7 +134,8 @@ static char *descrip = + " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n" + " i - Asterisk will ignore any forwarding requests it may receive on this\n" + " dial attempt.\n" +-" j - Jump to priority n+101 if all of the requested channels were busy.\n" ++" j - Jump to priority n+101 if the called party was busy.\n" ++" Jump to priority n+201 if all of the requested channels were busy.\n" + " k - Allow the called party to enable parking of the call by sending\n" + " the DTMF sequence defined for call parking in features.conf.\n" + " K - Allow the calling party to enable parking of the call by sending\n" +@@ -1292,14 +1297,16 @@ static int dial_exec_full(struct ast_cha + } + + if (!outgoing) { +- strcpy(status, "CHANUNAVAIL"); ++ ast_copy_string(status, "CHANUNAVAIL", sizeof(status)); + if(fulldial == num_dialed) { + res = -1; + goto out; + } ++ /* See if there is a special message */ ++ ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201); + } else { + /* Our status will at least be NOANSWER */ +- strcpy(status, "NOANSWER"); ++ ast_copy_string(status, "NOANSWER", sizeof(status)); + if (ast_test_flag(outgoing, OPT_MUSICBACK)) { + moh = 1; + if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) { --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/xagi +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/xagi @@ -0,0 +1,499 @@ +--- a/include/asterisk/agi.h ++++ b/include/asterisk/agi.h +@@ -30,6 +30,7 @@ extern "C" { + typedef struct agi_state { + int fd; /* FD for general output */ + int audio; /* FD for audio output */ ++ int audio_in; /* FD for audio output */ + int ctrl; /* FD for input control */ + unsigned int fast:1; /* flag for fast agi or not */ + } AGI; +--- a/res/res_agi.c ++++ b/res/res_agi.c +@@ -11,6 +11,9 @@ + * the project provides a web site, mailing lists and IRC + * channels for your use. + * ++ * Copyright (C) 2005 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns ++ * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. +@@ -75,16 +78,19 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi + + static char *app = "AGI"; + ++static char *xapp = "XAGI"; ++ + static char *eapp = "EAGI"; + + static char *deadapp = "DeadAGI"; + + static char *synopsis = "Executes an AGI compliant application"; ++static char *xsynopsis = "Executes an XAGI compliant application"; + static char *esynopsis = "Executes an EAGI compliant application"; + static char *deadsynopsis = "Executes AGI on a hungup channel"; + + static char *descrip = +-" [E|Dead]AGI(command|args): Executes an Asterisk Gateway Interface compliant\n" ++" [E|Dead|X]AGI(command|args): Executes an Asterisk Gateway Interface compliant\n" + "program on a channel. AGI allows Asterisk to launch external programs\n" + "written in any language to control a telephony channel, play audio,\n" + "read DTMF digits, etc. by communicating with the AGI protocol on stdin\n" +@@ -97,6 +103,8 @@ static char *descrip = + "variable to \"no\" before executing the AGI application.\n" + " Using 'EAGI' provides enhanced AGI, with incoming audio available out of band\n" + "on file descriptor 3\n\n" ++"Using 'XAGI' provides enhanced AGI, with incoming audio available out of band" ++" on file descriptor 3 and outgoing audio available out of band on file descriptor 4\n\n" + " Use the CLI command 'agi show' to list available agi commands\n" + " This application sets the following channel variable upon completion:\n" + " AGISTATUS The status of the attempt to the run the AGI script\n" +@@ -236,13 +244,14 @@ static enum agi_result launch_netscript( + return AGI_RESULT_SUCCESS_FAST; + } + +-static enum agi_result launch_script(char *script, char *argv[], int *fds, int *efd, int *opid) ++static enum agi_result launch_script(char *script, char *argv[], int *fds, int *efd, int *efd2, int *opid) + { + char tmp[256]; + int pid; + int toast[2]; + int fromast[2]; + int audio[2]; ++ int audio2[2]; + int x; + int res; + sigset_t signal_set, old_set; +@@ -287,6 +296,33 @@ static enum agi_result launch_script(cha + return AGI_RESULT_FAILURE; + } + } ++ if (efd2) { ++ if (pipe(audio2)) { ++ ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno)); ++ close(fromast[0]); ++ close(fromast[1]); ++ close(toast[0]); ++ close(toast[1]); ++ close(audio[0]); ++ close(audio[1]); ++ return AGI_RESULT_FAILURE; ++ } ++ res = fcntl(audio2[0], F_GETFL); ++ if (res > -1) ++ res = fcntl(audio2[0], F_SETFL, res | O_NONBLOCK); ++ if (res < 0) { ++ ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno)); ++ close(fromast[0]); ++ close(fromast[1]); ++ close(toast[0]); ++ close(toast[1]); ++ close(audio[0]); ++ close(audio[1]); ++ close(audio2[0]); ++ close(audio2[1]); ++ return AGI_RESULT_FAILURE; ++ } ++ } + + /* Block SIGHUP during the fork - prevents a race */ + sigfillset(&signal_set); +@@ -322,6 +358,11 @@ static enum agi_result launch_script(cha + } else { + close(STDERR_FILENO + 1); + } ++ if (efd2) { ++ dup2(audio2[1], STDERR_FILENO + 2); ++ } else { ++ close(STDERR_FILENO + 2); ++ } + + /* Before we unblock our signals, return our trapped signals back to the defaults */ + signal(SIGHUP, SIG_DFL); +@@ -339,7 +380,7 @@ static enum agi_result launch_script(cha + } + + /* Close everything but stdin/out/error */ +- for (x=STDERR_FILENO + 2;x<1024;x++) ++ for (x=STDERR_FILENO + 3;x<1024;x++) + close(x); + + /* Execute script */ +@@ -359,12 +400,19 @@ static enum agi_result launch_script(cha + if (efd) { + *efd = audio[1]; + } ++ if (efd2) { ++ *efd2 = audio2[0]; ++ } + /* close what we're not using in the parent */ + close(toast[1]); + close(fromast[0]); + +- if (efd) ++ if (efd) { + close(audio[0]); ++ } ++ if (efd2) { ++ close(audio2[1]); ++ } + + *opid = pid; + return AGI_RESULT_SUCCESS; +@@ -394,7 +442,7 @@ static void setup_env(struct ast_channel + fdprintf(fd, "agi_context: %s\n", chan->context); + fdprintf(fd, "agi_extension: %s\n", chan->exten); + fdprintf(fd, "agi_priority: %d\n", chan->priority); +- fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0"); ++ fdprintf(fd, "agi_enhanced: %d%s\n", enhanced, ".0"); + + /* User information */ + fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : ""); +@@ -1835,8 +1883,13 @@ static enum agi_result run_agi(struct as + int ms; + enum agi_result returnstatus = AGI_RESULT_SUCCESS; + struct ast_frame *f; ++ struct ast_frame fr; + char buf[AGI_BUF_LEN]; ++ char audiobuf[AGI_BUF_LEN]; + char *res = NULL; ++ int audiobytes; ++ int fds[2]; ++ int enhanced = 0; + FILE *readf; + /* how many times we'll retry if ast_waitfor_nandfs will return without either + channel or file descriptor in case select is interrupted by a system call (EINTR) */ +@@ -1850,10 +1903,22 @@ static enum agi_result run_agi(struct as + return AGI_RESULT_FAILURE; + } + setlinebuf(readf); +- setup_env(chan, request, agi->fd, (agi->audio > -1)); ++ if (agi->audio > -1) { ++ enhanced = 1; ++ } ++ if (agi->audio_in > -1) { ++ enhanced++; ++ } ++ setup_env(chan, request, agi->fd, enhanced); ++ fds[0] = agi->ctrl; ++ fds[1] = agi->audio_in; + for (;;) { + ms = -1; +- c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); ++ if (agi->audio_in > -1) { ++ c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, fds, 2, NULL, &outfd, &ms); ++ } else { ++ c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); ++ } + if (c) { + retry = AGI_NANDFS_RETRY; + /* Idle the channel until we get a command */ +@@ -1871,6 +1936,16 @@ static enum agi_result run_agi(struct as + ast_frfree(f); + } + } else if (outfd > -1) { ++ if ((agi->audio_in > -1) && (outfd == agi->audio_in)) { ++ audiobytes = read(agi->audio_in, audiobuf, sizeof(audiobuf)); ++ if (audiobytes > 0) { ++ fr.frametype = AST_FRAME_VOICE; ++ fr.subclass = AST_FORMAT_SLINEAR; ++ fr.datalen = audiobytes; ++ fr.data = audiobuf; ++ ast_write(chan, &fr); ++ } ++ } else { + size_t len = sizeof(buf); + size_t buflen = 0; + +@@ -1922,6 +1997,7 @@ static enum agi_result run_agi(struct as + if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) { + break; + } ++ } + } else { + if (--retry <= 0) { + ast_log(LOG_WARNING, "No channel, no fd?\n"); +@@ -2034,6 +2110,7 @@ static int agi_exec_full(struct ast_chan + int argc = 0; + int fds[2]; + int efd = -1; ++ int efd2 = -1; + int pid; + char *stringp; + AGI agi; +@@ -2060,12 +2137,13 @@ static int agi_exec_full(struct ast_chan + } + #endif + ast_replace_sigchld(); +- res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid); ++ res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, (enhanced == 2) ? &efd2 : NULL, &pid); + if (res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) { + int status = 0; + agi.fd = fds[1]; + agi.ctrl = fds[0]; + agi.audio = efd; ++ agi.audio_in = efd2; + agi.fast = (res == AGI_RESULT_SUCCESS_FAST) ? 1 : 0; + res = run_agi(chan, argv[0], &agi, pid, &status, dead); + /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */ +@@ -2075,6 +2153,8 @@ static int agi_exec_full(struct ast_chan + close(fds[1]); + if (efd > -1) + close(efd); ++ if (efd2 > -1) ++ close(efd2); + } + ast_unreplace_sigchld(); + ast_module_user_remove(u); +@@ -2123,6 +2203,35 @@ static int eagi_exec(struct ast_channel + return res; + } + ++static int xagi_exec(struct ast_channel *chan, void *data) ++{ ++ int readformat, writeformat; ++ int res; ++ ++ if (chan->_softhangup) ++ ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n"); ++ readformat = chan->readformat; ++ if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) { ++ ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); ++ return -1; ++ } ++ writeformat = chan->writeformat; ++ if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { ++ ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name); ++ return -1; ++ } ++ res = agi_exec_full(chan, data, 2, 0); ++ if (!res) { ++ if (ast_set_read_format(chan, readformat)) { ++ ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat)); ++ } ++ if (ast_set_write_format(chan, writeformat)) { ++ ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(writeformat)); ++ } ++ } ++ return res; ++} ++ + static int deadagi_exec(struct ast_channel *chan, void *data) + { + if (!ast_check_hangup(chan)) +@@ -2178,6 +2287,7 @@ static int unload_module(void) + { + ast_module_user_hangup_all(); + ast_cli_unregister_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); ++ ast_unregister_application(xapp); + ast_unregister_application(eapp); + ast_unregister_application(deadapp); + return ast_unregister_application(app); +@@ -2188,6 +2298,7 @@ static int load_module(void) + ast_cli_register_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); + ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip); + ast_register_application(eapp, eagi_exec, esynopsis, descrip); ++ ast_register_application(xapp, xagi_exec, xsynopsis, descrip); + return ast_register_application(app, agi_exec, synopsis, descrip); + } + +--- /dev/null ++++ b/agi/xagi-test.c +@@ -0,0 +1,175 @@ ++/* ++ * Asterisk -- A telephony toolkit for Linux. ++ * ++ * XAGI sample script ++ * ++ * Copyright (C) 2005 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns ++ * ++ * based on eagi-test.c ++ * ++ * This program is free software, distributed under the terms of ++ * the GNU General Public License ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef SOLARIS ++#include ++#endif ++ ++#define AUDIO_FILENO_IN (STDERR_FILENO + 1) ++#define AUDIO_FILENO_OUT (STDERR_FILENO + 2) ++ ++static int read_environment(void) ++{ ++ char buf[256]; ++ char *val; ++ /* Read environment */ ++ for(;;) { ++ fgets(buf, sizeof(buf), stdin); ++ if (feof(stdin)) ++ return -1; ++ buf[strlen(buf) - 1] = '\0'; ++ /* Check for end of environment */ ++ if (!strlen(buf)) ++ return 0; ++ val = strchr(buf, ':'); ++ if (!val) { ++ fprintf(stderr, "Invalid environment: '%s'\n", buf); ++ return -1; ++ } ++ *val = '\0'; ++ val++; ++ val++; ++ /* Skip space */ ++ // fprintf(stderr, "Environment: '%s' is '%s'\n", buf, val); ++ ++ /* Load into normal environment */ ++ setenv(buf, val, 1); ++ ++ } ++ /* Never reached */ ++ return 0; ++} ++ ++static void app_echo(void) ++{ ++ fd_set fds; ++ int res; ++ int bytes = 0; ++ static char astresp[256]; ++ char audiobuf[16000]; /* 1 second of audio */ ++ for (;;) { ++ FD_ZERO(&fds); ++ FD_SET(STDIN_FILENO, &fds); ++ FD_SET(AUDIO_FILENO_IN, &fds); ++ /* Wait for *some* sort of I/O */ ++ res = select(AUDIO_FILENO_IN + 1, &fds, NULL, NULL, NULL); ++ if (res < 0) { ++ fprintf(stderr, "Error in select: %s\n", strerror(errno)); ++ return; ++ } ++ if (FD_ISSET(STDIN_FILENO, &fds)) { ++ fgets(astresp, sizeof(astresp), stdin); ++ if (feof(stdin)) { ++ return; ++ } ++ astresp[strlen(astresp) - 1] = '\0'; ++ fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp); ++ return; ++ } ++ if (FD_ISSET(AUDIO_FILENO_IN, &fds)) { ++ /* what goes in.... */ ++ res = read(AUDIO_FILENO_IN, audiobuf, sizeof(audiobuf)); ++ if (res > 0) { ++ bytes = res; ++ /* must come out */ ++ write(AUDIO_FILENO_OUT, audiobuf, bytes); ++ } ++ } ++ } ++} ++ ++static char *wait_result(void) ++{ ++ fd_set fds; ++ int res; ++ static char astresp[256]; ++ char audiobuf[4096]; ++ for (;;) { ++ FD_ZERO(&fds); ++ FD_SET(STDIN_FILENO, &fds); ++ FD_SET(AUDIO_FILENO_IN, &fds); ++ /* Wait for *some* sort of I/O */ ++ res = select(AUDIO_FILENO_IN + 1, &fds, NULL, NULL, NULL); ++ if (res < 0) { ++ fprintf(stderr, "Error in select: %s\n", strerror(errno)); ++ return NULL; ++ } ++ if (FD_ISSET(STDIN_FILENO, &fds)) { ++ fgets(astresp, sizeof(astresp), stdin); ++ if (feof(stdin)) { ++ fprintf(stderr, "Got hungup on apparently\n"); ++ return NULL; ++ } ++ astresp[strlen(astresp) - 1] = '\0'; ++ fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp); ++ return astresp; ++ } ++ if (FD_ISSET(AUDIO_FILENO_IN, &fds)) { ++ res = read(AUDIO_FILENO_IN, audiobuf, sizeof(audiobuf)); ++ /* drop it, like it's hot */ ++ } ++ } ++ ++} ++ ++static char *run_command(char *command) ++{ ++ fprintf(stdout, "%s\n", command); ++ return wait_result(); ++} ++ ++ ++static int run_script(void) ++{ ++ char *res; ++ res = run_command("STREAM FILE demo-echotest \"\""); ++ if (!res) { ++ fprintf(stderr, "Failed to execute command\n"); ++ return -1; ++ } ++ app_echo(); ++ return 0; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ char *tmp; ++ int ver = 0; ++ int subver = 0; ++ /* Setup stdin/stdout for line buffering */ ++ setlinebuf(stdin); ++ setlinebuf(stdout); ++ if (read_environment()) { ++ fprintf(stderr, "Failed to read environment: %s\n", strerror(errno)); ++ exit(1); ++ } ++ tmp = getenv("agi_enhanced"); ++ if (tmp) { ++ if (sscanf(tmp, "%d.%d", &ver, &subver) != 2) ++ ver = 0; ++ } ++ if (ver < 2) { ++ fprintf(stderr, "No XAGI services available. Use XAGI, not AGI or EAGI\n"); ++ exit(1); ++ } ++ if (run_script()) ++ return -1; ++ exit(0); ++} +--- a/agi/Makefile ++++ b/agi/Makefile +@@ -13,7 +13,7 @@ + + .PHONY: clean all uninstall + +-AGIS=agi-test.agi eagi-test eagi-sphinx-test jukebox.agi ++AGIS=agi-test.agi eagi-test eagi-sphinx-test jukebox.agi xagi-test + + ifeq ($(OSARCH),SunOS) + LIBS+=-lsocket -lnsl +@@ -38,7 +38,7 @@ uninstall: + for x in $(AGIS); do rm -f $(DESTDIR)$(AGI_DIR)/$$x ; done + + clean: +- rm -f *.so *.o look eagi-test eagi-sphinx-test ++ rm -f *.so *.o look eagi-test eagi-sphinx-test xagi-test + rm -f .*.o.d .*.oo.d *.s *.i + rm -f strcompat.c + --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/zapata_num_spans +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/zapata_num_spans @@ -0,0 +1,16 @@ +# Allow as many spans as Zaptel can take (defualt: 128). +# There is a static array of zt_pris allocated at this size. +# For that reason upstream only sort-of merged it: made it a +# compile-time option in 1.6 . + +--- a/channels/chan_zap.c ++++ b/channels/chan_zap.c +@@ -190,7 +190,7 @@ static const char config[] = "zapata.con + #define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) + #define SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) + +-#define NUM_SPANS 32 ++#define NUM_SPANS ZT_MAX_SPANS + #define NUM_DCHANS 4 /*!< No more than 4 d-channels */ + #define MAX_CHANNELS 672 /*!< No more than a DS3 per trunk group */ + --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/zapata-bri+euroisdn +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/zapata-bri+euroisdn @@ -0,0 +1,2171 @@ +--- a/include/asterisk/channel.h ++++ b/include/asterisk/channel.h +@@ -435,6 +435,7 @@ struct ast_channel { + unsigned int flags; /*!< channel flags of AST_FLAG_ type */ + unsigned short transfercapability; /*!< ISDN Transfer Capbility - AST_FLAG_DIGITAL is not enough */ + AST_LIST_HEAD_NOLOCK(, ast_frame) readq; ++ char lowlayercompat[16]; /*!< ISDN Low Layer Compatibility */ + int alertpipe[2]; + + int nativeformats; /*!< Kinds of data this channel can natively handle */ +--- a/channels/chan_zap.c ++++ b/channels/chan_zap.c +@@ -11,6 +11,10 @@ + * the project provides a web site, mailing lists and IRC + * channels for your use. + * ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns ++ * ++ * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. +@@ -216,8 +220,6 @@ static struct ast_channel inuse; + #ifdef PRI_GETSET_TIMERS + static int pritimers[PRI_MAX_TIMERS]; + #endif +-static int pridebugfd = -1; +-static char pridebugfilename[1024] = ""; + #endif + + /*! \brief Wait up to 16 seconds for first digit (FXO logic) */ +@@ -235,10 +237,6 @@ AST_MUTEX_DEFINE_STATIC(iflock); + + static int ifcount = 0; + +-#ifdef HAVE_PRI +-AST_MUTEX_DEFINE_STATIC(pridebugfdlock); +-#endif +- + /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not + when it's doing something critical. */ + AST_MUTEX_DEFINE_STATIC(monlock); +@@ -253,6 +251,7 @@ static enum ast_bridge_result zt_bridge( + + static int zt_sendtext(struct ast_channel *c, const char *text); + ++ + /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */ + static inline int zt_get_event(int fd) + { +@@ -297,6 +296,14 @@ static int ringt_base = DEFAULT_RINGT; + #define PRI_SPAN(p) (((p) >> 8) & 0xff) + #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01) + ++struct zt_suspended_call { ++ ast_mutex_t lock; /* Mutex */ ++ char msn[AST_MAX_EXTENSION]; /* the MSN to which this parked call belongs */ ++ char callid[10]; /* the callID provided by the user */ ++ int parked_at; /* extension in the call parking context */ ++ struct zt_suspended_call *next; ++}; ++ + struct zt_pri { + pthread_t master; /*!< Thread of master */ + ast_mutex_t lock; /*!< Mutex */ +@@ -310,6 +317,8 @@ struct zt_pri { + int nsf; /*!< Network-Specific Facilities */ + int dialplan; /*!< Dialing plan */ + int localdialplan; /*!< Local dialing plan */ ++ char nocid[AST_MAX_EXTENSION]; /*!< CallerID string to use if none provided */ ++ char withheldcid[AST_MAX_EXTENSION]; /*!< CallerID string to use if CallerID is withheld */ + char internationalprefix[10]; /*!< country access code ('00' for european dialplans) */ + char nationalprefix[10]; /*!< area access code ('0' for european dialplans) */ + char localprefix[20]; /*!< area access code + area code ('0'+area code for european dialplans) */ +@@ -321,6 +330,7 @@ struct zt_pri { + int prilogicalspan; /*!< Logical span number within trunk group */ + int numchans; /*!< Num of channels we represent */ + int overlapdial; /*!< In overlap dialing mode */ ++ int usercid; + int facilityenable; /*!< Enable facility IEs */ + struct pri *dchans[NUM_DCHANS]; /*!< Actual d-channels */ + int dchanavail[NUM_DCHANS]; /*!< Whether each channel is available */ +@@ -336,6 +346,8 @@ struct zt_pri { + struct zt_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */ + struct zt_pvt *crvs; /*!< Member CRV structs */ + struct zt_pvt *crvend; /*!< Pointer to end of CRV structs */ ++ struct zt_suspended_call *suspended_calls; /* Calls parked with SUSPEND messages */ ++ int debugfd; + }; + + +@@ -453,6 +465,8 @@ static struct zt_pvt { + unsigned int echocanbridged:1; + unsigned int echocanon:1; + unsigned int faxhandled:1; /*!< Has a fax tone already been handled? */ ++ /*!< KPJ: i will abuse this flag to implement a zapata option for dialing out ++ on a zap channel with EC to be off no matter what happens. */ + unsigned int firstradio:1; + unsigned int hanguponpolarityswitch:1; + unsigned int hardwaredtmf:1; +@@ -467,7 +481,8 @@ static struct zt_pvt { + unsigned int overlapdial:1; + unsigned int permcallwaiting:1; + unsigned int permhidecallerid:1; /*!< Whether to hide our outgoing caller ID or not */ +- unsigned int priindication_oob:1; ++ unsigned int priindication_oob:2; ++ unsigned int pritransfer:2; + unsigned int priexclusive:1; + unsigned int pulse:1; + unsigned int pulsedial:1; /*!< whether a pulse dial phone is detected */ +@@ -504,6 +519,7 @@ static struct zt_pvt { + #endif + char cid_num[AST_MAX_EXTENSION]; + int cid_ton; /*!< Type Of Number (TON) */ ++ int cid_pres; /*!< Calling Presentation */ + char cid_name[AST_MAX_EXTENSION]; + char lastcid_num[AST_MAX_EXTENSION]; + char lastcid_name[AST_MAX_EXTENSION]; +@@ -569,6 +585,8 @@ static struct zt_pvt { + struct zt_pvt *bearer; + struct zt_pvt *realcall; + q931_call *call; ++ int tei; /* channel in use by this tei */ ++ q931_call *holdedcall; + int prioffset; + int logicalspan; + #endif +@@ -614,11 +632,14 @@ static struct zt_chan_conf zt_chan_conf_ + .minunused = 2, + .idleext = "", + .idledial = "", ++ .nocid = "No CID available", ++ .withheldcid = "CID withheld", + .internationalprefix = "", + .nationalprefix = "", + .localprefix = "", + .privateprefix = "", + .unknownprefix = "", ++ .usercid = 0, + + .resetinterval = 3600 + }, +@@ -630,6 +651,8 @@ static struct zt_chan_conf zt_chan_conf_ + .mohinterpret = "default", + .mohsuggest = "", + .transfertobusy = 1, ++ .priindication_oob = 0, ++ .pritransfer = 0, + + .cid_signalling = CID_SIG_BELL, + .cid_start = CID_START_RING, +@@ -684,6 +707,8 @@ static int zt_indicate(struct ast_channe + static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); + static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen); + static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); ++static void enable_dtmf_detect(struct zt_pvt *p); ++static void disable_dtmf_detect(struct zt_pvt *p); + + static const struct ast_channel_tech zap_tech = { + .type = "Zap", +@@ -715,6 +740,13 @@ static const struct ast_channel_tech zap + struct zt_pvt *round_robin[32]; + + #ifdef HAVE_PRI ++struct app_tmp { ++ char app[256]; ++ char data[256]; ++ struct ast_channel *chan; ++ pthread_t t; ++}; ++ + static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri) + { + int res; +@@ -1410,12 +1442,16 @@ static void zt_enable_ec(struct zt_pvt * + int res; + if (!p) + return; ++ if (p->faxhandled) { ++ ast_log(LOG_DEBUG, "Not enabling echo cancellation on a fax/modem call\n"); ++ return; ++ } + if (p->echocanon) { + ast_log(LOG_DEBUG, "Echo cancellation already on\n"); + return; + } + if (p->digital) { +- ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n"); ++ ast_log(LOG_DEBUG, "Echo cancellation does not make any sense on digital connections!\n"); + return; + } + if (p->echocancel) { +@@ -1442,7 +1478,7 @@ static void zt_train_ec(struct zt_pvt *p + { + int x; + int res; +- if (p && p->echocancel && p->echotraining) { ++ if (p && p->echocancel && p->echotraining && (!p->digital) && (!p->faxhandled)) { + x = p->echotraining; + res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x); + if (res) +@@ -1803,7 +1839,12 @@ static int zt_call(struct ast_channel *a + ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel); + p->outgoing = 1; + +- set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); ++ if (IS_DIGITAL(ast->transfercapability)) { ++ set_actual_gain(p->subs[SUB_REAL].zfd, 0, 0, 0, p->law); ++ } else { ++ set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); ++ } ++ + + mysig = p->sig; + if (p->outsigmod > -1) +@@ -2034,6 +2075,7 @@ static int zt_call(struct ast_channel *a + case SIG_PRI: + /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ + p->dialdest[0] = '\0'; ++ disable_dtmf_detect(p); + break; + default: + ast_log(LOG_DEBUG, "not yet implemented\n"); +@@ -2054,6 +2096,12 @@ static int zt_call(struct ast_channel *a + const char *rr_str; + int redirect_reason; + ++ if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) { ++ // pass NO audio when ringing an isdn phone ++ p->dialing = 1; ++ // maybe we could allow passing audio when calling a p2p PBX, but well... ;-) ++ } ++ + c = strchr(dest, '/'); + if (c) + c++; +@@ -2076,6 +2124,7 @@ static int zt_call(struct ast_channel *a + ast_mutex_unlock(&p->lock); + return -1; + } ++ strncpy(p->dnid, (c + p->stripmsd), sizeof(p->dnid)-1); + if (mysig != SIG_FXSKS) { + p->dop.op = ZT_DIAL_OP_REPLACE; + s = strchr(c + p->stripmsd, 'w'); +@@ -2099,6 +2148,8 @@ static int zt_call(struct ast_channel *a + pri_rel(p->pri); + ast_mutex_unlock(&p->lock); + return -1; ++ } else { ++ // ast_log(LOG_NOTICE, "call %d\n", p->call); + } + if (!(sr = pri_sr_new())) { + ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); +@@ -2131,7 +2182,7 @@ static int zt_call(struct ast_channel *a + pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); + pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, + (p->digital ? -1 : +- ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))); ++ ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)), ast->lowlayercompat); + if (p->pri->facilityenable) + pri_facility_enable(p->pri->pri); + +@@ -2395,8 +2446,10 @@ static int pri_find_dchan(struct zt_pri + } + if (newslot < 0) { + newslot = 0; +- ast_log(LOG_WARNING, "No D-channels available! Using Primary channel %d as D-channel anyway!\n", ++ if (pri->nodetype != BRI_CPE_PTMP) { ++ ast_log(LOG_WARNING, "No D-channels available! Using Primary channel %d as D-channel anyway!\n", + pri->dchannels[newslot]); ++ } + } + if (old && (oldslot != newslot)) + ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n", +@@ -2406,6 +2459,16 @@ static int pri_find_dchan(struct zt_pri + } + #endif + ++static int zt_setlaw(int zfd, int law) ++{ ++ int res; ++ res = ioctl(zfd, ZT_SETLAW, &law); ++ if (res) ++ return res; ++ return 0; ++} ++ ++ + static int zt_hangup(struct ast_channel *ast) + { + int res; +@@ -2453,8 +2516,7 @@ static int zt_hangup(struct ast_channel + if (option_debug) + ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", + p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); +- p->ignoredtmf = 0; +- ++ + if (index > -1) { + /* Real channel, do some fixup */ + p->subs[index].owner = NULL; +@@ -2556,6 +2618,7 @@ static int zt_hangup(struct ast_channel + } + + if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { ++ int outgoing = p->outgoing; + p->owner = NULL; + p->ringt = 0; + p->distinctivering = 0; +@@ -2598,7 +2661,7 @@ static int zt_hangup(struct ast_channel + pri_call_set_useruser(p->call, useruser); + #endif + +- pri_hangup(p->pri->pri, p->call, -1); ++ pri_hangup(p->pri->pri, p->call, -1, -1); + p->call = NULL; + if (p->bearer) + p->bearer->call = NULL; +@@ -2618,7 +2681,28 @@ static int zt_hangup(struct ast_channel + if (atoi(cause)) + icause = atoi(cause); + } +- pri_hangup(p->pri->pri, p->call, icause); ++ ++ pri_hangup(p->pri->pri, p->call, icause, -1); ++ ++ /* if we send a rel9999ease complete we wont ge no hangup event, so clear the call here */ ++ if (icause == 34 || icause == 44 || icause == 82 || icause == 1 || icause == 81 || icause == 17) { ++ if ((ast->_state == AST_STATE_RING) || (ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING) || (ast->_state == AST_STATE_RESERVED)) { ++ p->call = NULL; ++ } else { ++ ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state); ++ icause = 16; /* Note, in pri_hangup() libpri will already override the cause */ ++ } ++ } ++ ++ if (p->pri->nodetype == BRI_NETWORK_PTMP) { ++ if ((icause == 16 || icause == -1) && (ast->_state != AST_STATE_UP)) { ++ if (outgoing) { ++ p->call = NULL; ++ } ++ } ++ } ++ ++ + } + if (res < 0) + ast_log(LOG_WARNING, "pri_disconnect failed\n"); +@@ -2802,10 +2886,14 @@ static int zt_answer(struct ast_channel + p->proceeding = 1; + res = pri_answer(p->pri->pri, p->call, 0, !p->digital); + pri_rel(p->pri); ++ /* stop ignoring inband dtmf */ ++ enable_dtmf_detect(p); + } else { + ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); + res = -1; + } ++ /* the audio path is complete now, train the echo canceler */ ++ zt_train_ec(p); + break; + #endif + case 0: +@@ -3436,6 +3524,15 @@ static int zt_fixup(struct ast_channel * + { + struct zt_pvt *p = newchan->tech_pvt; + int x; ++ if (newchan && newchan->tech_pvt) { ++ p = newchan->tech_pvt; ++ } ++ if (!p) { ++ if (newchan) { ++ ast_log(LOG_ERROR, "channel %s has no tech_pvt structure\n", newchan->name); ++ } ++ return 0; ++ } + ast_mutex_lock(&p->lock); + ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name); + if (p->owner == oldchan) { +@@ -3645,8 +3742,10 @@ static void zt_handle_dtmfup(struct ast_ + pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); + if (ast_async_goto(ast, target_context, "fax", 1)) + ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); +- } else ++ } else { ++ if (option_verbose > 2) + ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); ++ } + } else if (option_debug) + ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); + } else if (option_debug) +@@ -3805,7 +3904,7 @@ static struct ast_frame *zt_handle_event + if (p->call) { + if (p->pri && p->pri->pri) { + if (!pri_grab(p, p->pri)) { +- pri_hangup(p->pri->pri, p->call, -1); ++ pri_hangup(p->pri->pri, p->call, -1, -1); + pri_destroycall(p->pri->pri, p->call); + p->call = NULL; + pri_rel(p->pri); +@@ -4876,7 +4975,7 @@ static struct ast_frame *zt_read(struct + p->subs[index].f.data = NULL; + p->subs[index].f.datalen= 0; + } +- if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { ++ if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { + /* Perform busy detection. etc on the zap line */ + f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); + if (f) { +@@ -4888,8 +4987,9 @@ static struct ast_frame *zt_read(struct + } + } else if (f->frametype == AST_FRAME_DTMF) { + #ifdef HAVE_PRI +- if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) { +- /* Don't accept in-band DTMF when in overlap dial mode */ ++ if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) { ++ /* Don't accept in-band DTMF when in overlap dial mode ++ or when in non-overlap overlapdialing mode ... */ + f->frametype = AST_FRAME_NULL; + f->subclass = 0; + } +@@ -4964,7 +5064,9 @@ static int zt_write(struct ast_channel * + #endif + /* Write a frame of (presumably voice) data */ + if (frame->frametype != AST_FRAME_VOICE) { +- if (frame->frametype != AST_FRAME_IMAGE) ++ if (frame->frametype == AST_FRAME_TEXT) { ++ ast_log(LOG_NOTICE, "text\n"); ++ } else if (frame->frametype != AST_FRAME_IMAGE) + ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); + return 0; + } +@@ -5032,7 +5134,7 @@ static int zt_indicate(struct ast_channe + switch (condition) { + case AST_CONTROL_BUSY: + #ifdef HAVE_PRI +- if (p->priindication_oob && p->sig == SIG_PRI) { ++ if ((p->priindication_oob == 1) && p->sig == SIG_PRI) { + chan->hangupcause = AST_CAUSE_USER_BUSY; + chan->_softhangup |= AST_SOFTHANGUP_DEV; + res = 0; +@@ -5114,7 +5216,7 @@ static int zt_indicate(struct ast_channe + case AST_CONTROL_CONGESTION: + chan->hangupcause = AST_CAUSE_CONGESTION; + #ifdef HAVE_PRI +- if (p->priindication_oob && p->sig == SIG_PRI) { ++ if ((p->priindication_oob == 1) && p->sig == SIG_PRI) { + chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; + chan->_softhangup |= AST_SOFTHANGUP_DEV; + res = 0; +@@ -5311,8 +5413,12 @@ static struct ast_channel *zt_new(struct + if (state == AST_STATE_RING) + tmp->rings = 1; + tmp->tech_pvt = i; ++#ifdef HAVE_PRI ++ if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS) || (i->sig == SIG_PRI)) { ++#else + if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { +- /* Only FXO signalled stuff can be picked up */ ++#endif ++ /* Only FXO signalled stuff can be picked up */ /* i dont think so, mr. ulaw! we alaws like to pick up BRIs/PRIs */ + tmp->callgroup = i->callgroup; + tmp->pickupgroup = i->pickupgroup; + } +@@ -5442,6 +5548,7 @@ static void *ss_thread(void *data) + int len = 0; + int res; + int index; ++ int network; + + /* in the bizarre case where the channel has become a zombie before we + even get started here, abort safely +@@ -5470,10 +5577,17 @@ static void *ss_thread(void *data) + len = strlen(exten); + res = 0; + while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { +- if (len && !ast_ignore_pattern(chan->context, exten)) ++ if (len && !ast_ignore_pattern(chan->context, exten)) { + tone_zone_play_tone(p->subs[index].zfd, -1); +- else +- tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); ++ } else { ++ network = p->pri->nodetype == PRI_NETWORK || p->pri->nodetype == BRI_NETWORK || p->pri->nodetype == BRI_NETWORK_PTMP; ++ if (network) { ++ tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); ++ } else { ++ /* cpe be quiet */ ++ tone_zone_play_tone(p->subs[index].zfd, -1); ++ } ++ } + if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) + timeout = matchdigittimeout; + else +@@ -6687,9 +6801,20 @@ static int handle_init_event(struct zt_p + case ZT_EVENT_NOALARM: + i->inalarm = 0; + if (!i->unknown_alarm) { ++#ifdef HAVE_PRI ++ if (i->pri) { ++ if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) { ++ /* dont annoy BRI TE mode users with layer2layer alarms */ ++ } else { ++#endif + ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); + manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", + "Channel: %d\r\n", i->channel); ++#ifdef HAVE_PRI ++ } ++ } ++#endif ++ + } else { + i->unknown_alarm = 0; + } +@@ -6698,7 +6823,13 @@ static int handle_init_event(struct zt_p + i->inalarm = 1; + res = get_alarms(i); + do { +- const char *alarm_str = alarm2str(res); ++#ifdef HAVE_PRI ++ if (i->pri) { ++ if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) { ++ /* dont annoy BRI TE mode users with layer2layer alarms */ ++ } else { ++#endif ++ const char *alarm_str = alarm2str(res); + + /* hack alert! Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 + * doesn't know what to do with it. Don't confuse users with log messages. */ +@@ -6714,6 +6845,10 @@ static int handle_init_event(struct zt_p + "Alarm: %s\r\n" + "Channel: %d\r\n", + alarm_str, i->channel); ++#ifdef HAVE_PRI ++ } ++ } ++#endif + } while (0); + /* fall thru intentionally */ + case ZT_EVENT_ONHOOK: +@@ -6758,8 +6893,10 @@ static int handle_init_event(struct zt_p + zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); + break; + case SIG_PRI: +- zt_disable_ec(i); +- res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); ++ if (event != ZT_EVENT_ALARM) { ++ zt_disable_ec(i); ++ res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); ++ } + break; + default: + ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); +@@ -7052,6 +7189,8 @@ static int pri_resolve_span(int *span, i + } else { + if (si->totalchans == 31) { /* if it's an E1 */ + pris[*span].dchannels[0] = 16 + offset; ++ } else if (si->totalchans == 3) { /* if it's an S0 ZAPBRI */ ++ pris[*span].dchannels[0] = 3 + offset; + } else { + pris[*span].dchannels[0] = 24 + offset; + } +@@ -7305,6 +7444,11 @@ static struct zt_pvt *mkintf(int channel + destroy_zt_pvt(&tmp); + return NULL; + } ++ if ((pris[span].localdialplan) && (pris[span].localdialplan != conf->pri.localdialplan)) { ++ ast_log(LOG_ERROR, "Span %d is already a %s local dialing plan\n", span + 1, dialplan2str(pris[span].localdialplan)); ++ destroy_zt_pvt(&tmp); ++ return NULL; ++ } + if (pris[span].minunused && (pris[span].minunused != conf->pri.minunused)) { + ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.minunused); + destroy_zt_pvt(&tmp); +@@ -7322,6 +7466,11 @@ static struct zt_pvt *mkintf(int channel + return NULL; + } + pris[span].nodetype = conf->pri.nodetype; ++ ++ if (conf->pri.nodetype == BRI_NETWORK_PTMP) { ++ pris[span].dchanavail[0] = DCHAN_AVAILABLE; ++ pri_find_dchan(&pris[span]); ++ } + pris[span].switchtype = myswitchtype; + pris[span].nsf = conf->pri.nsf; + pris[span].dialplan = conf->pri.dialplan; +@@ -7330,9 +7479,13 @@ static struct zt_pvt *mkintf(int channel + pris[span].minunused = conf->pri.minunused; + pris[span].minidle = conf->pri.minidle; + pris[span].overlapdial = conf->pri.overlapdial; ++ pris[span].usercid = conf->pri.usercid; ++ pris[span].suspended_calls = NULL; + pris[span].facilityenable = conf->pri.facilityenable; + ast_copy_string(pris[span].idledial, conf->pri.idledial, sizeof(pris[span].idledial)); + ast_copy_string(pris[span].idleext, conf->pri.idleext, sizeof(pris[span].idleext)); ++ ast_copy_string(pris[span].nocid, conf->pri.nocid, sizeof(pris[span].nocid)); ++ ast_copy_string(pris[span].withheldcid, conf->pri.withheldcid, sizeof(pris[span].withheldcid)); + ast_copy_string(pris[span].internationalprefix, conf->pri.internationalprefix, sizeof(pris[span].internationalprefix)); + ast_copy_string(pris[span].nationalprefix, conf->pri.nationalprefix, sizeof(pris[span].nationalprefix)); + ast_copy_string(pris[span].localprefix, conf->pri.localprefix, sizeof(pris[span].localprefix)); +@@ -7485,6 +7638,7 @@ static struct zt_pvt *mkintf(int channel + tmp->restrictcid = conf->chan.restrictcid; + tmp->use_callingpres = conf->chan.use_callingpres; + tmp->priindication_oob = conf->chan.priindication_oob; ++ tmp->pritransfer = conf->chan.pritransfer; + tmp->priexclusive = conf->chan.priexclusive; + if (tmp->usedistinctiveringdetection) { + if (!tmp->use_callerid) { +@@ -7767,7 +7921,7 @@ static int pri_find_empty_chan(struct zt + break; + if (!backwards && (x >= pri->numchans)) + break; +- if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) { ++ if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner && !pri->pvts[x]->call) { + ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", + pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset); + return x; +@@ -7963,6 +8117,11 @@ static struct ast_channel *zt_request(co + p->digital = 1; + if (tmp) + tmp->transfercapability = AST_TRANS_CAP_DIGITAL; ++ } else if (opt == 'm') { ++ /* If this is a modem/fax call, pretend to have the fax handled and dont do EC */ ++ p->faxhandled = 1; ++ if (tmp) ++ tmp->transfercapability = AST_TRANS_CAP_3_1K_AUDIO; + } else { + ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); + } +@@ -7996,13 +8155,14 @@ next: + *cause = AST_CAUSE_BUSY; + } else if (groupmatched) { + *cause = AST_CAUSE_CONGESTION; ++ } else { ++ *cause = AST_CAUSE_CONGESTION; + } + } + + return tmp; + } + +- + #ifdef HAVE_PRI + static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv) + { +@@ -8047,6 +8207,7 @@ static int pri_find_principle(struct zt_ + static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c) + { + int x; ++ int res = 0; + struct zt_pvt *crv; + if (!c) { + if (principle < 0) +@@ -8077,6 +8238,7 @@ static int pri_fixup_principle(struct zt + } + /* Fix it all up now */ + new->owner = old->owner; ++ new->outgoing = old->outgoing; + old->owner = NULL; + if (new->owner) { + ast_string_field_build(new->owner, name, +@@ -8096,6 +8258,34 @@ static int pri_fixup_principle(struct zt + new->dsp_features = old->dsp_features; + old->dsp = NULL; + old->dsp_features = 0; ++ ++ /* Copy faxhandled/digial, alreadyhungup */ ++ new->faxhandled = old->faxhandled; ++ new->digital = old->digital; ++ new->alreadyhungup = old->alreadyhungup; ++ ++ /* Copy law, gains, etc */ ++ new->law = old->law; ++ if (ioctl(new->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &new->law) == -1) ++ ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", new->channel, new->law); ++ res = zt_setlaw(new->subs[SUB_REAL].zfd, new->law); ++ if (res < 0) ++ ast_log(LOG_WARNING, "Unable to set law on channel %d\n", new->channel); ++ if (!new->digital) { ++ res = set_actual_gain(new->subs[SUB_REAL].zfd, 0, new->rxgain, new->txgain, new->law); ++ } else { ++ res = set_actual_gain(new->subs[SUB_REAL].zfd, 0, 0, 0, new->law); ++ } ++ if (res < 0) ++ ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", new->channel); ++ ++ /* Shutdown old channel */ ++ zt_confmute(old, 0); ++ update_conf(old); ++ reset_conf(old); ++ restore_gains(old); ++ zt_disable_ec(old); ++ zt_setlinear(old->subs[SUB_REAL].zfd, 0); + } + return principle; + } +@@ -8124,7 +8314,9 @@ static int pri_fixup_principle(struct zt + } + crv = crv->next; + } +- ast_log(LOG_WARNING, "Call specified, but not found?\n"); ++ if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) { ++ ast_log(LOG_WARNING, "Call specified, but not found?\n"); ++ } + return -1; + } + +@@ -8183,86 +8375,21 @@ static void *do_idle_thread(void *vchan) + #ifndef PRI_RESTART + #error "Upgrade your libpri" + #endif +-static void zt_pri_message(struct pri *pri, char *s) ++static void zt_pri_message(char *s, int span) + { +- int x, y; +- int dchan = -1, span = -1; +- int dchancount = 0; +- +- if (pri) { +- for (x = 0; x < NUM_SPANS; x++) { +- for (y = 0; y < NUM_DCHANS; y++) { +- if (pris[x].dchans[y]) +- dchancount++; +- +- if (pris[x].dchans[y] == pri) +- dchan = y; +- } +- if (dchan >= 0) { +- span = x; +- break; +- } +- dchancount = 0; +- } +- if ((dchan >= 0) && (span >= 0)) { +- if (dchancount > 1) +- ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s); +- else +- ast_verbose("%s", s); +- } else +- ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n"); +- } else +- ast_verbose("%s", s); +- +- ast_mutex_lock(&pridebugfdlock); +- +- if (pridebugfd >= 0) +- write(pridebugfd, s, strlen(s)); +- +- ast_mutex_unlock(&pridebugfdlock); ++ ast_verbose("%d %s", span, s); + } + +-static void zt_pri_error(struct pri *pri, char *s) ++static void zt_pri_error(char *s, int span) + { +- int x, y; +- int dchan = -1, span = -1; +- int dchancount = 0; +- +- if (pri) { +- for (x = 0; x < NUM_SPANS; x++) { +- for (y = 0; y < NUM_DCHANS; y++) { +- if (pris[x].dchans[y]) +- dchancount++; +- +- if (pris[x].dchans[y] == pri) +- dchan = y; +- } +- if (dchan >= 0) { +- span = x; +- break; +- } +- dchancount = 0; +- } +- if ((dchan >= 0) && (span >= 0)) { +- if (dchancount > 1) +- ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s); +- else +- ast_log(LOG_ERROR, "%s", s); +- } else +- ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n"); +- } else +- ast_log(LOG_ERROR, "%s", s); +- +- ast_mutex_lock(&pridebugfdlock); +- +- if (pridebugfd >= 0) +- write(pridebugfd, s, strlen(s)); +- +- ast_mutex_unlock(&pridebugfdlock); ++ ast_log(LOG_WARNING, "%d %s", span, s); + } + + static int pri_check_restart(struct zt_pri *pri) + { ++ if ((pri->nodetype != PRI_NETWORK) && (pri->nodetype != PRI_CPE)) { ++ return 0; ++ } + do { + pri->resetpos++; + } while ((pri->resetpos < pri->numchans) && +@@ -8344,13 +8471,30 @@ static void apply_plan_to_number(char *b + } + } + +-static int zt_setlaw(int zfd, int law) +-{ +- int res; +- res = ioctl(zfd, ZT_SETLAW, &law); +- if (res) +- return res; +- return 0; ++static void pri_make_callerid(struct zt_pri *pri, char *callerid, int callerid_len, char *callingnum, int callingnum_len, int callingplan, int callingpres, int stripmsd) { ++ if (callingnum && (callingnum_len > stripmsd)) { ++ callingnum += stripmsd; ++ } ++ switch (callingplan) { ++ case PRI_INTERNATIONAL_ISDN: ++ snprintf(callerid, callerid_len, "%s%s", pri->internationalprefix, callingnum); ++ break; ++ case PRI_NATIONAL_ISDN: ++ snprintf(callerid, callerid_len, "%s%s", pri->nationalprefix, callingnum); ++ break; ++ case PRI_LOCAL_ISDN: ++ snprintf(callerid, callerid_len, "%s%s", pri->localprefix, callingnum); ++ break; ++ case PRI_PRIVATE: ++ snprintf(callerid, callerid_len, "%s%s", pri->privateprefix, callingnum); ++ break; ++ case PRI_UNKNOWN: ++ snprintf(callerid, callerid_len, "%s%s", pri->unknownprefix, callingnum); ++ break; ++ default: ++ snprintf(callerid, callerid_len, "%s", callingnum); ++ break; ++ } + } + + static void *pri_dchannel(void *vpri) +@@ -8530,15 +8674,44 @@ static void *pri_dchannel(void *vpri) + /* Check for an event */ + x = 0; + res = ioctl(pri->fds[which], ZT_GETEVENT, &x); +- if (x) ++ if ((pri->nodetype != BRI_CPE) && (pri->nodetype != BRI_CPE_PTMP)) { ++ /* dont annoy BRI TE mode users with layer2layer alarms */ ++ if (x) + ast_log(LOG_NOTICE, "PRI got event: %s (%d) on %s D-channel of span %d\n", event2str(x), x, pri_order(which), pri->span); ++ } + /* Keep track of alarm state */ + if (x == ZT_EVENT_ALARM) { + pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP); + pri_find_dchan(pri); ++ if ((pri->nodetype == BRI_CPE) || (pri->nodetype == BRI_CPE_PTMP)) { ++ if (pri->pri) { ++ for (i=0; inumchans; i++) { ++ struct zt_pvt *p = pri->pvts[i]; ++ if (p) { ++ if (p->call) { ++ if (p->pri && p->pri->pri) { ++ pri_destroycall(p->pri->pri, p->call); ++ p->call = NULL; ++ p->tei = -1; ++ } else ++ ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n"); ++ } ++ if (p->owner) ++ p->owner->_softhangup |= AST_SOFTHANGUP_DEV; ++ p->inalarm = 1; ++ } ++ } ++ pri_shutdown(pri->pri); ++ } ++ } + } else if (x == ZT_EVENT_NOALARM) { +- pri->dchanavail[which] |= DCHAN_NOTINALARM; +- pri_restart(pri->dchans[which]); ++ if ((pri->nodetype == BRI_CPE) || (pri->nodetype == BRI_CPE_PTMP)) { ++ pri->dchanavail[which] |= DCHAN_NOTINALARM; ++ // pri->dchanavail[which] |= DCHAN_UP; ++ } else { ++ pri->dchanavail[which] |= DCHAN_NOTINALARM; ++ pri_restart(pri->dchans[which]); ++ } + } + + if (option_debug) +@@ -8550,8 +8723,7 @@ static void *pri_dchannel(void *vpri) + break; + } + } else if (errno != EINTR) +- ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno)); +- ++ ast_log(LOG_WARNING, "pri_event returned error %d (%s) on span %d\n", errno, strerror(errno), pri->span); + if (e) { + if (pri->debug) + pri_dump_event(pri->dchans[which], e); +@@ -8576,6 +8748,17 @@ static void *pri_dchannel(void *vpri) + + switch (e->e) { + case PRI_EVENT_DCHAN_UP: ++ if (pri->nodetype == BRI_NETWORK_PTMP) { ++ if (option_verbose > 3) ++ ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up for TEI %d\n", pri_order(which), pri->span, e->gen.tei); ++ } else if (pri->nodetype == BRI_CPE_PTMP) { ++ if (option_verbose > 3) ++ ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span); ++ } else { ++ if (option_verbose > 1) ++ ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span); ++ } ++ + if (!pri->pri) pri_find_dchan(pri); + + /* Note presense of D-channel */ +@@ -8594,6 +8777,12 @@ static void *pri_dchannel(void *vpri) + } + break; + case PRI_EVENT_DCHAN_DOWN: ++ if (pri->nodetype == BRI_NETWORK_PTMP) { ++ if (option_verbose > 3) ++ ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down for TEI %d\n", pri_order(which), pri->span, e->gen.tei); ++ // PTMP BRIs have N dchans, handled by libpri ++ if (e->gen.tei == 0) break; ++ } + pri_find_dchan(pri); + if (!pri_is_up(pri)) { + pri->resetting = 0; +@@ -8601,16 +8790,18 @@ static void *pri_dchannel(void *vpri) + for (i = 0; i < pri->numchans; i++) { + struct zt_pvt *p = pri->pvts[i]; + if (p) { ++ if ((p->tei == e->gen.tei) || (pri->nodetype != BRI_NETWORK_PTMP)) { + if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { + /* T309 is not enabled : hangup calls when alarm occurs */ + if (p->call) { + if (p->pri && p->pri->pri) { +- pri_hangup(p->pri->pri, p->call, -1); ++ pri_hangup(p->pri->pri, p->call, -1, -1); + pri_destroycall(p->pri->pri, p->call); + p->call = NULL; + } else + ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n"); + } ++ p->tei = -1; + if (p->realcall) { + pri_hangup_all(p->realcall, pri); + } else if (p->owner) +@@ -8619,6 +8810,7 @@ static void *pri_dchannel(void *vpri) + p->inalarm = 1; + } + } ++ } + } + break; + case PRI_EVENT_RESTART: +@@ -8653,8 +8845,8 @@ static void *pri_dchannel(void *vpri) + pri_destroycall(pri->pri, pri->pvts[x]->call); + pri->pvts[x]->call = NULL; + } +- if (pri->pvts[chanpos]->realcall) +- pri_hangup_all(pri->pvts[chanpos]->realcall, pri); ++ if (pri->pvts[x]->realcall) ++ pri_hangup_all(pri->pvts[x]->realcall, pri); + else if (pri->pvts[x]->owner) + pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; + ast_mutex_unlock(&pri->pvts[x]->lock); +@@ -8688,7 +8880,6 @@ static void *pri_dchannel(void *vpri) + } + } + break; +- + case PRI_EVENT_INFO_RECEIVED: + chanpos = pri_find_principle(pri, e->ring.channel); + if (chanpos < 0) { +@@ -8697,9 +8888,11 @@ static void *pri_dchannel(void *vpri) + } else { + chanpos = pri_fixup_principle(pri, chanpos, e->ring.call); + if (chanpos > -1) { ++// ast_log(LOG_NOTICE, "INFO received on channel %d/%d span %d\n", ++// PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); + ast_mutex_lock(&pri->pvts[chanpos]->lock); + /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */ +- if (pri->overlapdial && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) { ++ if (pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) { + /* how to do that */ + int digitlen = strlen(e->ring.callednum); + char digit; +@@ -8711,6 +8904,14 @@ static void *pri_dchannel(void *vpri) + zap_queue_frame(pri->pvts[chanpos], &f, pri); + } + } ++ if (!pri->overlapdial) { ++ strncat(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten)); ++ if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten + 1)) { ++ tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1); ++ } else { ++ tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); ++ } ++ } + } + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } +@@ -8718,36 +8919,59 @@ static void *pri_dchannel(void *vpri) + break; + case PRI_EVENT_RING: + crv = NULL; +- if (e->ring.channel == -1) ++ if (e->ring.channel == -1) { ++ /* if no channel specified find one empty */ + chanpos = pri_find_empty_chan(pri, 1); +- else ++ } else { + chanpos = pri_find_principle(pri, e->ring.channel); ++ } + /* if no channel specified find one empty */ + if (chanpos < 0) { +- ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n", +- PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); ++ /* no channel specified and no free channel. this is a callwating SETUP */ ++ if (e->ring.channel <= 0) { ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Ignoring callwaiting SETUP on channel %d/%d span %d %d\n", PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span, e->ring.channel); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_USER_BUSY, -1); ++ break; ++ } + } else { ++ /* ok, we got a b channel for this call, lock it */ + ast_mutex_lock(&pri->pvts[chanpos]->lock); + if (pri->pvts[chanpos]->owner) { +- if (pri->pvts[chanpos]->call == e->ring.call) { +- ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", ++ /* safety check, for messed up retransmissions? */ ++ if (pri->pvts[chanpos]->call == e->ring.call) { ++ ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", + PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); +- break; ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ chanpos = -1; ++ break; ++ } else { ++ ast_log(LOG_WARNING, "Ring requested on channel %d/%d already in use on span %d. Hanging up owner.\n", ++ PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); ++ if (pri->pvts[chanpos]->realcall) { ++ pri_hangup_all(pri->pvts[chanpos]->realcall, pri); + } else { +- /* This is where we handle initial glare */ +- ast_log(LOG_DEBUG, "Ring requested on channel %d/%d already in use or previously requested on span %d. Attempting to renegotiating channel.\n", +- PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); +- ast_mutex_unlock(&pri->pvts[chanpos]->lock); +- chanpos = -1; ++ pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; ++ /* XXX destroy the call here, so we can accept the retransmission as a new call */ ++ pri_destroycall(pri->pri, e->ring.call); + } +- } +- if (chanpos > -1) + ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ chanpos = -1; ++ break; ++ } ++ } ++ if (chanpos > -1) { ++ /* everything is ok with the b channel */ ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ } + } +- if ((chanpos < 0) && (e->ring.flexible)) +- chanpos = pri_find_empty_chan(pri, 1); ++ /* actually, we already got a valid channel by now */ + if (chanpos > -1) { + ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ /* dont detect dtmfs before the signalling is done */ ++ disable_dtmf_detect(pri->pvts[chanpos]); ++ /* this channel is owned by this TEI */ ++ pri->pvts[chanpos]->tei = e->ring.tei; + if (pri->switchtype == PRI_SWITCH_GR303_TMC) { + /* Should be safe to lock CRV AFAIK while bearer is still locked */ + crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL)); +@@ -8761,13 +8985,14 @@ static void *pri_dchannel(void *vpri) + ast_log(LOG_WARNING, "Call received for busy CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span); + } else + ast_log(LOG_NOTICE, "Call received for unconfigured CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span); +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE, -1); + if (crv) + ast_mutex_unlock(&crv->lock); + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + break; + } + } ++ /* assign call to b channel */ + pri->pvts[chanpos]->call = e->ring.call; + apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan); + if (pri->pvts[chanpos]->use_callerid) { +@@ -8792,34 +9017,82 @@ static void *pri_dchannel(void *vpri) + } + apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri, + e->ring.redirectingnum, e->ring.callingplanrdnis); ++ /* get callingpres */ ++ pri->pvts[chanpos]->cid_pres = e->ring.callingpres; ++ switch (e->ring.callingpres) { ++ case PRES_PROHIB_USER_NUMBER_NOT_SCREENED: ++ case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: ++ case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: ++ case PRES_PROHIB_NETWORK_NUMBER: ++ ast_copy_string(pri->pvts[chanpos]->cid_name, pri->withheldcid, sizeof(pri->pvts[chanpos]->cid_name)); ++ break; ++ case PRES_NUMBER_NOT_AVAILABLE: ++ ast_copy_string(pri->pvts[chanpos]->cid_name, pri->nocid, sizeof(pri->pvts[chanpos]->cid_name)); ++ break; ++ } + /* If immediate=yes go to s|1 */ + if (pri->pvts[chanpos]->immediate) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n"); + pri->pvts[chanpos]->exten[0] = 's'; + pri->pvts[chanpos]->exten[1] = '\0'; +- } +- /* Get called number */ +- else if (!ast_strlen_zero(e->ring.callednum)) { +- ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten)); +- ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid)); +- } else if (pri->overlapdial) +- pri->pvts[chanpos]->exten[0] = '\0'; +- else { +- /* Some PRI circuits are set up to send _no_ digits. Handle them as 's'. */ +- pri->pvts[chanpos]->exten[0] = 's'; +- pri->pvts[chanpos]->exten[1] = '\0'; +- } +- /* Set DNID on all incoming calls -- even immediate */ +- if (!ast_strlen_zero(e->ring.callednum)) +- ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid)); +- /* No number yet, but received "sending complete"? */ +- if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) { ++ } else if (ast_strlen_zero(e->ring.callednum)) { ++ /* called party number is empty */ ++ if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) { ++ if (!pri->overlapdial) { ++ // be able to set digittimeout for BRI phones ++ pri->pvts[chanpos]->exten[0] = 's'; ++ pri->pvts[chanpos]->exten[1] = '\0'; ++ tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); ++ } else { ++ pri->pvts[chanpos]->exten[0] = '\0'; ++ } ++ } else { ++ if (pri->nodetype == BRI_CPE) { ++ /* fix for .at p2p bri lines */ ++ pri->pvts[chanpos]->exten[0] = 's'; ++ pri->pvts[chanpos]->exten[1] = '\0'; ++ } else if (pri->overlapdial) { ++ pri->pvts[chanpos]->exten[0] = '\0'; ++ } else { ++ /* Some PRI circuits are set up to send _no_ digits. Handle them as 's'. */ ++ pri->pvts[chanpos]->exten[0] = 's'; ++ pri->pvts[chanpos]->exten[1] = '\0'; ++ } ++ } ++ /* No number yet, but received "sending complete"? */ ++ if (e->ring.complete) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n"); + pri->pvts[chanpos]->exten[0] = 's'; + pri->pvts[chanpos]->exten[1] = '\0'; +- } ++ } ++ } else { ++ /* Get called number */ ++ pri_make_callerid(pri, pri->pvts[chanpos]->dnid, sizeof(pri->pvts[chanpos]->dnid), e->ring.callednum, sizeof(e->ring.callednum), e->ring.calledplan, 0, pri->pvts[chanpos]->stripmsd); ++ pri_make_callerid(pri, pri->pvts[chanpos]->exten, sizeof(pri->pvts[chanpos]->exten), e->ring.callednum, sizeof(e->ring.callednum), e->ring.calledplan, 0, pri->pvts[chanpos]->stripmsd); ++ if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) { ++ /* if we get the next digit we should stop the dialtone */ ++ if (!pri->overlapdial) { ++ // with overlapdial=no the exten is always prefixed by "s" ++ if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten + 1)) { ++ tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1); ++ } else { ++ tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); ++ } ++ } else { ++ if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten)) { ++ tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1); ++ } else { ++ tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); ++ } ++ } ++ } ++ } ++ /* Part 3: create channel, setup audio... */ ++ /* Set DNID on all incoming calls -- even immediate */ ++ if (!ast_strlen_zero(e->ring.callednum)) ++ strncpy(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid) - 1); + /* Make sure extension exists (or in overlap dial mode, can exist) */ + if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) || + ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { +@@ -8838,19 +9111,36 @@ static void *pri_dchannel(void *vpri) + res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law); + if (res < 0) + ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel); +- res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law); ++ if (IS_DIGITAL(e->ring.ctype)) { ++ res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[chanpos]->law); ++ } else { ++ res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law); ++ } + if (res < 0) + ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel); +- if (e->ring.complete || !pri->overlapdial) { ++ if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) { ++ if (e->ring.complete || !pri->overlapdial) { + /* Just announce proceeding */ + pri->pvts[chanpos]->proceeding = 1; + pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0); +- } else { ++ } else { + if (pri->switchtype != PRI_SWITCH_GR303_TMC) + pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); + else + pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); ++ } ++ } else { ++ /* BRI_NETWORK | BRI_NETWORK_PTMP */ ++ if (pri->overlapdial || (!strcasecmp(pri->pvts[chanpos]->exten, "s"))) { ++ /* send a SETUP_ACKNOWLEDGE */ ++ pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); ++ } else { ++ /* send an ALERTING ??? wtf */ ++ // pri_acknowledge(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); ++ pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0); ++ } + } ++ /* overlapdial = yes and the extension can be valid */ + /* Get the use_callingpres state */ + pri->pvts[chanpos]->callingpres = e->ring.callingpres; + +@@ -8862,10 +9152,17 @@ static void *pri_dchannel(void *vpri) + /* Set bearer and such */ + pri_assign_bearer(crv, pri, pri->pvts[chanpos]); + c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype); ++ if (c && (e->ring.lowlayercompat[0] > 0)) { ++ memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat)); ++ } + pri->pvts[chanpos]->owner = &inuse; + ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel); + } else { + c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype); ++ if (c && (e->ring.lowlayercompat[0] > 0)) { ++ memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat)); ++ } ++ zt_enable_ec(pri->pvts[chanpos]); /* XXX rethink */ + } + + ast_mutex_unlock(&pri->pvts[chanpos]->lock); +@@ -8873,6 +9170,16 @@ static void *pri_dchannel(void *vpri) + if (!ast_strlen_zero(e->ring.callingsubaddr)) { + pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr); + } ++ if (!ast_strlen_zero(e->ring.callingnum)) { ++ char tmpstr[256]; ++ pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingnum, sizeof(e->ring.callingnum), e->ring.callingplan, e->ring.callingpres, 0); ++ pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr); ++ } ++ if (!ast_strlen_zero(e->ring.callingani)) { ++ char tmpstr[256]; ++ pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingani, sizeof(e->ring.callingani), e->ring.callingplanuser, e->ring.callingpresuser, 0); ++ pbx_builtin_setvar_helper(c, "PRI_USER_CID", tmpstr); ++ } + if (e->ring.ani2 >= 0) { + snprintf(ani2str, 5, "%.2d", e->ring.ani2); + pbx_builtin_setvar_helper(c, "ANI2", ani2str); +@@ -8896,8 +9203,8 @@ static void *pri_dchannel(void *vpri) + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) { + if (option_verbose > 2) +- ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n", +- plancallingnum, S_OR(pri->pvts[chanpos]->exten, ""), ++ ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap %s call from '%s' to '%s' on channel %d/%d, span %d\n", ++ pri->pvts[chanpos]->digital ? "data" : "voice", plancallingnum, S_OR(pri->pvts[chanpos]->exten, ""), + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); + } else { + ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", +@@ -8905,15 +9212,19 @@ static void *pri_dchannel(void *vpri) + if (c) + ast_hangup(c); + else { +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1); + pri->pvts[chanpos]->call = NULL; + } + } + pthread_attr_destroy(&attr); + } else { ++ /* overlapdial = no */ + ast_mutex_unlock(&pri->lock); + /* Release PRI lock while we create the channel */ + c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype); ++ if (c && (e->ring.lowlayercompat[0] > 0)) { ++ memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat)); ++ } + if (c) { + char calledtonstr[10]; + +@@ -8940,26 +9251,43 @@ static void *pri_dchannel(void *vpri) + ast_mutex_lock(&pri->lock); + + if (option_verbose > 2) +- ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n", +- plancallingnum, pri->pvts[chanpos]->exten, ++ ast_verbose(VERBOSE_PREFIX_3 "Accepting %s call from '%s' to '%s' on channel %d/%d, span %d\n", ++ pri->pvts[chanpos]->digital ? "data" : "voice", e->ring.callingnum, pri->pvts[chanpos]->exten, + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); + zt_enable_ec(pri->pvts[chanpos]); ++ if(!ast_strlen_zero(e->ring.callingsubaddr)) { ++ pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr); ++ } ++ if (!ast_strlen_zero(e->ring.callingnum)) { ++ char tmpstr[256]; ++ pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingnum, sizeof(e->ring.callingnum), e->ring.callingplan, e->ring.callingpres, 0); ++ pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr); ++ } ++ if (!ast_strlen_zero(e->ring.callingani)) { ++ char tmpstr[256]; ++ pri_make_callerid(pri, tmpstr,sizeof(tmpstr), e->ring.callingani, sizeof(e->ring.callingani), e->ring.callingplanuser, e->ring.callingpresuser, 0); ++ pbx_builtin_setvar_helper(c, "PRI_USER_CID", e->ring.callednum); ++ } ++ if (!ast_strlen_zero(e->ring.useruserinfo)) { ++ pbx_builtin_setvar_helper(c, "UUI", e->ring.useruserinfo); ++ } + } else { + + ast_mutex_lock(&pri->lock); + + ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1); + pri->pvts[chanpos]->call = NULL; + } + } + } else { ++ /* invalid extension */ + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist. Rejecting call on channel %d/%d, span %d\n", + pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, + pri->pvts[chanpos]->prioffset, pri->span); +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED, -1); + pri->pvts[chanpos]->call = NULL; + pri->pvts[chanpos]->exten[0] = '\0'; + } +@@ -8968,9 +9296,9 @@ static void *pri_dchannel(void *vpri) + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } else { + if (e->ring.flexible) +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION, -1); + else +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL, -1); + } + break; + case PRI_EVENT_RINGING: +@@ -8986,7 +9314,7 @@ static void *pri_dchannel(void *vpri) + } else { + ast_mutex_lock(&pri->pvts[chanpos]->lock); + if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) { +- zt_enable_ec(pri->pvts[chanpos]); ++ // XXX zt_enable_ec(pri->pvts[chanpos]); + pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1; + pri->pvts[chanpos]->alerting = 1; + } else +@@ -9018,9 +9346,16 @@ static void *pri_dchannel(void *vpri) + } + break; + case PRI_EVENT_PROGRESS: +- /* Get chan value if e->e is not PRI_EVNT_RINGING */ ++ /* Get chan value if e->e is not PRI_EVENT_RINGING */ + chanpos = pri_find_principle(pri, e->proceeding.channel); + if (chanpos > -1) { ++ if ((pri->pvts[chanpos]->priindication_oob == 2) && (e->proceeding.cause == PRI_CAUSE_USER_BUSY)) { ++ /* received PROGRESS with cause BUSY, no inband callprogress wanted => hang up! */ ++ if (pri->pvts[chanpos]->owner) { ++ pri->pvts[chanpos]->owner->hangupcause = AST_CAUSE_USER_BUSY; ++ pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; ++ } ++ } else { + #ifdef PRI_PROGRESS_MASK + if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) { + #else +@@ -9062,11 +9397,18 @@ static void *pri_dchannel(void *vpri) + pri->pvts[chanpos]->progress = 1; + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } ++ } + } + break; + case PRI_EVENT_PROCEEDING: + chanpos = pri_find_principle(pri, e->proceeding.channel); + if (chanpos > -1) { ++ chanpos = pri_fixup_principle(pri, chanpos, e->proceeding.call); ++ if (chanpos < 0) { ++ ast_log(LOG_WARNING, "Received PROCEEDING on channel %d/%d not in use on span %d\n", ++ PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), pri->span); ++ chanpos = -1; ++ } else { + if (!pri->pvts[chanpos]->proceeding) { + struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, }; + +@@ -9091,6 +9433,7 @@ static void *pri_dchannel(void *vpri) + pri->pvts[chanpos]->proceeding = 1; + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } ++ } + } + break; + case PRI_EVENT_FACNAME: +@@ -9114,6 +9457,163 @@ static void *pri_dchannel(void *vpri) + } + } + break; ++ case PRI_EVENT_SUSPEND_REQ: ++ if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) { ++ pri_suspend_reject(pri->pri, e->suspend_req.call, ""); ++ break; ++ } ++ chanpos = pri_find_principle(pri, e->suspend_req.channel); ++ if (chanpos < 0) { ++ ast_log(LOG_WARNING, "Suspend requested on unconfigured channel %d span %d\n", chanpos, pri->span); ++ chanpos = -1; ++ } ++ ++ if (chanpos > -1) { ++ ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ if (pri->pvts[chanpos]->owner) { ++ if (ast_bridged_channel(pri->pvts[chanpos]->owner)) { ++ struct zt_suspended_call *zpc; ++ char tmpstr[256]; ++ zpc = malloc(sizeof(struct zt_suspended_call)); ++ if (!zpc) { ++ ast_log(LOG_ERROR, "unable to malloc zt_suspended_call\n"); ++ break; ++ } ++ strncpy(zpc->msn, pri->pvts[chanpos]->cid_num, sizeof(zpc->msn)); ++ strncpy(zpc->callid, e->suspend_req.callid, sizeof(zpc->callid)); ++ ast_masq_park_call(ast_bridged_channel(pri->pvts[chanpos]->owner), NULL, 0, &zpc->parked_at); ++ zpc->next = pri->suspended_calls; ++ pri->suspended_calls = zpc; ++ snprintf(tmpstr, sizeof(tmpstr), "Parked at %d", zpc->parked_at); ++ pri_suspend_acknowledge(pri->pri, e->suspend_req.call,tmpstr); ++ pri->pvts[chanpos]->call = NULL; ++ pri->pvts[chanpos]->tei = -1; ++ pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; ++ } else { ++ pri_suspend_reject(pri->pri, e->suspend_req.call, "cant park a non-bridge"); ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ break; ++ } ++ } else { ++ pri_suspend_reject(pri->pri, e->suspend_req.call, ""); ++ } ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ } ++ break; ++ case PRI_EVENT_RESUME_REQ: ++ if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) { ++ break; ++ } ++ chanpos = pri_find_empty_chan(pri, 1); ++ if (chanpos < 0) { ++ pri_resume_reject(pri->pri, e->resume_req.call,"All channels busy"); ++ ast_log(LOG_WARNING, "Resume requested on odd channel number %d span %d\n", chanpos, pri->span); ++ chanpos = -1; ++ } else if (!pri->pvts[chanpos]) { ++ pri_resume_reject(pri->pri, e->resume_req.call,"General protection fault in module 0x0BRI"); ++ chanpos = -1; ++ } ++ ++ if (chanpos > -1) { ++ ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ if (!pri->pvts[chanpos]->owner) { ++ struct zt_suspended_call *zpc, *zpcl; ++ int unparked=0; ++ char extenstr[255], temp[255]; ++ zpc = NULL; ++ zpcl = pri->suspended_calls; ++ while (zpcl) { ++ // ast_log(LOG_NOTICE, "zpc->parked_at %d zpcl->callid %s\n",zpcl->parked_at, zpcl->callid); ++ if (((strlen(zpcl->callid) == 0) && (strlen(e->resume_req.callid)==0)) || (!strcmp(zpcl->callid,e->resume_req.callid))) { ++ int law; ++ // found a parked call ++ snprintf(extenstr, sizeof(extenstr), "%d", zpcl->parked_at); ++ strncpy(pri->pvts[chanpos]->exten, extenstr, sizeof(pri->pvts[chanpos]->exten)); ++ // strncpy(pri->pvts[chanpos]->context, ast_parking_con(), sizeof(pri->pvts[chanpos]->context)); ++ pri->pvts[chanpos]->call = e->resume_req.call; ++ law = 1; ++ if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1) ++ ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]), law); ++ // uhh ohh...what shall we do without the bearer cap??? ++ law = ZT_LAW_ALAW; ++ res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law); ++ if (res < 0) ++ ast_log(LOG_WARNING, "Unable to set law on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos])); ++ if (!pri->pvts[chanpos]->digital) { ++ res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law); ++ } else { ++ res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[chanpos]->law); ++ } ++ if (res < 0) ++ ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos])); ++ /* Start PBX */ ++ c = zt_new(pri->pvts[chanpos], AST_STATE_UP, 1, SUB_REAL, law, PRI_TRANS_CAP_SPEECH); ++ if (c) { ++ pri->pvts[chanpos]->owner = c; ++ pri->pvts[chanpos]->call = e->resume_req.call; ++ zt_enable_ec(pri->pvts[chanpos]); ++ zt_train_ec(pri->pvts[chanpos]); ++ } else { ++ ast_log(LOG_ERROR, "unable to start pbx\n"); ++ } ++ ++ if (zpc) { ++ zpc->next = zpcl->next; ++ free(zpcl); ++ zpcl = zpc->next; ++ } else { ++ // remove head ++ pri->suspended_calls = zpcl->next; ++ free(zpcl); ++ zpcl = pri->suspended_calls; ++ zpc = NULL; ++ } ++ unparked = 1; ++ snprintf(temp, sizeof(temp), "Unparked %s", extenstr); ++ pri_resume_acknowledge(pri->pri, e->resume_req.call, chanpos + 1, temp); ++ break; ++ } ++ zpc = zpcl; ++ if (zpcl) zpcl = zpcl->next; ++ } ++ if (!unparked) ++ pri_resume_reject(pri->pri, e->resume_req.call,"No suspended call to unpark!"); ++ } else { ++ pri_resume_reject(pri->pri, e->resume_req.call,"No suspended call to unpark!"); ++ } ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ } ++ break; ++ case PRI_EVENT_HOLD_REQ: ++ if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) { ++ pri_hold_reject(pri->pri, e->hold_req.call); ++ break; ++ } ++ /* holded calls are not implemented yet */ ++ pri_hold_reject(pri->pri, e->hold_req.call); ++ break; ++ case PRI_EVENT_RETRIEVE_REQ: ++ if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) { ++ pri_retrieve_reject(pri->pri, e->retrieve_req.call); ++ break; ++ } ++ /* Holded calls are currently not supported */ ++ pri_retrieve_reject(pri->pri, e->retrieve_req.call); ++ chanpos = -1; ++ break; ++ case PRI_EVENT_DISPLAY_RECEIVED: ++ ast_log(LOG_NOTICE, "DISPLAY IE: [ %s ] received\n",e->display.text); ++ chanpos = pri_find_principle(pri, e->display.channel); ++ if (chanpos < 0) { ++ ast_log(LOG_WARNING, "odd channel number %d span %d\n", chanpos, pri->span); ++ chanpos = -1; ++ } ++ if (chanpos > -1) { ++ if (pri->pvts[chanpos]->owner) { ++ // ast_sendtext(pri->pvt[chanpos]->owner, e->display.text); ++ } ++ } ++ break; + case PRI_EVENT_ANSWER: + chanpos = pri_find_principle(pri, e->answer.channel); + if (chanpos < 0) { +@@ -9126,6 +9626,7 @@ static void *pri_dchannel(void *vpri) + PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); + } else { + ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ pri->pvts[chanpos]->tei = e->answer.tei; + /* Now we can do call progress detection */ + + /* We changed this so it turns on the DSP no matter what... progress or no progress. +@@ -9155,11 +9656,16 @@ static void *pri_dchannel(void *vpri) + ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr); + pri->pvts[chanpos]->dop.dialstr[0] = '\0'; + } else if (pri->pvts[chanpos]->confirmanswer) { +- ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel); ++ ast_log(LOG_DEBUG, "Waiting for answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel); ++ enable_dtmf_detect(pri->pvts[chanpos]); + } else { ++ pri->pvts[chanpos]->dialing = 0; + pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1; + /* Enable echo cancellation if it's not on already */ + zt_enable_ec(pri->pvts[chanpos]); ++ zt_train_ec(pri->pvts[chanpos]); ++ /* stop ignoring inband dtmf */ ++ enable_dtmf_detect(pri->pvts[chanpos]); + } + + #ifdef SUPPORT_USERUSER +@@ -9216,20 +9722,29 @@ static void *pri_dchannel(void *vpri) + ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause); + } else { +- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); ++ pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1); + pri->pvts[chanpos]->call = NULL; ++ pri->pvts[chanpos]->tei = -1; + } + if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) { +- if (option_verbose > 2) ++ if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) { ++ if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", +- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); +- pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); +- pri->pvts[chanpos]->resetting = 1; +- } +- if (e->hangup.aoc_units > -1) ++ PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); ++ pri->pvts[chanpos]->resetting = 1; ++ } ++ } ++ if (e->hangup.aoc_units > -1) { ++ if (pri->pvts[chanpos]->owner) { ++ char tmpstr[256]; ++ snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units); ++ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr); ++ } + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); ++ } + + #ifdef SUPPORT_USERUSER + if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) { +@@ -9242,8 +9757,9 @@ static void *pri_dchannel(void *vpri) + + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } else { +- ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", +- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei); ++ ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", ++ PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); + } + } + break; +@@ -9253,15 +9769,23 @@ static void *pri_dchannel(void *vpri) + case PRI_EVENT_HANGUP_REQ: + chanpos = pri_find_principle(pri, e->hangup.channel); + if (chanpos < 0) { +- ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", +- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); +- } else { ++ if (pri->nodetype == BRI_NETWORK_PTMP) { ++ pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1); ++ } else { ++ ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", ++ PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ } ++ } else if ((pri->pvts[chanpos]->priindication_oob != 2) || (!e->hangup.inband_progress) || (!pri->pvts[chanpos]->outgoing)) { ++ /* dont hang up if we want to hear inband call progress */ + chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); + if (chanpos > -1) { + ast_mutex_lock(&pri->pvts[chanpos]->lock); + if (pri->pvts[chanpos]->realcall) + pri_hangup_all(pri->pvts[chanpos]->realcall, pri); + else if (pri->pvts[chanpos]->owner) { ++ char tmpstr[256]; ++ snprintf(tmpstr, sizeof(tmpstr), "%d", e->hangup.cause); ++ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "PRI_CAUSE", tmpstr); + pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; + if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP) + pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; +@@ -9288,16 +9812,34 @@ static void *pri_dchannel(void *vpri) + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); ++ if (e->hangup.aoc_units > -1) { ++ if (pri->pvts[chanpos]->owner) { ++ char tmpstr[256]; ++ snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units); ++ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr); ++ } ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", ++ pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); ++ } ++ if (pri->nodetype == BRI_NETWORK_PTMP) { ++ pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1); ++ pri->pvts[chanpos]->call = NULL; ++ pri->pvts[chanpos]->tei = -1; ++ } + } else { +- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); ++ pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1); + pri->pvts[chanpos]->call = NULL; ++ pri->pvts[chanpos]->tei = -1; + } + if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) { +- if (option_verbose > 2) ++ if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) { ++ if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", + PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); +- pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); +- pri->pvts[chanpos]->resetting = 1; ++ pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); ++ pri->pvts[chanpos]->resetting = 1; ++ } + } + + #ifdef SUPPORT_USERUSER +@@ -9311,9 +9853,27 @@ static void *pri_dchannel(void *vpri) + + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } else { +- ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ if (pri->nodetype != BRI_NETWORK_PTMP) { ++ ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ } else { ++ ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ } + } + } ++ if ((chanpos > -1) && (pri->pvts[chanpos]->owner) && (pri->pvts[chanpos]->priindication_oob == 2) && (e->hangup.inband_progress) && (pri->pvts[chanpos]->outgoing)) { ++ ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ if (e->hangup.aoc_units > -1) { ++ char tmpstr[256]; ++ snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units); ++ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr); ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", ++ pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); ++ } ++ pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; ++ ast_channel_setwhentohangup(pri->pvts[chanpos]->owner, 5); ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ } + break; + case PRI_EVENT_HANGUP_ACK: + chanpos = pri_find_principle(pri, e->hangup.channel); +@@ -9325,6 +9885,7 @@ static void *pri_dchannel(void *vpri) + if (chanpos > -1) { + ast_mutex_lock(&pri->pvts[chanpos]->lock); + pri->pvts[chanpos]->call = NULL; ++ pri->pvts[chanpos]->tei = -1; + pri->pvts[chanpos]->resetting = 0; + if (pri->pvts[chanpos]->owner) { + if (option_verbose > 2) +@@ -9431,10 +9992,22 @@ static void *pri_dchannel(void *vpri) + ast_mutex_lock(&pri->pvts[chanpos]->lock); + switch (e->notify.info) { + case PRI_NOTIFY_REMOTE_HOLD: ++ if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) { ++ ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on NETWORK channel. Starting MoH\n"); ++ ast_moh_start(ast_bridged_channel(pri->pvts[chanpos]->owner), NULL, pri->pvts[chanpos]->mohinterpret); ++ } else { ++ ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on CPE channel. Not Starting MoH\n"); ++ } + f.subclass = AST_CONTROL_HOLD; + zap_queue_frame(pri->pvts[chanpos], &f, pri); + break; + case PRI_NOTIFY_REMOTE_RETRIEVAL: ++ if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) { ++ ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on NETWORK channel. Stopping MoH\n"); ++ ast_moh_stop(ast_bridged_channel(pri->pvts[chanpos]->owner)); ++ } else { ++ ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on CPE channel.\n"); ++ } + f.subclass = AST_CONTROL_UNHOLD; + zap_queue_frame(pri->pvts[chanpos], &f, pri); + break; +@@ -9442,6 +10015,23 @@ static void *pri_dchannel(void *vpri) + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } + break; ++ case PRI_EVENT_FACILITY: ++ if (e->facility.operation == 0x0D) { ++ struct ast_channel *owner = pri->pvts[chanpos]->owner; ++ ++ ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum); ++ ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ /* transfer */ ++ if (owner) { ++ ast_string_field_build(owner, call_forward, ++ "Local/%s@%s", e->facility.forwardnum, ++ owner->context); ++ } ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ } else { ++ ast_log(LOG_WARNING, "Unknown facility operation %#x requested.\n", e->facility.operation); ++ } ++ break; + default: + ast_log(LOG_DEBUG, "Event: %d\n", e->e); + } +@@ -9503,7 +10093,7 @@ static int start_pri(struct zt_pri *pri) + pri->fds[i] = -1; + return -1; + } +- pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype); ++ pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype, pri->span); + /* Force overlap dial if we're doing GR-303! */ + if (pri->switchtype == PRI_SWITCH_GR303_TMC) + pri->overlapdial = 1; +@@ -9571,39 +10161,77 @@ static char *complete_span_5(const char + + static int handle_pri_set_debug_file(int fd, int argc, char **argv) + { +- int myfd; ++ int myfd, x, d; ++ int span; ++ ++ if (argc < 6) ++ return RESULT_SHOWUSAGE; + + if (!strncasecmp(argv[1], "set", 3)) { +- if (argc < 5) ++ if (argc < 7) + return RESULT_SHOWUSAGE; + +- if (ast_strlen_zero(argv[4])) ++ if (!argv[4] || ast_strlen_zero(argv[4])) + return RESULT_SHOWUSAGE; + ++ if (!argv[5]) ++ return RESULT_SHOWUSAGE; ++ ++ if (!argv[6] || ast_strlen_zero(argv[6])) ++ return RESULT_SHOWUSAGE; ++ ++ span = atoi(argv[6]); ++ if ((span < 1) && (span > NUM_SPANS)) { ++ return RESULT_SUCCESS; ++ } ++ ++ + myfd = open(argv[4], O_CREAT|O_WRONLY, 0600); + if (myfd < 0) { + ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]); + return RESULT_SUCCESS; + } ++ for (x=0; x < NUM_SPANS; x++) { ++ ast_mutex_lock(&pris[x].lock); + +- ast_mutex_lock(&pridebugfdlock); +- +- if (pridebugfd >= 0) +- close(pridebugfd); +- +- pridebugfd = myfd; +- ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename)); +- +- ast_mutex_unlock(&pridebugfdlock); ++ if (pris[x].span == span) { ++ if (pris[x].debugfd >= 0) ++ close(pris[x].debugfd); ++ pris[x].debugfd = myfd; ++ for (d=0; d < NUM_DCHANS; d++) { ++ if (pris[x].dchans[d]) ++ pri_set_debug_fd(pris[x].dchans[d], myfd); ++ } ++ } ++ ast_mutex_unlock(&pris[x].lock); ++ } + +- ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]); ++ ast_cli(fd, "PRI debug output for span %d will be sent to '%s'\n", span, argv[4]); + } else { ++ if (!argv[5] || ast_strlen_zero(argv[5])) ++ return RESULT_SHOWUSAGE; + /* Assume it is unset */ +- ast_mutex_lock(&pridebugfdlock); +- close(pridebugfd); +- pridebugfd = -1; +- ast_cli(fd, "PRI debug output to file disabled\n"); +- ast_mutex_unlock(&pridebugfdlock); ++ span = atoi(argv[5]); ++ if ((span < 1) && (span > NUM_SPANS)) { ++ return RESULT_SUCCESS; ++ } ++ ++ for (x=0; x < NUM_SPANS; x++) { ++ ast_mutex_lock(&pris[x].lock); ++ ++ if (pris[x].span == span) { ++ if (pris[x].debugfd >= 0) ++ close(pris[x].debugfd); ++ pris[x].debugfd = -1; ++ for (d=0; d < NUM_DCHANS; d++) { ++ if (pris[x].dchans[d]) ++ pri_set_debug_fd(pris[x].dchans[d], -1); ++ } ++ } ++ ast_mutex_unlock(&pris[x].lock); ++ } ++ ++ ast_cli(fd, "PRI debug output to file for span %d disabled\n", span); + } + + return RESULT_SUCCESS; +@@ -9644,6 +10272,7 @@ static int handle_pri_debug(int fd, int + + + ++ + static int handle_pri_no_debug(int fd, int argc, char *argv[]) + { + int span; +@@ -9793,10 +10422,6 @@ static int handle_pri_show_debug(int fd, + } + + } +- ast_mutex_lock(&pridebugfdlock); +- if (pridebugfd >= 0) +- ast_cli(fd, "Logging PRI debug to file %s\n", pridebugfilename); +- ast_mutex_unlock(&pridebugfdlock); + + if (!count) + ast_cli(fd, "No debug set or no PRI running\n"); +@@ -9823,6 +10448,18 @@ static const char pri_show_spans_help[] + "Usage: pri show spans\n" + " Displays PRI Information\n"; + ++static char bri_debug_help[] = ++ "Usage: bri debug span \n" ++ " Enables debugging on a given BRI span\n"; ++ ++static char bri_no_debug_help[] = ++ "Usage: bri no debug span \n" ++ " Disables debugging on a given BRI span\n"; ++ ++static char bri_really_debug_help[] = ++ "Usage: bri intensive debug span \n" ++ " Enables debugging down to the Q.921 level\n"; ++ + static struct ast_cli_entry zap_pri_cli[] = { + { { "pri", "debug", "span", NULL }, + handle_pri_debug, "Enables PRI debugging on a span", +@@ -9847,6 +10484,15 @@ static struct ast_cli_entry zap_pri_cli[ + { { "pri", "show", "debug", NULL }, + handle_pri_show_debug, "Displays current PRI debug settings" }, + ++ { { "bri", "debug", "span", NULL }, handle_pri_debug, ++ "Enables BRI debugging on a span", bri_debug_help, complete_span_4 }, ++ ++ { { "bri", "no", "debug", "span", NULL }, handle_pri_no_debug, ++ "Disables BRI debugging on a span", bri_no_debug_help, complete_span_5 }, ++ ++ { { "bri", "intense", "debug", "span", NULL }, handle_pri_really_debug, ++ "Enables REALLY INTENSE BRI debugging", bri_really_debug_help, complete_span_5 }, ++ + { { "pri", "set", "debug", "file", NULL }, + handle_pri_set_debug_file, "Sends PRI debug output to the specified file" }, + +@@ -9859,8 +10505,76 @@ static struct ast_cli_entry zap_pri_cli[ + #endif + }; + ++static char *zapCD_tdesc = "Call Deflection"; ++static char *zapCD_app = "zapCD"; ++static char *zapCD_synopsis = "Call Deflection"; ++ ++static int app_zapCD(struct ast_channel *chan, void *data) ++{ ++ struct zt_pvt *p = chan->tech_pvt; ++ ++ if((!p->pri) || (!p->pri->pri)) { ++ return -1; ++ } ++ ++ if(!data) { ++ ast_log(LOG_WARNING, "zapCD wants a number to deflect to\n"); ++ return -1; ++ } ++ return pri_deflect(p->pri->pri, p->call, data); ++} ++ ++static char *zapInband_tdesc = "Inband Call Progress (pre-answer)"; ++static char *zapInband_app = "zapInband"; ++static char *zapInband_synopsis = "Inband Call Progress"; ++ ++static int app_zapInband(struct ast_channel *chan, void *data) ++{ ++ struct zt_pvt *p = chan->tech_pvt; ++ ++ return pri_acknowledge(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1); ++} ++ + #endif /* HAVE_PRI */ + ++static int app_zapEC(struct ast_channel *chan, void *data) ++{ ++ int res=-1; ++ struct zt_pvt *p = NULL; ++ ++ if (!data) { ++ ast_log(LOG_WARNING, "zapEC requires one argument (on | off)\n"); ++ } ++ if (chan && !strcasecmp("ZAP",chan->tech->type)) { ++ p = chan->tech_pvt; ++ if (!p) return res; ++ if (!strcasecmp("on",(char *)data)) { ++ zt_enable_ec(p); ++ res = 0; ++ if (option_verbose > 3) { ++ ast_verbose(VERBOSE_PREFIX_3 "Enabled echo cancelation on channel %s.\n", chan->name); ++ } ++ } else if (!strcasecmp("off",(char *)data)) { ++ zt_disable_ec(p); ++ res = 0; ++ if (option_verbose > 3) { ++ ast_verbose(VERBOSE_PREFIX_3 "Disabled echo cancelation on channel %s.\n", chan->name); ++ } ++ } else { ++ ast_log(LOG_WARNING, "Unknown argument %s to zapEC\n", (char *)data); ++ } ++ } else { ++ ast_log(LOG_WARNING, "zapNoEC only works on ZAP channels, check your extensions.conf!\n"); ++ res = 0; ++ } ++ ++ return res; ++} ++ ++static char *zapEC_tdesc = "Enable/disable Echo cancelation"; ++static char *zapEC_app = "zapEC"; ++static char *zapEC_synopsis = "Enable/Disable Echo Cancelation on a Zap channel"; ++ + static int zap_destroy_channel(int fd, int argc, char **argv) + { + int channel; +@@ -10441,8 +11155,11 @@ static int __unload_module(void) + } + ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); + ast_unregister_application(zap_send_keypad_facility_app); ++ ast_unregister_application(zapCD_app); ++ ast_unregister_application(zapInband_app); + #endif + ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); ++ ast_unregister_application(zapEC_app); + ast_manager_unregister( "ZapDialOffhook" ); + ast_manager_unregister( "ZapHangup" ); + ast_manager_unregister( "ZapTransfer" ); +@@ -10944,6 +11661,22 @@ static int process_zap(struct zt_chan_co + confp->chan.sig = SIG_GR303FXSKS; + confp->chan.radio = 0; + confp->pri.nodetype = PRI_CPE; ++ } else if (!strcasecmp(v->value, "bri_net_ptmp")) { ++ confp->chan.radio = 0; ++ confp->chan.sig = SIG_PRI; ++ confp->pri.nodetype = BRI_NETWORK_PTMP; ++ } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) { ++ confp->chan.sig = SIG_PRI; ++ confp->chan.radio = 0; ++ confp->pri.nodetype = BRI_CPE_PTMP; ++ } else if (!strcasecmp(v->value, "bri_net")) { ++ confp->chan.radio = 0; ++ confp->chan.sig = SIG_PRI; ++ confp->pri.nodetype = BRI_NETWORK; ++ } else if (!strcasecmp(v->value, "bri_cpe")) { ++ confp->chan.sig = SIG_PRI; ++ confp->chan.radio = 0; ++ confp->pri.nodetype = BRI_CPE; + #endif + } else { + ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); +@@ -11056,9 +11789,21 @@ static int process_zap(struct zt_chan_co + confp->chan.priindication_oob = 1; + else if (!strcasecmp(v->value, "inband")) + confp->chan.priindication_oob = 0; ++ else if (!strcasecmp(v->value, "passthrough")) ++ confp->chan.priindication_oob = 2; + else +- ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n", ++ ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband', 'outofband' or 'passthrough' at line %d\n", + v->value, v->lineno); ++ } else if (!strcasecmp(v->name, "pritransfer")) { ++ if (!strcasecmp(v->value, "no")) ++ confp->chan.pritransfer = 0; ++ else if (!strcasecmp(v->value, "ect")) ++ confp->chan.pritransfer = 1; ++ else if (!strcasecmp(v->value, "hangup")) ++ confp->chan.pritransfer = 2; ++ else ++ ast_log(LOG_WARNING, "'%s' is not a valid pri transfer value, should be 'no' , 'ect' or 'hangup' at line %d\n", ++ v->value, v->lineno); + } else if (!strcasecmp(v->name, "priexclusive")) { + confp->chan.priexclusive = ast_true(v->value); + } else if (!strcasecmp(v->name, "internationalprefix")) { +@@ -11071,6 +11816,10 @@ static int process_zap(struct zt_chan_co + ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix)); + } else if (!strcasecmp(v->name, "unknownprefix")) { + ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix)); ++ } else if (!strcasecmp(v->name, "nocid")) { ++ ast_copy_string(confp->pri.nocid, v->value, sizeof(confp->pri.nocid)); ++ } else if (!strcasecmp(v->name, "withheldcid")) { ++ ast_copy_string(confp->pri.withheldcid, v->value, sizeof(confp->pri.withheldcid)); + } else if (!strcasecmp(v->name, "resetinterval")) { + if (!strcasecmp(v->value, "never")) + confp->pri.resetinterval = -1; +@@ -11087,6 +11836,8 @@ static int process_zap(struct zt_chan_co + ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext)); + } else if (!strcasecmp(v->name, "idledial")) { + ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial)); ++ } else if (!strcasecmp(v->name, "pritrustusercid")) { ++ confp->pri.usercid = ast_true(v->value); + } else if (!strcasecmp(v->name, "overlapdial")) { + confp->pri.overlapdial = ast_true(v->value); + } else if (!strcasecmp(v->name, "pritimer")) { +@@ -11389,6 +12140,7 @@ static int setup_zap(int reload) + #ifdef HAVE_PRI + if (!reload) { + for (x = 0; x < NUM_SPANS; x++) { ++ pris[x].debugfd = -1; + if (pris[x].pvts[0]) { + if (start_pri(pris + x)) { + ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); +@@ -11436,7 +12188,10 @@ static int load_module(void) + ast_string_field_init(&inuse, 16); + ast_string_field_set(&inuse, name, "GR-303InUse"); + ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); ++ ast_register_application(zapCD_app, app_zapCD, zapCD_synopsis, zapCD_tdesc); ++ ast_register_application(zapInband_app, app_zapInband, zapInband_synopsis, zapInband_tdesc); + #endif ++ ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc); + ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); + + memset(round_robin, 0, sizeof(round_robin)); +@@ -11470,6 +12225,7 @@ static int zt_sendtext(struct ast_channe + float scont = 0.0; + int index; + ++ + index = zt_get_index(c, p, 0); + if (index < 0) { + ast_log(LOG_WARNING, "Huh? I don't exist?\n"); +--- a/configs/zapata.conf.sample ++++ b/configs/zapata.conf.sample +@@ -123,9 +123,20 @@ switchtype=national + ; + ; outofband: Signal Busy/Congestion out of band with RELEASE/DISCONNECT + ; inband: Signal Busy/Congestion using in-band tones ++; passthrough: Listen to the telco + ; + ; priindication = outofband + ; ++; PRI/BRI transfers (HOLD -> SETUP -> ECT/Hangup) ++; ++; Configure how transfers are initiated. ECT should be preferred ++; ++; no: no transfers allowed (results in hangup) ++; ect: use ECT (facility) ++; hangup: transfer on hangup (if your phones dont support ECT) ++; ++; pritransfer = ect ++; + ; If you need to override the existing channels selection routine and force all + ; PRI channels to be marked as exclusively selected, set this to yes. + ; priexclusive = yes --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/feature-holdedcalls +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/feature-holdedcalls @@ -0,0 +1,380 @@ +--- a/include/asterisk/features.h ++++ b/include/asterisk/features.h +@@ -72,6 +72,12 @@ int ast_park_call(struct ast_channel *ch + */ + int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *host, int timeout, int *extout); + ++extern int ast_hold_call(struct ast_channel *chan, struct ast_channel *host); ++extern int ast_masq_hold_call(struct ast_channel *rchan, struct ast_channel *host); ++extern int ast_retrieve_call(struct ast_channel *chan, char *uniqueid); ++extern int ast_retrieve_call_to_death(char *uniqueid); ++extern struct ast_channel *ast_get_holded_call(char *uniqueid); ++ + /*! \brief Determine system parking extension + * Returns the call parking extension for drivers that provide special + call parking help */ +--- a/res/res_features.c ++++ b/res/res_features.c +@@ -66,6 +66,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi + #include "asterisk/adsi.h" + #include "asterisk/devicestate.h" + #include "asterisk/monitor.h" ++#include "asterisk/indications.h" + + #define DEFAULT_PARK_TIME 45000 + #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000 +@@ -84,6 +85,7 @@ enum { + }; + + static char *parkedcall = "ParkedCall"; ++static char *holdedcall = "HoldedCall"; + + static int parkaddhints = 0; /*!< Add parking hints automatically */ + static int parkingtime = DEFAULT_PARK_TIME; /*!< No more than 45 seconds parked before you do something with them */ +@@ -168,6 +170,22 @@ struct parkeduser { + struct parkeduser *next; + }; + ++struct holdeduser { ++ struct ast_channel *chan; ++ struct timeval start; ++ int parkingnum; ++ int cref; ++ int tei; ++ /* Where to go if our parking time expires */ ++ char context[AST_MAX_EXTENSION]; ++ char exten[AST_MAX_EXTENSION]; ++ int priority; ++ int parkingtime; ++ char uniqueid[AST_MAX_UNIQUEID]; ++ char uniqueidpeer[AST_MAX_UNIQUEID]; ++ struct holdeduser *next; ++}; ++ + /* auto answer user */ + struct aauser { + struct ast_channel *chan; +@@ -187,10 +205,16 @@ static pthread_t autoanswer_thread; + + static struct parkeduser *parkinglot; + ++static struct holdeduser *holdlist; ++ + AST_MUTEX_DEFINE_STATIC(parking_lock); /*!< protects all static variables above */ + ++AST_MUTEX_DEFINE_STATIC(holding_lock); ++ + static pthread_t parking_thread; + ++static pthread_t holding_thread; ++ + char *ast_parking_ext(void) + { + return parking_ext; +@@ -2052,6 +2076,282 @@ static int park_exec(struct ast_channel + return res; + } + ++int ast_hold_call(struct ast_channel *chan, struct ast_channel *peer) ++{ ++ /* We put the user in the parking list, then wake up the parking thread to be sure it looks ++ after these channels too */ ++ struct holdeduser *pu; ++ pu = malloc(sizeof(struct holdeduser)); ++ if (pu) { ++ memset(pu, 0, sizeof(pu)); ++ ast_mutex_lock(&holding_lock); ++ chan->appl = "Holded Call"; ++ chan->data = NULL; ++ ++ pu->chan = chan; ++ strncpy(pu->uniqueid, chan->uniqueid, sizeof(pu->uniqueid)); ++ strncpy(pu->uniqueidpeer, peer->uniqueid, sizeof(pu->uniqueidpeer)); ++ /* Start music on hold */ ++ ast_moh_start(pu->chan, NULL, NULL); ++ gettimeofday(&pu->start, NULL); ++ pu->next = holdlist; ++ holdlist = pu; ++ ast_mutex_unlock(&holding_lock); ++ /* Wake up the (presumably select()ing) thread */ ++ pthread_kill(holding_thread, SIGURG); ++ ++ manager_event(EVENT_FLAG_CALL, "HoldedCall", ++ "Channel1: %s\r\n" ++ "Channel2: %s\r\n" ++ "Uniqueid1: %s\r\n" ++ "Uniqueid2: %s\r\n" ++ ,pu->chan->name, peer->name, pu->chan->uniqueid, peer->uniqueid); ++ ++ } else { ++ ast_log(LOG_WARNING, "Out of memory\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++int ast_masq_hold_call(struct ast_channel *rchan, struct ast_channel *peer) ++{ ++ struct ast_channel *chan; ++ struct ast_frame *f; ++ /* Make a new, fake channel that we'll use to masquerade in the real one */ ++ chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Onhold/%s",rchan->name); ++ if (chan) { ++ /* Let us keep track of the channel name */ ++ ast_string_field_build(chan, name, "Onhold/%s",rchan->name); ++ /* Make formats okay */ ++ chan->readformat = rchan->readformat; ++ chan->writeformat = rchan->writeformat; ++ ast_channel_masquerade(chan, rchan); ++ /* Setup the extensions and such */ ++ strncpy(chan->context, rchan->context, sizeof(chan->context) - 1); ++ strncpy(chan->exten, rchan->exten, sizeof(chan->exten) - 1); ++ chan->priority = rchan->priority; ++ /* this might be dirty, but we need to preserve the uniqueid */ ++ ast_string_field_build(chan, uniqueid, "%s",rchan->uniqueid); ++ /* Make the masq execute */ ++ f = ast_read(chan); ++ if (f) ++ ast_frfree(f); ++ ast_hold_call(chan, peer); ++ return -1; ++ } else { ++ ast_log(LOG_WARNING, "Unable to create holded channel\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++int ast_retrieve_call(struct ast_channel *chan, char *uniqueid) ++{ ++ int res=-1, dres=-1; ++ struct ast_channel *peer=NULL; ++ struct ast_bridge_config config; ++ ++ peer = ast_get_holded_call(uniqueid); ++ ++ /* JK02: it helps to answer the channel if not already up */ ++ if (chan->_state != AST_STATE_UP) { ++ ast_answer(chan); ++ } ++ ++ if (peer) { ++ ast_mutex_unlock(&peer->lock); ++ ast_moh_stop(peer); ++ res = ast_channel_make_compatible(chan, peer); ++ if (res < 0) { ++ ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name); ++ ast_hangup(peer); ++ return -1; ++ } ++ /* This runs sorta backwards, since we give the incoming channel control, as if it ++ were the person called. */ ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to holded call %s\n", chan->name, peer->name); ++ ++ memset(&config,0,sizeof(struct ast_bridge_config)); ++ ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT); ++ ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT); ++ config.timelimit = 0; ++ config.play_warning = 0; ++ config.warning_freq = 0; ++ config.warning_sound=NULL; ++ res = ast_bridge_call(chan,peer,&config); ++ ++ /* Simulate the PBX hanging up */ ++ if (res != AST_PBX_NO_HANGUP_PEER) ++ ast_hangup(peer); ++ return res; ++ } else { ++ /* XXX Play a message XXX */ ++ dres = ast_streamfile(chan, "pbx-invalidpark", chan->language); ++ if (!dres) ++ dres = ast_waitstream(chan, ""); ++ else { ++ ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", "pbx-invalidpark", chan->name); ++ dres = 0; ++ } ++ } ++ return res; ++} ++ ++int ast_retrieve_call_to_death(char *uniqueid) ++{ ++ int res=-1; ++ struct ast_channel *peer=NULL; ++ ++ peer = ast_get_holded_call(uniqueid); ++ ++ if (peer) { ++ res=0; ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s removed from hold.\n", peer->name); ++ ast_mutex_unlock(&peer->lock); ++ ast_hangup(peer); ++ } else { ++ ast_log(LOG_WARNING, "Could not find channel with uniqueid %s to retrieve.\n", uniqueid); ++ } ++ return res; ++} ++ ++struct ast_channel *ast_get_holded_call(char *uniqueid) ++{ ++ int res=-1; ++ struct ast_channel *peer=NULL; ++ struct holdeduser *pu, *pl=NULL; ++ ++ ast_mutex_lock(&holding_lock); ++ pu = holdlist; ++ while(pu) { ++ if (!strncmp(uniqueid,pu->uniqueid,sizeof(pu->uniqueid))) { ++ if (pl) ++ pl->next = pu->next; ++ else ++ holdlist = pu->next; ++ break; ++ } ++ pl = pu; ++ pu = pu->next; ++ } ++ ast_mutex_unlock(&holding_lock); ++ if (pu) { ++ peer = ast_get_channel_by_uniqueid_locked(pu->uniqueid); ++ free(pu); ++ if (peer) { ++ res=0; ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s removed from hold.\n", peer->name); ++ ast_moh_stop(peer); ++ return peer; ++ } else { ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Could not find channel with uniqueid %s.\n", uniqueid); ++ return NULL; ++ } ++ } else { ++ ast_log(LOG_WARNING, "Could not find held channel with uniqueid %s to retrieve.\n", uniqueid); ++ } ++ return NULL; ++} ++ ++/* this is our autmagically service thread that keeps channels onhold happy */ ++static void *do_holding_thread(void *ignore) ++{ ++ int ms, tms, max; ++ struct holdeduser *pu, *pl, *pt = NULL; ++ struct timeval tv; ++ struct ast_frame *f; ++ int x; ++ fd_set rfds, efds; ++ fd_set nrfds, nefds; ++ FD_ZERO(&rfds); ++ FD_ZERO(&efds); ++ for (;;) { ++ ms = -1; ++ max = -1; ++ ast_mutex_lock(&holding_lock); ++ pl = NULL; ++ pu = holdlist; ++ gettimeofday(&tv, NULL); ++ FD_ZERO(&nrfds); ++ FD_ZERO(&nefds); ++ while(pu) { ++ tms = (tv.tv_sec - pu->start.tv_sec) * 1000 + (tv.tv_usec - pu->start.tv_usec) / 1000; ++ for (x=0;xchan->fds[x] > -1) && (FD_ISSET(pu->chan->fds[x], &rfds) || FD_ISSET(pu->chan->fds[x], &efds))) { ++ if (FD_ISSET(pu->chan->fds[x], &efds)) ++ ast_set_flag(pu->chan, AST_FLAG_EXCEPTION); ++ else ++ ast_clear_flag(pu->chan, AST_FLAG_EXCEPTION); ++ pu->chan->fdno = x; ++ /* See if they need servicing */ ++ f = ast_read(pu->chan); ++ if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) { ++ /* There's a problem, hang them up*/ ++ if (option_verbose > 1) ++ ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being onhold\n", pu->chan->name); ++ ast_hangup(pu->chan); ++ /* find the corresponding channel and hang them up too! */ ++ /* but only if it is not bridged yet! */ ++ /* And take them out of the parking lot */ ++ if (pl) ++ pl->next = pu->next; ++ else ++ holdlist = pu->next; ++ pt = pu; ++ pu = pu->next; ++ free(pt); ++ break; ++ } else { ++ /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */ ++ ast_frfree(f); ++ goto std; /* XXX Ick: jumping into an else statement??? XXX */ ++ } ++ } ++ } ++ if (x >= AST_MAX_FDS) { ++std: for (x=0;xchan->fds[x] > -1) { ++ FD_SET(pu->chan->fds[x], &nrfds); ++ FD_SET(pu->chan->fds[x], &nefds); ++ if (pu->chan->fds[x] > max) ++ max = pu->chan->fds[x]; ++ } ++ } ++ /* Keep track of our longest wait */ ++ if ((tms < ms) || (ms < 0)) ++ ms = tms; ++ pl = pu; ++ pu = pu->next; ++ } ++ } ++ ast_mutex_unlock(&holding_lock); ++ rfds = nrfds; ++ efds = nefds; ++ tv.tv_sec = ms / 1000; ++ tv.tv_usec = (ms % 1000) * 1000; ++ /* Wait for something to happen */ ++ ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL); ++ pthread_testcancel(); ++ } ++ return NULL; /* Never reached */ ++} ++ ++static int retrieve_call_exec(struct ast_channel *chan, void *data) { ++ int res=0; ++ struct ast_module_user *u; ++ char *uniqueid = (char *)data; ++ u = ast_module_user_add(chan); ++ res = ast_retrieve_call(chan, uniqueid); ++ ast_module_user_remove(u); ++ return res; ++} ++ + static int handle_showfeatures(int fd, int argc, char *argv[]) + { + int i; +@@ -2933,6 +3233,7 @@ static int load_module(void) + return res; + ast_cli_register_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry)); + ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL); ++ ast_pthread_create(&holding_thread, NULL, do_holding_thread, NULL); + res = ast_register_application(parkedcall, park_exec, synopsis, descrip); + if (!res) + res = ast_register_application(parkcall, park_call_exec, synopsis2, descrip2); +@@ -2942,6 +3243,7 @@ static int load_module(void) + "Park a channel", mandescr_park); + } + ++ res |= ast_register_application(holdedcall, retrieve_call_exec, synopsis, descrip); + ast_pthread_create(&autoanswer_thread, NULL, do_autoanswer_thread, NULL); + if (!res) + res |= ast_register_application(autoanswerlogin, autoanswer_login_exec, synopsis3, descrip3); +@@ -2964,6 +3266,7 @@ static int unload_module(void) + ast_unregister_application(parkcall); + ast_unregister_application(autoanswer); + ast_unregister_application(autoanswerlogin); ++ ast_unregister_application(holdedcall); + ast_devstate_prov_del("Park"); + return ast_unregister_application(parkedcall); + } --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/misc-app-segfault +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/misc-app-segfault @@ -0,0 +1,58 @@ +--- /dev/null ++++ b/apps/app_segfault.c +@@ -0,0 +1,55 @@ ++/* ++ * Segfault application ++ * ++ * An application to provoke a segmentation fault from the dialplan. ++ * (I know what you are thinking now...., but since Asterisk is too stable... ++ * I needed something to test my failover switches.) ++ * ++ * Copyright (C) 2005 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns ++ * ++ * This program is free software, distributed under the terms of ++ * the GNU General Public License. THIS APPLICATION _WILL_ CRASH YOUR ++ * ASTERISK SERVER SO OF COURSE THERE IS NOT LIABILITY FOR NOTHING! ++ */ ++ ++#include "asterisk.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static char *app = "Segfault"; ++ ++static char *synopsis = "This application will crash Asterisk with a segmentation fault."; ++ ++static char *descrip = ++" Segfault(): Crash with a segfault. Never returns nufin.\n"; ++ ++static int segfault_exec(struct ast_channel *chan, void *data) ++{ ++ ((char *)0)[0] = 0; ++ return 0; ++} ++ ++static int unload_module(void) ++{ ++ return ast_unregister_application(app); ++} ++ ++static int load_module(void) ++{ ++ return ast_register_application(app, segfault_exec, synopsis, descrip); ++} ++ ++AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Application for crashing Asterisk with a segmentation fault", ++ .load = load_module, ++ .unload = unload_module, ++); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/zapata_euroisdn_holded +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/zapata_euroisdn_holded @@ -0,0 +1,470 @@ +--- a/main/pbx.c ++++ b/main/pbx.c +@@ -5146,7 +5146,7 @@ struct app_tmp { + }; + + /*! \brief run the application and free the descriptor once done */ +-static void *ast_pbx_run_app(void *data) ++void *ast_pbx_run_app(void *data) + { + struct app_tmp *tmp = data; + struct ast_app *app; +--- a/include/asterisk/pbx.h ++++ b/include/asterisk/pbx.h +@@ -145,6 +145,8 @@ void ast_unregister_switch(struct ast_sw + */ + struct ast_app *pbx_findapp(const char *app); + ++void *ast_pbx_run_app(void *data); ++ + /*! + * \brief Execute an application + * +--- a/channels/chan_zap.c ++++ b/channels/chan_zap.c +@@ -304,6 +304,19 @@ struct zt_suspended_call { + struct zt_suspended_call *next; + }; + ++struct zt_holded_call { ++ ast_mutex_t lock; /* Mutex */ ++ char msn[AST_MAX_EXTENSION]; /* the MSN to which this parked call belongs */ ++ char uniqueid[AST_MAX_EXTENSION]; /* unique id of the onhold channel */ ++ int tei; ++ int cref; ++ int alreadyhungup; ++ struct ast_channel *channel; ++ struct ast_channel *bridge; ++ q931_call *call; /* this also covers tei mumbojumbo */ ++ struct zt_holded_call *next; ++}; ++ + struct zt_pri { + pthread_t master; /*!< Thread of master */ + ast_mutex_t lock; /*!< Mutex */ +@@ -347,6 +360,7 @@ struct zt_pri { + struct zt_pvt *crvs; /*!< Member CRV structs */ + struct zt_pvt *crvend; /*!< Pointer to end of CRV structs */ + struct zt_suspended_call *suspended_calls; /* Calls parked with SUSPEND messages */ ++ struct zt_holded_call *holded_calls; /* Calls on hold */ + int debugfd; + }; + +@@ -7490,6 +7504,7 @@ static struct zt_pvt *mkintf(int channel + pris[span].overlapdial = conf.pri.overlapdial; + pris[span].usercid = conf.pri.usercid; + pris[span].suspended_calls = NULL; ++ pris[span].holded_calls = NULL; + pris[span].facilityenable = conf.pri.facilityenable; + ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial)); + ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext)); +@@ -8174,6 +8189,58 @@ static struct zt_pvt *pri_find_crv(struc + return NULL; + } + ++static int pri_find_tei(struct zt_pri *pri, q931_call *c, int tei) ++{ ++ int x=0; ++ for (x=0;xnumchans;x++) { ++ if (!pri->pvts[x]) continue; ++ if ((pri->pvts[x]->tei == tei) && (pri->pvts[x]-> call != c)) { ++ return x; ++ } ++ } ++ return -1; ++} ++ ++static struct zt_holded_call *pri_get_callonhold(struct zt_pri *pri, int cref, int tei) { ++ struct zt_holded_call *zhc = pri->holded_calls; ++ struct zt_holded_call *zhctemp = NULL; ++ ++ while (zhc) { ++ if ((zhc->tei == tei) && ((zhc->cref == cref) || (cref == -1))) { ++ return zhc; ++ } ++ zhctemp = zhc; ++ if (zhc) zhc = zhc->next; ++ } ++ return NULL; ++} ++ ++static int pri_destroy_callonhold(struct zt_pri *pri, struct zt_holded_call *onhold) { ++ struct zt_holded_call *zhc = pri->holded_calls; ++ struct zt_holded_call *zhctemp = NULL; ++ ++ while (zhc) { ++ if (zhc == onhold) { ++ if (zhctemp) { ++ zhctemp->next = zhc->next; ++ zhc = zhctemp; ++ } else { ++ pri->holded_calls = zhc->next; ++ zhc = pri->holded_calls; ++ zhctemp = NULL; ++ } ++ } ++ zhctemp = zhc; ++ if (zhc) zhc = zhc->next; ++ } ++ if (onhold) { ++ free(onhold); ++ onhold = NULL; ++ return 1; ++ } ++ return 0; ++} ++ + + static int pri_find_principle(struct zt_pri *pri, int channel) + { +@@ -9589,18 +9656,150 @@ static void *pri_dchannel(void *vpri) + pri_hold_reject(pri->pri, e->hold_req.call); + break; + } +- /* holded calls are not implemented yet */ +- pri_hold_reject(pri->pri, e->hold_req.call); ++ chanpos = pri_find_principle(pri, e->hold_req.channel); ++ if (chanpos < 0) { ++ ast_log(LOG_WARNING, "Hold requested on unconfigured channel %d span %d\n", chanpos, pri->span); ++ chanpos = -1; ++ } ++ if (chanpos > -1) { ++ // ast_log(LOG_NOTICE, "Hold request for channel number %d span %d\n", chanpos, pri->span); ++ ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ if (pri->pvts[chanpos]->owner) { ++ struct zt_pvt *p = pri->pvts[chanpos]; ++ struct zt_holded_call *zhc; ++ int holdacked=0; ++ ++// ast_log(LOG_NOTICE,"HOLD request from channel %s tei %d\n",p->owner->name, e->hold_req.tei); ++ if (ast_bridged_channel(p->owner)) { ++ zhc = malloc(sizeof(struct zt_holded_call)); ++ if (!zhc) { ++ ast_log(LOG_ERROR, "unable to malloc zt_holded_call\n"); ++ break; ++ } ++ memset(zhc, 0, sizeof(zhc)); ++ strncpy(zhc->msn, pri->pvts[chanpos]->cid_num, sizeof(zhc->msn)); ++ strncpy(zhc->uniqueid, ast_bridged_channel(p->owner)->uniqueid, sizeof(zhc->uniqueid)); ++ zhc->tei = e->hold_req.tei; ++ zhc->cref = e->hold_req.cref; ++ zhc->call = e->hold_req.call; ++ zhc->channel = p->owner; ++ zhc->alreadyhungup = 0; ++ zhc->bridge = ast_bridged_channel(p->owner); ++ zhc->next = pri->holded_calls; ++ pri->holded_calls = zhc; ++ ++ /* put channel on hold */ ++ ast_masq_hold_call(ast_bridged_channel(p->owner), p->owner); ++ ++ pri_hold_acknowledge(pri->pri, e->hold_req.call); ++ holdacked = 1; ++ p->call = NULL; // free the bchannel withouth destroying the call ++ p->tei = -1; ++ } else { ++ // cant hold a non-bridge,...yet ++ ++ // make a fake channel ++ ++ // masquerade ++ ++ // put on hold ++ pri_hold_reject(pri->pri, e->hold_req.call); ++ } ++ } else { ++ pri_hold_reject(pri->pri, e->hold_req.call); ++ } ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ } else { ++ pri_hold_reject(pri->pri, e->hold_req.call); ++ } + break; + case PRI_EVENT_RETRIEVE_REQ: + if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) { + pri_retrieve_reject(pri->pri, e->retrieve_req.call); + break; + } +- /* Holded calls are currently not supported */ +- pri_retrieve_reject(pri->pri, e->retrieve_req.call); +- chanpos = -1; +- break; ++ chanpos = pri_find_empty_chan(pri, 1); ++ if (chanpos < 0) { ++ pri_retrieve_reject(pri->pri, e->retrieve_req.call); ++ ast_log(LOG_WARNING, "Retrieve requested on odd channel number %d span %d\n", chanpos, pri->span); ++ chanpos = -1; ++ break; ++ } else if (!pri->pvts[chanpos]) { ++ ast_log(LOG_WARNING, "Retrieve requested on unconfigured channel number %d span %d\n", chanpos, pri->span); ++ pri_retrieve_reject(pri->pri, e->retrieve_req.call); ++ chanpos = -1; ++ break; ++ } ++ if (chanpos > -1) { ++ struct zt_holded_call *onhold = NULL; ++ int retrieved = 0; ++ int res = -1; ++ struct app_tmp *tmp; ++ pthread_attr_t attr; ++ int law; ++ ++ onhold = pri_get_callonhold(pri, e->retrieve_req.cref, e->retrieve_req.tei); ++ ++ if (!onhold) { ++ pri_retrieve_reject(pri->pri, e->retrieve_req.call); ++ break; ++ } ++ ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ // found a parked call ++ law = 1; ++ if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1) ++ ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]), law); ++ // uhh ohh...what shall we do without the bearer cap??? ++ law = ZT_LAW_ALAW; ++ res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law); ++ if (res < 0) ++ ast_log(LOG_WARNING, "Unable to set law on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos])); ++ res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law); ++ if (res < 0) ++ ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos])); ++ /* Start PBX */ ++ c = zt_new(pri->pvts[chanpos], AST_STATE_UP, 0, SUB_REAL, law, PRI_TRANS_CAP_SPEECH); ++ if (c) { ++ pri->pvts[chanpos]->owner = c; ++ pri->pvts[chanpos]->outgoing = 1; /* for not sending proceedings... */ ++ pri->pvts[chanpos]->call = e->retrieve_req.call; ++ pri->pvts[chanpos]->tei = e->retrieve_req.tei; ++ zt_enable_ec(pri->pvts[chanpos]); ++ zt_train_ec(pri->pvts[chanpos]); ++ } else { ++ ast_log(LOG_ERROR, "unable to start pbx\n"); ++ } ++ ++ retrieved = 1; ++ // ast_log(LOG_NOTICE, "sending RETRIEVE ACK on channel %d, span %d for tei %d cref %d\n",chanpos,pri->span, e->retrieve_req.tei, e->retrieve_req.cref); ++ pri_retrieve_acknowledge(pri->pri, e->retrieve_req.call, chanpos + 1); ++ ++ // the magic begins here: .... ++ tmp = malloc(sizeof(struct app_tmp)); ++ if (tmp) { ++ memset(tmp, 0, sizeof(struct app_tmp)); ++ strncpy(tmp->app, "holdedcall", sizeof(tmp->app) - 1); ++ strncpy(tmp->data, onhold->uniqueid, sizeof(tmp->data) - 1); ++ tmp->chan = c; ++ } ++ pri_destroy_callonhold(pri, onhold); ++ onhold = NULL; ++ ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ pthread_attr_init(&attr); ++ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); ++ if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { ++ ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", c->name, strerror(errno)); ++ free(tmp); ++ ast_hangup(c); ++ retrieved = 0; ++ } ++ ++ if (!retrieved) { ++ pri_retrieve_reject(pri->pri, e->retrieve_req.call); ++ } ++ } ++ break; + case PRI_EVENT_DISPLAY_RECEIVED: + ast_log(LOG_NOTICE, "DISPLAY IE: [ %s ] received\n",e->display.text); + chanpos = pri_find_principle(pri, e->display.channel); +@@ -9757,9 +9956,20 @@ static void *pri_dchannel(void *vpri) + + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } else { +- ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei); +- ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", +- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ struct zt_holded_call *onhold = NULL; ++ /* check calls on hold */ ++ onhold = pri_get_callonhold(pri, e->hangup.cref, e->hangup.tei); ++ ++ if (onhold) { ++ // ast_log(LOG_NOTICE, "hangup, found cref %d, tei %d\n",e->hangup.cref, e->hangup.tei); ++ pri_hangup(pri->pri, onhold->call, e->hangup.cause, -1); ++ pri_destroy_callonhold(pri, onhold); ++ onhold = NULL; ++ } else { ++ ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei); ++ ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", ++ PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ } + } + } + break; +@@ -9822,11 +10032,63 @@ static void *pri_dchannel(void *vpri) + ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); + } +- if (pri->nodetype == BRI_NETWORK_PTMP) { +- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1); +- pri->pvts[chanpos]->call = NULL; +- pri->pvts[chanpos]->tei = -1; +- } ++ if (pri->nodetype == BRI_NETWORK_PTMP) { ++ // check for bri transfers, not everybody uses ECT... ++ if (pri->pvts[chanpos]->owner) { ++ // find on hold call ++ struct zt_holded_call *onhold = NULL; ++ struct ast_channel *transferee = NULL; ++ int transfer_ok = 0; ++ ++ onhold = pri_get_callonhold(pri, -1, e->hangup.tei); ++ ++ if (onhold) { ++ if (pri->pvts[chanpos]->pritransfer == 2) { ++ if (((pri->pvts[chanpos]->owner->_state != AST_STATE_RING) && (pri->pvts[chanpos]->owner->_state != AST_STATE_RESERVED)) || ((!ast_strlen_zero(pri->pvts[chanpos]->exten)) && (strncasecmp(pri->pvts[chanpos]->exten, "s", sizeof(pri->pvts[chanpos]->exten))))) { ++ transferee = ast_get_holded_call(onhold->uniqueid); ++ ++ if (transferee) { ++ if (pri->pvts[chanpos]->owner->_state == AST_STATE_RINGING) { ++ ast_indicate(transferee, AST_CONTROL_RINGING); ++ } ++ ++ pri->pvts[chanpos]->owner->_softhangup &= ~AST_SOFTHANGUP_DEV; ++ ++ ast_mutex_unlock(&transferee->lock); ++ if (ast_channel_masquerade(pri->pvts[chanpos]->owner, transferee)) { ++ ast_log(LOG_WARNING, "unable to masquerade\n"); ++ } else { ++ /* beware of zombies!!! */ ++ ast_set_flag(transferee, AST_FLAG_ZOMBIE); ++ pri->pvts[chanpos]->owner = NULL; ++ pri->pvts[chanpos]->tei = -1; ++ transfer_ok = 1; ++ } ++ } ++ } ++ } else if (pri->pvts[chanpos]->pritransfer == 0) { ++ ast_log(LOG_NOTICE, "killing channel %s \n", onhold->uniqueid); ++ ast_retrieve_call_to_death(onhold->uniqueid); ++ transfer_ok = 1; ++ } else if (pri->pvts[chanpos]->pritransfer == 1) { ++ /* we use ECT transfers, so just ignore this */ ++ transfer_ok = 0; ++ } ++ ++ if (transfer_ok) { ++ onhold->alreadyhungup = 1; ++ pri_hangup(pri->pri, onhold->call, e->hangup.cause, -1); ++ onhold = NULL; ++ } ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ break; ++ } else { ++ pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1); ++ pri->pvts[chanpos]->call = NULL; ++ pri->pvts[chanpos]->tei = -1; ++ } ++ } ++ } + } else { + pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1); + pri->pvts[chanpos]->call = NULL; +@@ -9856,7 +10118,19 @@ static void *pri_dchannel(void *vpri) + if (pri->nodetype != BRI_NETWORK_PTMP) { + ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); + } else { +- ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ // check holded_calls!!! ++ struct zt_holded_call *onhold = NULL; ++ ++ onhold = pri_get_callonhold(pri, e->hangup.cref, e->hangup.tei); ++ ++ if (onhold) { ++ pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1); ++ ast_retrieve_call_to_death(onhold->uniqueid); ++ pri_destroy_callonhold(pri, onhold); ++ onhold = NULL; ++ } else { ++ ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); ++ } + } + } + } +@@ -10016,16 +10290,73 @@ static void *pri_dchannel(void *vpri) + } + break; + case PRI_EVENT_FACILITY: +- if (e->facility.operation == 0x0D) { +- struct ast_channel *owner = pri->pvts[chanpos]->owner; ++ if (e->facility.operation == 0x06) { ++ struct ast_channel *chan = NULL; ++ struct zt_holded_call *onhold = NULL; ++ if (option_verbose > 2) { ++ ast_verbose(VERBOSE_PREFIX_3 "ECT requested by TEI %d for cref %d\n", e->facility.tei, e->facility.cref); ++ } ++ /* search for cref/tei in held calls */ ++ onhold = pri_get_callonhold(pri, e->facility.cref, e->facility.tei); ++ if (onhold) { ++ chan = ast_get_holded_call(onhold->uniqueid); ++ onhold->alreadyhungup = 1; ++ onhold = NULL; ++ if (!chan) { ++ /* hang up */ ++ pri_hangup(pri->pri, e->facility.call, 16, -1); ++ break; ++ } ++ } else { ++ /* unknown cref/tei */ ++ ast_log(LOG_WARNING, "did not find call on hold for cref %d tei %d\n", e->facility.tei, e->facility.cref); ++ /* hang up */ ++ pri_hangup(pri->pri, e->facility.call, 16, -1); ++ break; ++ } + ++ /* find an active call for the same tei */ ++ chanpos = pri_find_tei(pri, e->facility.call, e->facility.tei); ++ if (chanpos < 0) { ++ /* did not find active call, hangup call on hold */ ++ if (chan) { ++ ast_hangup(chan); ++ chan = NULL; ++ } ++ } else { ++ ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ /* transfer */ ++ if (pri->pvts[chanpos]->owner) { ++ if (option_verbose > 3) { ++ ast_verbose(VERBOSE_PREFIX_3 "ECT: found %s on channel %d for tei %d\n", pri->pvts[chanpos]->owner->name ,chanpos, e->facility.tei); ++ } ++ /* pass callprogress if the channel is not up yet */ ++ if (pri->pvts[chanpos]->owner->_state == AST_STATE_RINGING) { ++ ast_indicate(chan, AST_CONTROL_RINGING); ++ } ++ /* unlock the channel we removed from hold */ ++ ast_mutex_unlock(&chan->lock); ++ if (ast_channel_masquerade(pri->pvts[chanpos]->owner, chan)) { ++ ast_log(LOG_WARNING, "unable to masquerade\n"); ++ } else { ++ /* beware of zombies !!! */ ++ ast_set_flag(chan, AST_FLAG_ZOMBIE); ++ // chan->zombie = 1; ++ } ++ } ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ } ++ /* disconnect */ ++ pri_hangup(pri->pri, e->facility.call, 16, -1); ++ } else if (e->facility.operation == 0x0D) { + ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum); + ast_mutex_lock(&pri->pvts[chanpos]->lock); + /* transfer */ +- if (owner) { +- ast_string_field_build(owner, call_forward, +- "Local/%s@%s", e->facility.forwardnum, +- owner->context); ++ if (pri->pvts[chanpos]->owner) { ++ struct ast_channel *owner = pri->pvts[chanpos]->owner; ++ ast_string_field_build(owner, call_forward, ++ "Local/%s@%s", e->facility.forwardnum, ++ owner->context); + } + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } else { --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/answer-before-say +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/answer-before-say @@ -0,0 +1,57 @@ +Answer the channel before saying things (SayNumber, SayDigits, +SayCharacters, SayPhonetic). + +--- a/main/pbx.c ++++ b/main/pbx.c +@@ -6076,6 +6076,9 @@ static int pbx_builtin_saynumber(struct + return -1; + } + } ++ if (chan->_state != AST_STATE_UP) { ++ ast_answer(chan); ++ } + + if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) { + ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp); +@@ -6088,8 +6091,12 @@ static int pbx_builtin_saydigits(struct + { + int res = 0; + +- if (data) ++ if (data) { ++ if (chan->_state != AST_STATE_UP) { ++ ast_answer(chan); ++ } + res = ast_say_digit_str(chan, data, "", chan->language); ++ } + return res; + } + +@@ -6097,8 +6104,12 @@ static int pbx_builtin_saycharacters(str + { + int res = 0; + +- if (data) ++ if (data) { ++ if (chan->_state != AST_STATE_UP) { ++ ast_answer(chan); ++ } + res = ast_say_character_str(chan, data, "", chan->language); ++ } + return res; + } + +@@ -6106,8 +6117,12 @@ static int pbx_builtin_sayphonetic(struc + { + int res = 0; + +- if (data) ++ if (data) { ++ if (chan->_state != AST_STATE_UP) { ++ ast_answer(chan); ++ } + res = ast_say_phonetic_str(chan, data, "", chan->language); ++ } + return res; + } + --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/ast-send-message +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/ast-send-message @@ -0,0 +1,238 @@ +Change the ABI of ast_channel_tech to add a new function, send_message that is +to be used by channels wanting to send text messages with a destination number +(mainly GSM). + +--- a/include/asterisk/channel.h ++++ b/include/asterisk/channel.h +@@ -247,6 +247,11 @@ struct ast_channel_tech { + /*! \brief Display or transmit text */ + int (* const send_text)(struct ast_channel *chan, const char *text); + ++#if 0 /* we (Debian) disable that addition because of ABI breakage */ ++ /*! \brief send a message */ ++ int (* const send_message)(struct ast_channel *chan, const char *dest, const char *text, int ispdu); ++#endif ++ + /*! \brief Display or send an image */ + int (* const send_image)(struct ast_channel *chan, struct ast_frame *frame); + +@@ -689,6 +694,16 @@ struct ast_channel *ast_request_and_dial + + struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, struct outgoing_helper *oh); + ++/*! \brief "Requests" a channel for sending a message ++ * \param type type of channel to request ++ * \param data data to pass to the channel requester ++ * \param status status ++ * Request a channel of a given type, with data as optional information used ++ * by the low level module ++ * \return Returns 0 on success, -1 on failure. ++ */ ++int ast_send_message(const char *type, void *data, char *to, char *from, char *message, int ispdu); ++ + /*!\brief Register a channel technology (a new channel driver) + * Called by a channel module to register the kind of channels it supports. + * \param tech Structure defining channel technology or "type" +@@ -910,6 +925,16 @@ int ast_set_write_format(struct ast_chan + */ + int ast_sendtext(struct ast_channel *chan, const char *text); + ++/*! \brief Sends message to a channel ++ * Write text to a display on a channel ++ * \param chan channel to act upon ++ * \param dest destination number/user ++ * \param text string of text to send on the channel ++ * \param ispdu message is in PDU format ++ * \return Returns 0 on success, -1 on failure ++ */ ++int ast_sendmessage(struct ast_channel *chan, const char *dest, const char *text, int ispdu); ++ + /*! \brief Receives a text character from a channel + * \param chan channel to act upon + * \param timeout timeout in milliseconds (0 for infinite wait) +--- a/main/channel.c ++++ b/main/channel.c +@@ -2472,6 +2472,21 @@ int ast_sendtext(struct ast_channel *cha + return res; + } + ++int ast_sendmessage(struct ast_channel *chan, const char *dest, const char *text, int ispdu) ++{ ++ int res = 0; ++ /* Stop if we're a zombie or need a soft hangup */ ++ if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) ++ return -1; ++ CHECK_BLOCKING(chan); ++#if 0 /* we (Debian) disable that addition because of ABI breakage */ ++ if (chan->tech->send_message) ++ res = chan->tech->send_message(chan, dest, text, ispdu); ++#endif ++ ast_clear_flag(chan, AST_FLAG_BLOCKING); ++ return res; ++} ++ + int ast_senddigit_begin(struct ast_channel *chan, char digit) + { + /* Device does not support DTMF tones, lets fake +@@ -4515,6 +4530,25 @@ void ast_channel_stop_silence_generator( + } + + ++int ast_send_message(const char *type, void *data, char *to, char *from, char *message, int ispdu) { ++ struct ast_channel *chan = NULL; ++ int status; ++ int res = -1; ++ ++ chan = ast_request(type, AST_FORMAT_SLINEAR, data, &status); ++ if (chan) { ++ if (from) { ++ ast_set_callerid(chan, from, from, from); ++ } ++ res = ast_sendmessage(chan, to, message, ispdu); ++ /* XXX what about message CDRs ??? XXX */ ++ ast_hangup(chan); ++ return res; ++ } ++ ++ return res; ++} ++ + /*! \ brief Convert channel reloadreason (ENUM) to text string for manager event */ + const char *channelreloadreason2txt(enum channelreloadreason reason) + { +--- a/main/manager.c ++++ b/main/manager.c +@@ -11,6 +11,9 @@ + * the project provides a web site, mailing lists and IRC + * channels for your use. + * ++ * Copyright (C) 2003-2004, Junghanns.NET Gmbh ++ * Klaus-Peter Junghanns ++ * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. +@@ -1430,6 +1433,49 @@ static int action_hangup(struct mansessi + return 0; + } + ++static char mandescr_message[] = ++"Description: Send a message\n" ++"Variables: \n" ++" Channel: The destination channel(e.g. SIP/phone1)\n" ++" From: \n" ++" Message: The message to send\n"; ++ ++static int action_message(struct mansession *s, const struct message *m) ++{ ++ const char *name = astman_get_header(m, "Channel"); ++ const char *from = astman_get_header(m, "From"); ++ const char *message = astman_get_header(m, "Message"); ++ const char *pdu = astman_get_header(m, "PDU"); ++ char tmp[256]; ++ char *tech, *data; ++ int res; ++ if (ast_strlen_zero(name) || (ast_strlen_zero(message) && ast_strlen_zero(pdu))) { ++ astman_send_error(s, m, "No channel or message/PDU specified"); ++ return 0; ++ } ++ ast_copy_string(tmp, name, sizeof(tmp)); ++ tech = tmp; ++ data = strchr(tmp, '/'); ++ if (!data) { ++ astman_send_error(s, m, "Invalid channel\n"); ++ return 0; ++ } ++ *data = '\0'; ++ data++; ++ if (ast_strlen_zero(pdu)) { ++ res = ast_send_message(tech, (char *)data, (char *)name, (char *)from, (char *)message, 0); ++ } else { ++ res = ast_send_message(tech, (char *)data, (char *)name, (char *)from, (char *)pdu, 1); ++ } ++ ++ if (res) { ++ astman_send_error(s, m, "Error sending message"); ++ return 0; ++ } ++ astman_send_ack(s, m, "Message sent"); ++ return 0; ++} ++ + static char mandescr_setvar[] = + "Description: Set a global or local channel variable.\n" + "Variables: (Names marked with * are required)\n" +@@ -2894,6 +2940,7 @@ int init_manager(void) + ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events); + ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff); + ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup); ++ ast_manager_register2("Message", EVENT_FLAG_CALL, action_message, "Send Message", mandescr_message); + ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" ); + ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar ); + ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar ); +--- a/pbx/pbx_spool.c ++++ b/pbx/pbx_spool.c +@@ -87,6 +87,10 @@ struct outgoing { + char app[256]; + char data[256]; + ++ /* If SMS */ ++ char message[256]; ++ char pdu[256]; ++ + /* If extension/context/priority */ + char exten[256]; + char context[256]; +@@ -181,6 +185,10 @@ static int apply_outgoing(struct outgoin + ast_copy_string(o->app, c, sizeof(o->app)); + } else if (!strcasecmp(buf, "data")) { + ast_copy_string(o->data, c, sizeof(o->data)); ++ } else if (!strcasecmp(buf, "message")) { ++ strncpy(o->message, c, sizeof(o->message) - 1); ++ } else if (!strcasecmp(buf, "pdu")) { ++ strncpy(o->pdu, c, sizeof(o->pdu) - 1); + } else if (!strcasecmp(buf, "maxretries")) { + if (sscanf(c, "%d", &o->maxretries) != 1) { + ast_log(LOG_WARNING, "Invalid max retries at line %d of %s\n", lineno, fn); +@@ -241,8 +249,8 @@ static int apply_outgoing(struct outgoin + } + } + ast_copy_string(o->fn, fn, sizeof(o->fn)); +- if (ast_strlen_zero(o->tech) || ast_strlen_zero(o->dest) || (ast_strlen_zero(o->app) && ast_strlen_zero(o->exten))) { +- ast_log(LOG_WARNING, "At least one of app or extension must be specified, along with tech and dest in file %s\n", fn); ++ if (ast_strlen_zero(o->tech) || ast_strlen_zero(o->dest) || ((ast_strlen_zero(o->app) && ast_strlen_zero(o->exten) && ast_strlen_zero(o->message) && ast_strlen_zero(o->pdu)))) { ++ ast_log(LOG_WARNING, "At least one of app or extension (or keyword message/pdu)must be specified, along with tech and dest in file %s\n", fn); + return -1; + } + return 0; +@@ -332,6 +340,14 @@ static void *attempt_thread(void *data) + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries); + res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL); ++ } else if (!ast_strlen_zero(o->message)) { ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Attempting to send message on %s/%s (Retry %d)\n", o->tech, o->dest, o->retries); ++ res = ast_send_message(o->tech, o->dest, o->dest, (ast_strlen_zero(o->cid_name) ? o->cid_num : o->cid_name), o->message, 0); ++ } else if (!ast_strlen_zero(o->pdu)) { ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Attempting to send message in PDU format on %s/%s (Retry %d)\n", o->tech, o->dest, o->retries); ++ res = ast_send_message(o->tech, o->dest, o->dest, (ast_strlen_zero(o->cid_name) ? o->cid_num : o->cid_name), o->pdu, 1); + } else { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries); +@@ -348,9 +364,14 @@ static void *attempt_thread(void *data) + safe_append(o, time(NULL), "EndRetry"); + } + } else { ++ if (!ast_strlen_zero(o->message)) { ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_2 "Message sent to %s/%s\n", o->tech, o->dest); ++ } else { + ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest); + ast_log(LOG_EVENT, "Queued call to %s/%s completed\n", o->tech, o->dest); +- remove_from_queue(o, "Completed"); ++ } ++ remove_from_queue(o, "Completed"); + } + free_outgoing(o); + return NULL; --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/bristuff-notice +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/bristuff-notice @@ -0,0 +1,47 @@ +--- a/README ++++ b/README +@@ -4,6 +4,8 @@ and the Asterisk.org developer community + + Copyright (C) 2001-2006 Digium, Inc. + and other copyright holders. ++Copyright (C) 2002-2005 Junghanns.NET GmbH ++and other copyright holders. + ================================================================ + + * SECURITY +--- a/LICENSE ++++ b/LICENSE +@@ -1,7 +1,7 @@ +-Asterisk is distributed under the GNU General Public License version 2 +-and is also available under alternative licenses negotiated directly +-with Digium, Inc. If you obtained Asterisk under the GPL, then the GPL +-applies to all loadable Asterisk modules used on your system as well, ++BRIstuffed Asterisk is distributed under the GNU General Public License version 2 ++and is not available under any alternative licenses. ++If you obtained BRIstuffed Asterisk under the GPL, then the GPL ++applies to all loadable BRIstuffed Asterisk modules used on your system as well, + except as defined below. The GPL (version 2) is included in this + source tree in the file COPYING. + +--- a/doc/hardware.txt ++++ b/doc/hardware.txt +@@ -31,6 +31,19 @@ Zaptel compatible hardware + * Wildcard TE410P - Quad T1/E1 switchable interface. Supports PRI and + RBS signalling, as well as PPP, FR, and HDLC data modes. + ++-- Junghanns.NET (Primary author of BRIstuff) ++ http://www.junghanns.net ++ ++ * quadBRI PCI ISDN - 4port BRI ISDN interface, supports NT and TE mode ++ ++ * octoBRI PCI ISDN - 8port BRI ISDN interface, supports NT and TE mode ++ ++ * singleE1 PCI ISDN - Single E1 interface ++ ++ * doubleE1 PCI ISDN - Double E1 interface ++ ++ * uno/duo/quad GSM PCI - 1/2/4 channel GSM interface cards ++ + Non-zaptel compatible hardware + ============================== + --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/misc-app-pickup +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/misc-app-pickup @@ -0,0 +1,314 @@ +--- a/apps/app_directed_pickup.c ++++ b/apps/app_directed_pickup.c +@@ -45,7 +45,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi + + #define PICKUPMARK "PICKUPMARK" + +-static const char *app = "Pickup"; ++static const char *app = "DPickup"; + static const char *synopsis = "Directed Call Pickup"; + static const char *descrip = + " Pickup(extension[@context][&extension2@context...]): This application can pickup any ringing channel\n" +--- /dev/null ++++ b/apps/app_pickup.c +@@ -0,0 +1,300 @@ ++/* ++ * Asterisk -- A telephony toolkit for Linux. ++ * ++ * Pickup, channel independent call pickup ++ * ++ * Copyright (C) 2004, Junghanns.NET GmbH ++ * ++ * Klaus-Peter Junghanns ++ * ++ * Copyright (C) 2004, Florian Overkamp ++ * ++ * This program is free software, distributed under the terms of ++ * the GNU General Public License ++ */ ++ ++#include "asterisk.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++static char *app = "PickUp"; ++ ++static char *synopsis = "Channel independent call pickup."; ++ ++static char *descrip = ++" PickDown([group]): Tries to pickup the first ringing channel with callgroup == group.\n" ++" If called without the group argument, the pickupgroup of the channel will be used.\n"; ++ ++static char *app2 = "Steal"; ++ ++static char *synopsis2 = "Channel independent call stealing. Just like pickup but for answered channels."; ++ ++static char *descrip2 = ++" Steal([group]): Tries to steal the first bridged channel with callgroup == group.\n" ++" If called without the group argument, the pickupgroup of the channel will be used.\n"; ++ ++static char *app3 = "PickDown"; ++ ++static char *synopsis3 = "Channel independent call pickdown."; ++ ++static char *descrip3 = ++" PickDown([group]): Tries to hangup the first ringing channel with callgroup == group.\n" ++" If called without the group argument, the pickupgroup of the channel will be used.\n"; ++ ++static char *app4 = "PickupChan"; ++ ++static char *synopsis4 = "Channel independent call pickup."; ++ ++static char *descrip4 = ++" PickupChan(Technology/resource[&Technology2/resource2...]): Tries to pickup the first ringing channel in the parameter list.\n"; ++ ++static char *app5 = "StealChan"; ++ ++static char *synopsis5 = "Channel independent call stealing. Just like pickup but for answered channels."; ++ ++static char *descrip5 = ++" StealChan(Technology/resource[&Technology2/resource2...]): Tries to steal the first ringing channel in the parameter list.\n"; ++ ++ ++static int my_pickup_call(struct ast_channel *chan, unsigned int pickupgroup, int chanstate, int bridge) { ++ struct ast_channel *cur; ++ int res = -1; ++ cur = ast_channel_walk_locked(NULL); ++ while(cur) { ++ if ((cur != chan) && ++ (pickupgroup & cur->callgroup) && ++ (cur->_state == chanstate)) { ++ break; ++ } ++ ast_mutex_unlock(&cur->lock); ++ cur = ast_channel_walk_locked(cur); ++ } ++ if (cur) { ++ if(option_verbose > 2) { ++ if (chanstate == AST_STATE_RINGING) { ++ if (bridge == 1) { ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s picked up ringing channel %s\n",chan->name,cur->name); ++ } else { ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s hung up ringing channel %s\n",chan->name,cur->name); ++ } ++ } else { ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s stole channel %s\n",chan->name,cur->name); ++ } ++ } ++ if (bridge == 1) { ++ if (chan->_state != AST_STATE_UP) { ++ ast_answer(chan); ++ } ++ if (ast_channel_masquerade(cur, chan)) { ++ ast_log(LOG_ERROR, "unable to masquerade\n"); ++ } ++ ast_mutex_unlock(&cur->lock); ++ ast_mutex_unlock(&chan->lock); ++ } else { ++ cur->_softhangup = AST_SOFTHANGUP_DEV; ++ ast_mutex_unlock(&cur->lock); ++ } ++ } else { ++ if(option_verbose > 2) { ++ ast_verbose(VERBOSE_PREFIX_3 "No channel found %d.\n",pickupgroup); ++ } ++ } ++ return res; ++} ++ ++static int my_pickup_channel(struct ast_channel *chan, void *data, int chanstate, int bridge) { ++ struct ast_channel *cur; ++ char channels[256]; ++ char evalchan[256]; ++ char *endptr; ++ int res = -1; ++ cur = ast_channel_walk_locked(NULL); ++ strncpy(channels, (char *)data, sizeof(channels) - 1); ++ while(cur) { ++ if ((cur != chan) && ++ (cur->_state == chanstate)) { ++ /* This call is a candidate (correct ringstate and not ourselves), now check if the channel is in our list */ ++ strncpy(evalchan, (char *)cur->name, sizeof(evalchan) - 1); ++ /* strip the subchannel tag */ ++ endptr = strrchr(evalchan, '-'); ++ if(endptr) { ++ *endptr = '\0'; ++ } ++ /* check for each of the members if they match (probably a stristr will do ?) */ ++ /* if we match the code, break */ ++ if(strstr(channels, evalchan) != NULL) { ++ ast_verbose(VERBOSE_PREFIX_1 "Nice channel, I'll take it: %s\n",evalchan); ++ break; ++ } ++ } ++ ast_mutex_unlock(&cur->lock); ++ cur = ast_channel_walk_locked(cur); ++ } ++ if (cur) { ++ if(option_verbose > 2) { ++ if (chanstate == AST_STATE_RINGING) { ++ if (bridge == 1) { ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s picked up ringing channel %s\n",chan->name,cur->name); ++ } else { ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s hung up ringing channel %s\n",chan->name,cur->name); ++ } ++ } else { ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s stole channel %s\n",chan->name,cur->name); ++ } ++ } ++ if (bridge == 1) { ++ if (chan->_state != AST_STATE_UP) { ++ ast_answer(chan); ++ } ++ if (ast_channel_masquerade(cur, chan)) { ++ ast_log(LOG_ERROR, "unable to masquerade\n"); ++ } ++ ast_mutex_unlock(&cur->lock); ++ ast_mutex_unlock(&chan->lock); ++ } else { ++ cur->_softhangup = AST_SOFTHANGUP_DEV; ++ ast_mutex_unlock(&cur->lock); ++ } ++ } else { ++ if(option_verbose > 2) { ++ ast_verbose(VERBOSE_PREFIX_3 "No channel found %s.\n",channels); ++ } ++ } ++ return res; ++} ++ ++ ++static int pickup_exec(struct ast_channel *chan, void *data) ++{ ++ int res=0; ++ unsigned int pickupgroup=0; ++ struct ast_module_user *u; ++ if (!data || !strlen(data)) { ++ pickupgroup = chan->pickupgroup; ++ } else { ++ pickupgroup = ast_get_group(data); ++ } ++ u = ast_module_user_add(chan); ++ if (!res) { ++ res = my_pickup_call(chan, pickupgroup, AST_STATE_RINGING, 1); ++ } ++ if (res > 0) ++ res = 0; ++ ast_module_user_remove(u); ++ return res; ++} ++ ++static int steal_exec(struct ast_channel *chan, void *data) ++{ ++ int res=0; ++ unsigned int pickupgroup=0; ++ struct ast_module_user *u; ++ if (!data || !strlen(data)) { ++ pickupgroup = chan->pickupgroup; ++ } else { ++ pickupgroup = ast_get_group(data); ++ } ++ u = ast_module_user_add(chan); ++ if (!res) { ++ res = my_pickup_call(chan, pickupgroup, AST_STATE_UP, 1); ++ } ++ if (res > 0) ++ res = 0; ++ ast_module_user_remove(u); ++ return res; ++} ++ ++static int pickdown_exec(struct ast_channel *chan, void *data) ++{ ++ int res=0; ++ unsigned int pickupgroup=0; ++ struct ast_module_user *u; ++ if (!data || !strlen(data)) { ++ pickupgroup = chan->pickupgroup; ++ } else { ++ pickupgroup = ast_get_group(data); ++ } ++ u = ast_module_user_add(chan); ++ if (!res) { ++ res = my_pickup_call(chan, pickupgroup, AST_STATE_RINGING, 0); ++ } ++ if (res > 0) ++ res = 0; ++ ast_module_user_remove(u); ++ return res; ++} ++ ++static int pickupchan_exec(struct ast_channel *chan, void *data) { ++ int res=0; ++ struct ast_module_user *u; ++ if (!data) { ++ ast_log(LOG_WARNING, "PickupChan requires an argument (technology1/number1&technology2/number2...)\n"); ++ return -1; ++ } ++ u = ast_module_user_add(chan); ++ if (!res) { ++ res = my_pickup_channel(chan, data, AST_STATE_RINGING, 1); ++ } ++ if (res > 0) ++ res = 0; ++ ast_module_user_remove(u); ++ return res; ++} ++ ++static int stealchan_exec(struct ast_channel *chan, void *data) ++{ ++ int res=0; ++ struct ast_module_user *u; ++ if (!data) { ++ ast_log(LOG_WARNING, "StealChan requires an argument (technology1/number1&technology2/number2...)\n"); ++ return -1; ++ } ++ ++ u = ast_module_user_add(chan); ++ if (!res) { ++ res = my_pickup_channel(chan, data, AST_STATE_UP, 1); ++ } ++ if (res > 0) ++ res = 0; ++ ast_module_user_remove(u); ++ return res; ++} ++ ++ ++static int unload_module(void) ++{ ++ ast_module_user_hangup_all(); ++ ast_unregister_application(app5); ++ ast_unregister_application(app4); ++ ast_unregister_application(app3); ++ ast_unregister_application(app2); ++ return ast_unregister_application(app); ++} ++ ++static int load_module(void) ++{ ++ ast_register_application(app5, stealchan_exec, synopsis5, descrip5); ++ ast_register_application(app4, pickupchan_exec, synopsis4, descrip4); ++ ast_register_application(app3, pickdown_exec, synopsis3, descrip3); ++ ast_register_application(app2, steal_exec, synopsis2, descrip2); ++ return ast_register_application(app, pickup_exec, synopsis, descrip); ++} ++ ++AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "PickUp/PickDown/Steal/PickupChan/StealChan", ++ .load = load_module, ++ .unload = unload_module, ++); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/uniqueid-30-app-chanspy +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/uniqueid-30-app-chanspy @@ -0,0 +1,207 @@ +--- a/apps/app_chanspy.c ++++ b/apps/app_chanspy.c +@@ -57,6 +57,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi + + static const char *tdesc = "Listen to a channel, and optionally whisper into it"; + static const char *app_chan = "ChanSpy"; ++static const char *app_chan_uniqueid = "ChanSpyChan"; + static const char *desc_chan = + " ChanSpy([chanprefix][|options]): This application is used to listen to the\n" + "audio from an Asterisk channel. This includes the audio coming in and\n" +@@ -87,6 +88,27 @@ static const char *desc_chan = + " channel.\n" + ; + ++static const char *desc_uniqueid = ++" ChanSpyChan(uniqueid[|options]): This application is used to listen to the\n" ++"audio from an Asterisk channel. This includes the audio coming in and\n" ++"out of the channel being spied on. The 'uniqueid' parameter has to be specified,\n" ++" While spying, the following actions may be performed:\n" ++" - Dialing # cycles the volume level.\n" ++" Options:\n" ++" q - Don't play a beep when beginning to spy on a channel, or speak the\n" ++" selected channel name.\n" ++" r[(basename)] - Record the session to the monitor spool directory. An\n" ++" optional base for the filename may be specified. The\n" ++" default is 'chanspy'.\n" ++" v([value]) - Adjust the initial volume in the range from -4 to 4. A\n" ++" negative value refers to a quieter setting.\n" ++" w - Enable 'whisper' mode, so the spying channel can talk to\n" ++" the spied-on channel.\n" ++" W - Enable 'private whisper' mode, so the spying channel can\n" ++" talk to the spied-on channel but cannot listen to that\n" ++" channel.\n" ++; ++ + static const char *app_ext = "ExtenSpy"; + static const char *desc_ext = + " ExtenSpy(exten[@context][|options]): This application is used to listen to the\n" +@@ -458,7 +480,7 @@ static struct chanspy_ds *setup_chanspy_ + + static struct chanspy_ds *next_channel(struct ast_channel *chan, + const struct ast_channel *last, const char *spec, +- const char *exten, const char *context, struct chanspy_ds *chanspy_ds) ++ const char *exten, const char *context, struct chanspy_ds *chanspy_ds, const char *uniqueid) + { + struct ast_channel *this; + +@@ -467,6 +489,8 @@ redo: + this = ast_walk_channel_by_name_prefix_locked(last, spec, strlen(spec)); + else if (exten) + this = ast_walk_channel_by_exten_locked(last, exten, context); ++ else if (uniqueid) ++ this = ast_get_channel_by_uniqueid_locked(uniqueid); + else + this = ast_channel_walk_locked(last); + +@@ -487,7 +511,7 @@ redo: + + static int common_exec(struct ast_channel *chan, const struct ast_flags *flags, + int volfactor, const int fd, const char *mygroup, const char *spec, +- const char *exten, const char *context) ++ const char *exten, const char *context, const char *uniqueid) + { + char nameprefix[AST_NAME_STRLEN]; + char peer_name[AST_NAME_STRLEN + 5]; +@@ -534,11 +558,11 @@ static int common_exec(struct ast_channe + waitms = 100; + num_spyed_upon = 0; + +- for (peer_chanspy_ds = next_channel(chan, prev, spec, exten, context, &chanspy_ds); ++ for (peer_chanspy_ds = next_channel(chan, prev, spec, exten, context, &chanspy_ds, NULL); + peer_chanspy_ds; + chanspy_ds_free(peer_chanspy_ds), prev = peer, + peer_chanspy_ds = next_chanspy_ds ? next_chanspy_ds : +- next_channel(chan, prev, spec, exten, context, &chanspy_ds), next_chanspy_ds = NULL) { ++ next_channel(chan, prev, spec, exten, context, &chanspy_ds, NULL), next_chanspy_ds = NULL) { + const char *group; + int igrp = !mygroup; + char *groups[25]; +@@ -737,7 +761,7 @@ static int chanspy_exec(struct ast_chann + } + } + +- res = common_exec(chan, &flags, volfactor, fd, mygroup, spec, NULL, NULL); ++ res = common_exec(chan, &flags, volfactor, fd, mygroup, spec, NULL, NULL, NULL); + + if (fd) + close(fd); +@@ -822,7 +846,7 @@ static int extenspy_exec(struct ast_chan + } + } + +- res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, exten, context); ++ res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, exten, context, NULL); + + if (fd) + close(fd); +@@ -835,14 +859,100 @@ static int extenspy_exec(struct ast_chan + return res; + } + ++static int chanspychan_exec(struct ast_channel *chan, void *data) ++{ ++ struct ast_module_user *u; ++ char *options = NULL; ++ char *uniqueid = NULL; ++ char *argv[2]; ++ char *mygroup = NULL; ++ char *recbase = NULL; ++ int fd = 0; ++ struct ast_flags flags; ++ int oldwf = 0; ++ int argc = 0; ++ int volfactor = 0; ++ int res; ++ ++ data = ast_strdupa(data); ++ ++ u = ast_module_user_add(chan); ++ ++ if ((argc = ast_app_separate_args(data, '|', argv, sizeof(argv) / sizeof(argv[0])))) { ++ uniqueid = argv[0]; ++ if (argc > 1) ++ options = argv[1]; ++ ++ if (ast_strlen_zero(uniqueid)) { ++ ast_log(LOG_ERROR, "no uniqueid specified.\n"); ++ ast_module_user_remove(u); ++ return -1; ++ } ++ } ++ ++ if (options) { ++ char *opts[OPT_ARG_ARRAY_SIZE]; ++ ++ ast_app_parse_options(spy_opts, &flags, opts, options); ++ if (ast_test_flag(&flags, OPTION_GROUP)) ++ mygroup = opts[OPT_ARG_GROUP]; ++ ++ if (ast_test_flag(&flags, OPTION_RECORD) && ++ !(recbase = opts[OPT_ARG_RECORD])) ++ recbase = "chanspy"; ++ ++ if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) { ++ int vol; ++ ++ if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4)) ++ ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n"); ++ else ++ volfactor = vol; ++ } ++ ++ if (ast_test_flag(&flags, OPTION_PRIVATE)) ++ ast_set_flag(&flags, OPTION_WHISPER); ++ } ++ ++ oldwf = chan->writeformat; ++ if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { ++ ast_log(LOG_ERROR, "Could Not Set Write Format.\n"); ++ ast_module_user_remove(u); ++ return -1; ++ } ++ ++ if (recbase) { ++ char filename[512]; ++ ++ snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL)); ++ if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644)) <= 0) { ++ ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename); ++ fd = 0; ++ } ++ } ++ ++ res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, NULL, NULL, uniqueid); ++ ++ if (fd) ++ close(fd); ++ ++ if (oldwf && ast_set_write_format(chan, oldwf) < 0) ++ ast_log(LOG_ERROR, "Could Not Set Write Format.\n"); ++ ++ ast_module_user_remove(u); ++ ++ return res; ++} ++ ++ + static int unload_module(void) + { + int res = 0; + + res |= ast_unregister_application(app_chan); ++ res |= ast_unregister_application(app_chan_uniqueid); + res |= ast_unregister_application(app_ext); + +- ast_module_user_hangup_all(); + + return res; + } +@@ -853,6 +963,7 @@ static int load_module(void) + + res |= ast_register_application(app_chan, chanspy_exec, tdesc, desc_chan); + res |= ast_register_application(app_ext, extenspy_exec, tdesc, desc_ext); ++ res |= ast_register_application(app_chan_uniqueid, chanspychan_exec, tdesc, desc_uniqueid); + + return res; + } --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/misc-manager-dbdel +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/misc-manager-dbdel @@ -0,0 +1,49 @@ +--- a/main/db.c ++++ b/main/db.c +@@ -574,7 +574,7 @@ static int manager_dbget(struct mansessi + astman_append(s, "Event: DBGetResponse\r\n" + "Family: %s\r\n" + "Key: %s\r\n" +- "Val: %s\r\n" ++ "Value: %s\r\n" + "%s" + "\r\n", + family, key, tmp, idText); +@@ -582,11 +582,35 @@ static int manager_dbget(struct mansessi + return 0; + } + ++static int manager_dbdel(struct mansession *s, const struct message *m) ++{ ++ const char *family = astman_get_header(m, "Family"); ++ const char *key = astman_get_header(m, "Key"); ++ ++ if (!strlen(family)) { ++ astman_send_error(s, m, "No family specified"); ++ return 0; ++ } ++ if (!strlen(key)) { ++ astman_send_error(s, m, "No key specified"); ++ return 0; ++ } ++ ++ if (ast_db_del(family, key)) { ++ astman_send_error(s, m, "Failed to delete entry"); ++ } else { ++ astman_send_ack(s, m, "Deleted entry successfully"); ++ } ++ ++ return 0; ++} ++ + int astdb_init(void) + { + dbinit(); + ast_cli_register_multiple(cli_database, sizeof(cli_database) / sizeof(struct ast_cli_entry)); +- ast_manager_register("DBGet", EVENT_FLAG_SYSTEM, manager_dbget, "Get DB Entry"); +- ast_manager_register("DBPut", EVENT_FLAG_SYSTEM, manager_dbput, "Put DB Entry"); ++ ast_manager_register("DBget", EVENT_FLAG_SYSTEM, manager_dbget, "Get DB Entry"); ++ ast_manager_register("DBput", EVENT_FLAG_SYSTEM, manager_dbput, "Put DB Entry"); ++ ast_manager_register("DBdel", EVENT_FLAG_SYSTEM, manager_dbdel, "Delete DB Entry"); + return 0; + } --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/feature-autoanswer +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/feature-autoanswer @@ -0,0 +1,608 @@ +--- a/include/asterisk/features.h ++++ b/include/asterisk/features.h +@@ -47,6 +47,8 @@ struct ast_call_feature { + }; + + ++extern int ast_autoanswer_login(struct ast_channel *chan, void *data); ++extern int ast_masq_autoanswer_login(struct ast_channel *rchan, void *data); + + /*! \brief Park a call and read back parked location + * \param chan the channel to actually be parked +--- a/res/res_features.c ++++ b/res/res_features.c +@@ -11,6 +11,10 @@ + * the project provides a web site, mailing lists and IRC + * channels for your use. + * ++ * Copyright (C) 2004, Junghanns.NET GmbH ++ * ++ * Klaus-Peter Junghanns ++ * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. +@@ -132,6 +136,20 @@ static char *descrip2 = "Park():" + "it already exists. In that case, execution will continue at next\n" + "priority.\n" ; + ++static char *autoanswerlogin = "AutoanswerLogin"; ++ ++static char *synopsis3 = "Log in for autoanswer"; ++ ++static char *descrip3 = "AutoanswerLogin([context]|exten):" ++"Used to login to the autoanswer application for an extension.\n"; ++ ++static char *autoanswer = "Autoanswer"; ++ ++static char *synopsis4 = "Autoanswer a call"; ++ ++static char *descrip4 = "Autoanswer([context]|exten):" ++"Used to autoanswer a call for an extension.\n"; ++ + static struct ast_app *monitor_app = NULL; + static int monitor_ok = 1; + +@@ -150,6 +168,23 @@ struct parkeduser { + struct parkeduser *next; + }; + ++/* auto answer user */ ++struct aauser { ++ struct ast_channel *chan; ++ struct timeval start; ++ /* waiting on this extension/context */ ++ char exten[AST_MAX_EXTENSION]; ++ char context[AST_MAX_EXTENSION]; ++ int priority; ++ int notquiteyet; ++ struct aauser *next; ++}; ++ ++ ++static struct aauser *aalot; ++AST_MUTEX_DEFINE_STATIC(autoanswer_lock); ++static pthread_t autoanswer_thread; ++ + static struct parkeduser *parkinglot; + + AST_MUTEX_DEFINE_STATIC(parking_lock); /*!< protects all static variables above */ +@@ -405,11 +440,13 @@ static int park_call_full(struct ast_cha + "From: %s\r\n" + "Timeout: %ld\r\n" + "CallerID: %s\r\n" +- "CallerIDName: %s\r\n", ++ "CallerIDName: %s\r\n" ++ "Uniqueid: %s\r\n", + pu->parkingexten, pu->chan->name, peer ? peer->name : "", + (long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL), + S_OR(pu->chan->cid.cid_num, ""), +- S_OR(pu->chan->cid.cid_name, "") ++ S_OR(pu->chan->cid.cid_name, ""), ++ pu->chan->uniqueid + ); + + if (peer && adsipark && ast_adsi_available(peer)) { +@@ -1656,11 +1693,13 @@ static void post_manager_event(const cha + "Exten: %s\r\n" + "Channel: %s\r\n" + "CallerID: %s\r\n" +- "CallerIDName: %s\r\n\r\n", ++ "CallerIDName: %s\r\n" ++ "Uniqueid: %s\r\n\r\n", + parkingexten, + chan->name, + S_OR(chan->cid.cid_num, ""), +- S_OR(chan->cid.cid_name, "") ++ S_OR(chan->cid.cid_name, ""), ++ chan->uniqueid + ); + } + +@@ -1928,10 +1967,12 @@ static int park_exec(struct ast_channel + "Channel: %s\r\n" + "From: %s\r\n" + "CallerID: %s\r\n" +- "CallerIDName: %s\r\n", ++ "CallerIDName: %s\r\n" ++ "Uniqueid: %s\r\n", + pu->parkingexten, pu->chan->name, chan->name, + S_OR(pu->chan->cid.cid_num, ""), +- S_OR(pu->chan->cid.cid_name, "") ++ S_OR(pu->chan->cid.cid_name, ""), ++ pu->chan->uniqueid + ); + + free(pu); +@@ -2085,15 +2126,10 @@ static struct ast_cli_entry cli_show_fea + handle_showfeatures, NULL, + NULL }; + +-static struct ast_cli_entry cli_features[] = { +- { { "feature", "show", NULL }, +- handle_showfeatures, "Lists configured features", +- showfeatures_help, NULL, &cli_show_features_deprecated }, ++static char showautoanswer_help[] = ++"Usage: show autoanswer\n" ++" Lists currently logged in autoanswer users.\n"; + +- { { "show", "parkedcalls", NULL }, +- handle_parkedcalls, "Lists parked calls", +- showparked_help }, +-}; + + /*! \brief Dump lot status */ + static int manager_parking_status( struct mansession *s, const struct message *m) +@@ -2117,12 +2153,13 @@ static int manager_parking_status( struc + "Timeout: %ld\r\n" + "CallerID: %s\r\n" + "CallerIDName: %s\r\n" ++ "Uniqueid: %s\r\n\r\n" + "%s" + "\r\n", + cur->parkingnum, cur->chan->name, cur->peername, + (long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - (long) time(NULL), + S_OR(cur->chan->cid.cid_num, ""), /* XXX in other places it is */ +- S_OR(cur->chan->cid.cid_name, ""), ++ S_OR(cur->chan->cid.cid_name, ""), cur->chan->uniqueid, + idText); + } + +@@ -2197,6 +2234,427 @@ static int manager_park(struct mansessio + return 0; + } + ++static int handle_autoanswer(int fd, int argc, char *argv[]) ++{ ++ struct aauser *cur; ++ ++ ast_cli(fd, "%25s %10s %15s \n", "Channel" ++ , "Extension", "Context"); ++ ++ ast_mutex_lock(&autoanswer_lock); ++ ++ cur=aalot; ++ while(cur) { ++ ast_cli(fd, "%25s %10s %15s\n",cur->chan->name, cur->exten, cur->context); ++ ++ cur = cur->next; ++ } ++ ++ ast_mutex_unlock(&autoanswer_lock); ++ ++ return RESULT_SUCCESS; ++} ++ ++static struct ast_cli_entry cli_features[] = { ++ { { "feature", "list", NULL }, ++ handle_showfeatures, "Lists configured features", ++ showfeatures_help, NULL, &cli_show_features_deprecated }, ++ ++ { { "show", "parkedcalls", NULL }, ++ handle_parkedcalls, "Lists parked calls", ++ showparked_help }, ++ ++ { { "show", "autoanswer", NULL }, ++ handle_autoanswer, "Lists autoanswer users", ++ showautoanswer_help }, ++}; ++int ast_masq_autoanswer_login(struct ast_channel *rchan, void *data) ++{ ++ struct ast_channel *chan; ++ struct ast_frame *f; ++ /* Make a new, fake channel that we'll use to masquerade in the real one */ ++ chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Autoanswer/%s", rchan->name); ++ if (chan) { ++ /* Let us keep track of the channel name */ ++ ast_string_field_build(chan, name, "Autoanswer/%s",rchan->name); ++ /* Make formats okay */ ++ chan->readformat = rchan->readformat; ++ chan->writeformat = rchan->writeformat; ++ ast_channel_masquerade(chan, rchan); ++ /* Setup the extensions and such */ ++ strncpy(chan->context, rchan->context, sizeof(chan->context) - 1); ++ strncpy(chan->exten, rchan->exten, sizeof(chan->exten) - 1); ++ chan->priority = rchan->priority; ++ /* might be dirty but we want trackable channels */ ++ ast_string_field_build(chan, uniqueid, "%s",rchan->uniqueid); ++ /* Make the masq execute */ ++ f = ast_read(chan); ++ if (f) ++ ast_frfree(f); ++ ast_autoanswer_login(chan, data); ++ } else { ++ ast_log(LOG_WARNING, "Unable to create aa channel\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int autoanswer_login_exec(struct ast_channel *chan, void *data) ++{ ++ int res=0; ++ struct ast_module_user *u; ++ ++ u = ast_module_user_add(chan); ++ if (!data) { ++ ast_log(LOG_WARNING, "AutoanswerLogin requires an argument (extension number)\n"); ++ return -1; ++ } ++ res = ast_masq_autoanswer_login(chan, data); ++ ast_module_user_remove(u); ++ return res; ++} ++ ++int ast_autoanswer_login(struct ast_channel *chan, void *data) ++{ ++ /* We put the user in the parking list, then wake up the parking thread to be sure it looks ++ after these channels too */ ++ struct ast_context *con; ++ char exten[AST_MAX_EXTENSION]; ++ struct aauser *pu,*pl = NULL; ++ char *s, *stringp, *aacontext, *aaexten = NULL; ++ ++ s = ast_strdupa((void *) data); ++ stringp=s; ++ aacontext = strsep(&stringp, "|"); ++ aaexten = strsep(&stringp, "|"); ++ if (!aaexten) { ++ aaexten = aacontext; ++ aacontext = NULL; ++ } ++ if (!aaexten) { ++ ast_log(LOG_WARNING, "AutoanswerLogin requires at least an extension!\n"); ++ return -1; ++ } else { ++ if (!aacontext) { ++ aacontext = "default"; ++ } ++ } ++ ++ ast_mutex_lock(&autoanswer_lock); ++ pu = aalot; ++ while(pu) { ++ if ((!strncasecmp(pu->exten, aaexten, sizeof(pu->exten)-1)) && (!strncasecmp(pu->context, aacontext, sizeof(pu->context)-1))){ ++ if (pl) ++ pl->next = pu->next; ++ else ++ aalot = pu->next; ++ break; ++ } ++ pl = pu; ++ pu = pu->next; ++ } ++ ast_mutex_unlock(&autoanswer_lock); ++ if (pu) { ++ ast_log(LOG_NOTICE, "Logout old Channel %s for %s@%s.\n",pu->chan->name, pu->exten, pu->context); ++ manager_event(EVENT_FLAG_CALL, "AutoanswerLogout", ++ "Channel: %s\r\n" ++ "Uniqueid: %s\r\n" ++ "Context: %s\r\n" ++ "Exten: %s\r\n" ++ ,pu->chan->name, pu->chan->uniqueid, pu->context, pu->exten); ++ ast_hangup(pu->chan); ++ free(pu); ++ } ++ pu = malloc(sizeof(struct aauser)); ++ if (pu) { ++ memset(pu, 0, sizeof(pu)); ++ ast_mutex_lock(&autoanswer_lock); ++ chan->appl = "Autoanswer"; ++ chan->data = NULL; ++ ++ pu->chan = chan; ++ if (chan->_state != AST_STATE_UP) { ++ ast_answer(chan); ++ } ++ ++ /* Start music on hold */ ++ ast_moh_start(pu->chan, NULL, NULL); ++ gettimeofday(&pu->start, NULL); ++ strncpy(pu->exten, aaexten, sizeof(pu->exten)-1); ++ strncpy(pu->context, aacontext, sizeof(pu->exten)-1); ++ pu->next = aalot; ++ aalot = pu; ++ con = ast_context_find(aacontext); ++ if (!con) { ++ con = ast_context_create(NULL,aacontext, registrar); ++ if (!con) { ++ ast_log(LOG_ERROR, "Context '%s' does not exist and unable to create\n", aacontext); ++ } ++ } ++ if (con) { ++ snprintf(exten, sizeof(exten), "%s", aaexten); ++ ast_add_extension2(con, 1, exten, 1, NULL, NULL, autoanswer, strdup((char *)data), free, registrar); ++ } ++ ++ ast_mutex_unlock(&autoanswer_lock); ++ /* Wake up the (presumably select()ing) thread */ ++ pthread_kill(autoanswer_thread, SIGURG); ++ if (option_verbose > 1) ++ ast_verbose(VERBOSE_PREFIX_2 "Autoanswer login from %s for %s@%s.\n", pu->chan->name, pu->exten, pu->context); ++ manager_event(EVENT_FLAG_CALL, "AutoanswerLogin", ++ "Channel: %s\r\n" ++ "Uniqueid: %s\r\n" ++ "Context: %s\r\n" ++ "Exten: %s\r\n" ++ ,pu->chan->name, pu->chan->uniqueid, pu->context, pu->exten); ++ ++ return 0; ++ } else { ++ ast_log(LOG_WARNING, "Out of memory\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static void autoanswer_reregister_extensions(void) ++{ ++ struct aauser *cur; ++ struct ast_context *con; ++ char exten[AST_MAX_EXTENSION]; ++ char args[AST_MAX_EXTENSION]; ++ ++ ast_mutex_lock(&autoanswer_lock); ++ ++ cur=aalot; ++ while(cur) { ++ con = ast_context_find(cur->context); ++ if (!con) { ++ con = ast_context_create(NULL,cur->context, registrar); ++ if (!con) { ++ ast_log(LOG_ERROR, "Context '%s' does not exist and unable to create\n", cur->context); ++ } ++ } ++ if (con) { ++ snprintf(exten, sizeof(exten), "%s", cur->exten); ++ snprintf(args, sizeof(args), "%s|%s", cur->context, cur->exten); ++ ast_add_extension2(con, 1, exten, 1, NULL, NULL, autoanswer, strdup((char *)args), free, registrar); ++ } ++ cur = cur->next; ++ } ++ ++ ast_mutex_unlock(&autoanswer_lock); ++} ++static void *do_autoanswer_thread(void *ignore) ++{ ++ int ms, tms, max; ++ struct ast_context *con; ++ char exten[AST_MAX_EXTENSION]; ++ struct aauser *pu, *pl, *pt = NULL; ++ struct timeval tv; ++ struct ast_frame *f; ++ int x; ++ fd_set rfds, efds; ++ fd_set nrfds, nefds; ++ FD_ZERO(&rfds); ++ FD_ZERO(&efds); ++ for (;;) { ++ ms = -1; ++ max = -1; ++ ast_mutex_lock(&autoanswer_lock); ++ pl = NULL; ++ pu = aalot; ++ gettimeofday(&tv, NULL); ++ FD_ZERO(&nrfds); ++ FD_ZERO(&nefds); ++ while(pu) { ++ tms = (tv.tv_sec - pu->start.tv_sec) * 1000 + (tv.tv_usec - pu->start.tv_usec) / 1000; ++ for (x=0;xchan->fds[x] > -1) && (FD_ISSET(pu->chan->fds[x], &rfds) || FD_ISSET(pu->chan->fds[x], &efds))) { ++ if (FD_ISSET(pu->chan->fds[x], &efds)) ++ ast_set_flag(pu->chan, AST_FLAG_EXCEPTION); ++ else ++ ast_clear_flag(pu->chan, AST_FLAG_EXCEPTION); ++ pu->chan->fdno = x; ++ /* See if they need servicing */ ++ f = ast_read(pu->chan); ++ if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) { ++ /* There's a problem, hang them up*/ ++ if (option_verbose > 1) ++ ast_verbose(VERBOSE_PREFIX_2 "%s logged out of autoanswer app\n", pu->chan->name); ++ manager_event(EVENT_FLAG_CALL, "AutoanswerLogout", ++ "Channel: %s\r\n" ++ "Uniqueid: %s\r\n" ++ "Context: %s\r\n" ++ "Exten: %s\r\n" ++ ,pu->chan->name, pu->chan->uniqueid, pu->context, pu->exten); ++ ast_hangup(pu->chan); ++ con = ast_context_find(pu->context); ++ if (con) { ++ snprintf(exten, sizeof(exten), "%s", pu->exten); ++ if (ast_context_remove_extension2(con, exten, 1, registrar)) ++ ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n"); ++ } else { ++ ast_log(LOG_WARNING, "Whoa, no %s context?\n", pu->exten); ++ } ++ /* And take them out of the parking lot */ ++ if (pl) ++ pl->next = pu->next; ++ else ++ aalot = pu->next; ++ pt = pu; ++ pu = pu->next; ++ free(pt); ++ break; ++ } else { ++ /* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */ ++ ast_frfree(f); ++ goto std; /* XXX Ick: jumping into an else statement??? XXX */ ++ } ++ } ++ } ++ if (x >= AST_MAX_FDS) { ++std: for (x=0;xchan->fds[x] > -1) { ++ FD_SET(pu->chan->fds[x], &nrfds); ++ FD_SET(pu->chan->fds[x], &nefds); ++ if (pu->chan->fds[x] > max) ++ max = pu->chan->fds[x]; ++ } ++ } ++ /* Keep track of our longest wait */ ++ if ((tms < ms) || (ms < 0)) ++ ms = tms; ++ pl = pu; ++ pu = pu->next; ++ } ++ } ++ ast_mutex_unlock(&autoanswer_lock); ++ rfds = nrfds; ++ efds = nefds; ++ tv.tv_sec = ms / 1000; ++ tv.tv_usec = (ms % 1000) * 1000; ++ /* Wait for something to happen */ ++ ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL); ++ pthread_testcancel(); ++ } ++ return NULL; /* Never reached */ ++} ++ ++static int autoanswer_exec(struct ast_channel *chan, void *data) ++{ ++ int res=0; ++ struct ast_channel *peer=NULL; ++ struct aauser *pu, *pl=NULL; ++ struct ast_bridge_config config; ++ char *s, *stringp, *aacontext, *aaexten = NULL; ++ char datastring[80]; ++ struct ast_module_user *u; ++ ++ ++ if (!data) { ++ ast_log(LOG_WARNING, "Autoanswer requires an argument (extension number)\n"); ++ return -1; ++ } ++ s = ast_strdupa((void *) data); ++ stringp=s; ++ aacontext = strsep(&stringp, "|"); ++ aaexten = strsep(&stringp, "|"); ++ if (!aaexten) { ++ aaexten = aacontext; ++ aacontext = NULL; ++ } ++ if (!aaexten) { ++ ast_log(LOG_WARNING, "AutoanswerLogin requires at least an extension!\n"); ++ return -1; ++ } else { ++ if (!aacontext) { ++ aacontext = "default"; ++ } ++ } ++ ++ u = ast_module_user_add(chan); ++ ast_mutex_lock(&autoanswer_lock); ++ pu = aalot; ++ while(pu) { ++ if ((!strncasecmp(pu->exten, aaexten, sizeof(pu->exten)-1)) && (!strncasecmp(pu->context, aacontext, sizeof(pu->context)-1))){ ++ if (pl) ++ pl->next = pu->next; ++ else ++ aalot = pu->next; ++ break; ++ } ++ pl = pu; ++ pu = pu->next; ++ } ++ ast_mutex_unlock(&autoanswer_lock); ++ if (pu) { ++ peer = pu->chan; ++ free(pu); ++ pu = NULL; ++ } ++ /* JK02: it helps to answer the channel if not already up */ ++ if (chan->_state != AST_STATE_UP) { ++ ast_answer(chan); ++ } ++ ++ if (peer) { ++ ast_moh_stop(peer); ++ /* Play a courtesy beep in the callED channel to prefix the bridge connecting */ ++ if (!ast_strlen_zero(courtesytone)) { ++ if (!ast_streamfile(peer, courtesytone, peer->language)) { ++ if (ast_waitstream(peer, "") < 0) { ++ ast_log(LOG_WARNING, "Failed to play courtesy tone!\n"); ++ ast_hangup(peer); ++ return -1; ++ } ++ } ++ } ++ ++ res = ast_channel_make_compatible(chan, peer); ++ if (res < 0) { ++ ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name); ++ ast_hangup(peer); ++ return -1; ++ } ++ /* This runs sorta backwards, since we give the incoming channel control, as if it ++ were the person called. */ ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %s autoanswered %s\n", peer->name, chan->name); ++ manager_event(EVENT_FLAG_CALL, "Autoanswer", ++ "Channel: %s\r\n" ++ "Uniqueid: %s\r\n" ++ "Channel2: %s\r\n" ++ "Uniqueid2: %s\r\n" ++ "Context: %s\r\n" ++ "Exten: %s\r\n" ++ ,chan->name, chan->uniqueid, peer->name, peer->uniqueid, aacontext, aaexten); ++ ++ ++ memset(&config,0,sizeof(struct ast_bridge_config)); ++ ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT); ++ ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT); ++ config.timelimit = 0; ++ config.play_warning = 0; ++ config.warning_freq = 0; ++ config.warning_sound=NULL; ++ res = ast_bridge_call(chan,peer,&config); ++ ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "returning from bridge %s\n", peer->name); ++ /* relogin */ ++ snprintf(datastring, sizeof(datastring) - 1, "%s|%s", aacontext, aaexten); ++ ast_autoanswer_login(peer, datastring); ++ return res; ++ } else { ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Nobody logged in for autoanswer %s@%s\n", aaexten, aacontext); ++ res = -1; ++ } ++ ast_module_user_remove(u); ++ return res; ++} ++ + + int ast_pickup_call(struct ast_channel *chan) + { +@@ -2460,6 +2918,7 @@ static int load_config(void) + + static int reload(void) + { ++ autoanswer_reregister_extensions(); + return load_config(); + } + +@@ -2483,6 +2942,12 @@ static int load_module(void) + "Park a channel", mandescr_park); + } + ++ ast_pthread_create(&autoanswer_thread, NULL, do_autoanswer_thread, NULL); ++ if (!res) ++ res |= ast_register_application(autoanswerlogin, autoanswer_login_exec, synopsis3, descrip3); ++ if (!res) ++ res |= ast_register_application(autoanswer, autoanswer_exec, synopsis4, descrip4); ++ + res |= ast_devstate_prov_add("Park", metermaidstate); + + return res; +@@ -2497,6 +2962,8 @@ static int unload_module(void) + ast_manager_unregister("Park"); + ast_cli_unregister_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry)); + ast_unregister_application(parkcall); ++ ast_unregister_application(autoanswer); ++ ast_unregister_application(autoanswerlogin); + ast_devstate_prov_del("Park"); + return ast_unregister_application(parkedcall); + } --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/app-dial-etc +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/app-dial-etc @@ -0,0 +1,45 @@ +--- a/apps/app_dial.c ++++ b/apps/app_dial.c +@@ -71,6 +71,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi + #include "asterisk/privacy.h" + #include "asterisk/stringfields.h" + #include "asterisk/global_datastores.h" ++#include "asterisk/transcap.h" + + static char *app = "Dial"; + +@@ -1652,23 +1653,25 @@ static int dial_exec_full(struct ast_cha + ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING); + if (play_to_callee) + ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING); +- if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER)) ++ if ((chan->transfercapability != AST_TRANS_CAP_DIGITAL) && (chan->transfercapability != AST_TRANS_CAP_RESTRICTED_DIGITAL)) { ++ /* only non-digital calls are allowed to go through userspace */ ++ if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER)) + ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT); +- if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER)) ++ if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER)) + ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT); +- if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP)) ++ if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP)) + ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT); +- if (ast_test_flag(peerflags, OPT_CALLER_HANGUP)) ++ if (ast_test_flag(peerflags, OPT_CALLER_HANGUP)) + ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT); +- if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR)) ++ if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR)) + ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON); +- if (ast_test_flag(peerflags, OPT_CALLER_MONITOR)) ++ if (ast_test_flag(peerflags, OPT_CALLER_MONITOR)) + ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON); +- if (ast_test_flag(peerflags, OPT_CALLEE_PARK)) ++ if (ast_test_flag(peerflags, OPT_CALLEE_PARK)) + ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL); +- if (ast_test_flag(peerflags, OPT_CALLER_PARK)) ++ if (ast_test_flag(peerflags, OPT_CALLER_PARK)) + ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL); +- ++ } + config.timelimit = timelimit; + config.play_warning = play_warning; + config.warning_freq = warning_freq; --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/chan-iax2-hangup-cause +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/chan-iax2-hangup-cause @@ -0,0 +1,31 @@ +--- a/channels/chan_iax2.c ++++ b/channels/chan_iax2.c +@@ -11,6 +11,9 @@ + * the project provides a web site, mailing lists and IRC + * channels for your use. + * ++ * Hangup cause signalling implementation by ++ * Levent Guendogdu ++ * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. +@@ -3373,7 +3376,7 @@ static int iax2_hangup(struct ast_channe + ast_mutex_lock(&iaxsl[callno]); + if (callno && iaxs[callno]) { + if (option_debug) +- ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); ++ ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); + alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); + /* Send the hangup unless we have had a transmission error or are already gone */ + iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); +@@ -3427,7 +3430,8 @@ static int iax2_setoption(struct ast_cha + + static struct ast_frame *iax2_read(struct ast_channel *c) + { +- ast_log(LOG_NOTICE, "I should never be called!\n"); ++ if (option_verbose > 3) ++ ast_log(LOG_NOTICE, "I should never be called!\n"); + return &ast_null_frame; + } + --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/uniqueid-20-monitor +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/uniqueid-20-monitor @@ -0,0 +1,82 @@ +--- a/res/res_monitor.c ++++ b/res/res_monitor.c +@@ -340,6 +340,11 @@ int ast_monitor_stop(struct ast_channel + result = ast_safe_system(tmp); + if (result == -1) + ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp); ++ manager_event(EVENT_FLAG_CALL, "MonitorStopped", ++ "Channel: %s\r\n" ++ "Uniqueid: %s\r\n" ++ "Result: %d\r\n" ++ ,chan->name, chan->uniqueid, result); + } + + free(chan->monitor->format); +@@ -518,18 +523,28 @@ static int start_monitor_action(struct m + const char *fname = astman_get_header(m, "File"); + const char *format = astman_get_header(m, "Format"); + const char *mix = astman_get_header(m, "Mix"); ++ const char *uniqueid = astman_get_header(m, "Uniqueid"); + const char *target_url = astman_get_header(m, "TargetURL"); + const char *target_script = astman_get_header(m, "TargetScript"); + char *d; + +- if (ast_strlen_zero(name)) { +- astman_send_error(s, m, "No channel specified"); ++ if (ast_strlen_zero(name) && ast_strlen_zero(uniqueid)) { ++ astman_send_error(s, m, "No channel/uniqueid specified"); ++ return 0; ++ } ++ ++ if (!ast_strlen_zero(uniqueid)) { ++ c = ast_get_channel_by_uniqueid_locked(uniqueid); ++ if (!c) { ++ astman_send_error(s, m, "No such uniqueid"); + return 0; +- } +- c = ast_get_channel_by_name_locked(name); +- if (!c) { ++ } ++ } else { ++ c = ast_get_channel_by_name_locked(name); ++ if (!c) { + astman_send_error(s, m, "No such channel"); + return 0; ++ } + } + + if (ast_strlen_zero(fname)) { +@@ -570,16 +585,30 @@ static int stop_monitor_action(struct ma + { + struct ast_channel *c = NULL; + const char *name = astman_get_header(m, "Channel"); ++ const char *uniqueid = astman_get_header(m, "Uniqueid"); + int res; + if (ast_strlen_zero(name)) { + astman_send_error(s, m, "No channel specified"); + return 0; + } +- c = ast_get_channel_by_name_locked(name); +- if (!c) { +- astman_send_error(s, m, "No such channel"); ++ if (ast_strlen_zero(name) && ast_strlen_zero(uniqueid)) { ++ astman_send_error(s, m, "No channel/uniqueid specified"); ++ return 0; ++ } ++ if (!ast_strlen_zero(uniqueid)) { ++ c = ast_get_channel_by_uniqueid_locked(uniqueid); ++ if (!c) { ++ astman_send_error(s, m, "No such uniqueid"); + return 0; ++ } ++ } else { ++ c = ast_get_channel_by_name_locked(name); ++ if (!c) { ++ astman_send_error(s, m, "No such channel"); ++ return 0; ++ } + } ++ + res = ast_monitor_stop(c, 1); + ast_channel_unlock(c); + if (res) { --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/misc-res-watchdog +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/misc-res-watchdog @@ -0,0 +1,165 @@ +--- /dev/null ++++ b/configs/watchdog.conf.sample +@@ -0,0 +1,22 @@ ++; ++; Configuration file for res_watchdog ++; ++; type = isdnguard | watchdog ++; device = /dev/... ++; interval = interval to trigger the watchdog in ms ++ ++;[ISDNguard-direct] ++;type = isdnguard ++;device = /dev/ttyS0 ++;interval = 200 ++ ++;[ISDNguard-with-daemon] ++;type = isdnguard ++;device = /var/run/guard.ctl ++;interval = 200 ++ ++;[kernel_watchdog] ++;type = watchdog ++;device = /dev/watchdog ++;interval = 100 ++ +--- /dev/null ++++ b/res/res_watchdog.c +@@ -0,0 +1,137 @@ ++/* ++ * Asterisk -- A telephony toolkit for Linux. ++ * ++ * Resource to make watchdogs happy ++ * ++ * Copyright (C) 2005, Junghanns.NET GmbH ++ * ++ * Klaus-Peter Junghanns ++ * ++ * This program is free software, distributed under the terms of ++ * the GNU General Public License ++ */ ++ ++#include "asterisk.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct watchdog_pvt *watchdogs = NULL; ++ ++typedef struct watchdog_pvt { ++ char device[80]; ++ int fd; ++ int type; ++ int interval; ++ pthread_t watchdog_thread; ++ struct watchdog_pvt *next; ++} watchdog_pvt; ++ ++static void *do_watchdog_thread(void *data) { ++ struct watchdog_pvt *woof = (struct watchdog_pvt *)data; ++ for (;;) { ++ if (woof->fd) { ++ write(woof->fd, "PING\n", 5); ++ } ++ usleep(woof->interval * 1000); ++ } ++ return NULL; ++} ++ ++ ++static int load_module(void) ++{ ++ int res = 0; ++ const char *cat, *utype, *udevice, *uinterval; ++ struct ast_config *cfg; ++ struct watchdog_pvt *woof = NULL; ++ ++ cfg = ast_config_load("watchdog.conf"); ++ if (cfg) { ++ cat = ast_category_browse(cfg, NULL); ++ while(cat) { ++ cat = ast_category_browse(cfg, cat); ++ utype = ast_variable_retrieve(cfg, cat, "type"); ++/* if (utype) { ++ ast_log(LOG_NOTICE, "type = %s\n", utype); ++ } */ ++ udevice = ast_variable_retrieve(cfg, cat, "device"); ++/* if (udevice) { ++ ast_log(LOG_NOTICE, "device = %s\n", udevice); ++ } */ ++ uinterval = ast_variable_retrieve(cfg, cat, "interval"); ++/* if (uinterval) { ++ ast_log(LOG_NOTICE, "interval = %s\n", uinterval); ++ } */ ++ if (uinterval && udevice && utype) { ++ woof = malloc(sizeof(struct watchdog_pvt)); ++ if (!woof) { ++ ast_log(LOG_ERROR, "unable to malloc!\n"); ++ return -1; ++ } ++ memset(woof, 0x0, sizeof(struct watchdog_pvt)); ++ strncpy(woof->device, udevice, sizeof(woof->device) - 1); ++ ++ woof->interval = atoi(uinterval);; ++ woof->next = watchdogs; ++ watchdogs = woof; ++ woof->fd = open(woof->device, O_WRONLY | O_SYNC); ++ if (woof->fd) { ++ if (!strncmp(utype, "isdnguard", sizeof(utype))) { ++ woof->type = 1; ++ write(woof->fd, "START\n", 6); ++ } ++ ast_pthread_create(&woof->watchdog_thread, NULL, do_watchdog_thread, woof); ++ } else { ++ ast_log(LOG_WARNING, "error opening watchdog device %s !\n", woof->device); ++ } ++ } ++ } ++ ast_config_destroy(cfg); ++ } ++ return res; ++} ++ ++ ++static int unload_module(void) ++{ ++ struct watchdog_pvt *dogs, *woof; ++ dogs = watchdogs; ++ while (dogs) { ++ pthread_cancel(dogs->watchdog_thread); ++ pthread_join(dogs->watchdog_thread, NULL); ++ close(dogs->fd); ++ woof = dogs->next; ++ free(dogs); ++ dogs = woof; ++ } ++ return 0; ++} ++ ++ ++AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Watchdog Resource", ++ .load = load_module, ++ .unload = unload_module, ++); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/app-dial-R-noinband +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/app-dial-R-noinband @@ -0,0 +1,99 @@ +--- a/apps/app_dial.c ++++ b/apps/app_dial.c +@@ -198,6 +198,8 @@ static char *descrip = + " family/key is not specified.\n" + " r - Indicate ringing to the calling party. Pass no audio to the calling\n" + " party until the called channel has answered.\n" ++" R - indicate ringing to the calling party when the called party indicates\n" ++" ringing, pass no audio until answered.\n" + " S(x) - Hang up the call after 'x' seconds *after* the called party has\n" + " answered the call.\n" + " t - Allow the called party to transfer the calling party by sending the\n" +@@ -254,6 +256,7 @@ enum { + OPT_CALLEE_PARK = (1 << 25), + OPT_CALLER_PARK = (1 << 26), + OPT_IGNORE_FORWARDING = (1 << 27), ++ OPT_NOINBAND = (1 << 28), + } dial_exec_option_flags; + + #define DIAL_STILLGOING (1 << 30) +@@ -297,6 +300,7 @@ AST_APP_OPTIONS(dial_exec_options, { + AST_APP_OPTION('p', OPT_SCREENING), + AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY), + AST_APP_OPTION('r', OPT_RINGBACK), ++ AST_APP_OPTION('R', OPT_NOINBAND), + AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP), + AST_APP_OPTION('t', OPT_CALLEE_TRANSFER), + AST_APP_OPTION('T', OPT_CALLER_TRANSFER), +@@ -412,7 +416,7 @@ static struct ast_channel *wait_for_answ + int orig = *to; + struct ast_channel *peer = NULL; + /* single is set if only one destination is enabled */ +- int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK); ++ int single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK | OPT_NOINBAND)); + + if (single) { + /* Turn off hold music, etc */ +@@ -633,7 +637,7 @@ static struct ast_channel *wait_for_answ + /* Setup early media if appropriate */ + if (single && CAN_EARLY_BRIDGE(peerflags)) + ast_rtp_early_bridge(in, c); +- if (!ast_test_flag(outgoing, OPT_RINGBACK)) ++ if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_NOINBAND)) + ast_indicate(in, AST_CONTROL_PROGRESS); + break; + case AST_CONTROL_VIDUPDATE: +@@ -651,7 +655,7 @@ static struct ast_channel *wait_for_answ + ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name); + if (single && CAN_EARLY_BRIDGE(peerflags)) + ast_rtp_early_bridge(in, c); +- if (!ast_test_flag(outgoing, OPT_RINGBACK)) ++ if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_NOINBAND)) + ast_indicate(in, AST_CONTROL_PROCEEDING); + break; + case AST_CONTROL_HOLD: +@@ -669,7 +673,7 @@ static struct ast_channel *wait_for_answ + /* Ignore going off hook and flash */ + break; + case -1: +- if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) { ++ if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK | OPT_NOINBAND)) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name); + ast_indicate(in, -1); +@@ -1091,7 +1095,7 @@ static int dial_exec_full(struct ast_cha + outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"); + } + +- ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING); ++ ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_NOINBAND); + /* loop through the list of dial destinations */ + rest = args.peers; + while ((cur = strsep(&rest, "&")) ) { +@@ -1116,7 +1120,7 @@ static int dial_exec_full(struct ast_cha + OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP | + OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | + OPT_CALLEE_PARK | OPT_CALLER_PARK | +- OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID); ++ OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID | OPT_NOINBAND); + ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML); + } + ast_copy_string(numsubst, number, sizeof(numsubst)); +@@ -1319,7 +1323,7 @@ static int dial_exec_full(struct ast_cha + ast_moh_start(chan, NULL, NULL); + } + ast_indicate(chan, AST_CONTROL_PROGRESS); +- } else if (ast_test_flag(outgoing, OPT_RINGBACK)) { ++ } else if (ast_test_flag(outgoing, OPT_RINGBACK | OPT_NOINBAND)) { + ast_indicate(chan, AST_CONTROL_RINGING); + sentringing++; + } +@@ -1442,7 +1446,7 @@ static int dial_exec_full(struct ast_cha + + if (ast_test_flag(&opts, OPT_MUSICBACK)) { + ast_moh_stop(chan); +- } else if (ast_test_flag(&opts, OPT_RINGBACK)) { ++ } else if (ast_test_flag(&opts, OPT_RINGBACK | OPT_NOINBAND)) { + ast_indicate(chan, -1); + sentringing=0; + } --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/isdn-fixes +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/isdn-fixes @@ -0,0 +1,24 @@ +--- a/apps/app_zapras.c ++++ b/apps/app_zapras.c +@@ -183,7 +183,7 @@ static void run_ras(struct ast_channel * + } + } + /* Throw back into audio mode */ +- x = 1; ++ x = 0; + ioctl(chan->fds[0], ZT_AUDIOMODE, &x); + + /* Restore saved values */ +--- a/main/channel.c ++++ b/main/channel.c +@@ -3898,6 +3898,10 @@ enum ast_bridge_result ast_channel_bridg + c1->name, c1->_bridge->name); + return -1; + } ++ ++ if (IS_DIGITAL(c0->transfercapability) || IS_DIGITAL(c1->transfercapability)) { ++ config->flags = 0; ++ } + + /* Stop if we're a zombie or need a soft hangup */ + if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/app-meetme-avoid-overflows +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/app-meetme-avoid-overflows @@ -0,0 +1,37 @@ +--- a/apps/app_meetme.c ++++ b/apps/app_meetme.c +@@ -1405,8 +1405,9 @@ static int conf_run(struct ast_channel * + char members[10] = ""; + int dtmf, opt_waitmarked_timeout = 0; + time_t timeout = 0; ++ int dyna_buff = CONF_SIZE; + ZT_BUFFERINFO bi; +- char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET]; ++ char __buf[ZT_MAX_BUF_SPACE / ZT_DEFAULT_NUM_BUFS + AST_FRIENDLY_OFFSET]; + char *buf = __buf + AST_FRIENDLY_OFFSET; + int setusercount = 0; + +@@ -1615,7 +1616,7 @@ static int conf_run(struct ast_channel * + } + /* Setup buffering information */ + memset(&bi, 0, sizeof(bi)); +- bi.bufsize = CONF_SIZE/2; ++ bi.bufsize = dyna_buff / 2; + bi.txbufpolicy = ZT_POLICY_IMMEDIATE; + bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; + bi.numbufs = audio_buffers; +@@ -1926,6 +1927,14 @@ static int conf_run(struct ast_channel * + f = ast_read(c); + if (!f) + break; ++ if (f->datalen && f->datalen != dyna_buff) { ++ ast_log(LOG_NOTICE, "Audio bytes: %d Buffer size: %d\n", f->datalen, dyna_buff); ++ if (f->datalen < ZT_MAX_BUF_SPACE/audio_buffers) { /* skip too large frame to avoid overflow */ ++ dyna_buff = f->datalen; ++ close(fd); ++ goto zapretry; ++ } ++ } + if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) { + if (user->talk.actual) + ast_frame_adjust_volume(f, user->talk.actual); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/ast-device-state-CID +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/ast-device-state-CID @@ -0,0 +1,434 @@ +--- a/include/asterisk/devicestate.h ++++ b/include/asterisk/devicestate.h +@@ -47,7 +47,7 @@ extern "C" { + #define AST_DEVICE_ONHOLD 8 + + /*! \brief Devicestate watcher call back */ +-typedef int (*ast_devstate_cb_type)(const char *dev, int state, void *data); ++typedef int (*ast_devstate_cb_type)(const char *dev, int state, void *data, char *cid_num, char *cid_name); + + /*! \brief Devicestate provider call back */ + typedef int (*ast_devstate_prov_cb_type)(const char *data); +@@ -92,7 +92,7 @@ int ast_device_state_changed(const char + * callbacks for the changed extensions + * Returns 0 on success, -1 on failure + */ +-int ast_device_state_changed_literal(const char *device); ++int ast_device_state_changed_literal(const char *device, const char *cid_num, const char *cid_name); + + /*! \brief Registers a device state change callback + * \param callback Callback +--- a/main/devicestate.c ++++ b/main/devicestate.c +@@ -78,6 +78,8 @@ static AST_LIST_HEAD_STATIC(devstate_cbs + + struct state_change { + AST_LIST_ENTRY(state_change) list; ++ char cid_num[AST_MAX_EXTENSION]; ++ char cid_name[AST_MAX_EXTENSION]; + char device[1]; + }; + +@@ -277,7 +279,7 @@ void ast_devstate_del(ast_devstate_cb_ty + /*! \brief Notify callback watchers of change, and notify PBX core for hint updates + Normally executed within a separate thread + */ +-static void do_state_change(const char *device) ++static void do_state_change(const char *device, char *cid_num, char *cid_name) + { + int state; + struct devstate_cb *devcb; +@@ -288,13 +290,13 @@ static void do_state_change(const char * + + AST_LIST_LOCK(&devstate_cbs); + AST_LIST_TRAVERSE(&devstate_cbs, devcb, list) +- devcb->callback(device, state, devcb->data); ++ devcb->callback(device, state, devcb->data, cid_num, cid_name); + AST_LIST_UNLOCK(&devstate_cbs); + +- ast_hint_state_changed(device); ++ ast_hint_state_changed(device, cid_num, cid_name); + } + +-static int __ast_device_state_changed_literal(char *buf, int norecurse) ++static int __ast_device_state_changed_literal(char *buf, int norecurse, char *cid_num, char *cid_name) + { + char *device; + struct state_change *change; +@@ -308,10 +310,16 @@ static int __ast_device_state_changed_li + if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) { + /* we could not allocate a change struct, or */ + /* there is no background thread, so process the change now */ +- do_state_change(device); ++ do_state_change(device, cid_num, cid_name); + } else { + /* queue the change */ + strcpy(change->device, device); ++ if (cid_num && (!ast_strlen_zero(cid_num))) { ++ strncpy(change->cid_num, cid_num, sizeof(change->cid_num) - 1); ++ } ++ if (cid_name && (!ast_strlen_zero(cid_name))) { ++ strncpy(change->cid_name, cid_name, sizeof(change->cid_name) - 1); ++ } + AST_LIST_LOCK(&state_changes); + AST_LIST_INSERT_TAIL(&state_changes, change, list); + if (AST_LIST_FIRST(&state_changes) == change) +@@ -329,17 +337,23 @@ static int __ast_device_state_changed_li + */ + if (!norecurse && (tmp = strrchr(device, '-'))) { + *tmp = '\0'; +- __ast_device_state_changed_literal(device, 1); ++ __ast_device_state_changed_literal(device, 1, cid_num, cid_name); + } + + return 1; + } + +-int ast_device_state_changed_literal(const char *dev) ++int ast_device_state_changed_literal(const char *dev, const char *cid_num, const char *cid_name) + { + char *buf; ++ char *buf2 = NULL; ++ char *buf3 = NULL; + buf = ast_strdupa(dev); +- return __ast_device_state_changed_literal(buf, 0); ++ if (cid_num) ++ buf2 = ast_strdupa(cid_num); ++ if (cid_name) ++ buf3 = ast_strdupa(cid_name); ++ return __ast_device_state_changed_literal(buf, 0, buf2, buf3); + } + + /*! \brief Accept change notification, add it to change queue */ +@@ -351,7 +365,7 @@ int ast_device_state_changed(const char + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); +- return __ast_device_state_changed_literal(buf, 0); ++ return __ast_device_state_changed_literal(buf, 0, NULL, NULL); + } + + /*! \brief Go through the dev state change queue and update changes in the dev state thread */ +@@ -366,7 +380,7 @@ static void *do_devstate_changes(void *d + if (cur) { + /* we got an entry, so unlock the list while we process it */ + AST_LIST_UNLOCK(&state_changes); +- do_state_change(cur->device); ++ do_state_change(cur->device, cur->cid_num, cur->cid_name); + free(cur); + AST_LIST_LOCK(&state_changes); + } else { +--- a/include/asterisk/channel.h ++++ b/include/asterisk/channel.h +@@ -613,8 +613,13 @@ int ast_channel_datastore_remove(struct + /*! \brief Find a datastore on a channel */ + struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, char *uid); + ++extern ast_mutex_t uniquelock; ++ ++/*! \brief Change the state of a channel and the callerid of the calling channel*/ ++int ast_setstate_and_callerid(struct ast_channel *chan, enum ast_channel_state state, char *cid_num, char *cid_name); ++ + /*! \brief Change the state of a channel */ +-int ast_setstate(struct ast_channel *chan, enum ast_channel_state); ++int ast_setstate(struct ast_channel *chan, enum ast_channel_state state); + + /*! \brief Create a channel structure + \return Returns NULL on failure to allocate. +--- a/main/channel.c ++++ b/main/channel.c +@@ -1261,7 +1261,7 @@ void ast_channel_free(struct ast_channel + free(chan); + AST_LIST_UNLOCK(&channels); + +- ast_device_state_changed_literal(name); ++ ast_device_state_changed_literal(name, NULL, NULL); + } + + struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, char *uid) +@@ -3673,7 +3673,7 @@ void ast_set_callerid(struct ast_channel + ast_channel_unlock(chan); + } + +-int ast_setstate(struct ast_channel *chan, enum ast_channel_state state) ++int ast_setstate_and_callerid(struct ast_channel *chan, enum ast_channel_state state, char *cid_num, char *cid_name) + { + int oldstate = chan->_state; + +@@ -3681,7 +3681,7 @@ int ast_setstate(struct ast_channel *cha + return 0; + + chan->_state = state; +- ast_device_state_changed_literal(chan->name); ++ ast_device_state_changed_literal(chan->name, cid_num, cid_name); + /* setstate used to conditionally report Newchannel; this is no more */ + manager_event(EVENT_FLAG_CALL, + "Newstate", +@@ -3698,6 +3698,11 @@ int ast_setstate(struct ast_channel *cha + return 0; + } + ++int ast_setstate(struct ast_channel *chan, enum ast_channel_state state) ++{ ++ return ast_setstate_and_callerid(chan, state, NULL, NULL); ++} ++ + /*! \brief Find bridged channel */ + struct ast_channel *ast_bridged_channel(struct ast_channel *chan) + { +--- a/include/asterisk/pbx.h ++++ b/include/asterisk/pbx.h +@@ -63,7 +63,7 @@ struct ast_ignorepat; + struct ast_sw; + + /*! \brief Typedef for devicestate and hint callbacks */ +-typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data); ++typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data, char *cid_num, char *cid_name); + + /*! \brief Data structure associated with a custom dialplan function */ + struct ast_custom_function { +@@ -875,7 +875,7 @@ int ast_func_read(struct ast_channel *ch + */ + int ast_func_write(struct ast_channel *chan, char *function, const char *value); + +-void ast_hint_state_changed(const char *device); ++void ast_hint_state_changed(const char *device, char *cid_num, char *cid_name); + + #if defined(__cplusplus) || defined(c_plusplus) + } +--- a/main/pbx.c ++++ b/main/pbx.c +@@ -2022,7 +2022,7 @@ int ast_extension_state(struct ast_chann + return ast_extension_state2(e); /* Check all devices in the hint */ + } + +-void ast_hint_state_changed(const char *device) ++void ast_hint_state_changed(const char *device, char *cid_num, char *cid_name) + { + struct ast_hint *hint; + +@@ -2053,11 +2053,11 @@ void ast_hint_state_changed(const char * + + /* For general callbacks */ + for (cblist = statecbs; cblist; cblist = cblist->next) +- cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); ++ cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data, cid_num, cid_name); + + /* For extension callbacks */ + for (cblist = hint->callbacks; cblist; cblist = cblist->next) +- cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); ++ cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data, cid_num, cid_name); + + hint->laststate = state; /* record we saw the change */ + } +@@ -2252,7 +2252,7 @@ static int ast_remove_hint(struct ast_ex + /* Notify with -1 and remove all callbacks */ + cbprev = cblist; + cblist = cblist->next; +- cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); ++ cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data, NULL, NULL); + free(cbprev); + } + hint->callbacks = NULL; +@@ -4021,7 +4021,7 @@ void ast_merge_contexts_and_delete(struc + while (thiscb) { + prevcb = thiscb; + thiscb = thiscb->next; +- prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); ++ prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data, NULL, NULL); + free(prevcb); + } + } else { +--- a/channels/chan_sip.c ++++ b/channels/chan_sip.c +@@ -1343,7 +1343,7 @@ static void ast_quiet_chan(struct ast_ch + static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target); + + /*--- Device monitoring and Device/extension state handling */ +-static int cb_extensionstate(char *context, char* exten, int state, void *data); ++static int cb_extensionstate(char *context, char* exten, int state, void *data, char *cid_num, char *cid_name); + static int sip_devicestate(void *data); + static int sip_poke_noanswer(const void *data); + static int sip_poke_peer(struct sip_peer *peer); +@@ -8599,7 +8599,7 @@ static void sip_peer_hold(struct sip_pvt + /*! \brief Callback for the devicestate notification (SUBSCRIBE) support subsystem + \note If you add an "hint" priority to the extension in the dial plan, + you will get notifications on device state changes */ +-static int cb_extensionstate(char *context, char* exten, int state, void *data) ++static int cb_extensionstate(char *context, char* exten, int state, void *data, char *cid_num, char *cid_name) + { + struct sip_pvt *p = data; + +@@ -12787,7 +12787,7 @@ static void handle_response(struct sip_p + if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { + /* Ready to send the next state we have on queue */ + ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); +- cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); ++ cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL); + } + } + } else if (sipmethod == SIP_REGISTER) +@@ -13040,7 +13040,7 @@ static void handle_response(struct sip_p + if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { + /* Ready to send the next state we have on queue */ + ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); +- cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); ++ cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL); + } + } + } else if (sipmethod == SIP_BYE) +--- a/apps/app_queue.c ++++ b/apps/app_queue.c +@@ -721,7 +721,7 @@ static void *device_state_thread(void *d + return NULL; + } + /*! \brief Producer of the statechange queue */ +-static int statechange_queue(const char *dev, int state, void *ign) ++static int statechange_queue(const char *dev, int state, void *ign, char *cid_num, char *cid_name) + { + struct statechange *sc; + +--- a/include/asterisk/manager.h ++++ b/include/asterisk/manager.h +@@ -55,6 +55,7 @@ + #define EVENT_FLAG_AGENT (1 << 5) /* Ability to read/set agent info */ + #define EVENT_FLAG_USER (1 << 6) /* Ability to read/set user info */ + #define EVENT_FLAG_CONFIG (1 << 7) /* Ability to modify configurations */ ++#define EVENT_FLAG_EXTENSIONSTATUS (1 << 8) /* ExtensionStatus events */ + + /* Export manager structures */ + #define AST_MAX_MANHEADERS 128 +--- a/main/manager.c ++++ b/main/manager.c +@@ -129,6 +129,7 @@ static struct permalias { + { EVENT_FLAG_AGENT, "agent" }, + { EVENT_FLAG_USER, "user" }, + { EVENT_FLAG_CONFIG, "config" }, ++ { EVENT_FLAG_EXTENSIONSTATUS, "extensionstatus" }, + { -1, "all" }, + { 0, "none" }, + }; +@@ -2592,10 +2593,12 @@ int ast_manager_unregister(char *action) + return 0; + } + +-static int manager_state_cb(char *context, char *exten, int state, void *data) ++static int manager_state_cb(char *context, char *exten, int state, void *data, char *cid_num, char *cid_name) + { ++ char hint[256] = ""; ++ ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); + /* Notify managers of change */ +- manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state); ++ manager_event(EVENT_FLAG_EXTENSIONSTATUS, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\nCallerID: \"%s\" <%s>\r\nHint: %s\r\n", exten, context, state, cid_num, cid_name, hint); + return 0; + } + +--- a/apps/app_devstate.c ++++ b/apps/app_devstate.c +@@ -50,7 +50,7 @@ static struct ast_cli_entry cli_dev_sta + static int devstate_cli(int fd, int argc, char *argv[]) + { + char devName[128]; +- if (argc != 3) ++ if ((argc != 3) && (argc != 4) && (argc != 5)) + return RESULT_SHOWUSAGE; + + if (ast_db_put("DEVSTATES", argv[1], argv[2])) +@@ -58,7 +58,15 @@ static int devstate_cli(int fd, int argc + ast_log(LOG_DEBUG, "ast_db_put failed\n"); + } + snprintf(devName, sizeof(devName), "DS/%s", argv[1]); +- ast_device_state_changed_literal(devName); ++ if (argc == 4) { ++ ast_log(LOG_NOTICE, "devname %s cid %s\n", devName, argv[3]); ++ ast_device_state_changed_literal(devName, argv[3], NULL); ++ } else if (argc == 5) { ++ ast_log(LOG_NOTICE, "devname %s cid %s cidname %s\n", devName, argv[3], argv[4]); ++ ast_device_state_changed_literal(devName, argv[3], argv[4]); ++ } else { ++ ast_device_state_changed_literal(devName, NULL, NULL); ++ } + return RESULT_SUCCESS; + } + +@@ -93,7 +101,7 @@ static int devstate_exec(struct ast_chan + } + + snprintf(devName, sizeof(devName), "DS/%s", device); +- ast_device_state_changed_literal(devName); ++ ast_device_state_changed_literal(devName, NULL, NULL); + + ast_module_user_remove(u); + return 0; +@@ -150,6 +158,8 @@ static int action_devstate(struct manses + const char *devstate = astman_get_header(m, "Devstate"); + const char *value = astman_get_header(m, "Value"); + const char *id = astman_get_header(m,"ActionID"); ++ const char *cid_num = astman_get_header(m, "CallerID"); ++ const char *cid_name = astman_get_header(m, "CallerIDName"); + char devName[128]; + char idText[256] = ""; + +@@ -166,7 +176,7 @@ static int action_devstate(struct manses + + if (!ast_db_put("DEVSTATES", devstate, (char *)value)) { + snprintf(devName, sizeof(devName), "DS/%s", devstate); +- ast_device_state_changed_literal(devName); ++ ast_device_state_changed_literal(devName, cid_num, cid_name); + astman_append(s, "Response: Success\r\n%s\r\n", idText); + } else { + ast_log(LOG_DEBUG, "ast_db_put failed\n"); +--- a/res/res_esel.c ++++ b/res/res_esel.c +@@ -51,6 +51,8 @@ typedef struct esel_extension_state { + char context[AST_MAX_EXTENSION]; + char exten[AST_MAX_EXTENSION]; + int state; ++ char cid_num[AST_MAX_EXTENSION]; ++ char cid_name[AST_MAX_EXTENSION]; + char devstate[AST_MAX_EXTENSION]; + struct esel_extension_state *next; + struct esel_extension_state *prev; +@@ -93,7 +95,7 @@ typedef struct esel_pvt { + + static struct esel_pvt *donkeys = NULL; + +-static int esel_queue_extension_state(struct esel_queue *queue, char *context, char *exten, int state, void *data) { ++static int esel_queue_extension_state(struct esel_queue *queue, char *context, char *exten, int state, void *data, char *cid_num, char *cid_name) { + struct esel_extension_state *exstate = NULL; + + exstate = malloc(sizeof(struct esel_extension_state)); +@@ -115,6 +117,8 @@ static int esel_queue_extension_state(st + } + ast_copy_string(exstate->exten, exten, sizeof(exstate->exten)); + ast_copy_string(exstate->context, context, sizeof(exstate->context)); ++ ast_copy_string(exstate->cid_num, cid_num, sizeof(exstate->cid_num)); ++ ast_copy_string(exstate->cid_name, cid_name, sizeof(exstate->cid_name)); + exstate->state = state; + if (!queue->head) { + /* Empty queue */ +@@ -161,7 +165,7 @@ static void esel_export_to_remote(struct + char msg[1024]; + int sent = 0; + memset(msg, 0x0, sizeof(msg)); +- snprintf(msg, sizeof(msg) - 1, "Action: Devstate\r\nDevstate: %s\r\nValue: %d\r\n\r\n", exstate->devstate, esel_state2devstate(exstate->state)); ++ snprintf(msg, sizeof(msg) - 1, "Action: Devstate\r\nDevstate: %s\r\nValue: %d\r\nCallerID: %s\r\nCallerIDName: %s\r\n\r\n", exstate->devstate, esel_state2devstate(exstate->state), exstate->cid_num, exstate->cid_name); + sent = send(esel->sockfd, msg, strlen(msg), 0); + if (sent == -1) { + esel->connected = 0; +@@ -250,13 +254,13 @@ static void *do_esel_thread(void *data) + return NULL; + } + +-static int esel_state_cb(char *context, char *exten, int state, void *data) { ++static int esel_state_cb(char *context, char *exten, int state, void *data, char *cid_num, char *cid_name) { + struct esel_pvt *esel; + + esel = donkeys; + ast_mutex_lock(&listlock); + while (esel) { +- esel_queue_extension_state(&esel->queue, context, exten, state, data); ++ esel_queue_extension_state(&esel->queue, context, exten, state, data, cid_num, cid_name); + esel = esel->next; + } + ast_mutex_unlock(&listlock); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/configurable-AST_SYSTEM_NAME +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/configurable-AST_SYSTEM_NAME @@ -0,0 +1,29 @@ +--- a/build_tools/make_defaults_h ++++ b/build_tools/make_defaults_h +@@ -17,6 +17,7 @@ cat << END + #define AST_KEY_DIR "${INSTALL_PATH}${ASTDATADIR}/keys" + #define AST_DB "${INSTALL_PATH}${ASTVARLIBDIR}/astdb" + #define AST_TMP_DIR "${INSTALL_PATH}${ASTSPOOLDIR}/tmp" ++#define AST_SYSTEM_NAME "asterisk" + + #define AST_CONFIG_FILE "${INSTALL_PATH}${ASTCONFPATH}" + +--- a/main/asterisk.c ++++ b/main/asterisk.c +@@ -2455,6 +2455,7 @@ static void ast_readconfig(void) + ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID)); + ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET)); + ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR)); ++ ast_copy_string(ast_config_AST_SYSTEM_NAME, AST_SYSTEM_NAME, sizeof(ast_config_AST_SYSTEM_NAME)); + + /* no asterisk.conf? no problem, use buildtime config! */ + if (!cfg) { +@@ -2579,6 +2580,8 @@ static void ast_readconfig(void) + ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP)); + } else if (!strcasecmp(v->name, "systemname")) { + ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME)); ++ } else if (!strcasecmp(v->name, "uniquename")) { ++ ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME)); + } else if (!strcasecmp(v->name, "languageprefix")) { + ast_language_is_prefix = ast_true(v->value); + } --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/misc-app-devstate +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/misc-app-devstate @@ -0,0 +1,205 @@ +--- /dev/null ++++ b/apps/app_devstate.c +@@ -0,0 +1,202 @@ ++/* ++ * Devstate application ++ * ++ * Since we like the snom leds so much, a little app to ++ * light the lights on the snom on demand .... ++ * ++ * Copyright (C) 2005, Druid Software ++ * ++ * This program is free software, distributed under the terms of ++ * the GNU General Public License ++ */ ++ ++#include "asterisk.h" ++ ++#include ++#include ++#include ++#include ++ ++#include "asterisk/lock.h" ++#include "asterisk/file.h" ++#include "asterisk/logger.h" ++#include "asterisk/channel.h" ++#include "asterisk/pbx.h" ++#include "asterisk/astdb.h" ++#include "asterisk/cli.h" ++#include "asterisk/manager.h" ++#include "asterisk/devicestate.h" ++#include "asterisk/module.h" ++ ++ ++static char type[] = "DS"; ++static char tdesc[] = "Application for sending device state messages"; ++ ++static char app[] = "Devstate"; ++ ++static char synopsis[] = "Generate a device state change event given the input parameters"; ++ ++static char descrip[] = " Devstate(device|state): Generate a device state change event given the input parameters. Returns 0. State values match the asterisk device states. They are 0 = unknown, 1 = not inuse, 2 = inuse, 3 = busy, 4 = invalid, 5 = unavailable, 6 = ringing\n"; ++ ++static char devstate_cli_usage[] = ++"Usage: devstate device state\n" ++" Generate a device state change event given the input parameters.\n Mainly used for lighting the LEDs on the snoms.\n"; ++ ++static int devstate_cli(int fd, int argc, char *argv[]); ++static struct ast_cli_entry cli_dev_state = ++ { { "devstate", NULL }, devstate_cli, "Set the device state on one of the \"pseudo devices\".", devstate_cli_usage }; ++ ++ ++static int devstate_cli(int fd, int argc, char *argv[]) ++{ ++ char devName[128]; ++ if (argc != 3) ++ return RESULT_SHOWUSAGE; ++ ++ if (ast_db_put("DEVSTATES", argv[1], argv[2])) ++ { ++ ast_log(LOG_DEBUG, "ast_db_put failed\n"); ++ } ++ snprintf(devName, sizeof(devName), "DS/%s", argv[1]); ++ ast_device_state_changed_literal(devName); ++ return RESULT_SUCCESS; ++} ++ ++static int devstate_exec(struct ast_channel *chan, void *data) ++{ ++ char *device, *state, *info; ++ char devName[128]; ++ struct ast_module_user *u; ++ ++ ++ if (!(info = ast_strdupa(data))) { ++ ast_log(LOG_WARNING, "Unable to dupe data :(\n"); ++ return -1; ++ } ++ ++ u = ast_module_user_add(chan); ++ device = info; ++ state = strchr(info, '|'); ++ if (state) { ++ *state = '\0'; ++ state++; ++ } ++ else ++ { ++ ast_log(LOG_DEBUG, "No state argument supplied\n"); ++ return -1; ++ } ++ ++ if (ast_db_put("DEVSTATES", device, state)) ++ { ++ ast_log(LOG_DEBUG, "ast_db_put failed\n"); ++ } ++ ++ snprintf(devName, sizeof(devName), "DS/%s", device); ++ ast_device_state_changed_literal(devName); ++ ++ ast_module_user_remove(u); ++ return 0; ++} ++ ++ ++static int ds_devicestate(void *data) ++{ ++ char *dest = data; ++ char stateStr[16]; ++ if (ast_db_get("DEVSTATES", dest, stateStr, sizeof(stateStr))) ++ { ++ ast_log(LOG_DEBUG, "ds_devicestate couldnt get state in astdb\n"); ++ return 0; ++ } ++ else ++ { ++ ast_log(LOG_DEBUG, "ds_devicestate dev=%s returning state %d\n", ++ dest, atoi(stateStr)); ++ return (atoi(stateStr)); ++ } ++} ++ ++static struct ast_channel_tech devstate_tech = { ++ .type = type, ++ .description = tdesc, ++ .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1), ++ .devicestate = ds_devicestate, ++ .requester = NULL, ++ .send_digit_begin = NULL, ++ .send_digit_end = NULL, ++ .send_text = NULL, ++ .call = NULL, ++ .hangup = NULL, ++ .answer = NULL, ++ .read = NULL, ++ .write = NULL, ++ .bridge = NULL, ++ .exception = NULL, ++ .indicate = NULL, ++ .fixup = NULL, ++ .setoption = NULL, ++}; ++ ++static char mandescr_devstate[] = ++"Description: Put a value into astdb\n" ++"Variables: \n" ++" Family: ...\n" ++" Key: ...\n" ++" Value: ...\n"; ++ ++static int action_devstate(struct mansession *s, const struct message *m) ++{ ++ const char *devstate = astman_get_header(m, "Devstate"); ++ const char *value = astman_get_header(m, "Value"); ++ const char *id = astman_get_header(m,"ActionID"); ++ char devName[128]; ++ char idText[256] = ""; ++ ++ if (!strlen(devstate)) { ++ astman_send_error(s, m, "No Devstate specified"); ++ return 0; ++ } ++ if (!strlen(value)) { ++ astman_send_error(s, m, "No Value specified"); ++ return 0; ++ } ++ if (!ast_strlen_zero(id)) ++ snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); ++ ++ if (!ast_db_put("DEVSTATES", devstate, (char *)value)) { ++ snprintf(devName, sizeof(devName), "DS/%s", devstate); ++ ast_device_state_changed_literal(devName); ++ astman_append(s, "Response: Success\r\n%s\r\n", idText); ++ } else { ++ ast_log(LOG_DEBUG, "ast_db_put failed\n"); ++ astman_append(s, "Response: Failed\r\n%s\r\n", idText); ++ } ++ return 0; ++} ++ ++static int load_module(void) ++{ ++ if (ast_channel_register(&devstate_tech)) { ++ ast_log(LOG_DEBUG, "Unable to register channel class %s\n", type); ++ return -1; ++ } ++ ast_cli_register(&cli_dev_state); ++ ast_manager_register2( "Devstate", EVENT_FLAG_CALL, action_devstate, "Change a device state", mandescr_devstate ); ++ return ast_register_application(app, devstate_exec, synopsis, descrip); ++} ++ ++static int unload_module(void) ++{ ++ int res = 0; ++ ++ ast_module_user_hangup_all(); ++ ast_manager_unregister( "Devstate"); ++ ast_cli_unregister(&cli_dev_state); ++ res = ast_unregister_application(app); ++ ast_channel_unregister(&devstate_tech); ++ return res; ++} ++ ++AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Simple Devstate Application"); ++ --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/misc-res-esel +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/misc-res-esel @@ -0,0 +1,402 @@ +--- /dev/null ++++ b/configs/esel.conf.sample +@@ -0,0 +1,12 @@ ++; ++; Configuration file for res_esel ++; ++ ++;[asterisk-2] ++;host = 192.168.0.1 ++;port = 5038 ++;username = manager ++;secret = donkey ++ ++; export the extension snom in context phones to DS/100 ++;export => snom@phones,100 +--- /dev/null ++++ b/res/res_esel.c +@@ -0,0 +1,384 @@ ++/* ++ * Asterisk -- A telephony toolkit for Linux. ++ * ++ * Extension State Export Logic (E.S.E.L) (Sorry, i couldnt resist...) ++ * ++ * Resource to export extension states to other Asterisk servers ++ * ++ * Copyright (C) 2006, Junghanns.NET GmbH ++ * ++ * Klaus-Peter Junghanns ++ * ++ * This program is free software, distributed under the terms of ++ * the GNU General Public License ++ */ ++ ++#include "asterisk.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "asterisk/file.h" ++#include "asterisk/logger.h" ++#include "asterisk/channel.h" ++#include "asterisk/pbx.h" ++#include "asterisk/options.h" ++#include "asterisk/module.h" ++#include "asterisk/translate.h" ++#include "asterisk/say.h" ++#include "asterisk/features.h" ++#include "asterisk/musiconhold.h" ++#include "asterisk/config.h" ++#include "asterisk/cli.h" ++#include "asterisk/manager.h" ++#include "asterisk/utils.h" ++#include "asterisk/lock.h" ++#include "asterisk/adsi.h" ++ ++ ++AST_MUTEX_DEFINE_STATIC(listlock); ++ ++typedef struct esel_extension_state { ++ char context[AST_MAX_EXTENSION]; ++ char exten[AST_MAX_EXTENSION]; ++ int state; ++ char devstate[AST_MAX_EXTENSION]; ++ struct esel_extension_state *next; ++ struct esel_extension_state *prev; ++} esel_extension_state; ++ ++typedef struct esel_export { ++ char context[AST_MAX_EXTENSION]; ++ char exten[AST_MAX_EXTENSION]; ++ char devstate[AST_MAX_EXTENSION]; ++ struct esel_export *next; ++} esel_export; ++ ++typedef struct esel_queue { ++ struct esel_extension_state *head; ++ struct esel_extension_state *tail; ++ int count; ++ ast_cond_t cond; ++ ast_mutex_t lock; ++} esel_queue; ++ ++typedef struct esel_pvt { ++ char name[80]; ++ char username[80]; ++ char secret[80]; ++ char host[80]; ++ int port; ++ struct sockaddr_in raddr; ++ int sockfd; ++ int connected; ++ pthread_t esel_thread; ++ ++ /* list of extensions to export */ ++ struct esel_export *extensions; ++ ++ /* queue */ ++ struct esel_queue queue; ++ ++ struct esel_pvt *next; ++} esel_pvt; ++ ++static struct esel_pvt *donkeys = NULL; ++ ++static int esel_queue_extension_state(struct esel_queue *queue, char *context, char *exten, int state, void *data) { ++ struct esel_extension_state *exstate = NULL; ++ ++ exstate = malloc(sizeof(struct esel_extension_state)); ++ if (!exstate) { ++ ast_log(LOG_ERROR, "Unable to malloc!\n"); ++ return 1; ++ } ++ memset(exstate,0,sizeof(struct esel_extension_state)); ++ exstate->next = NULL; ++ exstate->prev = NULL; ++ ++ ast_mutex_lock(&queue->lock); ++ if (queue->count > 100) { ++ ast_mutex_unlock(&queue->lock); ++ free(exstate); ++ if (option_verbose > 5) ++ ast_log(LOG_WARNING, "E.S.E.L Queue too long.\n"); ++ return -1; ++ } ++ ast_copy_string(exstate->exten, exten, sizeof(exstate->exten)); ++ ast_copy_string(exstate->context, context, sizeof(exstate->context)); ++ exstate->state = state; ++ if (!queue->head) { ++ /* Empty queue */ ++ queue->head = exstate; ++ queue->tail = exstate; ++ } else { ++ /* Double link */ ++ queue->tail->next = exstate; ++ exstate->prev = queue->tail; ++ queue->tail = exstate; ++ } ++ queue->count++; ++ ast_cond_signal(&queue->cond); ++ ast_mutex_unlock(&queue->lock); ++ return 0; ++} ++ ++static int esel_is_exported(struct esel_export *extensions, struct esel_extension_state *exstate) { ++ struct esel_export *export = NULL; ++ export = extensions; ++ while (export) { ++ if ((!strcasecmp(export->exten, exstate->exten)) && (!strcasecmp(export->context, exstate->context))) { ++ /* copy mapping */ ++ ast_copy_string(exstate->devstate, export->devstate, sizeof(exstate->devstate)); ++ return 1; ++ } ++ export = export->next; ++ } ++ return 0; ++} ++ ++static int esel_state2devstate(int state) { ++ switch(state) { ++ case 1: ++ return 2; ++ case 8: ++ return 6; ++ default: ++ return state; ++ } ++} ++ ++static void esel_export_to_remote(struct esel_extension_state *exstate, struct esel_pvt *esel) { ++ char msg[1024]; ++ int sent = 0; ++ memset(msg, 0x0, sizeof(msg)); ++ snprintf(msg, sizeof(msg) - 1, "Action: Devstate\r\nDevstate: %s\r\nValue: %d\r\n\r\n", exstate->devstate, esel_state2devstate(exstate->state)); ++ sent = send(esel->sockfd, msg, strlen(msg), 0); ++ if (sent == -1) { ++ esel->connected = 0; ++ } ++// ast_log(LOG_NOTICE, "%s", msg); ++} ++ ++static void *do_esel_thread(void *data) { ++ struct esel_pvt *esel = (struct esel_pvt *)data; ++ struct esel_queue *queue = &esel->queue; ++ struct esel_extension_state *exstate = NULL; ++ char msg[1024]; ++ char buf[1024]; ++ int numbytes = 0; ++ int sent = 0; ++ int res = 0; ++ for (;;) { ++ if (esel->connected) { ++ ast_mutex_lock(&queue->lock); ++ if (queue->count == 0) ++ ast_cond_wait(&queue->cond, &queue->lock); ++ exstate = queue->head; ++ if (exstate) { ++ if (exstate->next) { ++ queue->head = exstate->next; ++ } else { ++ queue->head = NULL; ++ queue->tail = NULL; ++ } ++ queue->count--; ++ } else { ++ ast_log(LOG_ERROR, "I SHOULD NEVER HAPPEN! EXPECT SOME MAJOR KABOOM! DUCK AND COVER!\n"); ++ } ++ ast_mutex_unlock(&queue->lock); ++ ++ if (exstate) { ++ if (esel_is_exported(esel->extensions, exstate)) { ++ esel_export_to_remote(exstate, esel); ++ } ++ free(exstate); ++ exstate = NULL; ++ } ++ } else { ++ if (esel->sockfd > 0) ++ close(esel->sockfd); ++ if ((esel->sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { ++ ast_log(LOG_ERROR, "unable to request socket!\n"); ++ return NULL; ++ } ++ /* try to connect */ ++ res = connect(esel->sockfd, (struct sockaddr *)&esel->raddr, sizeof(struct sockaddr)); ++ if (res) { ++ ast_log(LOG_NOTICE, "error connecting to %s:%d\n", esel->host, esel->port); ++ } else { ++ while (strncasecmp(buf, "Asterisk Call Manager:", 21)) { ++ if ((numbytes=recv(esel->sockfd, buf, sizeof(buf), 0)) == -1) { ++ esel->connected = 0; ++ continue; ++ } ++ buf[numbytes] = '\0'; ++ // ast_log(LOG_NOTICE, "read: %s", buf); ++ } ++ /* log into remote manager */ ++ memset(msg, 0x0, sizeof(msg)); ++ snprintf(msg, sizeof(msg) - 1, "Action: Login\r\nUsername: %s\r\nSecret: %s\r\n\r\n", esel->username, esel->secret); ++ sent = send(esel->sockfd, msg, strlen(msg), 0); ++ ++ while (strncasecmp(buf, "Response:", 9)) { ++ if ((numbytes=recv(esel->sockfd, buf, sizeof(buf), 0)) == -1) { ++ continue; ++ } ++ buf[numbytes] = '\0'; ++ // ast_log(LOG_NOTICE, "read: %s", buf); ++ } ++ ++ if (!strncasecmp(buf, "Response: Success", 17)) { ++ esel->connected = 1; ++ } else { ++ ast_log(LOG_ERROR, "error login into remote asterisk %s\n", esel->name); ++ } ++ } ++ /* time heals everything... */ ++ sleep(10); ++ } ++ } ++ return NULL; ++} ++ ++static int esel_state_cb(char *context, char *exten, int state, void *data) { ++ struct esel_pvt *esel; ++ ++ esel = donkeys; ++ ast_mutex_lock(&listlock); ++ while (esel) { ++ esel_queue_extension_state(&esel->queue, context, exten, state, data); ++ esel = esel->next; ++ } ++ ast_mutex_unlock(&listlock); ++ return 0; ++} ++ ++ ++static int load_module(void) ++{ ++ int res = 0; ++ const char *cat, *host, *port, *username, *secret, *name; ++ struct ast_config *cfg; ++ struct ast_variable *var; ++ struct esel_pvt *esel = NULL; ++ struct esel_export *export = NULL; ++ struct hostent *he; ++ struct ast_hostent h; ++ ++ cfg = ast_config_load("esel.conf"); ++ if (cfg) { ++ cat = ast_category_browse(cfg, NULL); ++ while(cat) { ++ name = cat; ++ host = ast_variable_retrieve(cfg, cat, "host"); ++ username = ast_variable_retrieve(cfg, cat, "username"); ++ secret = ast_variable_retrieve(cfg, cat, "secret"); ++ port = ast_variable_retrieve(cfg, cat, "port"); ++ ++ if (name && host && username && secret && port) { ++ esel = malloc(sizeof(struct esel_pvt)); ++ if (!esel) { ++ ast_log(LOG_ERROR, "unable to malloc!\n"); ++ return -1; ++ } ++ memset(esel, 0x0, sizeof(struct esel_pvt)); ++ ast_copy_string(esel->name, name, sizeof(esel->name)); ++ ast_copy_string(esel->host, host, sizeof(esel->host)); ++ ast_copy_string(esel->username, username, sizeof(esel->username)); ++ ast_copy_string(esel->secret, secret, sizeof(esel->secret)); ++ ++ esel->port = atoi(port); ++ if ((he=ast_gethostbyname(host, &h)) == NULL) { ++ ast_log(LOG_ERROR, "unknown host!\n"); ++ return -1; ++ } ++ ++ esel->raddr.sin_family = AF_INET; ++ esel->raddr.sin_port = htons(esel->port); ++ esel->raddr.sin_addr = *((struct in_addr *)he->h_addr); ++ bzero(&(esel->raddr.sin_zero), 8); ++ ++ esel->connected = 0; ++ ++ ast_mutex_init(&esel->queue.lock); ++ ast_cond_init(&esel->queue.cond, NULL); ++ ++ ++ /* read exports */ ++ var = ast_variable_browse(cfg, cat); ++ while (var) { ++ if (!strcasecmp(var->name, "export")) { ++ char *extenp = NULL, *contextp = NULL, *devstatep = NULL; ++ extenp = var->value; ++ devstatep = strchr(var->value, ',') + 1; ++ contextp = strchr(var->value, '@') + 1; ++ if (devstatep && contextp) { ++ export = malloc(sizeof(struct esel_export)); ++ if (!export) { ++ ast_log(LOG_ERROR, "unable to malloc!\n"); ++ return -1; ++ } ++ memset(export, 0x0, sizeof(struct esel_export)); ++ ast_copy_string(export->exten, extenp, contextp - extenp); ++ ast_copy_string(export->context, contextp, devstatep - contextp); ++ ast_copy_string(export->devstate, devstatep, sizeof(export->devstate)); ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "exporting %s @ %s as %s to %s\n", export->exten, export->context , export->devstate , esel->name); ++ export->next = esel->extensions; ++ esel->extensions = export; ++ export = NULL; ++ } ++ } ++ var = var->next; ++ } ++ ++ ++ ++ esel->next = donkeys; ++ donkeys = esel; ++ ++ ast_pthread_create(&esel->esel_thread, NULL, do_esel_thread, esel); ++ ++ } ++ cat = ast_category_browse(cfg, cat); ++ } ++ ast_config_destroy(cfg); ++ } ++ ast_extension_state_add(NULL, NULL, esel_state_cb, NULL); ++ return res; ++} ++ ++ ++static int unload_module(void) ++{ ++ struct esel_pvt *esel, *eseln; ++ ast_module_user_hangup_all(); ++ esel = donkeys; ++ ast_mutex_lock(&listlock); ++ while (esel) { ++ pthread_cancel(esel->esel_thread); ++ pthread_join(esel->esel_thread, NULL); ++ ast_mutex_destroy(&esel->queue.lock); ++ close(esel->sockfd); ++ eseln = esel->next; ++ free(esel); ++ esel = eseln; ++ } ++ ast_mutex_unlock(&listlock); ++ return 0; ++} ++ ++AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Extension State Export Logic (E.S.E.L.) Resource", ++ .load = load_module, ++ .unload = unload_module, ++); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/bristuff/ast_monitor_start-targetscript +++ asterisk-1.4.21.2~dfsg/debian/patches/bristuff/ast_monitor_start-targetscript @@ -0,0 +1,125 @@ +--- a/include/asterisk/monitor.h ++++ b/include/asterisk/monitor.h +@@ -38,6 +38,8 @@ struct ast_channel_monitor { + char write_filename[FILENAME_MAX]; + char filename_base[FILENAME_MAX]; + int filename_changed; ++ char target_url[FILENAME_MAX]; ++ char target_script[FILENAME_MAX]; + char *format; + int joinfiles; + enum AST_MONITORING_STATE state; +@@ -46,7 +48,7 @@ struct ast_channel_monitor { + + /* Start monitoring a channel */ + int ast_monitor_start(struct ast_channel *chan, const char *format_spec, +- const char *fname_base, int need_lock ); ++ const char *fname_base, const char *target_url, const char *target_script, int need_lock ); + + /* Stop monitoring a channel */ + int ast_monitor_stop(struct ast_channel *chan, int need_lock); +--- a/res/res_monitor.c ++++ b/res/res_monitor.c +@@ -130,7 +130,7 @@ static int ast_monitor_set_state(struct + + /* Start monitoring a channel */ + int ast_monitor_start( struct ast_channel *chan, const char *format_spec, +- const char *fname_base, int need_lock) ++ const char *fname_base, const char *target_url, const char *target_script, int need_lock) + { + int res = 0; + char tmp[256]; +@@ -154,6 +154,11 @@ int ast_monitor_start( struct ast_channe + return -1; + } + ++ if (target_url) ++ ast_copy_string(monitor->target_url, target_url, sizeof(monitor->target_url)); ++ if (target_script) ++ ast_copy_string(monitor->target_script, target_script, sizeof(monitor->target_script)); ++ + /* Determine file names */ + if (!ast_strlen_zero(fname_base)) { + int directory = strchr(fname_base, '/') ? 1 : 0; +@@ -297,6 +302,8 @@ int ast_monitor_stop(struct ast_channel + if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) { + char tmp[1024]; + char tmp2[1024]; ++ char tmp3[1024]; ++ int result; + const char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format; + char *name = chan->monitor->filename_base; + int directory = strchr(name, '/') ? 1 : 0; +@@ -325,8 +332,13 @@ int ast_monitor_stop(struct ast_channel + snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s%s%s-\"* ) &",tmp, dir, absolute, name); /* remove legs when done mixing */ + ast_copy_string(tmp, tmp2, sizeof(tmp)); + } +- ast_log(LOG_DEBUG,"monitor executing %s\n",tmp); +- if (ast_safe_system(tmp) == -1) ++ if (!ast_strlen_zero(chan->monitor->target_script) && !ast_strlen_zero(chan->monitor->target_url)) { ++ snprintf(tmp3,sizeof(tmp3), "( %s& nice -19 %s \"%s/%s.%s\" \"%s\" ) &",tmp, chan->monitor->target_script , dir, name, format, chan->monitor->target_url); ++ ast_copy_string(tmp, tmp3, sizeof(tmp)); ++ } ++ ast_log(LOG_NOTICE,"monitor executing %s\n",tmp); ++ result = ast_safe_system(tmp); ++ if (result == -1) + ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp); + } + +@@ -467,7 +479,7 @@ static int start_monitor_exec(struct ast + return 0; + } + +- res = ast_monitor_start(chan, format, fname_base, 1); ++ res = ast_monitor_start(chan, format, fname_base, NULL, NULL, 1); + if (res < 0) + res = ast_monitor_change_fname(chan, fname_base, 1); + ast_monitor_setjoinfiles(chan, joinfiles); +@@ -506,6 +518,8 @@ static int start_monitor_action(struct m + const char *fname = astman_get_header(m, "File"); + const char *format = astman_get_header(m, "Format"); + const char *mix = astman_get_header(m, "Mix"); ++ const char *target_url = astman_get_header(m, "TargetURL"); ++ const char *target_script = astman_get_header(m, "TargetScript"); + char *d; + + if (ast_strlen_zero(name)) { +@@ -530,7 +544,7 @@ static int start_monitor_action(struct m + *d = '-'; + } + +- if (ast_monitor_start(c, format, fname, 1)) { ++ if (ast_monitor_start(c, format, fname, target_url, target_script, 1)) { + if (ast_monitor_change_fname(c, fname, 1)) { + astman_send_error(s, m, "Could not start monitoring channel"); + ast_channel_unlock(c); +--- a/apps/app_queue.c ++++ b/apps/app_queue.c +@@ -2891,13 +2891,13 @@ static int try_calling(struct queue_ent + else + which = peer; + if (monitorfilename) +- ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1 ); ++ ast_monitor_start(which, qe->parent->monfmt, monitorfilename, NULL, NULL, 1 ); + else if (qe->chan->cdr) +- ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1 ); ++ ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, NULL, NULL, 1 ); + else { + /* Last ditch effort -- no CDR, make up something */ + snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random()); +- ast_monitor_start(which, qe->parent->monfmt, tmpid, 1 ); ++ ast_monitor_start(which, qe->parent->monfmt, tmpid, NULL, NULL, 1 ); + } + if (qe->parent->monjoin) + ast_monitor_setjoinfiles(which, 1); +--- a/channels/chan_agent.c ++++ b/channels/chan_agent.c +@@ -419,7 +419,7 @@ static int __agent_start_monitoring(stru + if ((pointer = strchr(filename, '.'))) + *pointer = '-'; + snprintf(tmp, sizeof(tmp), "%s%s", savecallsin, filename); +- ast_monitor_start(ast, recordformat, tmp, needlock); ++ ast_monitor_start(ast, recordformat, tmp, NULL, NULL, needlock); + ast_monitor_setjoinfiles(ast, 1); + snprintf(tmp2, sizeof(tmp2), "%s%s.%s", urlprefix, filename, recordformatext); + #if 0 --- asterisk-1.4.21.2~dfsg.orig/debian/patches/debian-banner +++ asterisk-1.4.21.2~dfsg/debian/patches/debian-banner @@ -0,0 +1,15 @@ + + -- Faidon Liambotis + +--- a/main/asterisk.c ++++ b/main/asterisk.c +@@ -151,6 +151,9 @@ int daemon(int, int); /* defined in lib + ast_verbose("This is free software, with components licensed under the GNU General Public\n"); \ + ast_verbose("License version 2 and other licenses; you are welcome to redistribute it under\n"); \ + ast_verbose("certain conditions. Type 'core show license' for details.\n"); \ ++ ast_verbose("=========================================================================\n"); \ ++ ast_verbose("This package has been modified for the Debian GNU/Linux distribution\n"); \ ++ ast_verbose("Please report all bugs to http://bugs.debian.org/asterisk\n"); \ + ast_verbose("=========================================================================\n") + + /*! \defgroup main_options Main Configuration Options --- asterisk-1.4.21.2~dfsg.orig/debian/patches/vpb-handle-nocards +++ asterisk-1.4.21.2~dfsg/debian/patches/vpb-handle-nocards @@ -0,0 +1,34 @@ +Set cards=0 to the default configuration so that autoload can load it without +stopping the startup process of Asterisk. +Of course, a fix for the code was needed to bail-out on cards=0 :-) + + -- Faidon Liambotis + +--- a/channels/chan_vpb.cc ++++ b/channels/chan_vpb.cc +@@ -2739,7 +2739,13 @@ static enum ast_module_load_result load_ + v = ast_variable_browse(cfg, "general"); + while (v){ + if (strcasecmp(v->name, "cards") == 0) { +- ast_log(LOG_NOTICE, "VPB Driver configured to use [%d] cards\n", atoi(v->value)); ++ if (atoi(v->value) == 0) { ++ ast_log(LOG_ERROR,"VPB Driver not configured\n"); ++ error = AST_MODULE_LOAD_DECLINE; ++ goto done; ++ } else { ++ ast_log(LOG_NOTICE,"VPB Driver configured to use [%d] cards\n", atoi(v->value)); ++ } + } else if (strcasecmp(v->name, "indication") == 0) { + use_ast_ind = 1; + ast_log(LOG_NOTICE, "VPB driver using Asterisk Indication functions!\n"); +--- a/configs/vpb.conf.sample ++++ b/configs/vpb.conf.sample +@@ -57,7 +57,7 @@ + type = v12pci + ;type = v6pci + ;type = v4pci +-cards = 1 ++cards = 0 + + [interfaces] + --- asterisk-1.4.21.2~dfsg.orig/debian/patches/zap-fix-timing-source +++ asterisk-1.4.21.2~dfsg/debian/patches/zap-fix-timing-source @@ -0,0 +1,18 @@ +Don't quit just because we don't have a good Zaptel timing source. +See http://bugs.debian.org/491310 + + -- Tzafrir Cohen + +--- a/main/asterisk.c ++++ b/main/asterisk.c +@@ -2985,8 +2985,8 @@ int main(int argc, char *argv[]) + "\n\t2. You only have to load Zaptel drivers if you want to take advantage of Zaptel services. One option is to unload zaptel modules if you don't need them." + "\n\t3. If you need Zaptel services, you must correctly configure Zaptel." + }; +- ast_log(LOG_ERROR, "%s\n", zaptel_timer_error); +- exit(1); ++ ast_log(LOG_WARNING, "%s\n", zaptel_timer_error); ++ ast_log(LOG_WARNING, "However, on Debian we don't quit that easily. See http://bugs.debian.org/491310\n"); + } + close(fd); + } --- asterisk-1.4.21.2~dfsg.orig/debian/patches/h323-no-deps-on-asterisk +++ asterisk-1.4.21.2~dfsg/debian/patches/h323-no-deps-on-asterisk @@ -0,0 +1,37 @@ +Don't link the Asterisk binary with the H.323 libraries since they are only +used by separate shared object, chan_h323.so. (Closes: #433884) + +WARNING: this will make Asterisk segfault (see #435146) when loading +chan_h323.so because libopenh323 is buggy (#438815). +We are working around this, see patch h323-workaround-openh323-segfault. + + -- Faidon Liambotis + +--- a/main/Makefile ++++ b/main/Makefile +@@ -131,13 +131,6 @@ AST_EMBED_LDFLAGS:=$(foreach dep,$(EMBED + AST_EMBED_LIBS:=$(foreach dep,$(EMBED_LIBS),$(value $(dep))) + OBJS:=$(sort $(OBJS)) + +-ifneq ($(wildcard ../channels/h323/Makefile.ast),) +- include ../channels/h323/Makefile.ast +-else +- H323LDFLAGS= +- H323LDLIBS= +-endif +- + asterisk: $(OBJS) editline/libedit.a db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS) + @$(ASTTOPDIR)/build_tools/make_build_h > $(ASTTOPDIR)/include/asterisk/build.h.tmp + @if cmp -s $(ASTTOPDIR)/include/asterisk/build.h.tmp $(ASTTOPDIR)/include/asterisk/build.h ; then echo ; else \ +@@ -146,11 +139,7 @@ asterisk: $(OBJS) editline/libedit.a db1 + @rm -f $(ASTTOPDIR)/include/asterisk/build.h.tmp + @$(CC) -c -o buildinfo.o $(ASTCFLAGS) buildinfo.c + $(ECHO_PREFIX) echo " [LD] $^ -> $@" +-ifneq ($(findstring chan_h323,$(MENUSELECT_CHANNELS)),) + $(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(ASTLDFLAGS) $^ buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) +-else +- $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(ASTLDFLAGS) $(H323LDFLAGS) $^ buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(H323LDLIBS) +-endif + $(CMD_PREFIX) $(ASTTOPDIR)/build_tools/strip_nonapi $@ || rm $@ + + clean:: --- asterisk-1.4.21.2~dfsg.orig/debian/patches/zap-fix-deadlock +++ asterisk-1.4.21.2~dfsg/debian/patches/zap-fix-deadlock @@ -0,0 +1,33 @@ +Backport a bristuff deadlock fix from changes made to chan_dahdi by Tzafrir. +(commit ccd11da0599c190f5b678aed3f164579ca873c71 on Xorcom's tree) + + -- Faidon Liambotis + +--- a/channels/chan_zap.c ++++ b/channels/chan_zap.c +@@ -8851,7 +8851,7 @@ static void *pri_dchannel(void *vpri) + int haveidles; + int activeidles; + int nextidle = -1; +- struct ast_channel *c; ++ struct ast_channel *c = NULL; + struct timeval tv, lowest, *next; + struct timeval lastidle = { 0, 0 }; + int doidling=0; +@@ -9590,6 +9590,7 @@ static void *pri_dchannel(void *vpri) + snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan); + pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); + ++ ast_mutex_lock(&c->lock); + ast_mutex_lock(&pri->pvts[chanpos]->lock); + ast_mutex_lock(&pri->lock); + +@@ -9637,6 +9638,8 @@ static void *pri_dchannel(void *vpri) + if (crv) + ast_mutex_unlock(&crv->lock); + ast_mutex_unlock(&pri->pvts[chanpos]->lock); ++ if (c) ++ ast_mutex_unlock(&c->lock); + } else { + if (e->ring.flexible) + pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION, -1); --- asterisk-1.4.21.2~dfsg.orig/debian/patches/zap-fix-cause34 +++ asterisk-1.4.21.2~dfsg/debian/patches/zap-fix-cause34 @@ -0,0 +1,23 @@ +fix "cause34" with BRI: reset 'call' when no call +Reset the 'call' of a zaptel channel if failing to make a call. + +(commit 232eb51c7572d8f4d73649103d51d70643bd4ad9 on Xorcom's tree) + + -- Faidon Liambotis + +--- a/channels/chan_zap.c ++++ b/channels/chan_zap.c +@@ -2735,11 +2735,12 @@ static int zt_hangup(struct ast_channel + /* if we send a rel9999ease complete we wont ge no hangup event, so clear the call here */ + if (icause == 34 || icause == 44 || icause == 82 || icause == 1 || icause == 81 || icause == 17) { + if ((ast->_state == AST_STATE_RING) || (ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING) || (ast->_state == AST_STATE_RESERVED)) { +- p->call = NULL; ++ /* no-op */ + } else { + ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state); + icause = 16; /* Note, in pri_hangup() libpri will already override the cause */ + } ++ p->call = NULL; + } + + if (p->pri->nodetype == BRI_NETWORK_PTMP) { --- asterisk-1.4.21.2~dfsg.orig/debian/patches/apptest_sleep +++ asterisk-1.4.21.2~dfsg/debian/patches/apptest_sleep @@ -0,0 +1,15 @@ +An extra little sleep that seems to work around a problem when +running the test between two PRI channels. + +Upstream bug: http://bugs.digium.com/12442 +--- a/apps/app_test.c ++++ b/apps/app_test.c +@@ -297,6 +297,8 @@ static int testclient_exec(struct ast_ch + res = 0; + else + res = -1; ++ ++ sleep(1); + } + if (option_debug && !res ) { + /* Step 12: Hangup! */ --- asterisk-1.4.21.2~dfsg.orig/debian/patches/make-clean-fixes +++ asterisk-1.4.21.2~dfsg/debian/patches/make-clean-fixes @@ -0,0 +1,26 @@ +Don't remove sounds on dist-clean, upstream tarballs come with +one of them. + + -- Faidon Liambotis + +--- a/Makefile ++++ b/Makefile +@@ -389,7 +389,6 @@ dist-clean: distclean + + distclean: $(SUBDIRS_DIST_CLEAN) clean + @$(MAKE) -C menuselect dist-clean +- @$(MAKE) -C sounds dist-clean + rm -f menuselect.makeopts makeopts menuselect-tree menuselect.makedeps + rm -f makeopts.embed_rules + rm -f config.log config.status +@@ -399,6 +398,10 @@ distclean: $(SUBDIRS_DIST_CLEAN) clean + rm -rf doc/api + rm -f build_tools/menuselect-deps + ++# tarballs distributed by Digium include sounds ++all-clean: distclean ++ @$(MAKE) -C sounds dist-clean ++ + datafiles: _all + if [ x`$(ID) -un` = xroot ]; then CFLAGS="$(ASTCFLAGS)" sh build_tools/mkpkgconfig $(DESTDIR)/usr/lib/pkgconfig; fi + # Should static HTTP be installed during make samples or even with its own target ala --- asterisk-1.4.21.2~dfsg.orig/debian/patches/safe_asterisk-nobg +++ asterisk-1.4.21.2~dfsg/debian/patches/safe_asterisk-nobg @@ -0,0 +1,32 @@ +Add an option to safe_asterisk so that it won't background. + +This is intended to work with start-stop-daemon's --background option which +results in a correct pidfile since the process doesn't fork. + +#376514, #362281 + +Needs more work from me to not change behavior for users but only for the +init script. After that, it can safely go upstream. + + -- Faidon Liambotis + +--- a/contrib/scripts/safe_asterisk ++++ b/contrib/scripts/safe_asterisk +@@ -15,6 +15,7 @@ DUMPDROP=/tmp + SLEEPSECS=4 + ASTSBINDIR=__ASTERISK_SBIN_DIR__ + ASTPIDFILE=__ASTERISK_VARRUN_DIR__/asterisk.pid ++BACKGROUND=0 + + # comment this line out to have this script _not_ kill all mpg123 processes when + # asterisk exits +@@ -179,4 +180,8 @@ run_asterisk() + done + } + +-run_asterisk & ++if [ "$BACKGROUND" = "1" ]; then ++ run_asterisk & ++else ++ run_asterisk ++fi --- asterisk-1.4.21.2~dfsg.orig/debian/changelog +++ asterisk-1.4.21.2~dfsg/debian/changelog @@ -0,0 +1,2085 @@ +asterisk (1:1.4.21.2~dfsg-2~bpo40+1) etch-backports; urgency=low + + * Rebuild for etch-backports. + * debian/control changed by debian/backports/etch.backports script. + * Added libisnnet-dev to Build-Depends in order to get chan_misdn. + * Used backport versions of: + - uw-imap ( uw-imap_2007b~dfsg-2~bpo40+1 ) + - zaptel ( 1.4.11~dfsg-1~bpo40+1 ) + - libpri ( 1.4.3-2~bpo40+1 ) + - misdn-kernel ( 1.1.8-1~bpo40+1 ) + - misdn-user ( 1.1.8-1~bp040+1 ) + + -- Victor Seva Mon, 06 Oct 2008 09:48:25 +0200 + +asterisk (1:1.4.21.2~dfsg-2) unstable; urgency=low + + [ Victor Seva ] + * support DEB_BUILD_OPTION noopt used to produce non-optimized builds. + (Closes: #492941). + * Depend on libcap2-dev instead of libcap-dev because libcap1 is no longer + maintained upstream. Thanks to Torsten Werner . + (Closes: #492620). + * Backport script fixes: + - Depend on debhelper >=5 on backport etch script. + - replace libcap2-dev by libcap-dev. + - remove lib-client2007b-dev. (Closes: #494405) + + [ Tzafrir Cohen ] + * Patch chan_zap so that asterisk starts even without a Zaptel timing + source. (Closes: #491310) + + [ Lionel Elie Mamane ] + * /etc/default/asterisk: Bring comments on AST_DUMPCORE_DIR in sync with + reality of implementation in /etc/init.d/asterisk. Change suggested + CORE_PATTERN to more secure ones. + * /etc/init.d/asterisk: Use the value of AST_DUMPCORE_DIR if it is a + directory, not if the value if DUMPCORE_DIR is a directory. + + [ Faidon Liambotis ] + * Backport a patch from Xorcom's tree fixing a deadlock situation caused + by the bristuff patch. (Closes: #493055) + * Backport a patch from Xorcom's tree fixing an occasional "Cause 34" error + on BRIs. + * Don't write /root/.asterisk_history when stopping asterisk with the init + script. (Closes: #500294) + * Eliminate warnings when calling some actions of the init script by + replacing obsolete asterisk commands with their newer counterpart. + + -- Faidon Liambotis Sat, 04 Oct 2008 01:21:40 +0300 + +asterisk (1:1.4.21.2~dfsg-1) unstable; urgency=high + + [ Victor Seva ] + * asterisk.postinst should always check group memberships (Closes: + #486097) patch by Tim Retout + * changed libc-client2007-dev to libc-client2007b-dev on Build-Depends + (fixes FTBFS). + + [ Tzafrir Cohen ] + * Depend on debhelper >= 6.0.7 due to dh_lintian (Closes: #492202). + * New upstream bugfix release. Fixes CVE-2008-3263 and CVE-2008-3264. + + [ Faidon Liambotis ] + * Do a quilt refresh on all patches. + * Remove the dh_makeshlibs call as it is unneeded and generates a lintian + warning. + + -- Faidon Liambotis Thu, 24 Jul 2008 19:51:20 +0300 + +asterisk (1:1.4.21.1~dfsg-1) unstable; urgency=low + + [ Tzafrir Cohen ] + * New upstream bugfix release. + * Fix get-orig-source target to remove temporary files left in that tarball. + * The asterisk.h symlink moved to asterisk-dev where it should be. + + [ Mark Purcell ] + * asterisk-dev Replaces: asterisk (<< 1:1.4.21.1~dfsg-1) + * lintian cleanup: debian-copyright-line-too-long + * Call dh_lintian lintian-cleanup: package-contains-empty-directory + + -- Mark Purcell Wed, 16 Jul 2008 21:14:10 +1000 + +asterisk (1:1.4.21~dfsg-1) unstable; urgency=low + + * New upstream release. + * bison no longer needed to build Asterisk (Since 1.4.0). + * Patch armel_support applied upstream. + * Patches bristuff/zapata-gsm and bristuff/zapata-bri+euroisdn adjusted to + chan_zap changes (conf became a pointer in mkintf). + + -- Tzafrir Cohen Thu, 12 Jun 2008 21:30:40 +0300 + +asterisk (1:1.4.20~dfsg-1) unstable; urgency=low + + [ Victor Seva ] + * Patch sample files pointing now to the correct doc files. (Closes: #475681) + * Added support for armel, thanks to Riku Voipio. (Closes: #477389) + * Added asterisk-config.dirs in order to create etc/asterisk/manager.d dir, + and added a README.conf on it on rule install-indep. + + [ Tzafrir Cohen ] + * Provide /usr/include/asterisk.h as well (through a symlink). + * Remove {,} bashism from debian/rules (Closes: #478361). + + [ Faidon Liambotis ] + * New upstream version. + - Fix IAX performance issues introduced by security fix in 1.4.19.1 + - Dropped patches samples, vpb-driver-4.2.18, vpb_no_cards, incorporated + by upstream. + * Update to bristuff-0.4.0-RC1: + - Revert API changes to res_agi (xagi). + - Revert API changes to ast_sendtext() (ast-send-message). + - Merge several chan_zap changes (zapata-bri+euroisdn, zapata-gsm). + - Remove unused zapata-device-state, feature-parking_con, find-feature, + chan-capi, ast_channel_masquerade_locked, find-feature patches, + obsoleted by upstream. + - Remove uniqueid-01-use-pid-on-uniqueid-generation patch, dropped by + upstream. + - Rename app-zapras-fix-audiomode to isdn-fixes and include another fix + that we dropped earlier by mistake (r5162). + - Merge ast-send-message with ast-send-message-users, following upstream + split. + - Other minor and cosmetic fixes. + - Comment-out the only use of ast-send-message (in GSM) to avoid an ABI + change. We are not shipping GSM, hence this is not a feature regression. + * Conflict with asterisk-chan-capi << 1.1.1-1 which we broke with an ABI + change :( (Closes: #472379). + * Drop doc-base entries for sip.conf and zapata.conf, there was no point in + just listing those two configuration files. + * Remove -1 revision dependency on libpri and libopenh323-dev. + * Override some lintian warnings for asterisk (empty IAX firmware and + static-http directories) and asterisk-sounds-main (empty MOH and es/fr + sounds directories). + + -- Faidon Liambotis Sat, 07 Jun 2008 19:18:56 +0300 + +asterisk (1:1.4.19.1~dfsg-1) unstable; urgency=low + + [ Faidon Liambotis ] + * New upstream release. + - Dropped configure-libc-client, incorporated upstream. + - Adapted bristuff patches uniqueid-10-channel-ops-uniqueid, + uniqueid-30-app-chanspy, zapata-bri+euroisdn. + - Fixes CVE-2008-1897 / AST-2008-006 (Closes: #477472). + * Build with -O2 instead of the default -O6 (bug introduced in + 1.4.18~dfsg-1). + * Depend on libspeexdsp-dev because of the use of preprocessor features, + which were split from libspeex >= 1.2. + - FTBFS: codec_speex.c:99: error: expected specifier-qualifier-list + before 'SpeexPreprocessState' (Closes: #474789) + - Asterisk fails to install due to broken libspeex dependency + (Closes: #477086) + + [ Lionel Elie Mamane ] + * debian/rules: fix get-orig-source to actually work + * Fix genastkey so that keys are not world-readable by default. + + [ Tzafrir Cohen ] + * Watching downloads.digium.com directly again. + * Patch apptest_sleep: A woraround for TestServer fail on SEND DTMF 8. + + -- Mark Purcell Wed, 23 Apr 2008 22:50:35 +1000 + +asterisk (1:1.4.18.1~dfsg-1) unstable; urgency=high + + * New upstream release. + - Fixes a vulnerability in the RTP codec payload type handling + (AST-2008-002, CVE-2008-1289). + - Fixes a critical vulnerability that could be exploited to bypass SIP + authentication (AST-2008-003, CVE-2008-1332). + - Fixes a potential DoS vulnerability in the Manager interface + (AST-2008-004, CVE-2008-1333). + * Urgency high because of critical security fixes. + + -- Faidon Liambotis Wed, 19 Mar 2008 00:49:17 +0200 + +asterisk (1:1.4.18~dfsg-1) unstable; urgency=low + + [ Faidon Liambotis ] + * Update debian/copyright (packaging copyright, formatting etc.) + * Remove workaround for gcc ICE on hppa (#445336), since apparently that has + been fixed. + * Do not provide asterisk-classic/asterisk-bristuff, we don't want to + satisfy those dependencies anymore. + * Provide asterisk-1.4 virtual package, so that all reverse-dependencies + that use 1.4's ABI can depend on that. + * Switch asterisk-h323 to the new asterisk-1.4 dependency. + * Remove libc-client-dev dependency since it is satisfied in etch by a + version (2002) incompatible to the one that works. (Closes: #465524) + * Backport upstream's patch for chan_vpb to avoid crashes when no + VoiceTronix cards are present. (Closes: #466729) + * Backport feature Bridge from 1.6, thanks to Jon Webster. (Closes: #458475) + + [ Tzafrir Cohen ] + * New upstream release. + * Break bristuff BRI/EuroISDN patch: + - zapata_num_spans - already accepted by upstream. Independent of libpri + bristuff patch. + - zapata-bri+euroisdn - now does not depend on most bristuff interface + changes. But lacks: + - zapata_euroisdn_holded - Support for putting an ISDN phone on hold. + Depends on some other bristuff patches, and adds another interface change. + * patch use-libpri-bristuffed right next to zapata-bri+euroisdn, as + zapata-bri+euroisdn depends on it to build. + * patch tos-libcap remeved: merged by upstream. + * Adjusted patch bristuff/ast-device-state-CID to Asterisk 1.4.18. + + -- Faidon Liambotis Thu, 06 Mar 2008 04:32:33 +0200 + +asterisk (1:1.4.17~dfsg-2) unstable; urgency=low + + * Allow building vs. libc-client2007 (Closes: #458877). + + -- Tzafrir Cohen Thu, 03 Jan 2008 15:14:23 +0200 + +asterisk (1:1.4.17~dfsg-1) unstable; urgency=low + + * New upstream release. Fixes ASA-2008-001. + + -- Faidon Liambotis Thu, 03 Jan 2008 00:27:16 +0200 + +asterisk (1:1.4.16.2~dfsg-2) unstable; urgency=low + + * asterisk.init: fix start so that it works again. (Closes: #458022) + + -- Tzafrir Cohen Fri, 28 Dec 2007 02:46:38 +0200 + +asterisk (1:1.4.16.2~dfsg-1) unstable; urgency=low + + * New upstream release. (Closes: #457063) (Fixes CVE-2007-6430) + - Remove keep-1.4-abi, merged upstream. + - Adapt hack-multiple-app-voicemail, use-libpri-bristuffed, tos-libcap. + - Adapt bristuff patches app-dial-etc, chan-iax2-hangup-cause, + app-dial-priority-202, zapata-bri+euroisdn. + * Silence upstream's build sum warning but generate one on all modules so + that we can enable it at a later point. + * Make the init script's detection of a running daemon to be more precise. + * Bump Standards-Version to 3.7.3, no changes needed. + * Remove modem.conf on upgrades from 1.2 (i.e. etch). (Closes: #454332) + * Ressurect long-forgotten logrotate script. + + -- Faidon Liambotis Fri, 21 Dec 2007 22:38:03 +0200 + +asterisk (1:1.4.15~dfsg-1) unstable; urgency=low + + * New upstream release (Closes: #452054) + - Fix a potential corrupt of voicemail.conf on simultaneous PIN updates + (Closes: #353227) + + [ Tzafrir Cohen ] + * Add some sample/reference config files as documentation. + * Provide asterisk-bristuff for upgrading from Etch. + * Move libc-client to not be last, so debian/backports/xorcom.etch would + still work. + + [ Faidon Liambotis ] + * Really enable the libcap/ToS functionality; the previous patch didn't + enable the functionality, even though the code and the libcap.so + dependency were there. (Closes: #454342) + * Fix a minor issue with init script's stop target when running with + safe_asterisk. + * Add chan_vpb, adding support for VoiceTronix OpenSwitch and OpenLine + cards. (Closes: #396499) + * Fix debian/watch by using a pkg-voip wrapper to avoid upstream's silly + redirections. (Closes: #449706) + * Use DEBVERSION as asterisk's version string. + * Disable the MD5 build sum that breaks all out-of-tree plugins (duh!). + * Create /usr/local/share/asterisk/sounds to put all site-specific + non-modifiable sounds. + * Add a note about bugs.debian.org to the banner. + * Add noload for res_config_* since loading them results in errors and + doesn't provide any functionality. + * News entries were added but we never shipped the file; ship NEWS.Debian. + * Add an entry to NEWS.Debian warning users about app_voicemail_*.so + (Closes: #452596) + * Provide options in /etc/default/asterisk for configuring safe_asterisk. + (Closes: #381786) + + [ Tzafrir Cohen ] + * Provide a custom sounds directory under /var/lib - user-modifieble at + runtime and hence not under /usr. (Closes: #337209) + + -- Faidon Liambotis Thu, 06 Dec 2007 17:20:21 +0200 + +asterisk (1:1.4.13~dfsg-1) unstable; urgency=low + + * New upstream release. + - Implemented Dynamic DUNDi peering support (Closes: #439331) + - Removed merged patches: bashism-safeasterisk, ast_key_dir, + h323-add-missing-ptrace-guard, CVE-2007-4521. + - Adapted patches: make-clean-fixes, h323-no-deps-on-asterisk. + - Adapted bristuff 0.4.0-test4 to apply to 1.4.12 (bristuff.notice, + xagi, app-dial-c-callback, app-dial-priority-202) + * When DFSG-ing the tarball, create a fake codecs/ilbc/Makefile so that + make doesn't fail on clean. + * Pass NOISY_BUILD to make so that the GCC arguments can be examined in + build logs. + * Remove versioned dependency on dpkg-dev since that particular version is + present since etch (sarge is not supported as a backport target anymore). + * Backport a patch from trunk so that Asterisk can set the IP ToS bits when + it is run as a simple user (as we do). + * Re-enable IMAP support and enable ODBC support; this time they are + provided as app_voicemail_imap.so and _odbc.so so that they don't break + existing setups. + * Build with -O1 on hppa to workaround gcc-4.2 ICE (#445336). + * Zaptel package added support for Voicetronix OpenPCI cards, mention it on + asterisk's description. + + -- Faidon Liambotis Wed, 10 Oct 2007 22:18:16 +0300 + +asterisk (1:1.4.11~dfsg-4) unstable; urgency=low + + * Remove imap support to get back original files voicemail functionality. + * Fix comment in patches/bristuff/zapata-bri+euroisdn (by nickzxcv). + + -- Tzafrir Cohen Sun, 30 Sep 2007 15:12:09 +0200 + +asterisk (1:1.4.11~dfsg-3) unstable; urgency=low + + * Depend on libsnmp-dev instead of libsnmp10-dev. Fixes FTBFS + (Closes: #444322) + + -- Faidon Liambotis Fri, 28 Sep 2007 05:58:29 +0300 + +asterisk (1:1.4.11~dfsg-2) unstable; urgency=low + + [ Faidon Liambotis ] + * Depend on libpri-dev >= 1.4.1-1 for the bristuffed header. + (Closes: #439197) + * Added a 1.4 backport of the DEVSTATE() dialplan function which allows + retrieving any device state in the dialplan, as well as creating custom + device states that are controllable from the dialplan. + * Replace Build-Depends libc-client-dev (which wasn't used) with + libc-client2006j2-dev and enable Voicemail IMAP storage + (configure-libc-client). + * Build depend on libcurl4-openssl-dev instead of libcurl4-dev which is a + virtual package. This also means using the more complete OpenSSL libcurl + backend instead of the GnuTLS one. + * Add a versioned >= 1.4 dependency of asterisk in asterisk-h323. + * Don't use MAKEFLAGS as a variable in debian/rules since it has a special + meaning for make. Reported by Simon Richter. + * Add Homepage field, as supported by dpkg 1.14.6. + * Fix init.d stop when using safe_asterisk. (Closes: #376514) + * Drop asterisk-web-vmail package and place the script in + /usr/share/doc/asterisk. + * Move static-http and sample.call to asterisk's examples. + + [ Kilian Krause ] + * Update backports scripts for libcurl4*-dev + * Fix IMAP crash with upstream source snipplet. (Closes: #440187) + + [ Tzafrir Cohen ] + * Support increasing open files limit from init.d script. + + -- Faidon Liambotis Wed, 26 Sep 2007 13:32:01 +0300 + +asterisk (1:1.4.11~dfsg-1) unstable; urgency=low + + [ Tzafrir Cohen ] + * Remove libgtk2.0-dev from Build-Depends since the GTK+ console was not + getting built anyway. + + [ Kilian Krause ] + * Add dpkg-dev (>= 1.13.19) to Build-Depends for binary:Version and + source:Version. + + [ Faidon Liambotis ] + * New upstream release. (Closes: #439062) + - AST-2007-020 Resource Exhaustion vulnerability in SIP channel driver + * Switch to quilt as a patch management system instead of dpatch. + * Add bristuff 0.4.0-test4 + - Split into smaller, individual patches (bristuff/). + - Mention HFC-S/HFC-4S support in the Description. + - Use libpri-bristuffed.so.1 and its respective header + (use-libpri-bristuffed). + - Ship xagi-test.c as an example. + - Add a news item to NEWS.Debian stating bristuff's inclusion. + * Major overhaul of the postinst scripts, completely replacing asterisk_fix. + - Create Asterisk's directories on asterisk.dirs to track them using dpkg. + - Add asterisk.postinst which calls adduser, chown, chmod. Improve error + handling. + - Don't do unnecessary stuff on asterisk-config postinst. + (Closes: #431506) + - chmod /etc/asterisk on build-time to allow the user to modify the + permissions; this required a lintian override. + - Honor dpkg-statoverride on all the chowned/chmoded directories and + configuration files under /etc/asterisk. + - Handle asterisk-config -> asterisk installation order properly + (Closes: #408708) + - Don't add asterisk user to audio and dialout groups if existed before. + This allows the administrator to remove the membership. + - Don't depend on adduser from asterisk-config. + * Remove Suggests to gnomemeeting (it's a dummy package nowdays), + asterisk-rate-engine and add one for twinkle. + * Remove Conflicts for an old version of asterisk-oh323 which was only + present until sarge. + * Remove versioned dependencies on ancient (pre-sarge) versions of sed and + adduser. + * Patch channels/h323/ast_h323.cxx to add some missing PTRACING #ifdef + (h323-add-missing-ptrace-guard). + * h323-workaround-openh323-segfault patch: workaround a libopenh323 bug + (#438815) which causes Asterisk to segfault on startup. (Closes: #435146) + * Remove -XCVS from dh_installexamples arguments. Upstream doesn't use CVS + anymore. + * Add a README.Debian for asterisk-h323 that explains the differences + between the different H.323 channel drivers, taken from the asterisk-oh323 + package. + * Clarify asterisk-h323's description and mention the other channel drivers. + * Suggest asterisk-h323 from asterisk. + + -- Faidon Liambotis Wed, 22 Aug 2007 20:55:12 +0300 + +asterisk (1:1.4.10~dfsg-1) unstable; urgency=low + + * New upstream release + - Fwd: [asterisk-announce] ASA-2007-019: Remote crash vulnerability in + Skinny channel driver (Closes: #436808) + + [ Mark Purcell ] + * debhelper(1) states Build-Depends: debhelper (>= 5) + - aids backports + * Update debian/backports for etch, edgy, dapper and feisty + - http://status.buildserver.net/packages/status.php?package=asterisk&subdist=pkg-voip + + [ Faidon Liambotis ] + * Refer to /usr/share/common-licenses/GPL-2 instead of GPL. The code is + -for now- GPLv2-only and in light of GPLv3, pointing to GPL is misleading. + * Add ast_key_dir patch to move keys from /var/lib/asterisk/keys to + /usr/share/asterisk/keys where they should be. + * Actually ship keys, including Junction Networks' by fixing pubkey_jnctn + patch. + * Handle space/newline-delimited directories on /etc/asterisk when doing + chmod on postinst. + * Correct descriptions of packages in debian/control, adapting them to the + present and correcting some spelling mistakes. (Closes: #428671) + * Add a noload directive for cdr_sqlite.so in the default modules.conf since + it writes unconditionally to the database file without being rotated, + resulting in unexpected waste of disk space. (Closes: #301883) + * Delete duplicated creation of /var/run/asterisk in the init script. + + -- Mark Purcell Thu, 09 Aug 2007 22:47:00 +0100 + +asterisk (1:1.4.9~dfsg-1) unstable; urgency=high + + [ Tzafrir Cohen ] + * New upstream release. + - ASA-2007-018 - DoS Resource Exhaustion vulnerability in IAX2 + + [ Faidon Liambotis ] + * Add myself to Uploaders. + * Fix "debian/rules clean" to cleanup correctly the tree by calling "make + distclean" instead of "make clean". Also, fix some stuff in the upstream + Makefiles (debian/patches/make-clean-fixes). Fixes a lintian warning. + * Add XS-Vcs-Svn and XS-Vcs-Browser to debian/control. + * Move examples from all packages (debian/examples) to asterisk-config only. + * Add eagi-test.c, eagi-sphinx-test.c, fastagi-test and static-http to + examples. + * Remove Conflicts/Replaces/Depends to pre-sarge versions, they're useless + even for backports. + + [ Mark Purcell ] + * Include asterisk.init changes from Martin + - Asterisk does not create /var/run/asterisk directory if not existent + (Closes: #413541) + * Backout asterisk-h323 Suggests:/ Recommends: asterisk-oh323. The former + works, the latter does not with asterisk-1.4.x + * Upstream fixes from 1.4.x branch: + - Multiple security flaws in Asterisk (Closes: #421467) + - Debug switch wrong in /etc/default/asterisk (Closes: #413544) + - Upgrading destroys astdb (Closes: #354132) + - Upgrading destroys astdb (Closes: #354132) + - asterisk bindaddr in sip and iax config is to fixed ip not + Interfaces (Closes: #316443) + - Incorrect callerid syntax in sip.conf causes incorrect error + (Closes: #323275) + - dropouts (Closes: #335079) + - Does not include cdr_sqlite userfield support by default (Closes: + #344097) + - Asterisk crashes on sparc when playing 'demo-moreinfo' + (Closes: #344484) + - fresh install - crash after dialing IAX test (Closes: #350001) + - asterisk_fix script fails to set variables for adduser, user + creation fails (Closes: #383075) + - Debug switch wrong in /etc/default/asterisk (Closes: #413544) + - When using L option on Dial, instead of warning asterisk disconnects + the call (Closes: #419894) + - Patch for fastagi handling (Closes: #368948) + - bristuff patch breaks cause codes in Hangup() (Closes: #320350) + * add debian/patches/basim-safeasterisk.dpatch + - contrib/scripts/safe_asterisk should explicitly link to a cli + (Closes: #413543) + * Adding a restart when convenient in Asterisk (Closes: #413816) + * asterisk-h323: libpt.so.1.10.2 => not found (Closes: #434076) + + -- Mark Purcell Thu, 26 Jul 2007 16:52:29 +0100 + +asterisk (1:1.4.8~dfsg-2) unstable; urgency=low + + * Add patch from Faidon debian/patches/dbug433884.dpatch: + - Should not depend on libopenH323, libpt, libSDL, libssl, libldap, + ... (Closes: #433884) + - Fails to restart after upgrade due to dep on libpt.so.1.10.2 + (Closes: #434066) + + -- Mark Purcell Sat, 21 Jul 2007 11:41:01 +0100 + +asterisk (1:1.4.8~dfsg-1) unstable; urgency=high + + * New upstream release + - ASA-2007-017: Remote crash vulnerability in + STUN implementation (Closes: #433681) + * Urgency high for remote crash vulnerability + * Updated standard version to 3.7.2 . + + -- Mark Purcell Wed, 18 Jul 2007 20:51:46 +0100 + +asterisk (1:1.4.6~dfsg-1) unstable; urgency=low + + [ Mark Purcell ] + * CVE-2007-2488 was addressed 1:1.4.5~dfsg-1 + * CVE-2007-1595 was addressed 1:1.4.0~dfsg-1 + + [ Tzafrir Cohen ] + * New upstream release. + * Added asterisk-dbg for debugging symbols. + * Updated priorities of some packages. + * Updated list of supported hardware in description. + + -- Mark Purcell Wed, 04 Jul 2007 18:31:00 +0100 + +asterisk (1:1.4.5~dfsg-1) unstable; urgency=low + + [ Tzafrir Cohen ] + * New upstream release. + + [ Mark Purcell ] + * Debconf7 Release :-) + * Build-Depends: libpq-dev + - obsolete build dependency postgresql-dev (Closes: #389376) + + -- Mark Purcell Mon, 18 Jun 2007 10:18:13 +0100 + +asterisk (1:1.4.4~dfsg-3) unstable; urgency=low + + * Build-Depends: libcurl4-dev | libcurl-dev + - uninstallable due to dependancy on libcurl3 (Closes: #426393) + + -- Mark Purcell Sat, 02 Jun 2007 10:52:05 +0100 + +asterisk (1:1.4.4~dfsg-2) unstable; urgency=low + + * Missing debian/changelog entries + * Upstream calls make twice to build h323, copy in debian/rules + - Asterisks chan_h323 doesn't work because of an undefined symbol + (Closes: #421552) + * Cleanup debian/patches + * chmod +x asterisk-fix + - Setting up asterisk (1.4.3~dfsg-1) -> id: asterisk: No such user + (Closes: #422237) + + -- Mark Purcell Thu, 17 May 2007 07:35:30 +0100 + +asterisk (1:1.4.4~dfsg-1) unstable; urgency=low + + * New Upstream Release + - Fix a crash in chan_zap + - Fix some cases where IAX2 calls would get dropped + - Merge a re-write of channel group counting support that fixes a lot of + issues + - Fix some DTMF issues related to the use of chan_agent + - Fix a crash that occurs when using dialplan functions to set global + variables + + -- Mark Purcell Wed, 25 Apr 2007 18:11:44 +1000 + +asterisk (1:1.4.3~dfsg-1) unstable; urgency=high + + * Urgency high as this fixes a number of Asterisk Security Advisories (ASA) + + * New upstream release + - [asteriskteam@digium.com: [asterisk-announce] ASA-2007-011: Multiple + problems in SIP channel parser handling response codes] (Closes: + #420864) + - [asteriskteam@digium.com: [asterisk-announce] ASA-2007-012: Remote + Crash Vulnerability in Manager Interface] (Closes: #420866) + - [asteriskteam@digium.com: [asterisk-announce] ASA-2007-010: Two + stack buffer overflows in SIP channel's T.38 SDP parsing code] + (Closes: #420868) + - CVE-2007-1594: Asterisk segfaults upon receipt of a certain SIP + packet (SIP Response code 0) (Closes: #419820) + + * Update debian/NEWS to broadcast the demise of bristuff + * Asterisk-classic, asterisk-bristuff are depreciated + - asterisk has circular Depends on asterisk-bristuff|asterisk-classic + (Closes: #384674) + * Ship UPGRADE.txt and refer to it in debian/NEWS + - UPGRADE.txt cannot be found in any package (Closes: #419164) + + -- Mark Purcell Wed, 25 Apr 2007 16:47:31 +1000 + +asterisk (1:1.4.2~dfsg-5) unstable; urgency=low + + * Bump Build-Depends: libsnmp10-dev | libsnmp-dev + * Only ship default/asterisk in asterisk package + - Asterisk-config and asterisk 1:1.4.2~dfsg-4 both contain + /etc/default/asterisk (Closes: #418656) + * Lintian fixes debian-rules-sets-DH_COMPAT + + -- Mark Purcell Sat, 14 Apr 2007 16:44:18 +0100 + +asterisk (1:1.4.2~dfsg-4) experimental; urgency=low + + [ Tzafrir Cohen ] + * The dummy fetch was not executable when generated from tar+diff. + + [ Mark Purcell ] + * Create debian/rules binary-arch & binary-indep targets + * Move debian/rules magic to package.install files + + -- Mark Purcell Thu, 29 Mar 2007 00:31:41 +0100 + +asterisk (1:1.4.2~dfsg-3) experimental; urgency=low + + * Fix syntax of for dummy fetch (Closes: #416143). + * LSB init section in init.d script. + * Merge other init.d changes from trunk. + + -- Tzafrir Cohen Sun, 25 Mar 2007 16:19:37 +0200 + +asterisk (1:1.4.2~dfsg-2) experimental; urgency=low + + [ Tzafrir Cohen ] + * Fix default varrundir using make vars (Closes: #415799). + * Don't run autoconf if you don't need (Closes: #415865). + * Require zaptel >= 1.4.1, for ZT_EVENT_REMOVED . + + [ Mark Purcell ] + * Include chan_h323.so in debian/asterisk-h323.install + * Please package Asterisk-1.4.0 (Closes: #405723) + * Add Build-Depends: libgtk2.0-dev, libc-client-dev + * configure --with-pwlib=/usr/share/pwlib/include/ \ + --with-h323=/usr/share/openh323/ + * debian/asterisk.default - fix -D/-d typo in PARAMS (Closes LP#68169) + * debian/asterisk.init: + - create /var/run/ directory if necessary and set proper permissions + * Move dh_installinit to architecture dependant + * Move ASTVARRUNDIR to /var/run/asterisk/ + - PID & control files go in wrong place (Closes: #415799) + + -- Mark Purcell Sat, 24 Mar 2007 18:32:45 +0000 + +asterisk (1:1.4.2~dfsg-1) experimental; urgency=low + + * New upstream release. + - SIP INVITE DoS, supposedly fixed in 1.4.2 and 1.2.17, which is + released today 19/03/2007 (Closes: #415466) + * asterisk Depends: ${shlibs:Depends} + + -- Mark Purcell Tue, 20 Mar 2007 19:07:18 +0000 + +asterisk (1:1.4.1~dfsg-1) experimental; urgency=low + + [ Tzafrir Cohen ] + * New upstream release. + - Please package Asterisk-1.4.0 (Closes: #405723) + * A package that builds. + * Removed asterisk-sounds.install: does not belong here. + * Removed makefile_noiaxy.dpatch: applied by upstream. + * Config examples in a separate examples subdirectory. + * Generate explicitly some missing subdirectories. + * Man pages are included in upstream now. + * set ASTDATADIR=/usr/share/asterisk . + * A bunch of other fils moved for 1.4 . + * Use system gsm (only requires an explicit --with-gsm) + * Allow chrooted building with no wget. + * h323_no_exit.dpatch: Don't requires two rounds of building. + + [ Mark Purcell ] + * configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) + --prefix=/usr --mandir=\$${prefix}/share/man -- + infodir=\$${prefix}/share/info + + -- Mark Purcell Mon, 19 Mar 2007 06:24:43 +0000 + +asterisk (1:1.4.0~dfsg-1) UNRELEASED; urgency=low + + * New upstream release (1.4) + * Sandbox to start playing with 1.4, it uses autotools :-), + it also uses ASTDATADIR :-) :-) + * need to understand this menuselect and how to encorporate into debian. + * need to discuss with upstream iLBC conflict with GPL + * Ugly hack in version number. + * get-orig-source now works, though. + * No more asterisk-classic and asterisk-bristuff + * FreePlay Music files location changed + * Disabling h323 build for now, until I figure what's wrong. + * Extra Build-Deps: libiksemel-dev, libradiusclient-ng2-dev, freetds-dev, + libvorbis-dev, libsnmp9-dev + * Simply use configure. No workarounds. + * Edit menuselect.makeopts to avoid downloading MOH files. + * makefile_noiaxy.dpatch: don't try to copy the non-existing iaxy.bin , + * zapbri.dpatch: support zapbri devices + * chanzap_chanremoved.dpatch: handle ZT_EVENT_REMOVED event from zaptel + + -- Mark Purcell Mon, 25 Sep 2006 08:46:16 +0100 + +asterisk (1:1.2.16~dfsg-1) unstable; urgency=high + + [ Tzafrir Cohen ] + * New upstream release. Also fixes remote SIP security hole. + * Updated bristuff patch. + * Fix umask of Asterisk for the voicemail. + + -- Tzafrir Cohen Sun, 4 Mar 2007 00:35:53 +0200 + +asterisk (1:1.2.15~dfsg-1) unstable; urgency=low + + [ Tzafrir Cohen ] + * New upstream release. + * ukcid.dpatch: adapted to chan_conf. + * bristuff.dpatch: adapted to chan_conf. + * daemon_color.dpatch: make rastrisk colourful even without safe_asterisk. + * No need to edit a config file to start Asterisk. + * Use asterisk.conf based on README.asterisk.conf: + - Set default user to asterisk. + - Make the control socket writabe by the group asterisk. + * don't remove stereorize and streamplayer. + * A man page for stereorize. + * Create /etc/asterisk/manager.d (Closes: #410715). + * Check that Asterisk is alive before sending a command (Closes: #389448). + * Use MAKEBUILDOPTS instead of MAKEFLAGS, which is a reserved gmake name. + * Removing build depepndency on obsolete and unused libzap-dev. + * New transcoding interfaces from zaptel.h of zaptel 1.2.13 or 1.4 seem + to be required for Asterisk 1.2.15 . + + -- Mark Purcell Sat, 3 Mar 2007 17:14:25 +0000 + +asterisk (1:1.2.14~dfsg-5) UNRELEASED; urgency=low + + [ Tzafrir Cohen ] + * Bristuff 0.3.0-PRE-1x + + -- Tzafrir Cohen Mon, 22 Jan 2007 23:30:34 +0200 + +asterisk (1:1.2.14~dfsg-4) unstable; urgency=high + + * Add missing "fi" to asterisk_fix. (Closes: #406961) + + -- Kilian Krause Mon, 15 Jan 2007 12:05:18 +0100 + +asterisk (1:1.2.14~dfsg-3) unstable; urgency=low + + * Write a more robust version of the FHS-update for + /usr/share/asterisk/sounds/priv-callerintros. + * Update 30_ast-data-dir to complete fix for #406714. Thanks to Lionel! + + -- Kilian Krause Sun, 14 Jan 2007 13:38:57 +0100 + +asterisk (1:1.2.14~dfsg-2) unstable; urgency=low + + * Install private callerinfos in /var/lib/ where they belong acording to + FHS. (Closes: #406714) + + -- Kilian Krause Sat, 13 Jan 2007 12:01:33 +0100 + +asterisk (1:1.2.14~dfsg-1) unstable; urgency=low + + * New upstream release. + * Build against libspeex-dev (>= 1.1.12-3) with updated shlibs + (Closes: #403544) + * Update bristuff patch to apply cleanly with 1.2.14 until new upstream + version is out. + * Remove hardcoded gcc (Closes: #316802) + * Fix upstream clean target. (Closes: #393659) + + -- Kilian Krause Wed, 3 Jan 2007 21:03:19 +0100 + +asterisk (1:1.2.13~dfsg-2) unstable; urgency=low + + [ Tzafrir Cohen ] + * less_docs.dpatch: remove unnecessary doxygen docs. asterisk-doc's size + is now 1.6M (7.7M installed). + + [ Mark Purcell ] + * asterisk-classic, asterisk-bristuff: + /usr/lib/asterisk/modules/format_ogg_vorbis.so gone missing when + rebuilt (Closes: #397147) + + -- Mark Purcell Mon, 6 Nov 2006 06:33:19 +0000 + +asterisk (1:1.2.13~dfsg-1) unstable; urgency=high + + [ Kilian Krause ] + * Fixup dfsg versions with increased upstream build count. + + [ Santiago Ruano Rincón ] + * Added cdr_sqlite3_custom dpatch + + [ Mark Purcell ] + * New upstream release + - Remote compromise (Closes: #394025) + - CVE-2006-5444/5:security issues in asterisk (Closes: #395080) + - Urgency high as this fixes remote compromise security issue + - Information disclosure of voice mail messages through vmail.cgi + (Closes: #338116) + - package asterisk-dev should contain asterisk.h main header (Closes: + #342138) + - format_ogg_vorbis.so was present in i386, no longer in packages + (Closes: #375141) + * Update debian/patches/bristuff.dpatch + * bristuff-0.3.0-PRE-1v + - Please package bristuff 0.3.0PREu (Closes: #394122) + - please include app_pickup.c from bristuff (Closes: #348194) + * Build Depends: dpkg ( >= 1.13.19) + - Asterisk must build-depend upon dpkg ( >= 1.13.19) (Closes: #386113) + * Build-Depends: libpq-dev + - obsolete build dependency postgresql-dev (Closes: #389376) + + -- Mark Purcell Wed, 25 Oct 2006 06:46:52 +0100 + +asterisk (1:1.2.12.1.dfsg-1) unstable; urgency=low + + [ Tzafrir Cohen ] + * New upstream release + * bristuff.dpatch: version adapted. + * apprecord_sprintf.dpatch removed: already applied. + + [ Mark Purcell ] + * binary blob in asterisk-classic package (Closes: #386361) + * Cleanup bristuff.dpatch + + -- Mark Purcell Sun, 24 Sep 2006 14:45:58 +0100 + +asterisk (1:1.2.11.dfsg-1) unstable; urgency=high + + [ Tzafrir Cohen] + * apprecord_sprintf.dpatch: fix format string issue in app_record.so . + + [ Mark Purcell ] + * New Upstream Release + * Urgency high as fixes CVE-2006-4346 + * CVE-2006-4346: Asterisk MGCP AUEP Response Handling Buffer + Overflow (Closes: Bug#385060) + * Please package Asterisk 1.2.11 and Zaptel 1.2.8 (Closes: #384283) + * Better error handling on init.d reload, if asterisk isn't running + * Lintian cleanup: not-binnmuable-any-depends-all + * Lintian cleanup: not-binnmuable-all-depends-any + * Use restart in asterisk_fix + + -- Mark Purcell Sat, 2 Sep 2006 13:01:02 +0100 + +asterisk (1:1.2.10.dfsg-3) unstable; urgency=low + + [ Kilian Krause ] + * Add iaxy.bin to asterisk debs to have working IAX support. + * asterisk_fix is included on the main asterisk package + (Closes: Bug#287025, Bug#360233, Bug#381861) + * Various fixes to asterisk_fix + + [ Mark Purcell ] + * Remove Build-Depends: libgtk1.2-dev (only for asterisk-gtk) + * export PROC := $(shell dpkg-architecture -qDEB_BUILD_GNU_CPU) + * asterisk-{classic-bristuff} Depends: asterisk + * asterisk_fix needs to fix /var/run/asterisk + * Move doc/asterisk -> asterisk-doc package + + [ Tzafrir Cohen] + * New upstream release (Closes: #385060). + * bristuff 0.3.0-PRE-1s (adapted to asterisk 1.2.11). + + -- Mark Purcell Thu, 17 Aug 2006 20:31:02 +0100 + +asterisk (1:1.2.10.dfsg-2) unstable; urgency=high + + * IAX2 channel driver security patch [CVE-2006-2898] + - CVE-2006-2898: Denial of service in Asterisk (Closes: #380054) + + -- Mark Purcell Thu, 27 Jul 2006 08:09:47 +0100 + +asterisk (1:1.2.10.dfsg-1) unstable; urgency=low + + [ Tzafrir Cohen ] + * New upstream release. + * bristuff.dpatch updated for the new version. + * dfsg tarball also removes ilbc. + * Cleanups to asterisk_fix + + [ Mark Purcell ] + * Build-Depends: libpri-dev (>= 1.2.3-1) + * Fixes: + - Please package version 1.2.9.1 (Closes: #372527) + + -- Mark Purcell Mon, 17 Jul 2006 21:15:50 +0100 + +asterisk (1:1.2.9.1.dfsg-1) unstable; urgency=high + + * New upstream release. [CVE-2006-2898] + + [ Mark Purcell ] + * Update debian/watch for numeric upstream versions + + [ Kilian Krause ] + * Remove unused correct_pid.dpatch (has apparently been fixed with 1.2 + upstream) + * debian/patches/100_nonroot.dpatch, debian/patches/20_Makefile.dpatch, + debian/patches/25_subdirs_Makefiles.dpatch: Remove unused patches + + [ Tzafrir Cohen ] + * reunite init.d and logrotate scripts in the package asterisk + * Re-add correct_pid_display.dpatch + * bristuff 0.3.0-PRE1s (gsm functionality missing: needs libgstam) + * sys_readline.dpatch: Realine support in the CLI. TODO: tab completion + * sys_editline.dpatch: alternativly, simply use the system version of + editline (not used). + * func_odbc_12.dpatch: backport of func_odbc (Closes: #364633) + * brazilian_syntax.dpatch (using "pt_BR") + * vm_he.dpatch: Hebrew in app_voicemail + * The data_dir patch also moves agi-bin/ and firmware/ + * option_detach: using -F instead of -D (the same as upstream) + * asterisk.init: added "zaptel-fix" to unload and reload zaptel modules + + -- Kilian Krause Fri, 16 Jun 2006 18:04:50 +0000 + +asterisk (1:1.2.7.1.dfsg-3) unstable; urgency=high + + * Urgency high as this is a security fix [CVE-2006-2898] + * Added 99_CVE-2006-2898.dpatch from Joey Schulze + - Fixes: Bug in the IAX2 channel allows remote attackers to craft + a denial of service. + + -- Mark Purcell Tue, 13 Jun 2006 05:11:44 +0100 + +asterisk (1:1.2.7.1.dfsg-2) unstable; urgency=high + + [ Kilian Krause ] + * Urgency bumped since 1.2.7 is a security update [CVE-2006-1827] + (Closes: #364195) + + [ Mark Purcell ] + * Previous Upload also fixes: + - cannot install - directories not created (Closes: #360233) + - package uninstallable (Closes: #359970) + * Update postinst to fix: fails to upgrade when /etc/asterisk/voicemail.conf + is deleted (Closes: #360220) + * Link debian/asterisk-bristuff.asterisk.{logrotate,init} & + provide debian/asterisk-classic.asterisk.logfile + - Fixes: init.d and logrotate.d conflicts (Closes: #360181) + + -- Mark Purcell Sun, 23 Apr 2006 13:26:29 +0100 + +asterisk (1:1.2.7.1.dfsg-1) unstable; urgency=low + + [ Tzafrir Cohen ] + * New upstream release. + * nomarch.dpatch: removed the patching to internal libgsm, as we don't use + it (and it broke in this version) + * bristuff.dpatch: based on the patch from bristuff-0.3.0-PRE1n + * bristuff.dpatch: A small fix in chan_sip.c + * bristuff.dpatch: Disabling "libgsm" until it is renamed + * 30_ast-data-dir.dpatch: the symlink sounds/voicemail is now gone + * rules: do fail if bristuff patching hasfailed + * zap_restart.dpatch: allow restarting zaptel channel with "zap restart" + * backport_playdtmf.dpatch: a harmless backport (no impact if not used) + * completed the merge of logrotate and init.d scripts + + [ Lionel Elie Mamane ] + * When not running asterisk, do it successfully, not by failure. + (closes: #360234) + * Create /var/log/asterisk/cdr-csv, not cdr-cvs. + + [ Mark Purcell ] + * Update debian/control for asterisk-h323 package description + * Create /var/spool/asterisk & /var/lib/asterisk in debian/*.postinst + * New upstream release. Fixes: + - Version 1.2.5 is out (Closes: #355299) + - since 1.2.0 no chan_modem (Closes: #343232) + - Undefined symbol in chan_zap.so (Closes: #339559) + - Unapplying patches fail (Closes: #345676) + - utils.c:619 tvfix: warning negative timestamp... (Closes: #347929) + - creates /.asterisk_history on reboot (Closes: #307218) + * h323 modules can be unstable so dont load my default + * Cleanup debian/patches to remove obsolete/ old patches + + -- Mark Purcell Fri, 21 Apr 2006 17:33:31 +0100 + +asterisk (1:1.2.6.dfsg-1) unstable; urgency=low + + * New upstream release. (Closes: #355299) + * correct_pid_display.dpatch: adjusted to 1.2.6 + * 30_ast-data-dir.dpatch: adjusted to 1.2.6 + * debian/control: Add adduser to depends of asterisk-config to shut up + lintian. + * rules: no need to copy config to the bristuff install + * rules: but use cp -a for ast_config, as there may be subdirs. + + -- Tzafrir Cohen Mon, 10 Apr 2006 19:00:12 +0300 + +asterisk (1:1.2.4.dfsg-7) unstable; urgency=low + + * Recompile to fix missing asterisk-config from last binNMU round + (Closes: #356712, #358413, #355524, #358145) + * postinstall: Add /var/spool/asterisk/meetme if nonexistant. + (Closes: #355046) + * asterisk.init: Install both asterisk-classic and asterisk-bristuff with + /etc/init.d/asterisk (Closes: #354729) + * logroate: create /var/log/asterisk/cdr-custom/ as well as cdr-csv + (Closes: #355048) + * logrotate: share location of logrotate file as /etc/logrotate.d/asterisk + for both classic and bristuff version (Closes: #356712) + * delete chan_capi modules from bristuff + * Move postinstall and postrm to asterisk-classsic, asterisk-bristuff and + asterisk-config. (Closes: #355524) + + -- Kilian Krause Thu, 30 Mar 2006 11:55:03 +0200 + +asterisk (1:1.2.4.dfsg-6) unstable; urgency=low + + * Add chan_h323 back with new Atlas_devel3 OpenH323. + + -- Kilian Krause Sat, 18 Feb 2006 17:55:24 +0000 + +asterisk (1:1.2.4.dfsg-5) unstable; urgency=low + + * Fix install of asterisk-bristuff with dh_install. + + -- Kilian Krause Tue, 14 Feb 2006 20:23:56 +0100 + +asterisk (1:1.2.4.dfsg-4) unstable; urgency=low + + * Create missing /var/spool/asterisk/voicemail in postinst (Closes: #352586) + + -- Kilian Krause Sun, 12 Feb 2006 22:51:50 +0100 + +asterisk (1:1.2.4.dfsg-3) unstable; urgency=low + + * Fix asterisk-bristuff install target to catch correct versions. + + -- Kilian Krause Sun, 12 Feb 2006 12:34:31 +0000 + +asterisk (1:1.2.4.dfsg-2) unstable; urgency=low + + * update to bristuff 0.3.0-PRE-1k + + -- Kilian Krause Thu, 9 Feb 2006 18:12:08 +0000 + +asterisk (1:1.2.4.dfsg-1) unstable; urgency=low + + [ Tzafrir Cohen ] + * Fix PID display (Closes: #338646) + * changes to the init.d script (Tzafrir) + * debian/ast_config/ place here configurutaion files that will override + the defaults from the source, though not get into the sample documentation + dir + * debian/ast_config/manager.conf: asterisk does listen onthe manager by + default, but only on localhost. Other packages need not edit manager.conf + to get a manager acount + * bristuff 0.3.0-PRE-1f + * option_detach.dpatch: Adds option -D: always daemonize (even with -v,-d) + (conflicts with bristuff, though) + * ukcid.dpatch: UK Caller ID patch for the X100P. (Closes: #302380) + + [ Kilian Krause ] + * New upstream release. (Closes: #350905) + * Bumping depends on libpri and zaptel to according 1.2 versions. + * Build-Depends on libpri1.2 since new ABI caused new package name. + * Removed alternatives from Build-Depends since sbuild will only take first + anyway to ensure constant rebuilds. + * Add a noload for chan_capi by default, so that we d not stop loading when + no CAPI is installed. (Closes: #328835) + * Include smsq by adding Build-Depends on libpopt-dev (Closes: #348090) + + -- Kilian Krause Sun, 5 Feb 2006 11:44:28 +0100 + +asterisk (1:1.2.1.dfsg-3) unstable; urgency=low + + * Remove -msoft-float from compile flags to fix compilation on arm. + (Closes: #343154) + * Provide nonexistant dirs before running chown on them. (Closes: #341810) + * Depend on Perl module in libapache-dbi-perl or libdbi-perl or web-vmail + (Closes: #337448) + * Fix permissions on voicemail.conf. (Closes: #304615) + * Build-Depend on gsfonts to have Helvetica font for doxygen + (Closes: #343079) + + -- Kilian Krause Mon, 2 Jan 2006 00:15:59 +0000 + +asterisk (1:1.2.1.dfsg-2) unstable; urgency=low + + [ Tzafrir Cohen ] + * bristuff 0.3.0-PRE-1d . Still disabled by default + * libpri_bristuffed.dpatch: link chan_zap with libpri-bristuffed.so.1 + * Use asterisk(8) as a man page for rasterisk + * Removing binary steroize: can be done with soxmix of package sox. + * Removing binary streamplay: can be done with netcat + + [ Kilian Krause ] + * Fix asterisk-dev to include asterisk.h + + -- Tzafrir Cohen Sat, 31 Dec 2005 21:17:44 +0200 + +asterisk (1:1.2.1.dfsg-1) unstable; urgency=low + + * New upstream release + - Please package asterisk 1.2.1 (Closes: #342463) + * Temporary disable bristuff for upstream release + * sip-1.914.dpatch merged upstream + + -- Mark Purcell Wed, 7 Dec 2005 21:59:20 +0000 + +asterisk (1:1.2.0.dfsg-6) unstable; urgency=low + + * Add Build-Depends: libcurl3-dev | libcurl-dev + - Should build-depend on libcurl3-dev (Closes: #341363) + * Add Build-Depends: doxygen + - Missing build-dependency on doxygen (Closes: #341362) + * Build-Depends: adduser (>= 3.63) + * disable chan_zap building (in channels makefile) against old + libmfcr2 (Closes: #342139) + * seperate api docs and configuration samples (Closes: #341395) + * Add sip-1.913.dpatch; SIP error 400 on outgoing calls (Closes: #340574) + + -- Mark Purcell Mon, 5 Dec 2005 23:49:40 +0000 + +asterisk (1:1.2.0.dfsg-5) unstable; urgency=low + + [ Tzafrir Cohen ] + * Added bristuff 0.3.0-PRE1 + + [ Mark Purcell ] + * asterisk-sounds-main Replaces: asterisk-sounds-extra + - asterisk-sounds-{main,extra}: file conflict (Closes: #339791) + + -- Mark Purcell Thu, 1 Dec 2005 17:37:13 +0000 + +asterisk (1:1.2.0.dfsg-4) unstable; urgency=low + + * Fix 50_debian-libgsm.dpatch to apply correctly + - asterisk - FTBFS: Tries to build a i386 assembler file (Closes: + #340102) + + -- Mark Purcell Mon, 21 Nov 2005 19:56:03 +0000 + +asterisk (1:1.2.0.dfsg-3) unstable; urgency=low + + * Remove -march to fix FTBFS. (Closes: #338753) + + -- Kilian Krause Sat, 19 Nov 2005 19:36:31 +0000 + +asterisk (1:1.2.0.dfsg-2) unstable; urgency=low + + * libreadline4-dev is superseeded by libreadline5-dev. Fixed build-depends. + + -- Kilian Krause Sat, 19 Nov 2005 12:12:51 +0000 + +asterisk (1:1.2.0.dfsg-1) unstable; urgency=low + + * New upstream release + + -- Mark Purcell Thu, 17 Nov 2005 18:17:02 +0000 + +asterisk (1:1.2.0-rc2.dfsg-1) experimental; urgency=low + + * New upstream release + + -- Mark Purcell Sun, 13 Nov 2005 17:58:08 +0000 + +asterisk (1:1.2.0-rc1.dfsg-1) experimental; urgency=low + + * New upstream release + * Suggests: asterisk-rate-engine + * debian/rules touch .cleancount (upstream bug?) + + -- Mark Purcell Wed, 9 Nov 2005 22:05:30 +0000 + +asterisk (1:1.2.0-beta2.dfsg-3) experimental; urgency=low + + * Fix debian/patches/30_ast-data-dir with /var/run/asterisk. Thanks + Alessandro Polverini + + -- Mark Purcell Tue, 8 Nov 2005 22:00:29 +0000 + +asterisk (1:1.2.0-beta2.dfsg-2) experimental; urgency=low + + * Copyright audit into debian/copyright (Closes: #331318) + * Please package 1.2 beta 2 (Closes: #336749) + + -- Mark Purcell Mon, 7 Nov 2005 22:58:27 +0000 + +asterisk (1:1.2.0-beta2.dfsg-1) experimental; urgency=low + + * New upstream release + * Update Build-Depends: libpri1 >= 1.2.0-beta2 + * Remove Build-Depends: doxygen. Takes too long for experimental ;-) + + -- Mark Purcell Tue, 1 Nov 2005 22:27:43 +0000 + +asterisk (1:1.2.0-beta1.dfsg-1) experimental; urgency=low + + [ Tzafrir Cohen ] + * recreated system_libgsm patch, http://bugs.digium.com/view.php?id=5434 + * Added public key from Junction Networks (pubkey_jnctn.dpatch). + Any other keys for IAX providers we can add? + * updating to a beta of Asterisk 1.2 + * added defaults_debian.dpatch to set pathes + * BuildDepends on graphviz + * disabled most patches: still need to review them + * What about h323? + * deleted from patches/00list a number of patches that should not go in + + [ Mark Purcell ] + * Fix: old-fsf-address-in-copyright-file + * Please package version 1.2 betas (Closes: #325268) + + -- Mark Purcell Thu, 20 Oct 2005 19:42:14 +0100 + +asterisk (1:1.0.9.dfsg-6) UNRELEASED; urgency=low + + * Fix memleak bug (http://bugs.digium.com/view.php?id=4318) + * Fix depends to adduser 3.64 (Closes: #326198) + + -- Kilian Krause Wed, 7 Sep 2005 21:22:40 +0200 + +asterisk (1:1.0.9.dfsg-5) unstable; urgency=low + + [ Kilian Krause ] + * debian/control: fix GCI to read CGI. (Closes: #311291) + + [ Mark Purcell ] + * /var/lib/dpkg/info/asterisk.postinst: line 22: adduser: command not + found (Closes: #322115) + * debian/patches/chan-modem.dpatch from Simon Peter + - chan_modem.c should set default read & write format (Closes: + #303903) + * apply patch from Jérôme Warnier + - Asterisk autosupport script not recognized as such (Closes: #316799) + * Updated debian/postrm: + - 'apt-get --purge remove asterisk' removes configuration files from + another package (Closes: #318455) + + -- Mark Purcell Tue, 9 Aug 2005 22:07:13 +0100 + +asterisk (1:1.0.9.dfsg-4) unstable; urgency=low + + * Cleanup bristuff to build under gcc4, thanks for the suggestions + - Closes: #318337: FTBFS. channel.c:64: error: static declaration of + 'uniquelock' follows non-static declaration + + -- Mark Purcell Fri, 22 Jul 2005 10:28:15 +1000 + +asterisk (1:1.0.9.dfsg-3) unstable; urgency=low + + * Cleanup 70_debian-libpe-fe.dpatch to check in Makefile + * Enable bristuff-0.2.0-RC8j.dpatch + * Remove debian/patches/08_debian-zaptel.dpatch as it is no longer + needed with new zaptel-source package + * Cleanup debian/patches/ + * Conflicts: asterisk-oh323 (<= 0.6.6pre3-3) + - Closes: #318189: asterisk-oh323: chan_oh323.so cannot find symbol + and Asterisk crashes + - Closes: #318216: chan_oh323.so symbols + * Cleanup postinit error: adduser asterisk audio; adduser asterisk + dialout + * Incorporate suggestions from Tzafrir Cohen + - postinst script has an error + - modified astdir patch, so it won't conflict with bristuff patch + - typo in the debian/asterisk.default: s/exra/extra/ + - build-depends both on zaptel-source (>= 1.0.6) and simply + on zaptel-source, The latter is probably unnecessary + - man pages for the other executables in the package + + -- Mark Purcell Thu, 14 Jul 2005 07:22:59 +0100 + +asterisk (1:1.0.9.dfsg-2) unstable; urgency=low + + * Closes: #301490: Please add patch for Italian syntax + * Closes: #305734: On PowerPC, hanging up on voicemail causes non-stop + log messages + + -- Mark Purcell Fri, 1 Jul 2005 23:24:53 +0100 + +asterisk (1:1.0.9.dfsg-1) unstable; urgency=low + + * New upstream release + - Closes: #315578: New version of asterisk and bristuff released + * Remove BRI patch while we work on it, to allow 1.0.9 to unstable + + -- Mark Purcell Fri, 1 Jul 2005 22:38:24 +0100 + +asterisk (1:1.0.8.dfsg-1) UNRELEASED; urgency=low + + * (NOT RELEASED YET) New upstream release + + -- Mark Purcell Fri, 24 Jun 2005 23:25:02 +0100 + +asterisk (1:1.0.7.dfsg.1-4) unstable; urgency=low + + * debian/control: fixed build-depends on sed's version greater than Woody. + (Closes: #308885) + + -- Kilian Krause Sat, 21 May 2005 14:15:03 +0200 + +asterisk (1:1.0.7.dfsg.1-3) unstable; urgency=low + + * Jose Carlos + + Fix a typo in NEWS.Readme + + debian/postint: Add asterisk user to dialout group too. This is needed + for asterisk to have enoug permissions to access zaptel devices. + + debian/control: allow a local asterisk-config-local package to satisfy + dependencies. Conflict with asterisk-config + + -- Jose Carlos Garcia Sogo Sun, 8 May 2005 22:06:44 +0200 + +asterisk (1:1.0.7.dfsg.1-2) unstable; urgency=low + + * Mark Purcell + + Update debian/watch to use svn-upgrade + * Kilian Krause + + debian/asterisk.init: fixed restart problem with breaking up after stop. + + debian/asterisk.init: fixed reference to WRAPPER_DEAMON which is only + DEAMON for us. (Closes:#300707) + + -- Kilian Krause Mon, 21 Mar 2005 10:59:01 +0100 + +asterisk (1:1.0.7.dfsg.1-1) unstable; urgency=low + + * New upstream release (Ensure non-dfsg MOH is not included in orig.tar) + + -- Mark Purcell Sun, 20 Mar 2005 10:30:44 +0000 + +asterisk (1:1.0.7-1) unstable; urgency=low + + * New upstream release. (Closes: #300403) + + Fixed music on hold. (Closes: #300370) + * Re-enabled speex codec. (Closes: #300373) + * As asterisk-h323 is empty, we are no longer depending on openh323, so + we don't have build conflicts between asterisk and zaptel. (Closes: #287260) + * debian/rules: Fixed duplicate execution of configure and unrepresentable + changes to source. (Closes: #299184) + * debian/patches/80_skinny.dpatch: removed. Incorporated in the 1.0.7 + release. + * debian/patches/97_bristuff.dpatch: fixed problems to build on AMD64 with + gcc-4.0 (Closes: #297561) + + -- Kilian Krause Sat, 19 Mar 2005 22:26:45 +0100 + +asterisk (1:1.0.6-2) unstable; urgency=low + + * fixed location of sounds dir in addmailbox (Closes: #298769) + + -- Kilian Krause Wed, 9 Mar 2005 22:09:05 +0100 + +asterisk (1:1.0.6-1) unstable; urgency=low + + * New upstream release. (asterisk 1.0.6, bristuff RC7k, Closes: #298128) + * debian/control: explicitly depend on zlib1g-dev. (Closes: #296967) + * Make sure we have the newer asterisk-config to not conflict + /etc/default/asterisk. (Closes: #297719) + * as there is no longer a conflict with libnewt-dev, it was added to the + build deps for astman + * debian/control: add astman and cdr_sqlite (Closes: #259342) + * asterisk.default, asterisk.init: removed hack to load zaphfc correctly. + We'll leave this to zaptel and it's modprobe.d features. + + -- Kilian Krause Sat, 5 Mar 2005 20:03:42 +0100 + +asterisk (1:1.0.5-4) unstable; urgency=low + + * debian/patches/00list,debian/control: Enable bristuff RC7f by default. + * debian/asterisk.init, debian/asterisk.default: Cleanup zaphfc preloading + as inspired by Tzafrir Cohen. + * debian/control: Remove speex as B-D, it's broken when imported from + debian. Added autotools-dev for editline. + * deiban/rules: fix asterisk.8.gz error in lintian. Bring new autotools for + editline's configure. + * reintroduce chan_zap (Closes: #296656) + + -- Kilian Krause Thu, 24 Feb 2005 01:24:45 +0100 + +asterisk (1:1.0.5-3) unstable; urgency=low + + * debian/patches/08_debian-zaptel.dpatch, debian/control: fixed zaptel.h + include to take zaptel-source's version. + * debian/patches/97_bristuff.dpatch: + include bristuff from junghanns.net (not enabled by default now, would + close: #286797). We need libpri and zaptel with bristuff patch first. + * 18_debian-libedit.dpatch: removed due to command history problem. + (Closes:#281690) + * debian/asterisk.init: Added grace timeout of 2 secs before hard shutting + down running daemons to don't scatter incorrect warnings. Don't run the + asterisk daemon unless RUNASTERISK=yes. (Will not bind ports from chroots) + * debian/asterisk-config.default: Disabled autostart - especially when + installing in chroots this was quite annoying. + * debian/rules: Remove the asterisk.8.gz recompression. (Closes: #295220) + * debian/README.Debian: Added first version. Thanks to Tzafrir Cohen for the + template! (Closes: #270072) + * debian/asterisk.deafult: moved the /etc/default to the asterisk package, + as /etc/init.d/asterisk in there needs it. + * debian/80_skinny.dpatch: Added + http://bugs.digium.com/bug_view_page.php?bug_id=0003496. Thanks to Johan + Thelmén . (Closes:#295658) + * debian/control: remove chan_h323 from being built for now. For now it's + being replaced by asterisk-oh323 until chan_h323 does build and work ok + with latest OpenH323 again. + + -- Kilian Krause Mon, 21 Feb 2005 23:13:57 +0100 + +asterisk (1:1.0.5-2) unstable; urgency=low + + * Debian VoIP Team upload. + * asterisk.init, asterisk-config.default: probably fixed start-as-user-with- + multiple-groups-problem. + * patches/40_initgroups.dpatch: added patch from Florian Weimer + . Thanks! (Closes: #293124) + * debian/postinst: Make asterisk user's home /var/lib/asterisk upon user + request. + * debian/control: Bump libpri build-depends to 1.0.4-1. (Closes: #293990) + + -- Kilian Krause Tue, 8 Feb 2005 11:40:43 +0100 + +asterisk (1:1.0.5-1) unstable; urgency=low + + * Debian VoIP Team upload. + * New upstream release. + + * Kilian Krause: + - debian/asterisk.init: fixed multiple GID problem when starting asterisk (as + reported by Raoul Bönisch and Simon Peter). Unfortunatelly this does + remove the chance to run as real-time prio. + - debian/asterisk.init: fixed stale stop by using start-stop-server after + soft shutdown (Closes: #263879) + - debian/asterisk.init: Fixed running as root problem for #279052. At least + through the /etc/init.d/asterisk you won't be able to run asterisk as + root (not even with another username). (Closes: #279052) + - debian/asterisk.init: Added switch to run asterisk via safe_asterisk + optionally for automatic restart (Closes: #266805) + - debian/patches/01_security_hotfix_287851.dpatch: Removed, as is + incorporated in 1.0.4 upstream release. + + * Jose Carlos + - debian/rules: add a check at build time for fpm sounds. If they exist, + abort, as we must remember to remove those from sources in each new + upstream release. + - debian/patches: 20_Makefile.dpatch: updated + + -- Jose Carlos Garcia Sogo Fri, 28 Jan 2005 23:31:14 +0100 + +asterisk (1:1.0.3-2) unstable; urgency=low + + * Apply missing 25_subdirs_Makefile patch. + + -- Jose Carlos Garcia Sogo Sat, 15 Jan 2005 18:23:40 +0100 + +asterisk (1:1.0.3-1) unstable; urgency=high + + * Debian VoIP Team upload. + * New upstream version. (Closes: #284889) + + * Kilian Krause: + - ACK NMU. (Thanks Steve!): + + debian/patches/01_security_hotfix_287851.dpatch: Patched to + fix logging strings vulnerability. (Closes: #287851) + + * Jose Carlos Garcia Sogo + - Using again dpatch. + - debian/patches: populated with different patches. + - 08_debian-zaptel: Using zaptel.h file from version 1:1.0.0-2 of + zaptel-source package. + - removed sounds licensed from FreePlayMusic from source, + as the license for them is not DFSG compliant (Closes: #288429) + - applied patch to make asterisk compile on amd64 with + gcc-4.0 (Closes: #288831) + - debian/asterisk.init: + + Changed how daemon is restarted in init file. (Closes: #287025) + + Using -r in checks in init file. (Closes: #287456) + - debian/asterisk-config.default + + Run by default as group asterisk. + - Fix some lintian warnings and errors: + + Description: should start with lowercase letter. + + Bumped Standars-Version to 3.6.1. No changes needed. + + Removed duplicate dependencies. + + Recompress asterisk.8 manpage with max level (--best option) + + -- Jose Carlos Garcia Sogo Sat, 15 Jan 2005 13:11:49 +0100 + +asterisk (1:1.0.2-3.1) unstable; urgency=high + + * Non-maintainer upload. + * High-urgency upload for sarge-targetted RC bugfix + * Fix multiple format string vulnerabilities, reported by Jan + Niehusmann. Closes: #287851. + + -- Steve Langasek Sat, 8 Jan 2005 02:54:45 -0800 + +asterisk (1:1.0.2-3) unstable; urgency=low + + * Closes: #281524: running asterisk with realtime priority + * Include changes from Tzafrir Cohen + + -- Mark Purcell Thu, 2 Dec 2004 02:10:12 +1100 + +asterisk (1:1.0.2-2) unstable; urgency=low + + * fixup init.d/asterisk to logger reload. Thanks Daniel Pocock + * Closes: #260575: chan_zap.so: undefined symbol + * Build-Depends: libpri1 >= 0.6 + * Closes: #279905: dependency issue breaks voicemail setup + * Build-Depends: asterisk-sounds-main (>= 1.0.2) + * Closes: #269942: package Debian asterisk-sounds + * Rename asterisk-sounds to asterisk-sounds-main to avoid upstream + conflict + * Closes: #277404: Please split out GTK console + * Split off asterisk-gtk-console package to contain all X11 + dependancies + + -- Mark Purcell Sat, 6 Nov 2004 13:20:33 +1100 + +asterisk (1:1.0.2-1) unstable; urgency=low + + * New upstream release + * Closes: #279540: Please package newer version of asterisk + * Closes: #275808: logrotate errors and emails + + -- Mark Purcell Thu, 4 Nov 2004 18:19:09 +1100 + +asterisk (1:1.0.1-2) unstable; urgency=low + + * Closes: #275808: logrotate errors and emails + * Add init.d/asterisk logger-reload|extensions-reload options & use + logger reload in asterisk.logrotate. Thanks Daniel Pocock + + -- Mark Purcell Wed, 13 Oct 2004 22:31:22 +1000 + +asterisk (1:1.0.1-1) unstable; urgency=low + + * New upstream release + + -- Mark Purcell Wed, 6 Oct 2004 14:39:12 +1000 + +asterisk (1:1.0.0-4) unstable; urgency=high + + * Urgency high for sarge release + * Closes: #273570: asterisk-sounds: sounds/letters directory is missing + + -- Mark Purcell Wed, 29 Sep 2004 07:48:16 +1000 + +asterisk (1:1.0.0-3) unstable; urgency=low + + * Closes: #273780: under ALSA, infinite-loops immediately on + installation + * Comment out autoload of chan_oss from modules.conf + * Closes: #272999: asterisk_1:0.9.1+1.0RC2-2_hppa: FTBFS: + [anaFilter.o] Error 1 + * Version 1.0.0 now builds on hppa + * Closes: #273576: chan_zap.so module is missing + * check for ../include/linux/zaptel.h in channels/Makefile + * Closes: #273572: Music on hold has wrong default directory + * refer to correct /usr/share/asterisk/mohmp3 directory + + -- Mark Purcell Tue, 28 Sep 2004 23:06:03 +1000 + +asterisk (1:1.0.0-2) unstable; urgency=medium + + * Rebuild with zaptel.h_1.0.0 and libpri-dev_1.0.0 + + -- Mark Purcell Sun, 26 Sep 2004 08:32:11 +1000 + +asterisk (1:1.0.0-1) unstable; urgency=low + + * New upstream release + + -- Mark Purcell Fri, 24 Sep 2004 20:23:31 +1000 + +asterisk (1:0.9.1+1.0RC2-2) unstable; urgency=low + + * Use asterisk.8.gz man page + * Remove back PROC optomizations from Makefile, enable build on hppa + + -- Mark Purcell Thu, 23 Sep 2004 18:20:45 +1000 + +asterisk (1:0.9.1+1.0RC2-1) unstable; urgency=low + + * New upstream release + * Back out dpatch (Makes new upstream release straight forward) + + -- Mark Purcell Thu, 23 Sep 2004 08:35:08 +1000 + +asterisk (1:0.9.1+1.0RC1-9) unstable; urgency=low + + * Breakup monolithic patch into components. + + -- Mark Purcell Wed, 22 Sep 2004 18:47:31 +1000 + +asterisk (1:0.9.1+1.0RC1-8) unstable; urgency=medium + + * debian/patches/11_makefile-sanitize.dpatch: fixed patch to make gsm + work again. (Closes: #266167) + + -- Kilian Krause Tue, 17 Aug 2004 15:34:21 +0200 + +asterisk (1:0.9.1+1.0RC1-7) unstable; urgency=low + + * debian/rules, debian/patches/10_rollup-1.0-1.dpatch, + debian/patches/11_makefile-sanitize.dpatch: Incorporate fixes proposed by + Thiemo Seufer . + Should fix the FTBFS on hppa. + + -- Kilian Krause Sun, 15 Aug 2004 20:16:26 +0200 + +asterisk (1:0.9.1+1.0RC1-6) unstable; urgency=low + + * debian/control: suggest gnomemeeting. (At least tell people, which clients + they need) Also add dpatch as Build-Dep. (Closes: #265036) + * Closes: #262011: SIP cancels fail due to Request-URI mismatch + * debian/patches/20_chan_sip.dpatch: Apply chan_sip patch from Jan Niehusmann + + -- Kilian Krause Sat, 14 Aug 2004 14:05:36 +0000 + +asterisk (1:0.9.1+1.0RC1-5) unstable; urgency=low + + * debian/control: make sure we're rebuilding with rtti enabled openh323 + * debian/rules: make svn-buildpacakge not choke on failing clean target + + -- Kilian Krause Mon, 9 Aug 2004 14:37:38 +0200 + +asterisk (1:0.9.1+1.0RC1-4) unstable; urgency=low + + * Cleanup wierd .diff.gz file + + -- Mark Purcell Wed, 28 Jul 2004 19:00:32 +1000 + +asterisk (1:0.9.1+1.0RC1-3) unstable; urgency=low + + * Rebuild with existing libtonezone1 + + -- Mark Purcell Wed, 28 Jul 2004 18:10:52 +1000 + +asterisk (1:0.9.1+1.0RC1-2) unstable; urgency=low + + * Cleanup codecs/ilbc/Makefile to remove -march sillyness (which is + already defined above anyway + * Debian already has libedit.a Don't build, fails on mips anyway due to old config.guess + + -- Mark Purcell Wed, 21 Jul 2004 19:21:51 +1000 + +asterisk (1:0.9.1+1.0RC1-1) unstable; urgency=low + + * New upstream release (Closes: Bug#260370) + * Closes: #247401: doesn't upgrade cleanly - initscript + problems ? + + -- Mark Purcell Tue, 20 Jul 2004 19:20:37 +1000 + +asterisk (1:0.9.1-3) unstable; urgency=low + + * allow init.d/asterisk distribution via GPL + * Remove -I/usr/include/ptlib/unix from h323 Makefile, Thanks Ray + Dassen (Closes: Bug#259564) + * Closes: #259572: Unmet dependencies + * Maintainer: Debian VoIP Team + Uploaders: Mark Purcell , + Kilian Krause , + Jose Carlos Garcia Sogo , + Goedson Teixeira Paixao , + Santiago Garcia Mantinan + * Next step. Get this all back into svn! + + -- Mark Purcell Sun, 18 Jul 2004 10:40:22 +1000 + +asterisk (1:0.9.1-2) unstable; urgency=low + + * Rebuild with libopenh323-dev (1.12.2-4) from sarge for H.323 support + + -- Mark Purcell Wed, 14 Jul 2004 18:35:42 +1000 + +asterisk (1:0.9.1-1) unstable; urgency=low + + * New upstream release. Previous version WAS tagged as 1.0 in CVS :-( + * Closes: #249046: no ring indication + * Closes: #254654: init.d/asterisk restart kills asterisk + * Build-Depends: libgtk1.2-dev, libspeex-dev (Closes: Bug#253639) + * Turn off broken H.323 support (Closes: Bug#255662) + * Closes: #250302: Package description is slightly outdated and + incorrect + * Closes: #255685: Syntax error in configuration file, + /etc/asterisk/sip.conf + * Closes: #228722: please add postgres support for asterisk + + -- Mark Purcell Sat, 3 Jul 2004 22:47:41 +1000 + +asterisk (1.0-2) unstable; urgency=low + + * Rebuild for new libopenh323-dev + + -- Mark Purcell Sat, 3 Jul 2004 21:56:58 +1000 + +asterisk (1.0-2) unstable; urgency=low + + * Merged 1.0-1 and 0.9.0-2 + + -- Jose Carlos Garcia Sogo Tue, 8 Jun 2004 00:10:16 +0200 + +asterisk (1.0-1) unstable; urgency=low + + * New upstream release + + -- Mark Purcell Mon, 31 May 2004 21:51:18 +1000 + +asterisk (0.9.0-1) unstable; urgency=low + + * New upstream release + + -- Mark Purcell Sun, 18 Apr 2004 22:51:59 +1000 + +asterisk (0.7.2-4) unstable; urgency=low + + * Update channels/h323/Makefile Closes: #235010: + asterisk_0.7.2-3(unstable/sparc): arch-dependent CFLAGS + + -- Mark Purcell Fri, 27 Feb 2004 12:14:26 +1100 + +asterisk (0.7.2-3) unstable; urgency=low + + * Add Build-Depends: libopenh323-dev (Closes: Bug#233649) + + -- Mark Purcell Tue, 24 Feb 2004 11:55:57 +1100 + +asterisk (0.7.2-2) unstable; urgency=low + + * Build-Depends: libpri-dev (Closes:Bug#199548) + * Include Suggests: rate-engine + + -- Mark Purcell Thu, 5 Feb 2004 17:26:02 +1100 + +asterisk (0.7.2-1) unstable; urgency=low + + * New upstream release + + -- Mark Purcell Thu, 5 Feb 2004 16:25:28 +1100 + +asterisk (0.7.1-3) unstable; urgency=low + + * Build with libopenh323 support (Closes: Bug#195233) + * Include Suggests: ohphone + + -- Mark Purcell Tue, 3 Feb 2004 08:47:47 +1100 + +asterisk (0.7.1-2) unstable; urgency=low + + * Remove ppc fixup in codecs/lpc10/Makefile again. Prevents build on + ia64, mk68 et al + + -- Mark Purcell Fri, 16 Jan 2004 11:46:57 +1100 + +asterisk (0.7.1-1) unstable; urgency=low + + * New upstream release + * i686 optomised build + + -- Mark Purcell Thu, 15 Jan 2004 23:06:01 +1100 + +asterisk (0.7.0-1) unstable; urgency=low + + * LCA2004 release. Thanks Internode for the wireless access + * New upstream release + * Clean up bad symlinks in vm (Closes: Bug#220714) + * Apply restart gracefully patch from Nick Estes (Closes: Bug#217004) + * Fixup permission/ ownership problems in /etc/asterisk (Closes: + Bug#216995) + * Fixup master call log issues (Closes: Bug#217003) + * Remove Build-Depends: libmysql-dev - see doc/README.mysql (Closes: + Bug#222255) + * Build with include/linux/zaptel.h from zaptel-0.8.0.tar.gz + * Include Build-Depends: postgresql-dev + * Include Build-Depends: unixodbc-dev + + -- Mark Purcell Wed, 14 Jan 2004 10:10:02 +1100 + +asterisk (0.5.0-3) unstable; urgency=low + + * Remove Suggests: gnophone (Orphaned and removed) + * Clean up bad symlinks in vm (Closes: Bug#220714) + * Apply restart gracefully patch from Nick Estes (Closes: Bug#217004) + * Fixup permission/ ownership problems in /etc/asterisk (Closes: + Bug#216995) + * Fixup master call log issues (Closes: Bug#217003) + + -- Mark Purcell Tue, 13 Jan 2004 21:01:16 +1100 + +asterisk (0.5.0-2) unstable; urgency=low + + * Build-Depends: debhelper (>= 4.0.4) (Closes: Bug#216725) + + -- Mark Purcell Fri, 31 Oct 2003 06:59:11 +1100 + +asterisk (0.5.0-1) unstable; urgency=low + + * New upstream release (Closes: Bug#196761) + * Build with include/linux/zaptel.h from zaptel-0.7.0.tar.gz + + -- Mark Purcell Tue, 16 Sep 2003 23:40:05 +1000 + +asterisk (0.4.0-6) unstable; urgency=low + + * Include dh_install in debian/rules (Closes: Bug#207879) + + -- Mark Purcell Wed, 10 Sep 2003 23:07:37 +1000 + +asterisk (0.4.0-5) unstable; urgency=low + + * Rebuild for libnewt-utf8-0 (NOT AVAILABLE) + * Build-Depend: libnewt-dev + + -- Mark Purcell Sat, 5 Jul 2003 15:17:57 +1000 + +asterisk (0.4.0-4) unstable; urgency=low + + * include Build-Depends: libgtk1.2-dev (Closes: Bug#194489) + + -- Mark Purcell Sat, 5 Jul 2003 15:12:02 +1000 + +asterisk (0.4.0-3) unstable; urgency=low + + * Rebuild for libtonezone-0.60, libzaptel-0.60 + * Change codecs/codec_gsm.c:#include (Closes: Bug#190082) + * Start after isdnactivecards debian/rules dh_installinit (Closes: + Bug#191062) + * Change to Build-Depends: libnetw-utf8-dev + * Update Tormenta URL in debian/control + + -- Mark Purcell Sat, 10 May 2003 16:58:03 +1000 + +asterisk (0.4.0-2) unstable; urgency=low + + * Remove ppc 'fixup' in codecs/lpc10/Makefile (Closes: Bug#189743) + * Updated description (Closes: Bug#168779) + + -- Mark Purcell Sun, 20 Apr 2003 08:37:49 +1000 + +asterisk (0.4.0-1) unstable; urgency=low + + * New upstream release + * cdr/Makefile CFLAGS+=-fPIC -DPIC (Closes: Bug#188915) + * Include include/linux/zaptel.h from zaptel-0.6.0.tar.gz + + -- Mark Purcell Sat, 19 Apr 2003 21:11:45 +1000 + +asterisk (0.3.0-2) unstable; urgency=low + + * Build-Depends: libmysqlclient-dev, libgtk2.0-dev (Closes: Bug#188188) + + -- Mark Purcell Thu, 10 Apr 2003 20:08:38 +1000 + +asterisk (0.3.0-1) unstable; urgency=low + + * New upstream release + * channels/chan_zap_new.c is depreciated + * Debian patches to upstream Makefile are a lot cleaner!! + * Update /etc/init.d/asterisk stop to use 'stop now' command + * Hack AST_DATA_DIR to provide asterisk-sounds under /usr/share/asterisk + * `chown asterisk.asterisk /var/lib/asterisk` on install + * Remove dh_undocumented + * chan_oss failing again :-( + * Force Depends: libspeex1 (dpkg-shlibs bug?) + + -- Mark Purcell Tue, 8 Apr 2003 21:27:52 +1000 + +asterisk (0.2.0-cvs20030103-3) unstable; urgency=low + + * Include Build-Depends: libasounds2-dev + * Update channels/Makefile to include Debian zaptel.h dir (Closes: Bug#178868) + * Thanks to mdz for the new libzap-dev and other patches + + -- Mark Purcell Sat, 8 Mar 2003 15:45:40 +1100 + +asterisk (0.2.0-cvs20030103-2) unstable; urgency=low + + * Revert -march in codecs/lpc10/Makefile + + -- Mark Purcell Sat, 25 Jan 2003 08:38:51 +1100 + +asterisk (0.2.0-cvs20030103-1) unstable; urgency=low + + * New upstream release + * Use invoke-rc.d in logrotate script (Closes: Bug#174633) + + -- Mark Purcell Fri, 24 Jan 2003 21:57:43 +1100 + +asterisk (0.2.0-4) unstable; urgency=low + + * Add Build-Depends: bison (Closes: Bug#169312) + + -- Mark Purcell Sun, 17 Nov 2002 09:03:01 +1100 + +asterisk (0.2.0-3) unstable; urgency=low + + * Fixed bison problems. ThanksMartijn + * Move gethostname in app_voicemail.c (Closes: Bug#168936) + * Move 0.2.0 to unstable. If you have OSS problems use asterisk/testing. + + -- Mark Purcell Fri, 15 Nov 2002 20:36:03 +1100 + +asterisk (0.2.0-2) experimental; urgency=low + + * Incorporate changes from mdz (Remove graphviz, build astman) + * Force Build-Deps: bison-1.35 :( + + -- Mark Purcell Sat, 26 Oct 2002 12:59:12 +1000 + +asterisk (0.2.0-1) experimental; urgency=low + + * New upstream release (Closes: Bug#163852) + * Uploaded to experimental as I am having problems with the chan_oss driver + which is a critial component. + + -- Mark Purcell Wed, 9 Oct 2002 08:02:38 +1000 + +asterisk (0.1.12-5) unstable; urgency=low + + * Remove chown against /var/lib/asterisk (Closes: Bug#154774) + * Fixup vm symlink (Closes: Bug#158800) + * Fixup location of iaxtel.pub keys + + -- Mark Purcell Sun, 8 Sep 2002 20:56:24 +1000 + +asterisk (0.1.12-4) unstable; urgency=low + + * Seperate into indep packages; asterisk, asterisk-[sounds,dev,doc] + * Sounds & images from /var/lib/asterisk to FHS compliant /usr/share/asterisk + * Remove DEBUG options from normal build + * Include Build-Depends: doxygen + + -- Mark Purcell Wed, 24 Jul 2002 15:07:51 +1000 + +asterisk (0.1.12-3) unstable; urgency=low + + * Update Description + * Use dpkg-architecture to set processor optimisations (Closes: #153175) + + -- Mark Purcell Wed, 17 Jul 2002 21:23:33 +1000 + +asterisk (0.1.12-2) unstable; urgency=low + + * Fixup build check for /etc/asterisk + + -- Mark Purcell Tue, 9 Jul 2002 07:32:17 +1000 + +asterisk (0.1.12-1) unstable; urgency=low + + * New upstream release + * Fixup typo in /etc/init.d/asterisk + * Include [cdr_mysql.so] => (MySQL CDR Backend) + * Use excellent init.d script idea from Sim IJskes + * Fixup broken postinst & postinst scripts + + -- Mark Purcell Mon, 8 Jul 2002 23:07:27 +1000 + +asterisk (0.1.11-5) unstable; urgency=low + + * Include zaptel support (Closes: Bug#151274) + + -- Mark Purcell Fri, 5 Jul 2002 23:59:17 +1000 + +asterisk (0.1.11-4) unstable; urgency=low + + * Add init.d from Matt Zimmerman (Closes: Bug#150573) + * More updates from Matt Zimmerman: (Closes: Bug#151201) + - place socket and fifo in /var/run/asterisk instead of /var/run + - fix mkfifo call (bug uncovered by running as non-root), patch + sent upstream also + - create postinst with necessary adduser and chown calls + * Install logrotate from Matt Zimmerman (Closes: Bug#151198) + * Disable geteuid check to allow running as non-root + * Add asterisk to audio group by default + + -- Mark Purcell Sat, 29 Jun 2002 01:34:56 +1000 + +asterisk (0.1.11-3) unstable; urgency=high + + * Update cdr/Makefile to include CFLAGS+=-fPIC -DPIC (Closes: Bug#144052) + + -- Mark Purcell Sat, 27 Apr 2002 21:19:32 +1000 + +asterisk (0.1.11-2) unstable; urgency=low + + * Move from non-us to main/comm + * Update copyright file to reflect upstream CVS LICENCE change to permit + linking with OpenSSL/ OpenH323 (Closes: Bug#141164) + + -- Mark Purcell Fri, 19 Apr 2002 20:11:58 +1000 + +asterisk (0.1.11-1) unstable; urgency=low + + * New upstream release + * Update debian/control + * Include README.cdr & README.iax + + -- Mark Purcell Mon, 18 Mar 2002 15:46:39 +1100 + +asterisk (0.1.10-3) unstable; urgency=low + + * Include CFLAGS+=-fPIC -DPIC in res/Makefile for hppa build + + -- Mark Purcell Fri, 1 Mar 2002 20:58:02 +1100 + +asterisk (0.1.10-2) unstable; urgency=low + + * Change Build-Depends: libssl-dev (Closes: Bug#134821) + + -- Mark Purcell Wed, 20 Feb 2002 22:28:35 +1100 + +asterisk (0.1.10-1) unstable; urgency=low + + * New upstream release + + -- Mark Purcell Wed, 20 Feb 2002 22:28:00 +1100 + +asterisk (0.1.9-5) unstable; urgency=low + + * Better make that Architecture: any if I want this to autobuild :-) + + -- Mark Purcell Wed, 2 Jan 2002 13:00:09 +1100 + +asterisk (0.1.9-4) unstable; urgency=low + + * Exclude MMX optimsed asm codecs/gsm/src/k6opt.s to enable non-x86 & + non-k6 builds (Closes: Bug#127225) + + -- Mark Purcell Wed, 2 Jan 2002 12:59:38 +1100 + +asterisk (0.1.9-3) unstable; urgency=low + + * New maintainer (Closes: Bug#123497) + * Set Arch to i386 as this contains x86 assember code + + -- Mark Purcell Sat, 29 Dec 2001 10:25:21 +1100 + +asterisk (0.1.9-2) unstable; urgency=high + + * apps/Makefile, codecs/gsm/Makefile: Missed an -mpentium in CFLAGS. + Closes: #126552. + + -- Matej Vela Thu, 27 Dec 2001 04:00:50 +0100 + +asterisk (0.1.9-1) unstable; urgency=medium + + * QA upload. + * New upstream version. + * Package is orphaned; maintainer set to Debian QA Group. + * debian/postrm: Ensure correct exit status. Closes: #105523. + * debian/control: s/API's/APIs/ Closes: #124423. + * debian/conffiles: Already handled by debhelper; removed. + * Conforms to Standards version 3.5.6: + * debian/copyright: Include module licensing exception and GSM and + ADPCM copyrights. + * debian/rules: + * Use dh_undocumented rather than a verbatim copy of undocumented.7. + * Pass ChangeLog to dh_installchangelogs. + * Support DEB_BUILD_OPTIONS. + + -- Matej Vela Tue, 25 Dec 2001 19:16:48 +0100 + +asterisk (0.1.6-1.2) unstable; urgency=low + + * NMU + * Fix makefiles, add -fPIC to builds. Closes: #104779 + + -- LaMont Jones Sun, 15 Jul 2001 15:15:46 -0600 + +asterisk (0.1.6-1.1) unstable; urgency=low + + * NMU with permission of Raphael Bossek. + * Corrected an error in channels/adtranvofr.h that prevented + big endian from compiling. (closes: #87273, #89868, #93913) + * Added build dependencies. + * Added the location of the upstream source to debian/copyright. + + -- Adrian Bunk Tue, 15 May 2001 00:22:31 +0200 + +asterisk (0.1.6-1) unstable; urgency=low + + * New upstream version. + + -- Raphael Bossek Mon, 19 Feb 2001 15:48:43 +0100 + --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-h323.README.Debian +++ asterisk-1.4.21.2~dfsg/debian/asterisk-h323.README.Debian @@ -0,0 +1,26 @@ +asterisk-h323 vs. asterisk-oh323 vs. asterisk-ooh323c +===================================================== + + There are currently three implementations for H.323 in the Asterisk PBX: + chan_h323, chan_oh323 and chan_ooh323c. They are distributed by Debian as + asterisk-h323, asterisk-oh323 and asterisk-oh323c, respectively. + + chan_h323 was contributed by NuFone and is nowdays maintained and distributed + by Digium, Inc. Hence, it is considered the official H.323 chanel driver. + It is a fork of an earlier version of chan_oh323, but they are quite different + nowdays. + It is part of the main Asterisk distribution. + + In the 1.2 release cycle, another H.323 channel driver was contributed by + Objective Systems, Inc., called chan_ooh323c. It was made from scratch and, + unlike the other two, does not use the OpenH323 library; it also has a + totally different configuration file. + It is part of the asterisk-addons package, distributed by Digium, Inc. + + You have to use a different configuration file for each of the channel + drivers since they are quite different. All of them can happily coexist, as + long as you run them on a different port or disable their loading in + modules.conf and being careful of module autoloading (autoload=yes). + +Kilian Krause and Faidon Liambotis +for the Debian VoIP packaging team. --- asterisk-1.4.21.2~dfsg.orig/debian/dummyprogs/fetch +++ asterisk-1.4.21.2~dfsg/debian/dummyprogs/fetch @@ -0,0 +1,10 @@ +#!/bin/sh + +# a dummy script that can serve as 'fetch' to pass for autoconf tests +# but always returns false to make sure it is never used. +# +# Note: the configure script will look for wget first. If you actually +# want to download sound tarballs or whatever at build time, make sure +# you have wget installed, and this script should cause you no problems. + +exit 1 --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.examples +++ asterisk-1.4.21.2~dfsg/debian/asterisk.examples @@ -0,0 +1,3 @@ +sample.call +static-http +contrib/scripts/vmail.cgi --- asterisk-1.4.21.2~dfsg.orig/debian/astgenkey.8 +++ asterisk-1.4.21.2~dfsg/debian/astgenkey.8 @@ -0,0 +1,129 @@ +.\" $Header: /aolnet/dev/src/CVS/sgml/docbook-to-man/cmd/docbook-to-man.sh,v 1.1.1.1 1998/11/13 21:31:59 db3l Exp $ +.\" +.\" transcript compatibility for postscript use. +.\" +.\" synopsis: .P! +.\" +.de P! +.fl +\!!1 setgray +.fl +\\&.\" +.fl +\!!0 setgray +.fl \" force out current output buffer +\!!save /psv exch def currentpoint translate 0 0 moveto +\!!/showpage{}def +.fl \" prolog +.sy sed \-e 's/^/!/' \\$1\" bring in postscript file +\!!psv restore +. +.de pF +.ie \\*(f1 .ds f1 \\n(.f +.el .ie \\*(f2 .ds f2 \\n(.f +.el .ie \\*(f3 .ds f3 \\n(.f +.el .ie \\*(f4 .ds f4 \\n(.f +.el .tm ? font overflow +.ft \\$1 +.. +.de fP +.ie !\\*(f4 \{\ +. ft \\*(f4 +. ds f4\" +' br \} +.el .ie !\\*(f3 \{\ +. ft \\*(f3 +. ds f3\" +' br \} +.el .ie !\\*(f2 \{\ +. ft \\*(f2 +. ds f2\" +' br \} +.el .ie !\\*(f1 \{\ +. ft \\*(f1 +. ds f1\" +' br \} +.el .tm ? font underflow +.. +.ds f1\" +.ds f2\" +.ds f3\" +.ds f4\" +'\" t +.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n +.TH ASTGENKEY 8 "May 14th, 2005" "Asterisk" "Linux Programmer's Manual" +.SH NAME +.B astgenkey +-- generates keys for for Asterisk IAX2 RSA authentication +.SH SYNOPSIS +.PP +.B astgenkey +[ -q ] [ -n ] [ \fIkeyname\fP ] + +.SH DESCRIPTION +.B genzaptelconf +This script generates an RSA private and public key pair in PEM format +for use by Asterisk. The private key should be kept a secret, as it can +be used to fake your system's identity. Thus by default (without the +option +.I -n +) the script will create a passphrase-encrypted copy of your secret key: +without entering the passphrase you won't be able to use it. + +However if you want to use such a key with Asterisk, you'll have to start +it interactively, because the scripts that start asterisk can't use that +encrypted key. + +The key is identified by a name. If you don't write the name on the +command-line you'll be prompted for one. The outputs of the script are: + +.I name\fB.pub +.RS +The public key: not secret. Send this to the other side. +.RE + +.I name\fB.key +.RS +The private key: secret. +.RE + +Those files should be copied to +.I /var/lib/asterisk/keys + +(The private key: on your system. The public key: on other systems) + +To see the currently-installed keys from the asterisk CLI, use the command + +.RS +show keys +.RE + +.SH OPTIONS +.B -q +.RS +Run quietly. +.RE + +.B -n +.RS +Don't encrypt the private key. +.RE + +.SH FILES +.I /var/lib/asterisk/keys +.RS +.RE + +.SH "SEE ALSO" +asterisk(8), genrsa(1), rsa(1), + +http://www.voip-info.org/wiki-Asterisk+iax+rsa+auth + +.SH "AUTHOR" +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common-licenses/GPL. --- asterisk-1.4.21.2~dfsg.orig/debian/copyright +++ asterisk-1.4.21.2~dfsg/debian/copyright @@ -0,0 +1,272 @@ +This package was debianized by Mark Purcell on +Fri Apr 19 19:58:40 EST 2002 + +It is now maintained by the Debian VoIP Team + + +Asterisk was downloaded from http://www.asterisk.org/ +Bristuff was downloaded from http://www.junghanns.net/asterisk/ + +Upstream Authors: Asterisk: Digium, Inc. + Bristuff: Klaus-Peter Junghanns + +Debian asterisk-xxx.dfsg.tar.gz +=============================== + * The Debian version of the upstream asterisk source has had the fpm Music +on Hold removed as this music has only been licenced for use within +asterisk which is incompatible with the Debian Free Software Guildlines (DFSG) +. + + * The iLBC codec library code has been removed from the Debian asterisk +package as it does not conform with the DFSG. + + * The contrib/firmware/iax/iaxy.bin binary firmware without source has been + removed. + +Copyright +========= + +Copyright (C) 2001-2004 Digium and others.... + + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301, USA. + + On Debian GNU/Linux systems, the complete text of the GNU General + Public License version 2 can be found in `/usr/share/common-licenses/GPL-2'. + + Asterisk is distributed under GNU General Public License. The GPL also + must apply to all loadable modules as well, except as defined below. + + Digium, Inc. (formerly Linux Support Services) retains copyright to all + of the core Asterisk system, and therefore can grant, at its sole discretion, + the ability for companies, individuals, or organizations to create + proprietary or Open Source (but non-GPL'd) modules which may be dynamically + linked at runtime with the portions of Asterisk which fall under our + copyright umbrella, or are distributed under more flexible licenses than GPL + + If you wish to use our code in other GPL programs, don't worry -- there + is no requirement that you provide the same exemption in your GPL'd + products (although if you've written a module for Asterisk we would + strongly encourage you to make the same excemption that we do). + + Specific permission is also granted to OpenSSL and OpenH323 to link to + Asterisk. + + If you have any questions, whatsoever, regarding our licensing policy, + please contact us. + + The 'Asterisk' name and logos are trademarks owned by Digium, Inc., + and use of them is subject to our trademark licensing policies. If you + wish to use these trademarks for purposes other than simple + redistribution of Asterisk source code obtained from Digium, you + should contact our licensing department to determine the necessary + steps you must take. + + If you have any questions regarding our licensing policy, please + contact us: + + +1.877.546.8963 (via telephone in the USA) + +1.256.428.6000 (via telephone outside the USA) + +1.256.864.0464 (via FAX inside or outside the USA) + IAX2/misery.digium.com/6000 (via IAX2) + licensing@digium.com (via email) + + Digium, Inc. + 150 West Park Loop + Suite 100 + Huntsville, AL 35806 + USA + +Other source code in Asterisk: + + GSM source: + + Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, + Technische Universitaet Berlin + + Any use of this software is permitted provided that this notice is not + removed and that neither the authors nor the Technische Universitaet Berlin + are deemed to have made any representations as to the suitability of this + software for any purpose nor are held responsible for any defects of + this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + + As a matter of courtesy, the authors request to be informed about uses + this software has found, about bugs in this software, and about any + improvements that may be of general interest. + + Berlin, 28.11.1994 + Jutta Degener + Carsten Bormann + + ADPCM source: + + Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The + Netherlands. + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the names of Stichting Mathematisch + Centrum or CWI not be used in advertising or publicity pertaining to + distribution of the software without specific, written prior permission. + + STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO + THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE + FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Bristuff: + + Copyright (C) 2004, 2005 Junghanns.NET GmbH + + Klaus-Peter Junghanns + + This program is free software and may be modified and + distributed under the terms of the GNU General Public License. + + The packaging Debian (debian/ directory) is: + + Copyright (c) Kilian Krause + Copyright (c) Mark Purcell + Copyright (c) Tzafrir Cohen + Copyright (c) Faidon Liambotis + + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301, USA. + + On Debian GNU/Linux systems, the complete text of the GNU General + Public License can be found in `/usr/share/common-licenses/GPL'. + +Other portions of code: + +aescrypt.c: Copyright (c) 2003, Dr Brian Gladman , + Worcester, UK. +aeskey.c: Copyright (c) 2003, Dr Brian Gladman , + Worcester, UK. +dlfcn.c:Copyright (c) 2002 Jorge Acereda & + Peter O'Gorman +dns.c: * Copyright (C) 1999 - 2005 Thorsten Lockert +dnsmgr.c: * Copyright (C) 2005, Kevin P. Fleming +dsp.c: Copyright (C) 2001 Steve Underwood +indications.c: * Copyright (C) 2002, Pauline Middelink +jitterbuf.c: * Copyright (C) 2004-2005, Horizon Wimba, Inc. +jitterbuf.h: * Copyright (C) 2004-2005, Horizon Wimba, Inc. +md5.c: * written by Colin Plumb in 1993, no copyright is claimed. +plc.c: * Copyright (C) 2004 Steve Underwood +poll.c: Copyright (c) 1995-2002 Brian M. Clapper +slinfactory.c: * Copyright (C) 2005, Anthony Minessale II. +apps/app_alarmreceiver.c: * Copyright (C) 2004 - 2005 Steve Rodgers +apps/app_chanspy.c: * Copyright (C) 2005 Anthony Minessale II + (anthmct@yahoo.com) +apps/app_controlplayback.c: * Copyright (C) 1999 - 2005, Digium, Inc. +apps/app_curl.c: * Copyright (C) 2004 - 2005, Tilghman Lesher +apps/app_cut.c: * Copyright (c) 2003 Tilghman Lesher. +apps/app_db.c: * Copyright (C) 2003, Jefferson Noxon +apps/app_dictate.c: * Copyright (C) 2005, Anthony Minessale II +apps/app_directed_pickup.c: * Copyright (C) 2005, Joshua Colp +apps/app_dumpchan.c: * Copyright (C) 2004 - 2005, Anthony Minessale II. +apps/app_eval.c: * Copyright (c) 2004 - 2005, Tilghman Lesher. +apps/app_exec.c: * Copyright (c) 2004 - 2005, Tilghman Lesher. +apps/app_festival.c: * Copyright (C) 2002, Christos Ricudis +apps/app_forkcdr.c: * Copyright (C) 1999 - 2005, Anthony Minessale + anthmct@yahoo.com +apps/app_hasnewvoicemail.c: * Changes Copyright (c) 2004 - 2005 + Todd Freeman +apps/app_hasnewvoicemail.c: * Copyright (c) 2003 Tilghman Lesher. +apps/app_math.c: * Copyright (C) 2004 - 2005, Andy Powell +apps/app_md5.c: * Copyright (C) 2005, Olle E. Johansson, Edvina.net +apps/app_mixmonitor.c: * Copyright (C) 2005, Anthony Minessale II +apps/app_random.c: * Copyright (c) 2003 - 2005 Tilghman Lesher. +apps/app_rpt.c: * Copyright (C) 2002-2005, Jim Dixon, WB6NIL +apps/app_sayunixtime.c: * Copyright (c) 2003 Tilghman Lesher. +apps/app_settransfercapability.c: * Copyright (C) 2005, Frank Sautter, + levigo holding gmbh, www.levigo.de +apps/app_sms.c: * Copyright (C) 2004 - 2005, Adrian Kennard, +apps/app_sql_postgres.c: * Copyright (C) 2002, Christos Ricudis +apps/app_verbose.c: * Copyright (c) 2004 - 2005 Tilghman Lesher. +apps/app_while.c: * Copyright 2004 - 2005, Anthony Minessale +cdr/cdr_sqlite.c: * Copyright (C) 2004 - 2005, Holger Schurig +cdr/cdr_tds.c: Copyright (C) 1994, 1996, 1997, 2000, 2001 Free Software + Foundation, Inc. +channels/chan_misdn.c: * Copyright (C) 2004, Christian Richter +channels/chan_misdn_config.c: * Copyright (C) 2005, Christian Richter +channels/chan_modem_bestdata.c: * Copyright (C) 1999, Mark Spencer and + 2001 Jim Dixon +channels/chan_vpb.c: * Copyright (C) 2003, Paul Bagyenda +channels/chan_vpb.c: * Copyright (C) 2004 - 2005, Ben Kramer +channels/DialTone.h: * Copyright (C) 1999, Mark Spencer +channels/Makefile:# Copyright (C) 1999-2005, Mark Spencer +doc/README.backtrace:Copyright 2004 Free Software Foundation, Inc. +editline/: * Copyright (c) 1992, 1993 + * The Regents of the University of California. +editline/editline.3:.\" Copyright (c) 1997-1999 The NetBSD Foundation, Inc. +editline/install-sh:# Copyright 1991 by the Massachusetts Institute of + Technology +formats/format_au.c: * Copyright (C) 2005, Andriy Pylypenko +formats/format_g726.c: * Copyright (c) 2004 - 2005, inAccess Networks +formats/format_ogg_vorbis.c: * Copyright (C) 2005, Jeff Ollie +formats/format_sln.c: * Copyright (C) 1999 - 2005, Anthony Minessale +funcs/func_cdr.c: * Portions Copyright (C) 2005, Anthony Minessale II +funcs/func_db.c: * Copyright (C) 2005, Russell Bryant +funcs/func_db.c: * Copyright (C) 2003, Jefferson Noxon +funcs/func_logic.c: * Portions Copyright (C) 2005, Anthony Minessale II +funcs/func_math.c: * Copyright (C) 2004 - 2005, Andy Powell +funcs/func_md5.c: * Copyright (C) 2005, Olle E. Johansson, Edvina.net +funcs/func_md5.c: * Copyright (C) 2005, Russell Bryant +funcs/func_strings.c: * Portions Copyright (C) 2005, Tilghman Lesher. +funcs/func_strings.c: * Portions Copyright (C) 2005, Anthony Minessale II +res/res_config_odbc.c: * Copyright (C) 2004 - 2005 Anthony Minessale II +res/res_indications.c: * Copyright (C) 2002, Pauline Middelink +res/res_odbc.c: * Copyright (C) 2004 - 2005 Anthony Minessale II +utils/smsq.c: * Copyright (C) 2004 - 2005 Adrian Kennard +utils/streamplayer.c: fprintf(stderr, "Copyright (C) 2005 + -- Russell Bryant -- Digium, Inc.\n\n"); +channels/misdn/: * Copyright (C) 2004, Christian Richter +codecs/ilbc/: Copyright (C) The Internet Society (2004). +contrib/scripts/managerproxy.pl:# Copyright (c) 2004 David C. Troy + +contrib/scripts/retrieve_extensions_from_sql.pl:# Copyright: + 2004 Peter Nixon +db1-ast/*/*: * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. +editline/np/: * Copyright (c) 1998 The NetBSD Foundation, Inc. +editline/np/strlcat.c: * Copyright (c) 1998 Todd C. Miller + +include/asterisk/aes.h: Copyright (c) 2003, Dr Brian Gladman + , Worcester, UK. +include/asterisk/dlfcn-compat.h:Copyright (c) 2002 Jorge Acereda + & + Peter O'Gorman +include/asterisk/plc.h: * Copyright (C) 2004 Steve Underwood +include/asterisk/poll-compat.h: Copyright (c) 1995-2002 Brian M. Clapper +include/asterisk/res_odbc.h: * Copyright (C) 2004 - 2005, Anthony Minessale II +include/asterisk/slinfactory.h: * Copyright (C) 2005, Anthony Minessale II --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.lintian-overrides +++ asterisk-1.4.21.2~dfsg/debian/asterisk.lintian-overrides @@ -0,0 +1 @@ +asterisk: package-contains-empty-directory --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-config.dirs +++ asterisk-1.4.21.2~dfsg/debian/asterisk-config.dirs @@ -0,0 +1 @@ +etc/asterisk/manager.d --- asterisk-1.4.21.2~dfsg.orig/debian/safe_asterisk.8 +++ asterisk-1.4.21.2~dfsg/debian/safe_asterisk.8 @@ -0,0 +1,62 @@ +.TH SAFE_ASTERISK 8 "Jun 30th, 2005" "Asterisk" "Linux Programmer's Manual" +.SH NAME +.B safe_asterisk +\(em A wrapper to run the asterisk executable in a loop +.SH SYNOPSIS +.PP +.B safe_asterisk +.I [ asterisk_params ] + +.SH DESCRIPTION +.B safe_asterisk +is a script that runs asterisk in a loop, which can be useful if you +fear asterisk may crash. + +The script does not run in the background like a standard service. Rather, +it runs in its own linux virtual console (9, by default). +It also uses the option '-c' of asterisk(8) to avoid detaching asterisk +from that terminal. + +safe_asterisk also runs asterisk with unlimited core file size, and thus +asterisk will dump core in case of a crash. + +To get a "picture" of console 9, from another terminal (e.g: from a +remote shell session) you can use: + + screendump 9 + +The init script of the Debian package should be able to run safe_asterisk +as the asterisk service, if so configured. See coments in +/etc/default/asterisk + +.SH FILES +.B /tmp +.RS +safe_asterisk runs in that directory, rather than in / as usual. +.RE + +.B /tmp/core +.RS +If core files were generated there, they may be +.RE + +.SH BUGS +While showing the output on a console is useful, using screen(1) as +the terminal may be better. + +The script does not read configuration from standard location under /etc + +It uses fixed locations under /tmp , and thus may be exposed to a +symlink attacks. + +.SH SEE ALSO +asterisk(8), screendump(9) + +.SH "AUTHOR" +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common-licenses/GPL. --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-config.examples +++ asterisk-1.4.21.2~dfsg/debian/asterisk-config.examples @@ -0,0 +1,6 @@ +configs +agi/agi-test.agi +agi/eagi-test.c +agi/eagi-sphinx-test.c +agi/xagi-test.c +agi/fastagi-test --- asterisk-1.4.21.2~dfsg.orig/debian/control +++ asterisk-1.4.21.2~dfsg/debian/control @@ -0,0 +1,117 @@ +Source: asterisk +Priority: optional +Section: comm +Maintainer: Debian VoIP Team +Uploaders: Mark Purcell , Kilian Krause , Tzafrir Cohen , Faidon Liambotis +Build-Depends: debhelper (>= 5), quilt, zlib1g-dev, libreadline5-dev, libgsm1-dev, libssl-dev, libtonezone-dev (>= 1:1.4.1~0), libasound2-dev, libpq-dev, unixodbc-dev, libpri-dev (>= 1.4.1), zaptel-source (>= 1:1.4.1~0), autotools-dev, libnewt-dev, libsqlite-dev, libspeex-dev, graphviz, libcurl3-dev | libcurl-dev, doxygen, gsfonts, libpopt-dev, libopenh323-dev (>= 1.17.4), libiksemel-dev, libradiusclient-ng-dev, freetds-dev, libvorbis-dev, libsnmp9-dev, libcap-dev, libc-client2007b-dev, libisdnnet-dev +Standards-Version: 3.7.3 +Homepage: http://www.asterisk.org/ +Vcs-Svn: svn://svn.debian.org/pkg-voip/asterisk/trunk/ +Vcs-Browser: http://svn.debian.org/wsvn/pkg-voip/asterisk/?op=log + +Package: asterisk +Architecture: any +Section: comm +Depends: ${shlibs:Depends}, asterisk-config (= ${source:Version}) | asterisk-config-custom, adduser, asterisk-sounds-main +Conflicts: asterisk-classic, asterisk-bristuff, asterisk-chan-capi (<< 1.1.1-1~) +Replaces: asterisk-classic, asterisk-bristuff +Provides: asterisk-1.4 +Suggests: ekiga, ohphone, twinkle, kphone, asterisk-doc, asterisk-dev, asterisk-h323 +Description: Open Source Private Branch Exchange (PBX) + Asterisk is an Open Source PBX and telephony toolkit. It is, in a + sense, middleware between Internet and telephony channels on the bottom, + and Internet and telephony applications at the top. + . + Asterisk can be used with Voice over IP (SIP, H.323, IAX and more) standards, + or the Public Switched Telephone Network (PSTN) through supported hardware. + . + Supported hardware: + . + * All Wildcard (tm) ISDN PRI cards from Digium (http://www.digium.com) + * HFC-S/HFC-4S-based ISDN BRI cards (Junghanns.NET, beroNet, Digium etc.) + * All TDM (FXO/FXS) cards from Digium + * Various clones of Digium cards such as those by OpenVox + * Xorcom Astribank USB telephony adapter (http://www.xorcom.com) + * Voicetronix OpenPCI, OpenLine and OpenSwitch cards + * CAPI-compatible ISDN cards (using the add-on package chan-capi) + * Full Duplex Sound Card (ALSA or OSS) supported by Linux + * Tormenta T1/E1 card (http://www.zapatatelephony.org) + * QuickNet Internet PhoneJack and LineJack (http://www.quicknet.net) + . + This is the main package that includes the Asterisk daemon and most channel + drivers and applications. + +Package: asterisk-h323 +Architecture: any +Section: comm +Depends: asterisk-1.4, ${shlibs:Depends} +Description: H.323 protocol support for Asterisk + Asterisk is an Open Source PBX and telephony toolkit. + . + This channel driver (chan_h323) provides support for the H.323 protocol + for Asterisk. This is an implementation originally contributed by NuFone and + nowdays maintained and distributed by Digium, Inc. Hence, it is considered + the official H.323 chanel driver. + . + This is one of many H.323 channel implementations for Asterisk with others + being chan_oh323 and chan_ooh323c, distributed by Debian as asterisk-oh323 and + asterisk-ooh323c, respectively. + . + For more information about the Asterisk PBX, have a look at the Asterisk + package. + +Package: asterisk-doc +Recommends: asterisk +Section: doc +Priority: extra +Architecture: all +Description: Source code documentation for Asterisk + Asterisk is an Open Source PBX and telephony toolkit. + . + This package contains the source code documentation needed if you wish to + extend Asterisk by writing loadable modules for it. + +Package: asterisk-dev +Architecture: all +Recommends: asterisk +Section: devel +Priority: extra +Replaces: asterisk (<< 1:1.4.21.1~dfsg-1) +Description: Development files for Asterisk + Asterisk is an Open Source PBX and telephony toolkit. + . + This package contains the include files used if you wish to compile a + package which requires Asterisk's source file headers. + +Package: asterisk-dbg +Architecture: any +Depends: asterisk (= ${binary:Version}) +Section: devel +Priority: extra +Description: Debugging symbols for Asterisk + Asterisk is an Open Source PBX and telephony toolkit. + . + This package includes the debugging symbols useful for debugging + Asterisk. The debugging symbols are used for execution tracing and core + dump analysis. + +Package: asterisk-sounds-main +Architecture: all +Recommends: asterisk +Replaces: asterisk-sounds-extra +Section: comm +Description: Core Sound files for Asterisk (English) + Asterisk is an Open Source PBX and telephony toolkit. + . + This package contains the default (core) sound files in English, useful for + the operation of Asterisk. + +Package: asterisk-config +Recommends: asterisk +Conflicts: asterisk-config-custom +Architecture: all +Section: comm +Description: Configuration files for Asterisk + Asterisk is an Open Source PBX and telephony toolkit. + . + This package contains the default configuration files of Asterisk. --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.prerm +++ asterisk-1.4.21.2~dfsg/debian/asterisk.prerm @@ -0,0 +1,6 @@ +#! /bin/sh -e + +rmdir /usr/local/share/asterisk/sounds 2>/dev/null || true +rmdir /usr/local/share/asterisk 2>/dev/null || true + +#DEBHELPER# --- asterisk-1.4.21.2~dfsg.orig/debian/README.Debian +++ asterisk-1.4.21.2~dfsg/debian/README.Debian @@ -0,0 +1,72 @@ +Welcome to the world of telephone switch owners. Asterisk is a quite powerful +and probably one of the feature-richest open-source PBXes out there. To get you +a brief impression where to start tweaking, we've included this doc. (Thanks to +Tzafrir Cohen for a proposal of this) + +File Locations +============== +See /etc/asterisk/asterisk.conf for pathnames. All the configuration is done +from the *.conf files there. + +Sounds reside at /usr/share/asterisk/sounds. Voicemail mailboxes are below +/var/spool/asterisk/voicemail using symlinks. + +User, Groups, Permissions +========================= +By default the package will create user and group 'asterisk' and will run as +them. It will run with real-time priority (-p) by default. It will also add +itself to the group audio to enable the daemon to access sound cards and to +the group dialout to access Zaptel devices. Running as root is disabled in +/etc/init.d/asterisk for security reasons. + +To change those values you can edit /etc/default/asterisk. + +Alternatively, edit /etc/asterisk/asterisk.conf . + +init.d Script Commands +====================== +In addition to reload, that runs the asterisk CLI command 'reload' there +are also extensions-reload ('extensions reload') and logger-reload +('logger-reload') to load only parts of the configuration file. + +Asterisk supports a number of non-default parameters at startup. For debugging +it is often useful to run 'asterisk -U asterisk -vvvgc' from the console. Add +more -v for even higher verbosity. You can attach a remote console to a running +asterisk daemon with 'asterisk -vcr'. When testing, make sure to use the "-U +asterisk", or asterisk may write files with root ownership. In that case you +might not be able to restart the daemon without altering permissions to the +files first. + +Alternatively use '/etc/init.d/asterisk debug'. + +Asterisk is run with a umask of 007 by default, to allow writing +group-owned voicemail files. To change this value, set the value if 'UMASK' +in /etc/default/asterisk . + +Getting started with config and more features +============================================= +Of course the default config is far from a plug'n'play for every environment. +You need to setup a proper dialplan in extensions.conf, remove the demo entries +and maybe remove FreeWorldDialup too in case you don't participate there. For +more info on how to setup a proper dialplan, fax, enum and configuration of +asterisk, please checkout + http://www.voip-info.org/wiki-Asterisk+quickstart + http://www.voip-info.org/wiki-Asterisk+config+files +or the larger HowTos at: + http://www.automated.it/guidetoasterisk.htm +or + http://www.asteriskdocs.org/ (Asterisk Handbook) + + +Open Files Limit +=============== +Asterisk uses one file-handle (and sometimes more) per call. Hence if you +have many simultaneous calls, you often bump into the per-process limit +of 1024 file handles, and get the error: "Too man open files". + +To enlarge that limit, set: MAXFILES in /etc/default/zaptel. + + +Enjoy your PBX! + +Kilian Krause (for the pkg-voip team) --- asterisk-1.4.21.2~dfsg.orig/debian/astman.1 +++ asterisk-1.4.21.2~dfsg/debian/astman.1 @@ -0,0 +1,102 @@ +.\" $Header: /aolnet/dev/src/CVS/sgml/docbook-to-man/cmd/docbook-to-man.sh,v 1.1.1.1 1998/11/13 21:31:59 db3l Exp $ +.\" +.\" transcript compatibility for postscript use. +.\" +.\" synopsis: .P! +.\" +.de P! +.fl +\!!1 setgray +.fl +\\&.\" +.fl +\!!0 setgray +.fl \" force out current output buffer +\!!save /psv exch def currentpoint translate 0 0 moveto +\!!/showpage{}def +.fl \" prolog +.sy sed \-e 's/^/!/' \\$1\" bring in postscript file +\!!psv restore +. +.de pF +.ie \\*(f1 .ds f1 \\n(.f +.el .ie \\*(f2 .ds f2 \\n(.f +.el .ie \\*(f3 .ds f3 \\n(.f +.el .ie \\*(f4 .ds f4 \\n(.f +.el .tm ? font overflow +.ft \\$1 +.. +.de fP +.ie !\\*(f4 \{\ +. ft \\*(f4 +. ds f4\" +' br \} +.el .ie !\\*(f3 \{\ +. ft \\*(f3 +. ds f3\" +' br \} +.el .ie !\\*(f2 \{\ +. ft \\*(f2 +. ds f2\" +' br \} +.el .ie !\\*(f1 \{\ +. ft \\*(f1 +. ds f1\" +' br \} +.el .tm ? font underflow +.. +.ds f1\" +.ds f2\" +.ds f3\" +.ds f4\" +'\" t +.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n +.TH ASTMAN 1 "Jun 12th, 2005" "astman" "Linux Programmer's Manual" +.SH NAME +.B astman +-- a client to asterisk's manager interface +.SH SYNOPSIS +.PP +.B astman +.I hostname + +.SH DESCRIPTION +.B astman +This program is a full-screen (terminal) client for Asterisk's manager +interface. + +.SH OPTIONS +.B hostname + +The host name or IP address to connect to (TCP port 5038). If astman +fails to connect it will exit immidiately. + +.SH USAGE +If \fBastman\fR has successfully cunnected to the manager port it will +prompt the user for a username and a secret (password) for the manager +interface on the remote Asterisk manager interface. It will then be able +to report existing channels (calls). You will then be able to redirect +calls to or terminate them. + +.SH "SEE ALSO" +asterisk(8) + +http://www.voip-info.org/wiki-Asterisk+astman + +.SH BUGS +The hostname does not default to localhost. + +Impossible to use a port other than 5038. + +The username and password cannot be defined from the command-line. + +I mean, what's the point in a man page if the syntax is so simple? + +.SH "AUTHOR" +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common-licenses/GPL. --- asterisk-1.4.21.2~dfsg.orig/debian/autosupport.8 +++ asterisk-1.4.21.2~dfsg/debian/autosupport.8 @@ -0,0 +1,41 @@ +.TH AUTOSUPPORT 8 "Jul 5th, 2005" "Asterisk" "Linux Programmer's Manual" +.SH NAME +.B autosupport +\(em interactive script to provide Digium[tm]'s support with information +.SH SYNOPSIS +.PP +.B autosupport + +.SH DESCRIPTION +.B autoasupport +is a script that is normally run by a user contacting Digium's support +to automate gathering support information. + +It will probe the system for some configuration and run-time information, +and will also prompt the user for some optional access information (IP +address, login and password). + +The information is written to /root/digiuminfo which the user is expected +to attach to a support ticket to Digium. + +The script must be run as root as it reads Asterisk's configuration and +the disk information using hdparm(8). + +.SH FILES +.B /root/digiuminfo +.RS +The output of the script goes there +.RE + +.SH SEE ALSO +asterisk(8) + +.SH "AUTHOR" +autosupport was written by John Bigelow . +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common-licenses/GPL. --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk.default +++ asterisk-1.4.21.2~dfsg/debian/asterisk.default @@ -0,0 +1,78 @@ +# This file allows you to alter the configuration of the Asterisk +# init.d script. Normally you should leave the file as-is. +# +# RUNASTERISK: If set to anything other that 'yes', the asterisk init.d script +# will not run. The default is 'yes'. +#RUNASTERISK=no +# +# +# AST_REALTIME: if set to anything other than "no", asterisk will run in +# real-time priority (pass '-p' to asterisk). un-rem the +# following line to disable asterisk from running in real-time +# priority +#AST_REALTIME=no +# +# PARAMS: extra parameters to pass to asterisk: generate cores in +# case of crash, and be more verbose. -F guarantees that Asterisk +# will still run daemonized. +# +# Instead of adding switches here, consider editing +# /etc/asterisk/asterisk.conf +#PARAMS="-F -g -vvv" +# +# +# RUNASTSAFE: run safe_asterisk rather than asterisk (will auto-restart upon +# crash). This is generally less tested and has some known issues +# with properly starting and stopping Asterisk. +#RUNASTSAFE=yes +# +# ASTSAFE_CONSOLE: whether you want safe_asterisk to spawn a console for Asterisk. +#ASTSAFE_CONSOLE=yes +# +# ASTSAFE_TTY: tty for Asterisk to run on (only for safe_asterisk) +#ASTSAFE_TTY=9 +# +# MAXFILES: Set this to the number of open file handles the Asterisk +# process can have. Useful if you get "Too many open files" error. +#MAXFILES=8192 +# +# AST_DUMPCORE: if set to anything other than "no", asterisk will be run with +# the option -g (to tell it to dump core on crash) and its +# working directory will be set to /var/spool/asterisk, as that +# directory is writable and hence core files can be written there. +# See /etc/init.d/asterisk for some other relevant variables. +# +# It is recommended that you install asterisk-dbg to be able +# to produce meaningful backtraces from the core file. +# +# By default core files will be written to /tmp (can be +# changed by setting AST_DUMPCORE_DIR). Alternatively, see +# CORE_PATTERN below. +#AST_DUMPCORE=yes +# +# AST_DUMPCORE_DIR: By default asterisk runs in the directory '/' like any +# daemon. Setting this allows you to tell it to tell the +# Asterisk daemon to run in a different directory if +# AST_DUMPCORE is enabled. The default is +# /var/spool/asterisk. That is a good choice because it +# is writable (thus enabling the actual writing of the +# core file) but relatively immune to symlink attacks +# (because not world-writable like /tmp/). +# Note, however, that if CORE_PATTERN is an absolute +# path, it will override AST_DUMPCORE_DIR. +# +# CORE_PATTERN: If you use AST_DUMPCORE above, this is optionally set to a +# pattern of the core file. The default is not to touch the +# core_pattern settings, which is generally a good idea as +# it affects every core file generated on your system. +# +# However if you just enable generation of core files and run +# asterisk as a daemon it will fail to write core files. +# +# Alternatively you can set this independently elsewhere. +# See http://lxr.linux.no/source/Documentation/sysctl/kernel.txt +# Here is what Asterisk's ast_grab_core +# script would expect: +#CORE_PATTERN='core.%p' +# But you might prefer something like: +#CORE_PATTERN='core.%e.%t' --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-dev.links +++ asterisk-1.4.21.2~dfsg/debian/asterisk-dev.links @@ -0,0 +1 @@ +usr/include/asterisk/asterisk.h usr/include/asterisk.h --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-config.lintian-overrides +++ asterisk-1.4.21.2~dfsg/debian/asterisk-config.lintian-overrides @@ -0,0 +1 @@ +asterisk-config: non-standard-file-perm --- asterisk-1.4.21.2~dfsg.orig/debian/asterisk-doc.docs +++ asterisk-1.4.21.2~dfsg/debian/asterisk-doc.docs @@ -0,0 +1,9 @@ +BUGS +README +CREDITS +CHANGES +UPGRADE.txt +doc/* +contrib +images/*.gif +images/*.jpg