--- 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 <msp@debian.org>
+# (c) Tzafrir Cohen <tzafrir.cohen@xorcom.com>
+# (c) Faidon Liambotis <paravoid@debian.org>
+
+#   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 <miquels@cistron.nl>.
+#		Modified for Debian GNU/Linux
+#		by Ian Murdock <imurdock@gnu.ai.mit.edu>.
+#
+# 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.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/control
+++ asterisk-1.4.21.2~dfsg/debian/control
@@ -0,0 +1,117 @@
+Source: asterisk
+Priority: optional
+Section: comm
+Maintainer: Debian VoIP Team <pkg-voip-maintainers@lists.alioth.debian.org>
+Uploaders: Mark Purcell <msp@debian.org>, Kilian Krause <kilian@debian.org>, Tzafrir Cohen <tzafrir@debian.org>, Faidon Liambotis <paravoid@debian.org>
+Build-Depends: debhelper (>= 6.0.7), 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), libvpb-dev, zaptel-source (>= 1:1.4.1~0), autotools-dev, libnewt-dev, libsqlite-dev, libspeex-dev, libspeexdsp-dev, graphviz, libcurl4-openssl-dev | libcurl-dev, doxygen, gsfonts, libpopt-dev, libopenh323-dev (>= 1.17.4), libiksemel-dev, libradiusclient-ng-dev, freetds-dev, libvorbis-dev, libsnmp-dev, libc-client2007b-dev, libcap2-dev
+Standards-Version: 3.8.0
+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-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/copyright
+++ asterisk-1.4.21.2~dfsg/debian/copyright
@@ -0,0 +1,272 @@
+This package was debianized by Mark Purcell <msp@debian.org> on
+Fri Apr 19 19:58:40 EST 2002
+
+It is now maintained by the Debian VoIP Team
+<pkg-voip-maintainers@lists.alioth.debian.org>
+
+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 <kpj@junghanns.net> 
+
+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)
+<http://www.debian.org/social_contract#guidelines>.
+
+ * 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 <kpj@junghanns.net>
+
+    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 <kilian@debian.org>
+    Copyright (c) Mark Purcell <msp@debian.org>
+    Copyright (c) Tzafrir Cohen <tzafrir.cohen@xorcom.com>
+    Copyright (c) Faidon Liambotis <paravoid@debian.org>
+ 
+    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 <brg@gladman.me.uk>,
+ Worcester, UK.
+aeskey.c: Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>,
+ Worcester, UK.
+dlfcn.c:Copyright (c) 2002 Jorge Acereda  <jacereda@users.sourceforge.net> &
+                   Peter O'Gorman <ogorman@users.sourceforge.net>
+dns.c: * Copyright (C) 1999 - 2005 Thorsten Lockert
+dnsmgr.c: * Copyright (C) 2005, Kevin P. Fleming
+dsp.c:        Copyright (C) 2001  Steve Underwood <steveu@coppice.org>
+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 <freeman@andrews.edu>
+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 <anthmct@yahoo.com>
+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 <russelb@clemson.edu> 
+funcs/func_db.c: * Copyright (C) 2003, Jefferson Noxon <jeff@debian.org>
+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 <russelb@clemson.edu> 
+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 
+ <dave@popvox.com>
+contrib/scripts/retrieve_extensions_from_sql.pl:# Copyright:   
+ 2004 Peter Nixon <codemonkey@petenixon.net>
+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
+ <Todd.Miller@courtesan.com>
+include/asterisk/aes.h: Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>
+ , Worcester, UK.
+include/asterisk/dlfcn-compat.h:Copyright (c) 2002 Jorge Acereda
+  <jacereda@users.sourceforge.net> &
+  Peter O'Gorman <ogorman@users.sourceforge.net>
+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-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/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.examples
+++ asterisk-1.4.21.2~dfsg/debian/asterisk.examples
@@ -0,0 +1,2 @@
+sample.call
+contrib/scripts/vmail.cgi
--- asterisk-1.4.21.2~dfsg.orig/debian/watch
+++ asterisk-1.4.21.2~dfsg/debian/watch
@@ -0,0 +1,3 @@
+version=3
+opts=dversionmangle=s/\~dfsg//,downloadurlmangle=s/.*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-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
--- 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 <support@digium.com>.
+This manual page was written by Tzafrir Cohen <tzafrir.cohen@xorcom.com> 
+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/compat
+++ asterisk-1.4.21.2~dfsg/debian/compat
@@ -0,0 +1 @@
+5
--- 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 <kilian@debian.org> and Faidon Liambotis <paravoid@debian.org>
+for the Debian VoIP packaging team.
--- asterisk-1.4.21.2~dfsg.orig/debian/rules
+++ asterisk-1.4.21.2~dfsg/debian/rules
@@ -0,0 +1,253 @@
+#!/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
+	dh_lintian -s
+
+	$(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
+	dh_lintian -i
+
+	# 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.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:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+
+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/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-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/changelog
+++ asterisk-1.4.21.2~dfsg/debian/changelog
@@ -0,0 +1,2146 @@
+asterisk (1:1.4.21.2~dfsg-3+lenny5) oldstable-security; urgency=high
+
+  * Patch AST-2011-008: Use strlen rather than ast_str_len (Closes: #633481).
+
+ -- Tzafrir Cohen <tzafrir@debian.org>  Sun, 10 Jul 2011 21:56:22 +0300
+
+asterisk (1:1.4.21.2~dfsg-3+lenny3) oldstable-security; urgency=high
+
+  * Patch AST-2011-008 (CVE-2011-2529) - crash on a malformed SIP packet
+   (Closes: 631446).
+  * AST-2011-010 (CVE-2011-2535): crash due to dereferencing a remote pointer
+    (closes: #631448)
+  * AST-2011-011 (CVE-2011-2536): Don't leak SIP username information
+    (closes: #632029)
+
+ -- Tzafrir Cohen <tzafrir@debian.org>  Tue, 05 Jul 2011 00:08:08 +0300
+
+asterisk (1:1.4.21.2~dfsg-3+lenny2.1) oldstable-security; urgency=high
+
+  * AST-2011-002 (CVE-2011-1147): Multiple crash vulnerabilities in UDPTL code
+    (Closes: #614580).
+  * Patch AST-2011-005 (CVE-2011-1507): Resource exhaustion in Asterisk
+    Manager Interface.
+  * Patch AST-2011-005-p2: Resource exhaustion in chan_skinny and AJAM -
+    second part of the above (Closes: #618790).
+  * Patches AST-2011-003, manager_manager_bugfix_reload - its pre-requirements.
+  * My new @debian.org address
+
+ -- Tzafrir Cohen <tzafrir@debian.org>  Sat, 23 Apr 2011 17:30:13 +0300
+
+asterisk (1:1.4.21.2~dfsg-3+lenny2) oldstable-security; urgency=high
+
+  [ Tzafrir Cohen ]
+  * AST-2011-001/CVE-2011-0495: Stack buffer overflow in SIP channel driver
+    (Closes: #610487)
+  * Backport a one-liner patch from upstream (ast_uri_validhex) to
+    successfully apply the AST-2011-001 patch.
+
+ -- Faidon Liambotis <paravoid@debian.org>  Thu, 10 Feb 2011 17:06:37 +0200
+
+asterisk (1:1.4.21.2~dfsg-3+lenny1) stable-security; urgency=high
+
+  * Multiple security fixes:
+    - "Information leak in IAX2 authentication", AST-2009-001, CVE-2009-0041.
+    - "Remote Crash Vulnerability in SIP channel driver", AST-2009-002.
+    - "SIP responses expose valid usernames", AST-2009-003, CVE-2008-3903.
+      (Closes: #522528)
+    - "SIP responses expose valid usernames", AST-2009-008, CVE-2009-3727.
+      (Closes: #554487)
+    - Stop shipping old static-http code in examples. Among other things, it
+      includes a vulnerable version of the prototype Javascript library.
+      AST-2009-009, CVE-2008-7220. (Closes: #554486)
+    - "RTP Remote Crash Vulnerability", AST-2009-010, CVE-2009-4055.
+      (Closes: #559103)
+
+ -- Faidon Liambotis <paravoid@debian.org>  Mon, 14 Dec 2009 01:11:44 +0200
+
+asterisk (1:1.4.21.2~dfsg-3) unstable; urgency=medium
+
+  [ Faidon Liambotis ]
+  * Fix a segfault that occured on AEL parsing on amd64 systems.
+    (Closes: #507883)
+  * Remove bristuff/app-meetme-avoid-overflows patch as it apparently causes
+    more problems than it solves (if any).
+    (Closes: #505310)
+  * Urgency medium because of the RC bugfix.
+
+  [ Patrick Matthäi ]
+  * Bumped Standards-Version to 3.8.0.
+
+  [ Mark Purcell ]
+  * Update debian/watch
+
+ -- Faidon Liambotis <paravoid@debian.org>  Sun, 04 Jan 2009 21:07:37 +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 <twerner@debian.org>.
+    (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 <paravoid@debian.org>  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 <tim@retout.co.uk>
+  * 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 <paravoid@debian.org>  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 <msp@debian.org>  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 <tzafrir.cohen@xorcom.com>  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 <paravoid@debian.org>  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 <msp@debian.org>  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 <paravoid@debian.org>  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 <paravoid@debian.org>  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 <tzafrir.cohen@xorcom.com>  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 <paravoid@debian.org>  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 <tzafrir.cohen@xorcom.com>  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 <paravoid@debian.org>  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 <paravoid@debian.org>  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 <paravoid@debian.org>  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 <tzafrir.cohen@xorcom.com>  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 <paravoid@debian.org>  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 <paravoid@debian.org>  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 <paravoid@debian.org>  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 <msp@debian.org>  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 &#39;demo-moreinfo&#39;
+    (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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <tzafrir.cohen@xorcom.com>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <tzafrir.cohen@xorcom.com>  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 <msp@debian.org>  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 <tzafrir.cohen@xorcom.com>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <kilian@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <tzafrir.cohen@xorcom.com>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <kilian@debian.org>  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 <tzafrir.cohen@xorcom.com>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <kilian@debian.org>  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 <kilian@debian.org>  Sat, 19 Nov 2005 12:12:51 +0000
+
+asterisk (1:1.2.0.dfsg-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Mark Purcell <msp@debian.org>  Thu, 17 Nov 2005 18:17:02 +0000
+
+asterisk (1:1.2.0-rc2.dfsg-1) experimental; urgency=low
+
+  * New upstream release
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <kilian@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <tzafrir.cohen@xorcom.com>
+    - 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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <kk@verfaction.de>  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 <jsogo@debian.org>  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 <kk@verfaction.de>  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 <msp@debian.org>  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 <kk@nyx.verfaction.de>  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 <kk@verfaction.de>  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 <kk@verfaction.de>  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 <kk@verfaction.de>  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 <johan.thelmen@cygate.se>. (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 <kk@verfaction.de>  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
+    <fw@deneb.enyo.de>. 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 <kk@verfaction.de>  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 <jsogo@debian.org>  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 <jsogo@debian.org>  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 <jsogo@debian.org>  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 <vorlon@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  Wed, 13 Oct 2004 22:31:22 +1000
+
+asterisk (1:1.0.1-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  Sun, 26 Sep 2004 08:32:11 +1000
+
+asterisk (1:1.0.0-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <kk@verfaction.de>  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 <ica2_ts@csv.ica.uni-stuttgart.de>.
+    Should fix the FTBFS on hppa.
+
+ -- Kilian Krause <kk@verfaction.de>  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 <kk@verfaction.de>  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 <kk@verfaction.de>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <pkg-voip-maintainers@lists.alioth.debian.org>
+    Uploaders: Mark Purcell <msp@debian.org>, 
+    Kilian Krause <kk@verfaction.de>,
+    Jose Carlos Garcia Sogo <jsogo@debian.org>, 
+    Goedson Teixeira Paixao <goedson@debian.org>, 
+    Santiago Garcia Mantinan <manty@debian.org>
+  * Next step.  Get this all back into svn!
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  Sat,  3 Jul 2004 22:47:41 +1000
+
+asterisk (1.0-2) unstable; urgency=low
+
+  * Rebuild for new libopenh323-dev
+
+ -- Mark Purcell <msp@debian.org>  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 <jsogo@debian.org>  Tue,  8 Jun 2004 00:10:16 +0200
+
+asterisk (1.0-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Mark Purcell <msp@debian.org>  Mon, 31 May 2004 21:51:18 +1000
+
+asterisk (0.9.0-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  Thu,  5 Feb 2004 17:26:02 +1100
+
+asterisk (0.7.2-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  Fri, 16 Jan 2004 11:46:57 +1100
+
+asterisk (0.7.1-1) unstable; urgency=low
+
+  * New upstream release
+  * i686 optomised build
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <gsm/gsm.h> (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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  Wed, 17 Jul 2002 21:23:33 +1000
+
+asterisk (0.1.12-2) unstable; urgency=low
+
+  * Fixup build check for /etc/asterisk
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  Mon,  8 Jul 2002 23:07:27 +1000
+
+asterisk (0.1.11-5) unstable; urgency=low
+
+  * Include zaptel support (Closes: Bug#151274)
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  Wed, 20 Feb 2002 22:28:35 +1100
+
+asterisk (0.1.10-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Mark Purcell <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 <vela@debian.org>  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 <vela@debian.org>  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 <lamont@smallone.fc.hp.com>  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 <bunk@fs.tum.de>  Tue, 15 May 2001 00:22:31 +0200
+
+asterisk (0.1.6-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Raphael Bossek <bossekr@debian.org>  Mon, 19 Feb 2001 15:48:43 +0100
+
--- 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/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/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.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.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/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/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/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:
+#        * <new-preinst> `install'
+#        * <new-preinst> `install' <old-version>
+#        * <new-preinst> `upgrade' <old-version>
+#        * <old-preinst> `abort-upgrade' <new-version>
+#
+# 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/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/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 <tzafrir.cohen@xorcom.com> 
+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.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-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/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! <file.ps>
+.\"
+.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 <tzafrir.cohen@xorcom.com> 
+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.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:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+
+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/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/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! <file.ps>
+.\"
+.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 <tzafrir.cohen@xorcom.com> 
+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/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 <paravoid@debian.org>  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 <msp@debian.org>  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 <msp@debian.org>  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 
+  <http://www.debian.org/social_contract#guidelines>. Please drop your alternative
+  Music on Hold into the directory /usr/share/asterisk/mohmp3/
+
+ -- Mark Purcell <msp@debian.org>  Sun, 20 Mar 2005 10:30:44 +0000
+
--- 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/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/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/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/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/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 <paravoid@debian.org>
+
+--- 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/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 <linuxmaniac@torreviejawireless.org>
+
+--- 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/AST-2011-006
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2011-006
@@ -0,0 +1,53 @@
+From: Matthew Nicholson <mnicholson@digium.com>
+Date: Thu, 21 Apr 2011 18:19:21 +0000
+Bug: https://issues.asterisk.org/view.php?id=18787
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=314607
+Subject: Check for "system" privilege in the manager interface
+
+This patch is left in the tree bug not applied by default: in 1.4 it
+changes the behaviour (this change was only introduced in 1.6.0).
+
+This fix adds the missing test (added in later version, though apparently
+in a slightly wrong location) for the "system" write permissions in case
+a manager user attempts to execute an action that may eventually execute
+a shell command.
+
+Note that:
+1. In order to explit this one must already gain authenticated access to
+   the manager interface with some sort of write access.
+2. Asterisk is never run as root in Debian (if you use standard init.d
+   script, which slightly reduces the impact of this.
+3. Many poorly-written sample manager.conf config files just give any
+   manager user all priviliges. There's all to big a chance the manager
+   user already has the 'system' write priv (write=system in manager.conf).
+
+See also:
+  http://downloads.asterisk.org/pub/security/AST-2011-006.html
+
+--- a/main/manager.c
++++ b/main/manager.c
+@@ -2003,6 +2003,24 @@ static int action_originate(struct manse
+ 			l = NULL;
+ 	}
+  	uniqueid = ast_alloc_uniqueid();
++	if (!ast_strlen_zero(app)) {
++		/* To run the System application (or anything else that goes to
++		 * shell), you must have the additional System privilege */
++		if (!(s->writeperm & EVENT_FLAG_SYSTEM)
++			&& (
++				strcasestr(app, "system") == 0 || /* System(rm -rf /)
++				                                     TrySystem(rm -rf /)       */
++				strcasestr(app, "exec") ||        /* Exec(System(rm -rf /))
++				                                     TryExec(System(rm -rf /)) */
++				strcasestr(app, "agi") ||         /* AGI(/bin/rm,-rf /)
++				                                     EAGI(/bin/rm,-rf /)       */
++				strstr(appdata, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
++				strstr(appdata, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
++				)) {
++			astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
++			return 0;
++		}
++	}
+ 	if (ast_true(async)) {
+ 		struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
+ 		if (!fast) {
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/manager_bugfix_reload
+++ asterisk-1.4.21.2~dfsg/debian/patches/manager_bugfix_reload
@@ -0,0 +1,67 @@
+From: Brett Bryant <bbryant@digium.com>
+Date: Thu, 2 Sep 2010 20:25:03 +0000
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=284777
+Bug: https://issues.asterisk.org/view.php?id=17917
+Subject: Properly reset default manager.conf values on reload
+
+Fixes a bug in manager.c where the default configuration values weren't
+reset when the manager configuration was reloaded.
+
+This is a simple bugfix required for cleanly applying AST-2011-005
+
+---
+ main/manager.c |   28 +++++++++++++++++++++-------
+ 1 files changed, 21 insertions(+), 7 deletions(-)
+
+--- a/main/manager.c
++++ b/main/manager.c
+@@ -99,12 +99,21 @@ struct eventqent {
+ 	char eventdata[1];
+ };
+ 
++static const int DEFAULT_ENABLED			= 0;	/*!< Default setting for manager to be enabled */
++static const int DEFAULT_WEBENABLED			= 0;	/*!< Default setting for the web interface to be enabled */
++static const int DEFAULT_BLOCKSOCKETS		= 0;	/*!< Default setting for block-sockets */
++static const int DEFAULT_DISPLAYCONNECTS	= 1;	/*!< Default setting for displaying manager connections */
++static const int DEFAULT_TIMESTAMPEVENTS	= 0;	/*!< Default setting for timestampevents */	
++static const int DEFAULT_HTTPTIMEOUT 		= 60;	/*!< Default manager http timeout */
++static const int DEFAULT_BROKENEVENTSACTION	= 0;	/*!< Default setting for brokeneventsaction */
++
++
+ static int enabled;
+ static int portno = DEFAULT_MANAGER_PORT;
+ static int asock = -1;
+-static int displayconnects = 1;
++static int displayconnects;
+ static int timestampevents;
+-static int httptimeout = 60;
++static int httptimeout;
+ 
+ static pthread_t t;
+ static int block_sockets;
+@@ -2989,8 +2998,8 @@ int init_manager(void)
+ 	static struct sockaddr_in ba;
+ 	int x = 1;
+ 	int flags;
+-	int webenabled = 0;
+-	int newhttptimeout = 60;
++	int webenabled = DEFAULT_WEBENABLED;
++	int newhttptimeout = DEFAULT_HTTPTIMEOUT;
+ 	struct ast_manager_user *user = NULL;
+ 
+ 	if (!registered) {
+@@ -3022,8 +3031,13 @@ int init_manager(void)
+ 		/* Append placeholder event so master_eventq never runs dry */
+ 		append_event("Event: Placeholder\r\n\r\n", 0);
+ 	}
++
+ 	portno = DEFAULT_MANAGER_PORT;
+-	displayconnects = 1;
++	displayconnects = DEFAULT_DISPLAYCONNECTS;
++	block_sockets = DEFAULT_BLOCKSOCKETS;
++	timestampevents = DEFAULT_TIMESTAMPEVENTS;
++	httptimeout = DEFAULT_HTTPTIMEOUT;
++
+ 	cfg = ast_config_load("manager.conf");
+ 	if (!cfg) {
+ 		ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf.  Call management disabled.\n");
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/AST-2011-011
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2011-011
@@ -0,0 +1,40 @@
+From 63f92c985f212e59f56bb95b0c1bb02347195fea Mon Sep 17 00:00:00 2001
+From: Terry Wilson <twilson@digium.com>
+Date: Tue, 28 Jun 2011 20:03:19 +0000
+Subject: [PATCH] Don't leak SIP username information
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=325275
+
+Asterisk may respond differently to SIP requests from an invalid SIP
+user than it does to a user configured on the system, even when the
+alwaysauthreject option is set in the configuration. This can leak
+information about what SIP users are valid on the Asterisk system.
+
+Note: while alwaysauthreject=yes is not the default on 1.4 and 1.6.2 for
+backword-compatibility considerations, it is highly recommended to set it
+so.
+
+CVE: CVE-2011-2536
+See also: http://downloads.asterisk.org/pub/security/AST-2011-011.html
+---
+ channels/chan_sip.c |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/channels/chan_sip.c
++++ b/channels/chan_sip.c
+@@ -8670,14 +8670,14 @@ static void transmit_fake_auth_response(
+ 	if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
+ 		/* This is a retransmitted invite/register/etc, don't reconstruct authentication
+ 		 * information */
+-		transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
++		transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+ 		/* Schedule auto destroy in 32 seconds (according to RFC 3261) */
+ 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ 		return;
+ 	} else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
+ 		/* We have no auth, so issue challenge and request authentication */
+ 		ast_string_field_build(p, randdata, "%08lx", ast_random());	/* Create nonce for challenge */
+-		transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
++		transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+ 		/* Schedule auto destroy in 32 seconds */
+ 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ 		return;
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/AST-2011-002
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2011-002
@@ -0,0 +1,110 @@
+Subject: Multiple array overflow and crash vulnerabilities in UDPTL code
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=308506
+
+When decoding UDPTL packets, multiple stack and heap based arrays can be
+made to overflow by specially crafted packets. Systems doing T.38 pass
+through or termination are vulnerable.
+
+See also: http://downloads.asterisk.org/pub/security/AST-2011-002.html
+---
+ main/udptl.c |   49 +++++++++++++++++++++++--------------------------
+ 1 files changed, 23 insertions(+), 26 deletions(-)
+
+diff --git a/main/udptl.c b/main/udptl.c
+index 76b4a14..77946f0 100644
+--- a/main/udptl.c
++++ b/main/udptl.c
+@@ -175,37 +175,31 @@ static int decode_length(uint8_t *buf, int limit, int *len, int *pvalue)
+ 	}
+ 	*pvalue = (buf[*len] & 0x3F) << 14;
+ 	(*len)++;
+-	/* Indicate we have a fragment */
++	/* We have a fragment.  Currently we don't process fragments. */
++	if (option_debug) {
++		ast_log(LOG_DEBUG, "UDPTL packet with length greater than 16K received, decoding will fail\n");
++	}
+ 	return 1;
+ }
+ /*- End of function --------------------------------------------------------*/
+ 
+ static int decode_open_type(uint8_t *buf, int limit, int *len, const uint8_t **p_object, int *p_num_octets)
+ {
+-	int octet_cnt;
+-	int octet_idx;
+-	int stat;
+-	int i;
+-	const uint8_t **pbuf;
++	int octet_cnt = 0;
+ 
+-	for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt) {
+-		if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
+-			return -1;
+-		if (octet_cnt > 0) {
+-			*p_num_octets += octet_cnt;
++	if (decode_length(buf, limit, len, &octet_cnt) != 0)
++		return -1;
+ 
+-			pbuf = &p_object[octet_idx];
+-			i = 0;
+-			/* Make sure the buffer contains at least the number of bits requested */
+-			if ((*len + octet_cnt) > limit)
+-				return -1;
++	if (octet_cnt > 0) {
++		/* Make sure the buffer contains at least the number of bits requested */
++		if ((*len + octet_cnt) > limit)
++			return -1;
+ 
+-			*pbuf = &buf[*len];
+-			*len += octet_cnt;
+-		}
+-		if (stat == 0)
+-			break;
++		*p_num_octets = octet_cnt;
++		*p_object = &buf[*len];
++		*len += octet_cnt;
+ 	}
++
+ 	return 0;
+ }
+ /*- End of function --------------------------------------------------------*/
+@@ -290,8 +284,8 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len)
+ 	const uint8_t *data;
+ 	int ifp_len;
+ 	int repaired[16];
+-	const uint8_t *bufs[16];
+-	int lengths[16];
++	const uint8_t *bufs[ARRAY_LEN(s->f) - 1];
++	int lengths[ARRAY_LEN(s->f) - 1];
+ 	int span;
+ 	int entries;
+ 	int ifp_no;
+@@ -321,13 +315,13 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len)
+ 			do {
+ 				if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
+ 					return -1;
+-				for (i = 0; i < count; i++) {
++				for (i = 0; i < count && total_count + i < ARRAY_LEN(bufs); i++) {
+ 					if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
+ 						return -1;
+ 				}
+-				total_count += count;
++				total_count += i;
+ 			}
+-			while (stat2 > 0);
++			while (stat2 > 0 && total_count < ARRAY_LEN(bufs));
+ 			/* Step through in reverse order, so we go oldest to newest */
+ 			for (i = total_count; i > 0; i--) {
+ 				if (seq_no - i >= s->rx_seq_no) {
+@@ -390,6 +384,9 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len)
+ 		if (ptr + 1 > len)
+ 			return -1;
+ 		entries = buf[ptr++];
++		if (entries > MAX_FEC_ENTRIES) {
++			return -1;
++		}
+ 		s->rx[x].fec_entries = entries;
+ 
+ 		/* Decode the elements */
+-- 
+1.7.2.3
+
--- 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 <zaptel/tonezone.h>
+ 
+ #ifdef HAVE_PRI
+-#include <libpri.h>
++#include <bristuffed/libpri.h>
+ #endif
+ 
+ #include "asterisk/lock.h"
--- 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 <tzafrir.cohen@xorcom.com>
+
+--- 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/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 <paravoid@debian.org>
+
+--- 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/AST-2009-008
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2009-008
@@ -0,0 +1,13 @@
+Index: channels/chan_sip.c
+===================================================================
+--- a/channels/chan_sip.c	(revision 226137)
++++ b/channels/chan_sip.c	(working copy)
+@@ -9346,8 +9346,6 @@
+ 			   Asterisk uses the From: username for authentication. We need the
+ 			   users to use the same authentication user name until we support
+ 			   proper authentication by digest auth name */
+-			transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
+-			break;
+ 		case AUTH_NOT_FOUND:
+ 		case AUTH_PEER_NOT_DYNAMIC:
+ 		case AUTH_ACL_FAILED:
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/AST-2011-008
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2011-008
@@ -0,0 +1,30 @@
+From: Kinsey Moore <kmoore@digium.com>
+Date: Thu, 23 Jun 2011 18:21:12 +0000
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=324643
+Subject: Addresses AST-2011-008, memory corruption and remote crash in SIP driver.
+
+If a remote user sends a SIP packet containing a null, Asterisk assumes
+available data extends past the null to the end of the packet when the
+buffer is actually truncated when copied.  This causes SIP header parsing
+to modify data past the end of the buffer altering unrelated memory
+structures.  This vulnerability does not affect TCP/TLS connections.
+
+CVE: CVE-2011-2529
+See also http://downloads.asterisk.org/pub/security/AST-2011-008.html
+
+---
+ channels/chan_sip.c |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+--- a/channels/chan_sip.c
++++ b/channels/chan_sip.c
+@@ -15907,7 +15907,8 @@ static int sipsock_read(int *id, int fd,
+ 		ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
+ 
+ 	req.data[res] = '\0';
+-	req.len = res;
++	/* req.data will have the correct length in case of nulls */
++	req.len = strlen(req.data);
+ 	if(sip_debug_test_addr(&sin))	/* Set the debug flag early on packet level */
+ 		ast_set_flag(&req, SIP_PKT_DEBUG);
+ 	if (pedanticsipchecking)
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/series
+++ asterisk-1.4.21.2~dfsg/debian/patches/series
@@ -0,0 +1,112 @@
+### 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
+
+ael-segfault-fix
+
+### 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/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
+
+### lenny fixes
+AST-2009-001
+
+r132790
+AST-2009-002
+
+r171264
+AST-2009-003
+
+AST-2009-008
+
+AST-2009-010
+ast_uri_validhex
+AST-2011-001
+AST-2011-002
+AST-2011-003
+manager_bugfix_reload
+AST-2011-005
+AST-2011-005-p2
+AST-2011-008
+AST-2011-010
+AST-2011-011
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/AST-2011-001
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2011-001
@@ -0,0 +1,56 @@
+From: Leif Madsen <lmadsen@digium.com>
+Date: Mon, 17 Jan 2011 18:57:55 +0000
+Subject: [PATCH] AST-2011-001
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=302145
+---
+ main/utils.c                 |   27 ++--
+
+diff --git a/main/utils.c b/main/utils.c
+index a9b8872..5fbf755 100644
+--- a/main/utils.c
++++ b/main/utils.c
+@@ -387,28 +387,27 @@ char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserve
+ 	char *reserved = ";/?:@&=+$,# ";	/* Reserved chars */
+ 
+  	const char *ptr  = string;	/* Start with the string */
+-	char *out = NULL;
+-	char *buf = NULL;
++	char *out = outbuf;
+ 
+-	ast_copy_string(outbuf, string, buflen);
+-
+-	/* If there's no characters to convert, just go through and don't do anything */
+-	while (*ptr) {
++	/* If there's no characters to convert, just go through and copy the string */
++	while (*ptr && out - outbuf < buflen - 1) {
+ 		if ((*ptr < 32) || (doreserved && strchr(reserved, *ptr))) {
+-			/* Oops, we need to start working here */
+-			if (!buf) {
+-				buf = outbuf;
+-				out = buf + (ptr - string) ;	/* Set output ptr */
++			if (out - outbuf >= buflen - 3) {
++				break;
+ 			}
++
+ 			out += sprintf(out, "%%%02x", (unsigned char) *ptr);
+-		} else if (buf) {
+-			*out = *ptr;	/* Continue copying the string */
++		} else {
++			*out = *ptr;	/* copy the character */
+ 			out++;
+-		} 
++		}
+ 		ptr++;
+ 	}
+-	if (buf)
++
++	if (buflen) {
+ 		*out = '\0';
++	}
++
+ 	return outbuf;
+ }
+ 
+-- 
+1.7.2.3
+
--- 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 <lionel@mamane.lu>
+
+--- 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/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 <paravoid@debian.org>
+
+--- /dev/null
++++ b/funcs/func_devstate.c
+@@ -0,0 +1,228 @@
++/*
++ * Asterisk -- An open source telephony toolkit.
++ *
++ * Copyright (C) 2007, Digium, Inc.
++ *
++ * Russell Bryant <russell@digium.com> 
++ *
++ * 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 <russell@digium.com> 
++ *
++ * \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 <stdlib.h>
++
++#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/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 <tzafrir.cohen@xorcom.com>
+
+Also fix the Makefile to copy all keys on make install instead of mentioning
+them explicitely.
+
+Forwarded as a note to #10811.
+
+ -- Faidon Liambotis <paravoid@debian.org>
+
+--- /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/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 <paravoid@debian.org>
+
+--- 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-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 <paravoid@debian.org>
+
+--- 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/AST-2011-005
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2011-005
@@ -0,0 +1,247 @@
+From: Matthew Nicholson <mnicholson@digium.com>
+Date: Tue, 5 Apr 2011 14:10:34 +0000
+Subject:  Limit the number of unauthenticated manager and their time
+Bug: https://issues.asterisk.org/view.php?id=18996
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=312761
+
+Keeping many open manager connections at the initial unauthenticated
+stage can cause Asterisk to exhaust available CPU and memory resources.
+
+The manager interface is disabled by default in upstream, but enabled
+by default (listening on localhost only) in the version in Debian 5.0 (Lenny)
+and 6.0 (Squeeze).
+
+See also http://downloads.asterisk.org/pub/security/AST-2011-005.html
+
+---
+ configs/manager.conf.sample |   11 +++++
+ main/manager.c              |   87 +++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 95 insertions(+), 3 deletions(-)
+
+--- a/configs/manager.conf.sample
++++ b/configs/manager.conf.sample
+@@ -26,6 +26,17 @@ enabled = no
+ ;webenabled = yes
+ port = 5038
+ 
++; authtimeout specifies the maximum number of seconds a client has to
++; authenticate.  If the client does not authenticate beofre this timeout
++; expires, the client will be disconnected. (default: 30 seconds)
++
++;authtimeout = 30
++
++; authlimit specifies the maximum number of unauthenticated sessions that will
++; be allowed to connect at any given time.
++
++;authlimit = 50
++
+ ;httptimeout = 60
+ ; a) httptimeout sets the Max-Age of the http cookie
+ ; b) httptimeout is the amount of time the webserver waits 
+--- a/main/manager.c
++++ b/main/manager.c
+@@ -106,6 +106,8 @@ static const int DEFAULT_DISPLAYCONNECTS
+ static const int DEFAULT_TIMESTAMPEVENTS	= 0;	/*!< Default setting for timestampevents */	
+ static const int DEFAULT_HTTPTIMEOUT 		= 60;	/*!< Default manager http timeout */
+ static const int DEFAULT_BROKENEVENTSACTION	= 0;	/*!< Default setting for brokeneventsaction */
++static const int DEFAULT_AUTHTIMEOUT		= 30;	/*!< Default setting for authtimeout */
++static const int DEFAULT_AUTHLIMIT		= 50;	/*!< Default setting for authlimit */
+ 
+ 
+ static int enabled;
+@@ -114,10 +116,13 @@ static int asock = -1;
+ static int displayconnects;
+ static int timestampevents;
+ static int httptimeout;
++static int authtimeout;
++static int authlimit;
+ 
+ static pthread_t t;
+ static int block_sockets;
+ static int num_sessions;
++static int unauth_sessions = 0;
+ 
+ /* Protected by the sessions list lock */
+ struct eventqent *master_eventq = NULL;
+@@ -193,6 +198,7 @@ struct mansession {
+ 	struct eventqent *eventq;
+ 	/* Timeout for ast_carefulwrite() */
+ 	int writetimeout;
++	time_t authstart;
+ 	int pending_event;         /*!< Pending events indicator in case when waiting_thread is NULL */
+ 	AST_LIST_ENTRY(mansession) list;
+ 	int write_error:1;
+@@ -2290,6 +2296,7 @@ static int process_message(struct manses
+ 				return -1;
+ 			} else {
+ 				s->authenticated = 1;
++				ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ 				if (option_verbose > 1) {
+ 					if (displayconnects) {
+ 						ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", 
+@@ -2336,6 +2343,8 @@ static int get_input(struct mansession *
+ 	int res;
+ 	int x;
+ 	struct pollfd fds[1];
++	int timeout = -1;
++	time_t now;
+ 	for (x = 1; x < s->inlen; x++) {
+ 		if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
+ 			/* Copy output data up to and including \r\n */
+@@ -2354,7 +2363,22 @@ static int get_input(struct mansession *
+ 	}
+ 	fds[0].fd = s->fd;
+ 	fds[0].events = POLLIN;
++
+ 	do {
++		/* calculate a timeout if we are not authenticated */
++		if (!s->authenticated) {
++			if(time(&now) == -1) {
++				ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++				return -1;
++			}
++
++			timeout = (authtimeout - (now - s->authstart)) * 1000;
++			if (timeout < 0) {
++				/* we have timed out */
++				return 0;
++			}
++		}
++
+ 		ast_mutex_lock(&s->__lock);
+ 		if (s->pending_event) {
+ 			s->pending_event = 0;
+@@ -2364,7 +2388,7 @@ static int get_input(struct mansession *
+ 		s->waiting_thread = pthread_self();
+ 		ast_mutex_unlock(&s->__lock);
+ 
+-		res = poll(fds, 1, -1);
++		res = poll(fds, 1, timeout);
+ 
+ 		ast_mutex_lock(&s->__lock);
+ 		s->waiting_thread = AST_PTHREADT_NULL;
+@@ -2382,6 +2406,9 @@ static int get_input(struct mansession *
+ 			if (res < 1)
+ 				return -1;
+ 			break;
++		} else {
++			/* timeout */
++			return 0;
+ 		}
+ 	} while(1);
+ 	s->inlen += res;
+@@ -2394,6 +2421,7 @@ static int do_message(struct mansession
+ 	struct message m = { 0 };
+ 	char header_buf[sizeof(s->inbuf)] = { '\0' };
+ 	int res;
++	time_t now;
+ 
+ 	for (;;) {
+ 		/* Check if any events are pending and do them if needed */
+@@ -2403,6 +2431,17 @@ static int do_message(struct mansession
+ 		}
+ 		res = get_input(s, header_buf);
+ 		if (res == 0) {
++			if (!s->authenticated) {
++				if(time(&now) == -1) {
++					ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++					return -1;
++				}
++
++				if (now - s->authstart > authtimeout) {
++					ast_log(LOG_EVENT, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->sin.sin_addr), authtimeout);
++					return -1;
++				}
++			}
+ 			continue;
+ 		} else if (res > 0) {
+ 			/* Strip trailing \r\n */
+@@ -2436,6 +2475,7 @@ static void *session_do(void *data)
+ 		}
+ 		ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
+ 	} else {
++		ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ 		if (option_verbose > 1) {
+ 			if (displayconnects)
+ 				ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
+@@ -2515,14 +2555,25 @@ static void *accept_thread(void *ignore)
+ 			ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
+ 			continue;
+ 		}
++
++		if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
++			close(as);
++			ast_atomic_fetchadd_int(&unauth_sessions, -1);
++			ast_log(LOG_WARNING, "manager connection rejected, too many unauthenticated sessions.\n");
++			continue;
++		}
++
+ 		p = getprotobyname("tcp");
+ 		if (p) {
+ 			if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
+ 				ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
+ 			}
+ 		}
+-		if (!(s = ast_calloc(1, sizeof(*s))))
++		if (!(s = ast_calloc(1, sizeof(*s)))) {
++			close(as);
++			ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ 			continue;
++		}
+ 
+ 		memcpy(&s->sin, &sin, sizeof(sin));
+ 		s->writetimeout = 100;
+@@ -2549,8 +2600,16 @@ static void *accept_thread(void *ignore)
+ 			s->eventq = s->eventq->next;
+ 		ast_atomic_fetchadd_int(&s->eventq->usecount, 1);
+ 		AST_LIST_UNLOCK(&sessions);
+-		if (ast_pthread_create_background(&s->t, &attr, session_do, s))
++		if(time(&s->authstart) == -1) {
++			ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
++			ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ 			destroy_session(s);
++			continue;
++		}
++		if (ast_pthread_create_background(&s->t, &attr, session_do, s)) {
++			ast_atomic_fetchadd_int(&unauth_sessions, -1);
++			destroy_session(s);
++		}
+ 	}
+ 	pthread_attr_destroy(&attr);
+ 	return NULL;
+@@ -3037,6 +3096,8 @@ int init_manager(void)
+ 	block_sockets = DEFAULT_BLOCKSOCKETS;
+ 	timestampevents = DEFAULT_TIMESTAMPEVENTS;
+ 	httptimeout = DEFAULT_HTTPTIMEOUT;
++	authtimeout = DEFAULT_AUTHTIMEOUT;
++	authlimit = DEFAULT_AUTHLIMIT;
+ 
+ 	cfg = ast_config_load("manager.conf");
+ 	if (!cfg) {
+@@ -3071,6 +3132,26 @@ int init_manager(void)
+ 	if ((val = ast_variable_retrieve(cfg, "general", "httptimeout")))
+ 		newhttptimeout = atoi(val);
+ 
++	if ((val = ast_variable_retrieve(cfg, "general", "authtimeout"))) {
++		int timeout = atoi(val);
++
++		if (timeout < 1) {
++			ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", val);
++		} else {
++			authtimeout = timeout;
++		}
++	}
++
++	if ((val = ast_variable_retrieve(cfg, "general", "authlimit"))) {
++		int limit = atoi(val);
++
++		if (limit < 1) {
++			ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", val);
++		} else {
++			authlimit = limit;
++		}
++	}
++
+ 	memset(&ba, 0, sizeof(ba));
+ 	ba.sin_family = AF_INET;
+ 	ba.sin_port = htons(portno);
--- 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 <paravoid@debian.org>
+
+--- 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/AST-2011-010
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2011-010
@@ -0,0 +1,71 @@
+From: David Vossel <dvossel@digium.com>
+Date: Thu, 23 Jun 2011 18:16:52 +0000
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=324627
+Subject: Addresses AST-2011-010, crash due to dereferencing a remote pointer
+
+A memory address was inadvertently transmitted over the network via
+IAX2 via an option control frame and the remote party would try to access it.
+
+CVE: CVE-2011-2535
+See also: http://downloads.asterisk.org/pub/security/AST-2011-010.html
+---
+ channels/chan_iax2.c |   14 +++++++++++++-
+ res/res_features.c   |   15 ++++++++++++---
+ 2 files changed, 25 insertions(+), 4 deletions(-)
+
+--- a/channels/chan_iax2.c
++++ b/channels/chan_iax2.c
+@@ -3414,7 +3414,14 @@ static int iax2_setoption(struct ast_cha
+ 		/* these two cannot be sent, because they require a result */
+ 		errno = ENOSYS;
+ 		return -1;
+-	default:
++ 	/* These options are sent to the other side across the network where
++ 	 * they will be passed to whatever channel is bridged there. Don't
++ 	 * do anything silly like pass an option that transmits pointers to
++ 	 * memory on this machine to a remote machine to use */
++ 	case AST_OPTION_TONE_VERIFY:
++ 	case AST_OPTION_TDD:
++ 	case AST_OPTION_RELAXDTMF:
++ 	case AST_OPTION_AUDIO_MODE:
+ 		if (!(h = ast_malloc(datalen + sizeof(*h))))
+ 			return -1;
+ 
+@@ -3426,7 +3433,12 @@ static int iax2_setoption(struct ast_cha
+ 					  datalen + sizeof(*h), -1);
+ 		free(h);
+ 		return res;
++	default:
++		return -1;
+ 	}
++
++	/* Just in case someone does a break instead of a return */
++	return -1;
+ }
+ 
+ static struct ast_frame *iax2_read(struct ast_channel *c) 
+--- a/res/res_features.c
++++ b/res/res_features.c
+@@ -1590,10 +1590,19 @@ int ast_bridge_call(struct ast_channel *
+ 				break;
+ 			case AST_CONTROL_OPTION:
+ 				aoh = f->data;
+-				/* Forward option Requests */
++ 				/* Forward option Requests, but only ones we know are safe
++ 				 * These are ONLY sent by chan_iax2 and I'm not convinced that
++ 				 * they are useful. I haven't deleted them entirely because I
++ 				 * just am not sure of the ramifications of removing them. */
+ 				if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
+-					ast_channel_setoption(other, ntohs(aoh->option), aoh->data, 
+-						f->datalen - sizeof(struct ast_option_header), 0);
++ 				   	switch (ntohs(aoh->option)) {
++ 					case AST_OPTION_TONE_VERIFY:
++ 					case AST_OPTION_TDD:
++ 					case AST_OPTION_RELAXDTMF:
++ 					case AST_OPTION_AUDIO_MODE:
++						ast_channel_setoption(other, ntohs(aoh->option), aoh->data, 
++							f->datalen - sizeof(struct ast_option_header), 0);
++					}
+ 				}
+ 				break;
+ 			}
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/ast_uri_validhex
+++ asterisk-1.4.21.2~dfsg/debian/patches/ast_uri_validhex
@@ -0,0 +1,31 @@
+Subject: [PATCH] hex escape control and non 7-bit clean characters in uri_encode
+From: David Vossel <dvossel@digium.com>
+Date: Mon, 7 Dec 2009 23:24:59 +0000
+Bug: https://issues.asterisk.org/view.php?id=16299
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=233609
+
+In ast_uri_encode, non 7-bit clean characters were being hex escaped
+correctly, but control characters were not.
+
+Adding this one for the moment to help AST-2011-001 build.
+
+---
+ main/utils.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/main/utils.c b/main/utils.c
+index 97991ef..f835e11 100644
+--- a/main/utils.c
++++ b/main/utils.c
+@@ -394,7 +394,7 @@ char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserve
+ 
+ 	/* If there's no characters to convert, just go through and don't do anything */
+ 	while (*ptr) {
+-		if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
++		if ((*ptr < 32) || (doreserved && strchr(reserved, *ptr))) {
+ 			/* Oops, we need to start working here */
+ 			if (!buf) {
+ 				buf = outbuf;
+-- 
+1.7.2.3
+
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/AST-2009-001
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2009-001
@@ -0,0 +1,256 @@
+Index: channels/chan_iax2.c
+===================================================================
+--- a/channels/chan_iax2.c	(revision 166591)
++++ b/channels/chan_iax2.c	(working copy)
+@@ -155,6 +155,7 @@
+ static int authdebug = 1;
+ static int autokill = 0;
+ static int iaxcompat = 0;
++static int last_authmethod = 0;
+ 
+ static int iaxdefaultdpcache=10 * 60;	/* Cache dialplan entries for 10 minutes by default */
+ 
+@@ -228,10 +229,9 @@
+ static ast_cond_t sched_cond;
+ 
+ enum {
+-	IAX_STATE_STARTED = 		(1 << 0),
+-	IAX_STATE_AUTHENTICATED = 	(1 << 1),
+-	IAX_STATE_TBD = 		(1 << 2),
+-	IAX_STATE_UNCHANGED = 		(1 << 3),
++	IAX_STATE_STARTED =			(1 << 0),
++	IAX_STATE_AUTHENTICATED =	(1 << 1),
++	IAX_STATE_TBD =				(1 << 2),
+ } iax2_state;
+ 
+ struct iax2_context {
+@@ -512,7 +512,7 @@
+ 	/*! The jitterbuffer */
+         jitterbuf *jb;
+ 	/*! active jb read scheduler id */
+-        int jbid;                       
++        int jbid;
+ 	/*! LAG */
+ 	int lag;
+ 	/*! Error, as discovered by the manager */
+@@ -568,7 +568,8 @@
+ 		AST_STRING_FIELD(mohinterpret);
+ 		AST_STRING_FIELD(mohsuggest);
+ 	);
+-	
++	/*! AUTHREJ all AUTHREP frames */
++	int authrej;
+ 	/*! permitted authentication methods */
+ 	int authmethods;
+ 	/*! permitted encryption methods */
+@@ -5400,6 +5401,18 @@
+ 			ast_string_field_set(iaxs[callno], secret, user->secret);
+ 		res = 0;
+ 		user = user_unref(user);
++	} else {
++		 /* user was not found, but we should still fake an AUTHREQ.
++		  * Set authmethods to the last known authmethod used by the system
++		  * Set a fake secret, it's not looked at, just required to attempt authentication.
++		  * Set authrej so the AUTHREP is rejected without even looking at its contents */
++		iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
++		ast_string_field_set(iaxs[callno], secret, "badsecret");
++		iaxs[callno]->authrej = 1;
++		if (!ast_strlen_zero(iaxs[callno]->username)) {
++			/* only send the AUTHREQ if a username was specified. */
++			res = 0;
++		}
+ 	}
+ 	ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);	
+ 	return res;
+@@ -5506,6 +5519,9 @@
+ 		.name = p->username,	
+ 	};
+ 
++	if (p->authrej) {
++		return res;
++	}
+ 	user = ao2_find(users, &tmp_user, OBJ_POINTER);
+ 	if (user) {
+ 		if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
+@@ -5583,7 +5599,7 @@
+ 	int expire = 0;
+ 	int res = -1;
+ 
+-	ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
++	ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
+ 	/* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
+ 	if (ies->username)
+ 		ast_copy_string(peer, ies->username, sizeof(peer));
+@@ -5606,8 +5622,29 @@
+ 	p = find_peer(peer, 1);
+ 	ast_mutex_lock(&iaxsl[callno]);
+ 	if (!p || !iaxs[callno]) {
++		if (iaxs[callno]) {
++			int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
++
++			ast_string_field_set(iaxs[callno], secret, "badsecret");
++
++			/* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
++			 * 1. A challenge already exists indicating a AUTHREQ was already sent out.
++			 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
++			 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
++			 *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
++			 *
++			 * If none of these cases exist, res will be returned as 0 without authentication indicating
++			 * an AUTHREQ needs to be sent out. */
++
++			if (ast_strlen_zero(iaxs[callno]->challenge) &&
++				!(!ast_strlen_zero(secret) && plaintext)) {
++				/* by setting res to 0, an REGAUTH will be sent */
++				res = 0;
++			}
++		}
+ 		if (authdebug && !p)
+ 			ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
++
+ 		goto return_unref;
+ 	}
+ 
+@@ -5622,8 +5659,6 @@
+ 			ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
+ 		goto return_unref;
+ 	}
+-	if (!inaddrcmp(&p->addr, sin))
+-		ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
+ 	ast_string_field_set(iaxs[callno], secret, p->secret);
+ 	ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
+ 	/* Check secret against what we have on file */
+@@ -5639,7 +5674,7 @@
+ 				if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
+ 					ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
+ 					break;
+-				} else if (!key) 
++				} else if (!key)
+ 					ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
+ 				keyn = strsep(&stringp, ":");
+ 			}
+@@ -5657,7 +5692,7 @@
+ 		struct MD5Context md5;
+ 		unsigned char digest[16];
+ 		char *tmppw, *stringp;
+-		
++
+ 		tmppw = ast_strdupa(p->secret);
+ 		stringp = tmppw;
+ 		while((tmppw = strsep(&stringp, ";"))) {
+@@ -5667,7 +5702,7 @@
+ 			MD5Final(digest, &md5);
+ 			for (x=0;x<16;x++)
+ 				sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
+-			if (!strcasecmp(requeststr, md5secret)) 
++			if (!strcasecmp(requeststr, md5secret))
+ 				break;
+ 		}
+ 		if (tmppw) {
+@@ -5685,24 +5720,25 @@
+ 			goto return_unref;
+ 		} else
+ 			ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
+-	} else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
+-		if (authdebug)
+-			ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
++	} else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
++		/* if challenge has been sent, but no challenge response if given, reject. */
+ 		goto return_unref;
+ 	}
+-	ast_string_field_set(iaxs[callno], peer, peer);
+-	/* Choose lowest expiry number */
+-	if (expire && (expire < iaxs[callno]->expiry)) 
+-		iaxs[callno]->expiry = expire;
+-
+ 	ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
+ 
++	/* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
+ 	res = 0;
++return_unref:
++	if (iaxs[callno]) {
++		ast_string_field_set(iaxs[callno], peer, peer);
++	}
++	/* Choose lowest expiry number */
++	if (expire && (expire < iaxs[callno]->expiry)) {
++		iaxs[callno]->expiry = expire;
++	}
+ 
+-return_unref:
+ 	if (p)
+ 		peer_unref(p);
+-
+ 	return res;
+ }
+ 
+@@ -6375,24 +6411,33 @@
+ 	struct iax2_peer *p;
+ 	char challenge[10];
+ 	const char *peer_name;
+-	int res = -1;
++	int sentauthmethod;
+ 
+ 	peer_name = ast_strdupa(iaxs[callno]->peer);
+ 
+ 	/* SLD: third call to find_peer in registration */
+ 	ast_mutex_unlock(&iaxsl[callno]);
+-	p = find_peer(peer_name, 1);
++	if ((p = find_peer(peer_name, 1))) {
++		last_authmethod = p->authmethods;
++	}
++
+ 	ast_mutex_lock(&iaxsl[callno]);
+ 	if (!iaxs[callno])
+ 		goto return_unref;
++
++	memset(&ied, 0, sizeof(ied));
++	/* The selection of which delayed reject is sent may leak information,
++	 * if it sets a static response.  For example, if a host is known to only
++	 * use MD5 authentication, then an RSA response would indicate that the
++	 * peer does not exist, and vice-versa.
++	 * Therefore, we use whatever the last peer used (which may vary over the
++	 * course of a server, which should leak minimal information). */
++	sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
+ 	if (!p) {
+-		ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
+-		goto return_unref;
++		iaxs[callno]->authmethods = sentauthmethod;
+ 	}
+-	
+-	memset(&ied, 0, sizeof(ied));
+-	iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
+-	if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
++	iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
++	if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
+ 		/* Build the challenge */
+ 		snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
+ 		ast_string_field_set(iaxs[callno], challenge, challenge);
+@@ -6400,12 +6445,12 @@
+ 	}
+ 	iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
+ 
+-	res = 0;
+-
+ return_unref:
+-	peer_unref(p);
++	if (p) {
++		peer_unref(p);
++	}
+ 
+-	return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
++	return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
+ }
+ 
+ static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
+@@ -8347,8 +8392,9 @@
+ 					ast_mutex_unlock(&iaxsl[fr->callno]);
+ 					return 1;
+ 				}
+-				if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
+-						ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
++				if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
++						ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
++
+ 					if (f.subclass == IAX_COMMAND_REGREL)
+ 						memset(&sin, 0, sizeof(sin));
+ 					if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/AST-2011-005-p2
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2011-005-p2
@@ -0,0 +1,301 @@
+From: Matthew Nicholson <mnicholson@digium.com>
+Date: Thu, 21 Apr 2011 18:19:21 +0000
+Bug: https://issues.asterisk.org/view.php?id=18787
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=314607
+Subject: limits unauthenticated TCP sessions
+
+Added limits to the number of unauthenticated sessions TCP based protocols
+are allowed to have open simultaneously.  Also added timeouts for
+unauthenticated sessions where it made sense to do so.
+
+This patch is the secon upstream patch that fixes AST-2011-005. It applies
+a similar fix to chan_skinny and to manager interface over HTTP.
+
+Skinny, or SCCP, is enabled by default (though not used in most settings).
+To disable: 'noload => chan_skinny.so' in /etc/asterisk/modules.conf .
+
+Manager over HTTP is not enabled by default on Debian.
+
+CVE: CVE-2011-1507
+
+See also:
+  https://issues.asterisk.org/view.php?id=18996
+  http://downloads.asterisk.org/pub/security/AST-2011-005.html
+
+---
+ channels/chan_skinny.c     |   75 +++++++++++++++++++++++++++++++++++++++++--
+ configs/http.conf.sample   |    7 +++-
+ configs/skinny.conf.sample |    9 +++++
+ main/http.c                |   25 ++++++++++++++-
+ 4 files changed, 110 insertions(+), 6 deletions(-)
+
+--- a/channels/chan_skinny.c
++++ b/channels/chan_skinny.c
+@@ -96,8 +96,13 @@ enum skinny_codecs {
+ #define DEFAULT_SKINNY_PORT	2000
+ #define DEFAULT_SKINNY_BACKLOG	2
+ #define SKINNY_MAX_PACKET	1000
++#define DEFAULT_AUTH_TIMEOUT	30
++#define DEFAULT_AUTH_LIMIT	50
+ 
+ static int keep_alive = 120;
++static int auth_timeout = DEFAULT_AUTH_TIMEOUT;
++static int auth_limit = DEFAULT_AUTH_LIMIT;
++static int unauth_sessions = 0;
+ static char date_format[6] = "D-M-Y";
+ static char version_id[16] = "P002F202";
+ 
+@@ -1060,6 +1065,7 @@ struct skinny_paging_device {
+ static struct skinnysession {
+ 	pthread_t t;
+ 	ast_mutex_t lock;
++	time_t start;
+ 	struct sockaddr_in sin;
+ 	int fd;
+ 	char inbuf[SKINNY_MAX_PACKET];
+@@ -3058,6 +3064,7 @@ static int handle_register_message(struc
+ 		transmit_response(s, req);
+ 		return 0;
+ 	}
++	ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ 	if (option_verbose > 2)
+ 		ast_verbose(VERBOSE_PREFIX_3 "Device '%s' successfully registered\n", name);
+ 
+@@ -4421,6 +4428,9 @@ static void destroy_session(struct skinn
+ 		if (s->fd > -1) {
+ 			close(s->fd);
+ 		}
++		if (!s->device) {
++			ast_atomic_fetchadd_int(&unauth_sessions, -1);
++		}
+ 		ast_mutex_destroy(&s->lock);
+ 		free(s);
+ 	} else {
+@@ -4433,12 +4443,29 @@ static int get_input(struct skinnysessio
+ {
+ 	int res;
+ 	int dlen = 0;
++	int timeout = keep_alive * 1100;
++	time_t now;
+ 	struct pollfd fds[1];
+ 
++	if (!s->device) {
++		if(time(&now) == -1) {
++			ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++			return -1;
++		}
++
++		timeout = (auth_timeout - (now - s->start)) * 1000;
++		if (timeout < 0) {
++			/* we have timed out */
++			if (skinnydebug)
++				ast_verbose("Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
++			return -1;
++		}
++	}
++
+  	fds[0].fd = s->fd;
+ 	fds[0].events = POLLIN;
+ 	fds[0].revents = 0;
+-	res = poll(fds, 1, (keep_alive * 1100)); /* If nothing has happen, client is dead */
++	res = poll(fds, 1, timeout); /* If nothing has happen, client is dead */
+ 						 /* we add 10% to the keep_alive to deal */
+ 						 /* with network delays, etc */
+ 	if (res < 0) {
+@@ -4447,8 +4474,13 @@ static int get_input(struct skinnysessio
+ 			return res;
+ 		}
+  	} else if (res == 0) {
+-		if (skinnydebug)
+-			ast_verbose("Skinny Client was lost, unregistering\n");
++		if (skinnydebug) {
++			if (s->device) {
++				ast_verbose("Skinny Client was lost, unregistering\n");
++			} else {
++				ast_verbose("Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
++			}
++		}
+ 		skinny_unregister(NULL, s);
+ 		return -1;
+ 	}
+@@ -4584,18 +4616,35 @@ static void *accept_thread(void *ignore)
+ 			ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
+ 			continue;
+ 		}
++
++		if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= auth_limit) {
++			close(as);
++			ast_atomic_fetchadd_int(&unauth_sessions, -1);
++			continue;
++		}
++
+ 		p = getprotobyname("tcp");
+ 		if(p) {
+ 			if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
+ 				ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
+ 			}
+ 		}
+-		if (!(s = ast_calloc(1, sizeof(struct skinnysession))))
++		if (!(s = ast_calloc(1, sizeof(struct skinnysession)))) {
++			close(as);
++			ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ 			continue;
++		}
+ 
+ 		memcpy(&s->sin, &sin, sizeof(sin));
+ 		ast_mutex_init(&s->lock);
+ 		s->fd = as;
++
++		if(time(&s->start) == -1) {
++			ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
++			destroy_session(s);
++			continue;
++		}
++
+ 		ast_mutex_lock(&sessionlock);
+ 		s->next = sessions;
+ 		sessions = s;
+@@ -4746,6 +4795,24 @@ static int reload_config(void)
+ 			}
+ 		} else if (!strcasecmp(v->name, "keepalive")) {
+ 			keep_alive = atoi(v->value);
++		} else if (!strcasecmp(v->name, "authtimeout")) {
++			int timeout = atoi(v->value);
++
++			if (timeout < 1) {
++				ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", v->value);
++				auth_timeout = DEFAULT_AUTH_TIMEOUT;
++			} else {
++				auth_timeout = timeout;
++			}
++		} else if (!strcasecmp(v->name, "authlimit")) {
++			int limit = atoi(v->value);
++
++			if (limit < 1) {
++				ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", v->value);
++				auth_limit = DEFAULT_AUTH_LIMIT;
++			} else {
++				auth_limit = limit;
++			}
+ 		} else if (!strcasecmp(v->name, "dateformat")) {
+ 			memcpy(date_format, v->value, sizeof(date_format));
+ 		} else if (!strcasecmp(v->name, "allow")) {
+--- a/configs/http.conf.sample
++++ b/configs/http.conf.sample
+@@ -26,7 +26,12 @@ bindport=8088
+ ; requests must begin with /asterisk
+ ;
+ ;prefix=asterisk
+-
++;
++; sessionlimit specifies the maximum number of httpsessions that will be
++; allowed to exist at any given time. (default: 100)
++;
++;sessionlimit=100
++;
+ ; The post_mappings section maps URLs to real paths on the filesystem.  If a
+ ; POST is done from within an authenticated manager session to one of the
+ ; configured POST mappings, then any files in the POST will be placed in the
+--- a/configs/skinny.conf.sample
++++ b/configs/skinny.conf.sample
+@@ -9,6 +9,15 @@ dateformat=M-D-Y	; M,D,Y in any order (6
+ 			; Use M for month, D for day, Y for year, A for 12-hour time.
+ keepalive=120
+ 
++;authtimeout = 30       ; authtimeout specifies the maximum number of seconds a
++			; client has to authenticate.  If the client does not
++			; authenticate beofre this timeout expires, the client
++                        ; will be disconnected.  (default: 30 seconds)
++
++;authlimit = 50         ; authlimit specifies the maximum number of
++			; unauthenticated sessions that will be allowed to
++                        ; connect at any given time. (default: 50)
++
+ ;allow=all		; see doc/rtp-packetization for framing options
+ ;disallow=
+ 
+--- a/main/http.c
++++ b/main/http.c
+@@ -59,6 +59,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi
+ 
+ #define MAX_PREFIX 80
+ #define DEFAULT_PREFIX "/asterisk"
++#define DEFAULT_SESSION_LIMIT 100
+ 
+ struct ast_http_server_instance {
+ 	FILE *f;
+@@ -76,6 +77,8 @@ static char prefix[MAX_PREFIX];
+ static int prefix_len;
+ static struct sockaddr_in oldsin;
+ static int enablestatic;
++static int session_limit = DEFAULT_SESSION_LIMIT;
++static int session_count = 0;
+ 
+ /*! \brief Limit the kinds of files we're willing to serve up */
+ static struct {
+@@ -508,6 +511,7 @@ static void *ast_httpd_helper_thread(voi
+ 	}
+ 	fclose(ser->f);
+ 	free(ser);
++	ast_atomic_fetchadd_int(&session_count, -1);
+ 	return NULL;
+ }
+ 
+@@ -526,15 +530,23 @@ static void *http_root(void *data)
+ 		ast_wait_for_input(httpfd, -1);
+ 		sinlen = sizeof(sin);
+ 		fd = accept(httpfd, (struct sockaddr *)&sin, &sinlen);
++
+ 		if (fd < 0) {
+ 			if ((errno != EAGAIN) && (errno != EINTR))
+ 				ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
+ 			continue;
+ 		}
++
++		if (ast_atomic_fetchadd_int(&session_count, +1) >= session_limit) {
++			close(fd);
++			continue;
++		}
++
+ 		ser = ast_calloc(1, sizeof(*ser));
+ 		if (!ser) {
+ 			ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
+ 			close(fd);
++			ast_atomic_fetchadd_int(&session_count, -1);
+ 			continue;
+ 		}
+ 		flags = fcntl(fd, F_GETFL);
+@@ -549,12 +561,14 @@ static void *http_root(void *data)
+ 				ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
+ 				fclose(ser->f);
+ 				free(ser);
++				ast_atomic_fetchadd_int(&session_count, -1);
+ 			}
+ 			pthread_attr_destroy(&attr);
+ 		} else {
+ 			ast_log(LOG_WARNING, "fdopen failed!\n");
+ 			close(ser->fd);
+ 			free(ser);
++			ast_atomic_fetchadd_int(&session_count, -1);
+ 		}
+ 	}
+ 	return NULL;
+@@ -671,8 +685,17 @@ static int __ast_http_load(int reload)
+ 				} else {
+ 					newprefix[0] = '\0';
+ 				}
+-					
++			} else if (!strcasecmp(v->name, "sessionlimit")) {
++				int limit = atoi(v->value);
++
++				if (limit < 1) {
++					ast_log(LOG_WARNING, "Invalid sessionlimit value '%s', using default value\n", v->value);
++					session_limit = DEFAULT_SESSION_LIMIT;
++				} else {
++					session_limit = limit;
++				}
+ 			}
++
+ 			v = v->next;
+ 		}
+ 		ast_config_destroy(cfg);
--- asterisk-1.4.21.2~dfsg.orig/debian/patches/r171264
+++ asterisk-1.4.21.2~dfsg/debian/patches/r171264
@@ -0,0 +1,53 @@
+Upstream r171264
+
+Don't retransmit 401 on REGISTER requests when alwaysauthreject=yes
+
+(closes issue #14284)
+
+--- a/channels/chan_sip.c	(revision 171263)
++++ b/channels/chan_sip.c	(revision 171264)
+@@ -1264,7 +1264,7 @@
+ static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported);
+ static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
+ static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
+-static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, int reliable);
++static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable);
+ static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
+ static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
+ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init);
+@@ -8774,7 +8774,7 @@
+ /*! \brief Send a fake 401 Unauthorized response when the administrator
+   wants to hide the names of local users/peers from fishers
+  */
+-static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, int reliable)
++static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable)
+ {
+ 	ast_string_field_build(p, randdata, "%08lx", ast_random());	/* Create nonce for challenge */
+ 	transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
+@@ -8931,7 +8931,7 @@
+ 		case AUTH_PEER_NOT_DYNAMIC:
+ 		case AUTH_ACL_FAILED:
+ 			if (global_alwaysauthreject) {
+-				transmit_fake_auth_response(p, &p->initreq, 1);
++				transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
+ 			} else {
+ 				/* URI not found */
+ 				if (res == AUTH_PEER_NOT_DYNAMIC)
+@@ -14421,7 +14421,7 @@
+ 		if (res < 0) { /* Something failed in authentication */
+ 			if (res == AUTH_FAKE_AUTH) {
+ 				ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+-				transmit_fake_auth_response(p, req, 1);
++				transmit_fake_auth_response(p, req, XMIT_RELIABLE);
+ 			} else {
+   				ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
+ 				transmit_response_reliable(p, "403 Forbidden", req);
+@@ -15458,7 +15458,7 @@
+ 	if (res < 0) {
+ 		if (res == AUTH_FAKE_AUTH) {
+ 			ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+-			transmit_fake_auth_response(p, req, 1);
++			transmit_fake_auth_response(p, req, XMIT_UNRELIABLE);
+ 		} else {
+ 			ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
+ 			transmit_response_reliable(p, "403 Forbidden", req);
--- 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 <jon@elephantoutlook.com>
+
+--- 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(&current_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/AST-2009-010
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2009-010
@@ -0,0 +1,20 @@
+Source: http://svn.digium.com/svn/asterisk/branches/1.4@231441
+Debian Issue: #559103
+CVE: CVE-2009-4055
+Date: Mon Nov 30 17:14:08 2009 +0000
+Upstream Issue: https://issues.asterisk.org/view.php?id=16242
+
+fixes crash caused by RTP comfort noise payload greater than 24 bytes
+
+diff --git a/main/rtp.c b/main/rtp.c
+index 12e3638..a124bb7 100644
+--- a/main/rtp.c
++++ b/main/rtp.c
+@@ -848,7 +848,6 @@ static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *dat
+ 	}
+ 	rtp->f.frametype = AST_FRAME_CNG;
+ 	rtp->f.subclass = data[0] & 0x7f;
+-	rtp->f.datalen = len - 1;
+ 	rtp->f.samples = 0;
+ 	rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
+ 	f = &rtp->f;
--- 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 <paravoid@debian.org>
+
+--- 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/AST-2009-003
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2009-003
@@ -0,0 +1,164 @@
+Index: channels/chan_sip.c
+===================================================================
+--- a/channels/chan_sip.c	(revision 183280)
++++ b/channels/chan_sip.c	(working copy)
+@@ -1266,7 +1266,7 @@
+ static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported);
+ static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
+ static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
+-static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable);
++static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable);
+ static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
+ static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
+ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init);
+@@ -8873,10 +8873,96 @@
+ /*! \brief Send a fake 401 Unauthorized response when the administrator
+   wants to hide the names of local users/peers from fishers
+  */
+-static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable)
++static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable)
+ {
+-	ast_string_field_build(p, randdata, "%08lx", ast_random());	/* Create nonce for challenge */
+-	transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
++	/* We have to emulate EXACTLY what we'd get with a good peer
++	 * and a bad password, or else we leak information. */
++	const char *response = "407 Proxy Authentication Required";
++	const char *reqheader = "Proxy-Authorization";
++	const char *respheader = "Proxy-Authenticate";
++	const char *authtoken;
++	struct ast_dynamic_str *buf;
++	char *c;
++
++	/* table of recognised keywords, and their value in the digest */
++	enum keys { K_NONCE, K_LAST };
++	struct x {
++		const char *key;
++		const char *s;
++	} *i, keys[] = {
++		[K_NONCE] = { "nonce=", "" },
++		[K_LAST] = { NULL, NULL}
++	};
++
++	if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
++		response = "401 Unauthorized";
++		reqheader = "Authorization";
++		respheader = "WWW-Authenticate";
++	}
++	authtoken = get_header(req, reqheader);
++	if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
++		/* This is a retransmitted invite/register/etc, don't reconstruct authentication
++		 * information */
++		transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
++		/* Schedule auto destroy in 32 seconds (according to RFC 3261) */
++		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
++		return;
++	} else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
++		/* We have no auth, so issue challenge and request authentication */
++		ast_string_field_build(p, randdata, "%08lx", ast_random());	/* Create nonce for challenge */
++		transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
++		/* Schedule auto destroy in 32 seconds */
++		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
++		return;
++	}
++
++	if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
++		transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
++		return;
++	}
++
++	/* Make a copy of the response and parse it */
++	if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
++		transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
++		return;
++	}
++
++	c = buf->str;
++
++	while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
++		for (i = keys; i->key != NULL; i++) {
++			const char *separator = ",";	/* default */
++
++			if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
++				continue;
++			}
++			/* Found. Skip keyword, take text in quotes or up to the separator. */
++			c += strlen(i->key);
++			if (*c == '"') { /* in quotes. Skip first and look for last */
++				c++;
++				separator = "\"";
++			}
++			i->s = c;
++			strsep(&c, separator);
++			break;
++		}
++		if (i->key == NULL) { /* not found, jump after space or comma */
++			strsep(&c, " ,");
++		}
++	}
++
++	/* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
++	if (strcasecmp(p->randdata, keys[K_NONCE].s)) {
++		if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
++			ast_string_field_build(p, randdata, "%08lx", ast_random());
++		}
++		transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
++
++		/* Schedule auto destroy in 32 seconds */
++		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
++	} else {
++		transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
++	}
+ }
+ 
+ /*! \brief Verify registration of user 
+@@ -9010,6 +9096,14 @@
+ 			}
+ 		}
+ 	}
++	if (!peer && global_alwaysauthreject) {
++		/* If we found a peer, we transmit a 100 Trying.  Therefore, if we're
++		 * trying to avoid leaking information, we MUST also transmit the same
++		 * response when we DON'T find a peer. */
++		transmit_response(p, "100 Trying", req);
++		/* Insert a fake delay between the 100 and the subsequent failure. */
++		sched_yield();
++	}
+ 	if (!res) {
+ 		ast_device_state_changed("SIP/%s", peer->name);
+ 	}
+@@ -9020,7 +9114,7 @@
+ 			transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+ 			break;
+ 		case AUTH_USERNAME_MISMATCH:
+-			/* Username and digest username does not match. 
++			/* Username and digest username does not match.
+ 			   Asterisk uses the From: username for authentication. We need the
+ 			   users to use the same authentication user name until we support
+ 			   proper authentication by digest auth name */
+@@ -9030,7 +9124,7 @@
+ 		case AUTH_PEER_NOT_DYNAMIC:
+ 		case AUTH_ACL_FAILED:
+ 			if (global_alwaysauthreject) {
+-				transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
++				transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
+ 			} else {
+ 				/* URI not found */
+ 				if (res == AUTH_PEER_NOT_DYNAMIC)
+@@ -14557,7 +14651,7 @@
+ 		if (res < 0) { /* Something failed in authentication */
+ 			if (res == AUTH_FAKE_AUTH) {
+ 				ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+-				transmit_fake_auth_response(p, req, XMIT_RELIABLE);
++				transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
+ 			} else {
+   				ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
+ 				transmit_response_reliable(p, "403 Forbidden", req);
+@@ -15594,7 +15688,7 @@
+ 	if (res < 0) {
+ 		if (res == AUTH_FAKE_AUTH) {
+ 			ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+-			transmit_fake_auth_response(p, req, XMIT_UNRELIABLE);
++			transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
+ 		} else {
+ 			ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
+ 			transmit_response_reliable(p, "403 Forbidden", req);
--- 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 <paravoid@debian.org>
+
+--- 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/r132790
+++ asterisk-1.4.21.2~dfsg/debian/patches/r132790
@@ -0,0 +1,360 @@
+Upstream r132790
+
+Allow Spiraled INVITEs to work correctly within Asterisk.
+
+Prior to this change, a spiraled INVITE would cause a 482
+Loop Detected to be sent to the caller. With this change,
+if a potential loop is detected, the Request-URI is inspected
+to see if it has changed from what was originally received. If
+pedantic mode is on, then this inspection is fully RFC 3261
+compliant. If pedantic mode is not on, then a string comparison
+is used to test the equality of the two R-URIs.
+
+This has been tested by using OpenSER to rewrite the R-URI
+and send the INVITE back to Asterisk.
+
+(closes issue #7403)
+
+--- a/channels/chan_sip.c	(revision 132789)
++++ b/channels/chan_sip.c	(revision 132790)
+@@ -4643,8 +4643,6 @@
+ 			if (!found && option_debug > 4)
+ 				ast_log(LOG_DEBUG, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", p->callid, totag, sip_methods[req->method].text);
+ 		}
+-
+-
+ 		if (found) {
+ 			/* Found the call */
+ 			ast_mutex_lock(&p->lock);
+@@ -7204,7 +7202,7 @@
+ 		add_header_contentLength(&req, 0);
+ 	}
+ 
+-	if (!p->initreq.headers)
++	if (!p->initreq.headers || init > 2)
+ 		initialize_initreq(p, &req);
+ 	p->lastinvite = p->ocseq;
+ 	return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
+@@ -13767,7 +13765,264 @@
+ 	return 0;
+ }
+ 
++/*! \brief helper routine for sip_uri_cmp
++ *
++ * This takes the parameters from two SIP URIs and determines
++ * if the URIs match. The rules for parameters *suck*. Here's a breakdown
++ * 1. If a parameter appears in both URIs, then they must have the same value
++ *    in order for the URIs to match
++ * 2. If one URI has a user, maddr, ttl, or method parameter, then the other
++ *    URI must also have that parameter and must have the same value
++ *    in order for the URIs to match
++ * 3. All other headers appearing in only one URI are not considered when
++ *    determining if URIs match
++ *
++ * \param input1 Parameters from URI 1
++ * \param input2 Parameters from URI 2
++ * \return Return 0 if the URIs' parameters match, 1 if they do not
++ */
++static int sip_uri_params_cmp(const char *input1, const char *input2) 
++{
++	char *params1 = ast_strdupa(input1);
++	char *params2 = ast_strdupa(input2);
++	char *pos1;
++	char *pos2;
++	int maddrmatch = 0;
++	int ttlmatch = 0;
++	int usermatch = 0;
++	int methodmatch = 0;
+ 
++	/*Quick optimization. If both params are zero-length, then
++	 * they match
++	 */
++	if (ast_strlen_zero(params1) && ast_strlen_zero(params2)) {
++		return 0;
++	}
++
++	pos1 = params1;
++	while (!ast_strlen_zero(pos1)) {
++		char *name1 = pos1;
++		char *value1 = strchr(pos1, '=');
++		char *semicolon1 = strchr(pos1, ';');
++		int matched = 0;
++		if (semicolon1) {
++			*semicolon1++ = '\0';
++		}
++		if (!value1) {
++			goto fail;
++		}
++		*value1++ = '\0';
++		/* Checkpoint reached. We have the name and value parsed for param1 
++		 * We have to duplicate params2 each time through the second loop
++		 * or else we can't search and replace the semicolons with \0 each
++		 * time
++		 */
++		pos2 = ast_strdupa(params2);
++		while (!ast_strlen_zero(pos2)) {
++			char *name2 = pos2;
++			char *value2 = strchr(pos2, '=');
++			char *semicolon2 = strchr(pos2, ';');
++			if (semicolon2) {
++				*semicolon2++ = '\0';
++			}
++			if (!value2) {
++				goto fail;
++			}
++			if (!strcasecmp(name1, name2)) {
++				if (strcasecmp(value1, value2)) {
++					goto fail;
++				} else {
++					matched = 1;
++					break;
++				}
++			}
++			pos2 = semicolon2;
++		}
++		/* Need to see if the parameter we're looking at is one of the 'must-match' parameters */
++		if (!strcasecmp(name1, "maddr")) {
++			if (matched) {
++				maddrmatch = 1;
++			} else {
++				goto fail;
++			}
++		} else if (!strcasecmp(name1, "ttl")) {
++			if (matched) {
++				ttlmatch = 1;
++			} else {
++				goto fail;
++			}
++		} else if (!strcasecmp(name1, "user")) {
++			if (matched) {
++				usermatch = 1;
++			} else {
++				goto fail;
++			}
++		} else if (!strcasecmp(name1, "method")) {
++			if (matched) {
++				methodmatch = 1;
++			} else {
++				goto fail;
++			}
++		}
++		pos1 = semicolon1;
++	}
++
++	/* We've made it out of that horrible O(m*n) construct and there are no
++	 * failures yet. We're not done yet, though, because params2 could have
++	 * an maddr, ttl, user, or method header and params1 did not.
++	 */
++	pos2 = params2;
++	while (!ast_strlen_zero(pos2)) {
++		char *name2 = pos2;
++		char *value2 = strchr(pos2, '=');
++		char *semicolon2 = strchr(pos2, ';');
++		if (semicolon2) {
++			*semicolon2++ = '\0';
++		}
++		if (!value2) {
++			goto fail;
++		}
++		if ((!strcasecmp(name2, "maddr") && !maddrmatch) ||
++				(!strcasecmp(name2, "ttl") && !ttlmatch) ||
++				(!strcasecmp(name2, "user") && !usermatch) ||
++				(!strcasecmp(name2, "method") && !methodmatch)) {
++			goto fail;
++		}
++	}
++	return 0;
++
++fail:
++	return 1;
++}
++
++/*! \brief helper routine for sip_uri_cmp
++ *
++ * This takes the "headers" from two SIP URIs and determines
++ * if the URIs match. The rules for headers is simple. If a header
++ * appears in one URI, then it must also appear in the other URI. The
++ * order in which the headers appear does not matter.
++ *
++ * \param input1 Headers from URI 1
++ * \param input2 Headers from URI 2
++ * \return Return 0 if the URIs' headers match, 1 if they do not
++ */
++static int sip_uri_headers_cmp(const char *input1, const char *input2)
++{
++	char *headers1 = ast_strdupa(input1);
++	char *headers2 = ast_strdupa(input2);
++	int zerolength1 = ast_strlen_zero(headers1);
++	int zerolength2 = ast_strlen_zero(headers2);
++	int different = 0;
++	char *header1;
++
++	if ((zerolength1 && !zerolength2) ||
++			(zerolength2 && !zerolength1))
++		return 1;
++
++	if (zerolength1 && zerolength2)
++		return 0;
++
++	/* At this point, we can definitively state that both inputs are
++	 * not zero-length. First, one more optimization. If the length
++	 * of the headers is not equal, then we definitely have no match
++	 */
++	if (strlen(headers1) != strlen(headers2)) {
++		return 1;
++	}
++
++	for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) {
++		if (!strcasestr(headers2, header1)) {
++			different = 1;
++			break;
++		}
++	}
++
++	return different;
++}
++
++static int sip_uri_cmp(const char *input1, const char *input2)
++{
++	char *uri1 = ast_strdupa(input1);
++	char *uri2 = ast_strdupa(input2);
++	char *host1;
++	char *host2;
++	char *params1;
++	char *params2;
++	char *headers1;
++	char *headers2;
++
++	/* Strip off "sip:" from the URI. We know this is present
++	 * because it was checked back in parse_request()
++	 */
++	strsep(&uri1, ":");
++	strsep(&uri2, ":");
++
++	if ((host1 = strchr(uri1, '@'))) {
++		*host1++ = '\0';
++	}
++	if ((host2 = strchr(uri2, '@'))) {
++		*host2++ = '\0';
++	}
++
++	/* Check for mismatched username and passwords. This is the
++	 * only case-sensitive comparison of a SIP URI
++	 */
++	if ((host1 && !host2) ||
++			(host2 && !host1) ||
++			(host1 && host2 && strcmp(uri1, uri2))) {
++		return 1;
++	}
++
++	if (!host1)
++		host1 = uri1;
++	if (!host2)
++		host2 = uri2;
++
++	/* Strip off the parameters and headers so we can compare
++	 * host and port
++	 */
++
++	if ((params1 = strchr(host1, ';'))) {
++		*params1++ = '\0';
++	}
++	if ((params2 = strchr(host2, ';'))) {
++		*params2++ = '\0';
++	}
++
++	/* Headers come after parameters, but there may be headers without
++	 * parameters, thus the S_OR
++	 */
++	if ((headers1 = strchr(S_OR(params1, host1), '?'))) {
++		*headers1++ = '\0';
++	}
++	if ((headers2 = strchr(S_OR(params2, host2), '?'))) {
++		*headers2++ = '\0';
++	}
++
++	/* Now the host/port are properly isolated. We can get by with a string comparison
++	 * because the SIP URI checking rules have some interesting exceptions that make
++	 * this possible. I will note 2 in particular
++	 * 1. hostnames which resolve to the same IP address as well as a hostname and its
++	 *    IP address are not considered a match with SIP URI's.
++	 * 2. If one URI specifies a port and the other does not, then the URIs do not match.
++	 *    This includes if one URI explicitly contains port 5060 and the other implies it
++	 *    by not having a port specified.
++	 */
++
++	if (strcasecmp(host1, host2)) {
++		return 1;
++	}
++
++	/* Headers have easier rules to follow, so do those first */
++	if (sip_uri_headers_cmp(headers1, headers2)) {
++		return 1;
++	}
++
++	/* And now the parameters. Ugh */
++	return sip_uri_params_cmp(params1, params2);
++}
++
++
+ /*! \brief Handle incoming INVITE request
+ \note 	If the INVITE has a Replaces header, it is part of an
+  *	attended transfer. If so, we do not go through the dial
+@@ -13814,10 +14069,44 @@
+ 	   	being able to call yourself */
+ 		/* If pedantic is on, we need to check the tags. If they're different, this is
+ 	   	in fact a forked call through a SIP proxy somewhere. */
+-		transmit_response(p, "482 Loop Detected", req);
+-		p->invitestate = INV_COMPLETED;
+-		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+-		return 0;
++		int different;
++		if (pedanticsipchecking)
++			different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2);
++		else
++			different = strcmp(p->initreq.rlPart2, req->rlPart2);
++		if (!different) {
++			transmit_response(p, "482 Loop Detected", req);
++			p->invitestate = INV_COMPLETED;
++			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
++			return 0;
++		} else {
++			/* This is a spiral. What we need to do is to just change the outgoing INVITE
++			 * so that it now routes to the new Request URI. Since we created the INVITE ourselves
++			 * that should be all we need to do.
++			 */
++			char *uri = ast_strdupa(req->rlPart2);
++			char *at = strchr(uri, '@');
++			char *peerorhost;
++			struct sip_pkt *pkt = NULL;
++			if (option_debug > 2) {
++				ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2);
++			}
++			if (at) {
++				*at = '\0';
++			}
++			/* Parse out "sip:" */
++			if ((peerorhost = strchr(uri, ':'))) {
++				*peerorhost++ = '\0';
++			}
++			create_addr(p, peerorhost);
++			ast_string_field_free(p, theirtag);
++			for (pkt = p->packets; pkt; pkt = pkt->next) {
++				if (pkt->seqno == p->icseq && pkt->method == SIP_INVITE) {
++					AST_SCHED_DEL(sched, pkt->retransid);
++				}
++			}
++			return transmit_invite(p, SIP_INVITE, 1, 3);
++		}
+ 	}
+ 	
+ 	if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) {
+@@ -15332,7 +15621,7 @@
+ 		if (!p->initreq.headers) {
+ 			if (option_debug)
+ 				ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
+-			ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
++			ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ 			return 0;
+ 		} else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) {
+ 			if (option_debug)
--- 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/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 <paravoid@debian.org>
+
+--- 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/AST-2009-002
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2009-002
@@ -0,0 +1,70 @@
+Index: channels/chan_sip.c
+===================================================================
+--- a/channels/chan_sip.c	(revision 174081)
++++ b/channels/chan_sip.c	(revision 174082)
+@@ -14012,19 +14012,32 @@
+  */
+ static int sip_uri_params_cmp(const char *input1, const char *input2) 
+ {
+-	char *params1 = ast_strdupa(input1);
+-	char *params2 = ast_strdupa(input2);
++	char *params1 = NULL;
++	char *params2 = NULL;
+ 	char *pos1;
+ 	char *pos2;
++	int zerolength1 = 0;
++	int zerolength2 = 0;
+ 	int maddrmatch = 0;
+ 	int ttlmatch = 0;
+ 	int usermatch = 0;
+ 	int methodmatch = 0;
+ 
++	if (ast_strlen_zero(input1)) {
++		zerolength1 = 1;
++	} else {
++		params1 = ast_strdupa(input1);
++	}
++	if (ast_strlen_zero(input2)) {
++		zerolength2 = 1;
++	} else {
++		params2 = ast_strdupa(input2);
++	}
++
+ 	/*Quick optimization. If both params are zero-length, then
+ 	 * they match
+ 	 */
+-	if (ast_strlen_zero(params1) && ast_strlen_zero(params2)) {
++	if (zerolength1 && zerolength2) {
+ 		return 0;
+ 	}
+ 
+@@ -14139,13 +14152,25 @@
+  */
+ static int sip_uri_headers_cmp(const char *input1, const char *input2)
+ {
+-	char *headers1 = ast_strdupa(input1);
+-	char *headers2 = ast_strdupa(input2);
+-	int zerolength1 = ast_strlen_zero(headers1);
+-	int zerolength2 = ast_strlen_zero(headers2);
++	char *headers1 = NULL;
++	char *headers2 = NULL;
++	int zerolength1 = 0;
++	int zerolength2 = 0;
+ 	int different = 0;
+ 	char *header1;
+ 
++	if (ast_strlen_zero(input1)) {
++		zerolength1 = 1;
++	} else {
++		headers1 = ast_strdupa(input1);
++	}
++	
++	if (ast_strlen_zero(input2)) {
++		zerolength2 = 1;
++	} else {
++		headers2 = ast_strdupa(input2);
++	}
++
+ 	if ((zerolength1 && !zerolength2) ||
+ 			(zerolength2 && !zerolength1))
+ 		return 1;
--- 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 <paravoid@debian.org>
+
+--- 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/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 <paravoid@debian.org>
+
+--- 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/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 <paravoid@debian.org>
+
+--- 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/ael-segfault-fix
+++ asterisk-1.4.21.2~dfsg/debian/patches/ael-segfault-fix
@@ -0,0 +1,610 @@
+Fix a segfault that occured on AEL parsing on amd64 systems, e.g.
+	context blah {
+		lars => NoOp(Test);
+		123456 => goto foo|1;
+	};
+
+Backported from upstream's r162013.
+Upstream bug: http://bugs.digium.com/view.php?id=14019
+Debian bug: #507883
+
+  -- Faidon Liambotis <paravoid@debian.org>
+
+--- a/pbx/ael/ael.flex
++++ b/pbx/ael/ael.flex
+@@ -238,7 +238,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 
+ [-a-zA-Z0-9'"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9'"_/.!\*\+\<\>\{\}$#\[\]]*	{
+ 		STORE_POS;
+-		yylval->str = strdup(yytext);
++		yylval->str = ast_malloc(yyleng+1);
++		ast_copy_string(yylval->str, yytext, yyleng+1);
+ 		prev_word = yylval->str;
+ 		return word;
+ 	}
+@@ -257,7 +258,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 			STORE_LOC;
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression: %s !\n", my_file, my_lineno, my_col, yytext);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			prev_word = 0;
+ 			return word;
+ 		}
+@@ -266,8 +268,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 			yymore();
+ 		} else {
+ 			STORE_LOC;
+-			yylval->str = strdup(yytext);
+-			yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */
++			yylval->str = ast_malloc(yyleng);
++			ast_copy_string(yylval->str, yytext, yyleng);
+ 			unput(')');
+ 			BEGIN(0);
+ 			return word;
+@@ -289,7 +291,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n",
+ 				my_file, my_lineno, my_col, c);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			return word;
+ 		}
+ 		yymore();
+@@ -317,7 +320,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 			STORE_LOC;
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno, my_col);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			return word;
+ 		}
+ 
+@@ -329,8 +333,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 			BEGIN(0);
+ 			if ( !strcmp(yytext, ")") )
+ 				return RP;
+-			yylval->str = strdup(yytext);
+-			yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */
++			yylval->str = ast_malloc(yyleng);
++			ast_copy_string(yylval->str, yytext, yyleng);
+ 			unput(')');
+ 			return word;
+ 		}
+@@ -343,8 +347,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 			STORE_LOC;
+ 			if( !strcmp(yytext,"," ) )
+ 				return COMMA;
+-			yylval->str = strdup(yytext);
+-			yylval->str[yyleng-1] = '\0';
++			yylval->str = ast_malloc(yyleng);
++			ast_copy_string(yylval->str, yytext, yyleng);
+ 			unput(',');
+ 			return word;
+ 		}
+@@ -356,7 +360,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 			STORE_LOC;
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			return word;
+ 		}
+ 		yymore();
+@@ -379,7 +384,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 			STORE_LOC;
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			return word;
+ 		}
+ 		yymore();
+@@ -387,8 +393,8 @@ includes	{ STORE_POS; return KW_INCLUDES
+ 
+ <semic>{NOSEMIC};	{
+ 		STORE_LOC;
+-		yylval->str = strdup(yytext);
+-		yylval->str[yyleng-1] = '\0';
++		yylval->str = ast_malloc(yyleng);
++		ast_copy_string(yylval->str, yytext, yyleng);
+ 		unput(';');
+ 		BEGIN(0);
+ 		return word;
+--- a/pbx/pbx_ael.c
++++ b/pbx/pbx_ael.c
+@@ -710,7 +710,7 @@ static int extension_matches(pval *here,
+ 	regex_t preg;
+ 	
+ 	/* simple case, they match exactly, the pattern and exten name */
+-	if( !strcmp(pattern,exten) == 0 )
++	if( strcmp(pattern,exten) == 0 )
+ 		return 1;
+ 	
+ 	if ( pattern[0] == '_' ) {
+@@ -2959,7 +2959,7 @@ static void gen_prios(struct ael_extensi
+ 			pr->type = AEL_APPCALL;
+ 			p->u2.goto_target = get_goto_target(p);
+ 			if( p->u2.goto_target ) {
+-				p->u3.goto_target_in_case = p->u2.goto_target->u2.label_in_case = label_inside_case(p->u2.goto_target);
++				p->u3.goto_target_in_case = label_inside_case(p->u2.goto_target);
+ 			}
+ 			
+ 			if (!p->u1.list->next) /* just one */ {
+--- a/pbx/ael/ael_lex.c
++++ b/pbx/ael/ael_lex.c
+@@ -9,7 +9,7 @@
+ #define FLEX_SCANNER
+ #define YY_FLEX_MAJOR_VERSION 2
+ #define YY_FLEX_MINOR_VERSION 5
+-#define YY_FLEX_SUBMINOR_VERSION 33
++#define YY_FLEX_SUBMINOR_VERSION 35
+ #if YY_FLEX_SUBMINOR_VERSION > 0
+ #define FLEX_BETA
+ #endif
+@@ -32,7 +32,7 @@
+ 
+ /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+ 
+-#if !defined __STDC_VERSION__ || __STDC_VERSION__ >= 199901L
++#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ 
+ /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+  * if you want the limit (max/min) macros for int types. 
+@@ -55,7 +55,6 @@ typedef int flex_int32_t;
+ typedef unsigned char flex_uint8_t; 
+ typedef unsigned short int flex_uint16_t;
+ typedef unsigned int flex_uint32_t;
+-#endif /* ! C99 */
+ 
+ /* Limits of integral types. */
+ #ifndef INT8_MIN
+@@ -86,6 +85,8 @@ typedef unsigned int flex_uint32_t;
+ #define UINT32_MAX             (4294967295U)
+ #endif
+ 
++#endif /* ! C99 */
++
+ #endif /* ! FLEXINT_H */
+ 
+ #ifdef __cplusplus
+@@ -95,11 +96,12 @@ typedef unsigned int flex_uint32_t;
+ 
+ #else	/* ! __cplusplus */
+ 
+-#if __STDC__
++/* C99 requires __STDC__ to be defined as 1. */
++#if defined (__STDC__)
+ 
+ #define YY_USE_CONST
+ 
+-#endif	/* __STDC__ */
++#endif	/* defined (__STDC__) */
+ #endif	/* ! __cplusplus */
+ 
+ #ifdef YY_USE_CONST
+@@ -135,8 +137,6 @@ typedef void* yyscan_t;
+ #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+ #define yy_flex_debug yyg->yy_flex_debug_r
+ 
+-int ael_yylex_init (yyscan_t* scanner);
+-
+ /* Enter a start condition.  This macro really ought to take a parameter,
+  * but we do it the disgusting crufty way forced on us by the ()-less
+  * definition of BEGIN.
+@@ -194,14 +194,9 @@ typedef struct yy_buffer_state *YY_BUFFE
+ 
+ #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+ 
+-/* The following is because we cannot portably get our hands on size_t
+- * (without autoconf's help, which isn't available because we want
+- * flex-generated scanners to compile on their own).
+- */
+-
+ #ifndef YY_TYPEDEF_YY_SIZE_T
+ #define YY_TYPEDEF_YY_SIZE_T
+-typedef unsigned int yy_size_t;
++typedef size_t yy_size_t;
+ #endif
+ 
+ #ifndef YY_STRUCT_YY_BUFFER_STATE
+@@ -905,7 +900,7 @@ static void pbcwhere(const char *text, i
+ #define	STORE_POS
+ #define	STORE_LOC
+ #endif
+-#line 908 "ael_lex.c"
++#line 903 "ael_lex.c"
+ 
+ #define INITIAL 0
+ #define paren 1
+@@ -971,6 +966,10 @@ static int yy_init_globals (yyscan_t yys
+     
+     #    define yylloc yyg->yylloc_r
+     
++int ael_yylex_init (yyscan_t* scanner);
++
++int ael_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
++
+ /* Accessor methods to globals.
+    These are made visible to non-reentrant scanners for convenience. */
+ 
+@@ -1042,7 +1041,12 @@ static int input (yyscan_t yyscanner );
+ 
+ /* Amount of stuff to slurp up with each read. */
+ #ifndef YY_READ_BUF_SIZE
++#ifdef __ia64__
++/* On IA-64, the buffer size is 16k, not 8k */
++#define YY_READ_BUF_SIZE 16384
++#else
+ #define YY_READ_BUF_SIZE 8192
++#endif /* __ia64__ */
+ #endif
+ 
+ /* Copy whatever the last rule matched to the standard output. */
+@@ -1050,7 +1054,7 @@ static int input (yyscan_t yyscanner );
+ /* This used to be an fputs(), but since the string might contain NUL's,
+  * we now use fwrite().
+  */
+-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
++#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+ #endif
+ 
+ /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+@@ -1115,9 +1119,11 @@ static int input (yyscan_t yyscanner );
+ #ifndef YY_DECL
+ #define YY_DECL_IS_OURS 1
+ 
+-extern int ael_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
++extern int ael_yylex \
++               (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+ 
+-#define YY_DECL int ael_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
++#define YY_DECL int ael_yylex \
++               (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
+ #endif /* !YY_DECL */
+ 
+ /* Code executed at the beginning of each rule, after yytext and yyleng
+@@ -1147,7 +1153,7 @@ YY_DECL
+ #line 185 "ael.flex"
+ 
+ 
+-#line 1150 "ael_lex.c"
++#line 1156 "ael_lex.c"
+ 
+     yylval = yylval_param;
+ 
+@@ -1489,7 +1495,8 @@ YY_RULE_SETUP
+ #line 239 "ael.flex"
+ {
+ 		STORE_POS;
+-		yylval->str = strdup(yytext);
++		yylval->str = ast_malloc(yyleng+1);
++		ast_copy_string(yylval->str, yytext, yyleng+1);
+ 		prev_word = yylval->str;
+ 		return word;
+ 	}
+@@ -1504,13 +1511,14 @@ YY_RULE_SETUP
+ case 51:
+ /* rule 51 can match eol */
+ YY_RULE_SETUP
+-#line 255 "ael.flex"
++#line 256 "ael.flex"
+ {
+ 		if ( pbcpop(')') ) {	/* error */
+ 			STORE_LOC;
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression: %s !\n", my_file, my_lineno, my_col, yytext);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			prev_word = 0;
+ 			return word;
+ 		}
+@@ -1519,8 +1527,8 @@ YY_RULE_SETUP
+ 			yymore();
+ 		} else {
+ 			STORE_LOC;
+-			yylval->str = strdup(yytext);
+-			yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */
++			yylval->str = ast_malloc(yyleng);
++			ast_copy_string(yylval->str, yytext, yyleng);
+ 			unput(')');
+ 			BEGIN(0);
+ 			return word;
+@@ -1530,7 +1538,7 @@ YY_RULE_SETUP
+ case 52:
+ /* rule 52 can match eol */
+ YY_RULE_SETUP
+-#line 277 "ael.flex"
++#line 279 "ael.flex"
+ {
+ 		char c = yytext[yyleng-1];
+ 		if (c == '(')
+@@ -1542,7 +1550,7 @@ YY_RULE_SETUP
+ case 53:
+ /* rule 53 can match eol */
+ YY_RULE_SETUP
+-#line 285 "ael.flex"
++#line 287 "ael.flex"
+ {
+ 		char c = yytext[yyleng-1];
+ 		if ( pbcpop(c))  { /* error */
+@@ -1550,7 +1558,8 @@ YY_RULE_SETUP
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n",
+ 				my_file, my_lineno, my_col, c);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			return word;
+ 		}
+ 		yymore();
+@@ -1567,7 +1576,7 @@ YY_RULE_SETUP
+ case 54:
+ /* rule 54 can match eol */
+ YY_RULE_SETUP
+-#line 307 "ael.flex"
++#line 310 "ael.flex"
+ {
+ 		char c = yytext[yyleng-1];
+ 		if (c == '(')
+@@ -1579,13 +1588,14 @@ YY_RULE_SETUP
+ case 55:
+ /* rule 55 can match eol */
+ YY_RULE_SETUP
+-#line 315 "ael.flex"
++#line 318 "ael.flex"
+ {
+ 		if ( pbcpop(')') ) { /* error */
+ 			STORE_LOC;
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno, my_col);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			return word;
+ 		}
+ 
+@@ -1597,8 +1607,8 @@ YY_RULE_SETUP
+ 			BEGIN(0);
+ 			if ( !strcmp(yytext, ")") )
+ 				return RP;
+-			yylval->str = strdup(yytext);
+-			yylval->str[yyleng-1] = '\0'; /* trim trailing ')' */
++			yylval->str = ast_malloc(yyleng);
++			ast_copy_string(yylval->str, yytext, yyleng);
+ 			unput(')');
+ 			return word;
+ 		}
+@@ -1607,7 +1617,7 @@ YY_RULE_SETUP
+ case 56:
+ /* rule 56 can match eol */
+ YY_RULE_SETUP
+-#line 339 "ael.flex"
++#line 343 "ael.flex"
+ {
+ 		if( parencount != 0) { /* printf("Folding in a comma!\n"); */
+ 			yymore();
+@@ -1615,8 +1625,8 @@ YY_RULE_SETUP
+ 			STORE_LOC;
+ 			if( !strcmp(yytext,"," ) )
+ 				return COMMA;
+-			yylval->str = strdup(yytext);
+-			yylval->str[yyleng-1] = '\0';
++			yylval->str = ast_malloc(yyleng);
++			ast_copy_string(yylval->str, yytext, yyleng);
+ 			unput(',');
+ 			return word;
+ 		}
+@@ -1625,14 +1635,15 @@ YY_RULE_SETUP
+ case 57:
+ /* rule 57 can match eol */
+ YY_RULE_SETUP
+-#line 353 "ael.flex"
++#line 357 "ael.flex"
+ {
+ 		char c = yytext[yyleng-1];
+ 		if ( pbcpop(c) ) { /* error */
+ 			STORE_LOC;
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			return word;
+ 		}
+ 		yymore();
+@@ -1646,7 +1657,7 @@ YY_RULE_SETUP
+ case 58:
+ /* rule 58 can match eol */
+ YY_RULE_SETUP
+-#line 370 "ael.flex"
++#line 375 "ael.flex"
+ {
+ 		char c = yytext[yyleng-1];
+ 		yymore();
+@@ -1656,14 +1667,15 @@ YY_RULE_SETUP
+ case 59:
+ /* rule 59 can match eol */
+ YY_RULE_SETUP
+-#line 376 "ael.flex"
++#line 381 "ael.flex"
+ {
+ 		char c = yytext[yyleng-1];
+ 		if ( pbcpop(c) ) { /* error */
+ 			STORE_LOC;
+ 			ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '%c' in expression!\n", my_file, my_lineno, my_col, c);
+ 			BEGIN(0);
+-			yylval->str = strdup(yytext);
++			yylval->str = ast_malloc(yyleng+1);
++			ast_copy_string(yylval->str, yytext, yyleng+1);
+ 			return word;
+ 		}
+ 		yymore();
+@@ -1672,11 +1684,11 @@ YY_RULE_SETUP
+ case 60:
+ /* rule 60 can match eol */
+ YY_RULE_SETUP
+-#line 388 "ael.flex"
++#line 394 "ael.flex"
+ {
+ 		STORE_LOC;
+-		yylval->str = strdup(yytext);
+-		yylval->str[yyleng-1] = '\0';
++		yylval->str = ast_malloc(yyleng);
++		ast_copy_string(yylval->str, yytext, yyleng);
+ 		unput(';');
+ 		BEGIN(0);
+ 		return word;
+@@ -1685,7 +1697,7 @@ YY_RULE_SETUP
+ case 61:
+ /* rule 61 can match eol */
+ YY_RULE_SETUP
+-#line 397 "ael.flex"
++#line 403 "ael.flex"
+ {
+ 		char fnamebuf[1024],*p1,*p2;
+ 		int glob_ret;
+@@ -1731,7 +1743,7 @@ case YY_STATE_EOF(paren):
+ case YY_STATE_EOF(semic):
+ case YY_STATE_EOF(argg):
+ case YY_STATE_EOF(comment):
+-#line 438 "ael.flex"
++#line 444 "ael.flex"
+ {
+ 		char fnamebuf[2048];
+ 		if (include_stack_index > 0 && include_stack[include_stack_index-1].globbuf_pos < include_stack[include_stack_index-1].globbuf.gl_pathc-1) {
+@@ -1766,10 +1778,10 @@ case YY_STATE_EOF(comment):
+ 	YY_BREAK
+ case 62:
+ YY_RULE_SETUP
+-#line 470 "ael.flex"
++#line 476 "ael.flex"
+ ECHO;
+ 	YY_BREAK
+-#line 1772 "ael_lex.c"
++#line 1784 "ael_lex.c"
+ 
+ 	case YY_END_OF_BUFFER:
+ 		{
+@@ -2000,7 +2012,7 @@ static int yy_get_next_buffer (yyscan_t 
+ 
+ 		/* Read in more data. */
+ 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+-			yyg->yy_n_chars, num_to_read );
++			yyg->yy_n_chars, (size_t) num_to_read );
+ 
+ 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ 		}
+@@ -2024,6 +2036,14 @@ static int yy_get_next_buffer (yyscan_t 
+ 	else
+ 		ret_val = EOB_ACT_CONTINUE_SCAN;
+ 
++	if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
++		/* Extend the array by 50%, plus the number we really need. */
++		yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
++		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ael_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
++		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
++			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
++	}
++
+ 	yyg->yy_n_chars += number_to_move;
+ 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+@@ -2452,7 +2472,9 @@ static void ael_yyensure_buffer_stack (y
+ 		yyg->yy_buffer_stack = (struct yy_buffer_state**)ael_yyalloc
+ 								(num_to_alloc * sizeof(struct yy_buffer_state*)
+ 								, yyscanner);
+-		
++		if ( ! yyg->yy_buffer_stack )
++			YY_FATAL_ERROR( "out of dynamic memory in ael_yyensure_buffer_stack()" );
++								  
+ 		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+ 				
+ 		yyg->yy_buffer_stack_max = num_to_alloc;
+@@ -2470,6 +2492,8 @@ static void ael_yyensure_buffer_stack (y
+ 								(yyg->yy_buffer_stack,
+ 								num_to_alloc * sizeof(struct yy_buffer_state*)
+ 								, yyscanner);
++		if ( ! yyg->yy_buffer_stack )
++			YY_FATAL_ERROR( "out of dynamic memory in ael_yyensure_buffer_stack()" );
+ 
+ 		/* zero only the new slots.*/
+ 		memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+@@ -2514,7 +2538,7 @@ YY_BUFFER_STATE ael_yy_scan_buffer  (cha
+ 
+ /** Setup the input buffer state to scan a string. The next call to ael_yylex() will
+  * scan from a @e copy of @a str.
+- * @param str a NUL-terminated string to scan
++ * @param yystr a NUL-terminated string to scan
+  * @param yyscanner The scanner object.
+  * @return the newly allocated buffer state object.
+  * @note If you want to scan bytes that may contain NUL values, then use
+@@ -2528,8 +2552,8 @@ YY_BUFFER_STATE ael_yy_scan_string (yyco
+ 
+ /** Setup the input buffer state to scan the given bytes. The next call to ael_yylex() will
+  * scan from a @e copy of @a bytes.
+- * @param bytes the byte buffer to scan
+- * @param len the number of bytes in the buffer pointed to by @a bytes.
++ * @param yybytes the byte buffer to scan
++ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+  * @param yyscanner The scanner object.
+  * @return the newly allocated buffer state object.
+  */
+@@ -2788,6 +2812,42 @@ int ael_yylex_init(yyscan_t* ptr_yy_glob
+     return yy_init_globals ( *ptr_yy_globals );
+ }
+ 
++/* ael_yylex_init_extra has the same functionality as ael_yylex_init, but follows the
++ * convention of taking the scanner as the last argument. Note however, that
++ * this is a *pointer* to a scanner, as it will be allocated by this call (and
++ * is the reason, too, why this function also must handle its own declaration).
++ * The user defined value in the first argument will be available to ael_yyalloc in
++ * the yyextra field.
++ */
++
++int ael_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
++
++{
++    struct yyguts_t dummy_yyguts;
++
++    ael_yyset_extra (yy_user_defined, &dummy_yyguts);
++
++    if (ptr_yy_globals == NULL){
++        errno = EINVAL;
++        return 1;
++    }
++	
++    *ptr_yy_globals = (yyscan_t) ael_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
++	
++    if (*ptr_yy_globals == NULL){
++        errno = ENOMEM;
++        return 1;
++    }
++    
++    /* By setting to 0xAA, we expose bugs in
++    yy_init_globals. Leave at 0x00 for releases. */
++    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
++    
++    ael_yyset_extra (yy_user_defined, *ptr_yy_globals);
++    
++    return yy_init_globals ( *ptr_yy_globals );
++}
++
+ static int yy_init_globals (yyscan_t yyscanner)
+ {
+     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+@@ -2894,7 +2954,7 @@ void *ael_yyrealloc  (void * ptr, yy_siz
+ 
+ #define YYTABLES_NAME "yytables"
+ 
+-#line 470 "ael.flex"
++#line 476 "ael.flex"
+ 
+ 
+ 
--- 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 <paravoid@debian.org>
+
+--- 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/patches/AST-2011-003
+++ asterisk-1.4.21.2~dfsg/debian/patches/AST-2011-003
@@ -0,0 +1,52 @@
+Description: Resource exhaustion in Asterisk Manager Interface
+Origin: http://downloads.asterisk.org/pub/security/AST-2011-003-1.6.1.diff
+
+Rapidly opening manager connections, sending invalid data, and closing the
+connection can cause Asterisk to exhaust available CPU and memory resources.
+
+The manager interface is disabled by default in upstream, but enabled
+by default (listening on localhost only) in the version in Debian 5.0 (Lenny)
+and 6.0 (Squeeze).
+
+Backported from the upstream patch for 1.6.1.
+See also http://downloads.asterisk.org/pub/security/AST-2011-003.html
+
+diff --git a/main/manager.c b/main/manager.c
+index 2dc7664..f89a84d 100644
+--- a/main/manager.c
++++ b/main/manager.c
+@@ -180,6 +180,7 @@ struct mansession {
+ 	int writetimeout;
+ 	int pending_event;         /*!< Pending events indicator in case when waiting_thread is NULL */
+ 	AST_LIST_ENTRY(mansession) list;
++	int write_error:1;
+ };
+ 
+ static AST_LIST_HEAD_STATIC(sessions, mansession);
+@@ -494,9 +495,14 @@ void astman_append(struct mansession *s, const char *fmt, ...)
+ 	ast_dynamic_str_thread_set_va(&buf, 0, &astman_append_buf, fmt, ap);
+ 	va_end(ap);
+ 	
+-	if (s->fd > -1)
+-		ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout);
+-	else {
++	if (s->fd > -1) {
++		int res;
++
++		res = ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout);
++		if (res) {
++			s->write_error = 1;
++		}
++	} else {
+ 		if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) {
+ 			ast_mutex_unlock(&s->__lock);
+ 			return;
+@@ -2314,7 +2320,7 @@ static void *session_do(void *data)
+ 	
+ 	astman_append(s, "Asterisk Call Manager/1.0\r\n");
+ 	for (;;) {
+-		if ((res = do_message(s)) < 0)
++		if ((res = do_message(s)) < 0 || s->write_error)
+ 			break;
+ 	}
+ 	if (s->authenticated) {
--- 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 <msp@debian.org>
+
+--- 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/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 <kpj@junghanns.net>
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License
++ */
++
++#include "asterisk.h"
++#include <stdlib.h>
++#include <errno.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <sys/time.h>
++#include <sys/signal.h>
++#include <netinet/in.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>
++
++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/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 <unistd.h>
+ #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/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 <kpj@junghanns.net>
++ *
++ * Copyright (C) 2004, Florian Overkamp <florian@obsimref.com>
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License
++ */
++
++#include "asterisk.h"
++
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdio.h>
++#include <signal.h>
++#include <pthread.h>
++#include <asterisk/lock.h>
++#include <asterisk/file.h>
++#include <asterisk/logger.h>
++#include <asterisk/channel.h>
++#include <asterisk/pbx.h>
++#include <asterisk/module.h>
++#include <asterisk/features.h>
++#include <asterisk/options.h>
++
++
++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/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/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/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/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/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/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/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;x<AST_MAX_FDS;x++) {
++					if ((pu->chan->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;x<AST_MAX_FDS;x++) {
++						/* Keep this one for next one */
++						if (pu->chan->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-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 <kpj@junghanns.net>
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License
++ */
++
++#include "asterisk.h"
++
++#include <stdlib.h>
++#include <errno.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <sys/time.h>
++#include <sys/signal.h>
++#include <netinet/in.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++
++#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/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;x<pri->numchans;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/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/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 <levon@feature-it.com>
++ *
+  * 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/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 <kpj@junghanns.net>
++ *
+  * 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, "<unknown>"),
+-		S_OR(pu->chan->cid.cid_name, "<unknown>")
++		S_OR(pu->chan->cid.cid_name, "<unknown>"),
++		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, "<unknown>"),
+-		S_OR(chan->cid.cid_name, "<unknown>")
++		S_OR(chan->cid.cid_name, "<unknown>"),
++		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, "<unknown>"),
+-			S_OR(pu->chan->cid.cid_name, "<unknown>")
++			S_OR(pu->chan->cid.cid_name, "<unknown>"),
++			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 <unknown> */
+-			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;x<AST_MAX_FDS;x++) {
++				if ((pu->chan->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;x<AST_MAX_FDS;x++) {
++					/* Keep this one for next one */
++					if (pu->chan->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/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/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/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 <kpj@junghanns.net>
++ *
+  * 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/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/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/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/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/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 <kpj@junghanns.net>
++ *
++ *
+  * 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; i<pri->numchans; 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, "<unspecified>"),
++									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, "<unspecified>"),
+ 										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 <span>\n"
++	"       Enables debugging on a given BRI span\n";
++
++static char bri_no_debug_help[] =
++	"Usage: bri no debug span <span>\n"
++	"       Disables debugging on a given BRI span\n";
++
++static char bri_really_debug_help[] =
++	"Usage: bri intensive debug span <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/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 <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdio.h>
++
++#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-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 <kpj@junghanns.net>
++ *
++ * 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 <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdio.h>
++#include <asterisk/lock.h>
++#include <asterisk/file.h>
++#include <asterisk/logger.h>
++#include <asterisk/channel.h>
++#include <asterisk/pbx.h>
++#include <asterisk/module.h>
++
++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/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 <kpj@junghanns.net>
++ *
+  * 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/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 <kpj@junghanns.net>
++ *
+  * 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 <kpj@junghanns.net>
++ *
++ * based on eagi-test.c
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License
++ */
++
++#include <stdio.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <string.h>
++#include <sys/select.h>
++#ifdef SOLARIS
++#include <solaris-compat/compat.h>
++#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/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/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 <bristuffed/libpri.h>
+ #endif
++#ifdef HAVE_GSMAT
++#include <libgsmat.h>
++#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 <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 <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 <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 <span>\n"
++	"       Reset/Restart a zaptel span\n";
++
++static char gsm_debug_help[] =
++	"Usage: gsm debug channel <channel>\n"
++	"       Enables debugging on a given GSM channel\n";
++
++static char gsm_no_debug_help[] =
++	"Usage: gsm no debug channel <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 <channel> <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 <channel> <destination> <message> */
++	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 <channel> <destination> <message>\n"
++	"       Sends a SM on a GSM channel\n";
++
++
++static int handle_gsm_send_sms(int fd, int argc, char *argv[])
++{
++/* gsm send sms <channel> <destination> <message> */
++	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 <channel>>\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 <libgsmat.h>
++_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 <libgsmat.h>
++_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/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/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/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/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
