]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/commitdiff
Fixes an den Netzwerkscripts und der Netzwerkroutine im Setup.
authorms <ms@ea5c0bd1-69bd-2848-81d8-4f18e57aeed8>
Fri, 17 Aug 2007 11:14:27 +0000 (11:14 +0000)
committerms <ms@ea5c0bd1-69bd-2848-81d8-4f18e57aeed8>
Fri, 17 Aug 2007 11:14:27 +0000 (11:14 +0000)
Viele alte Patches entfernt.

git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@775 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8

18 files changed:
config/rootfiles/common/initscripts
src/initscripts/init.d/network
src/install+setup/setup/networking.c
src/patches/asterisk.patch [deleted file]
src/patches/capi4k-utils-2004-10-06_ppp-2.4.3.patch [deleted file]
src/patches/fritz-dsl-gcc-4-fix.patch [deleted file]
src/patches/fritz-fcdslusb-owner.patch [deleted file]
src/patches/ibod-config.patch [deleted file]
src/patches/isdn4k-utils-0202131200-true.patch [deleted file]
src/patches/isdn4k-utils-CVS-2004-11-18-autoconf25x.patch [deleted file]
src/patches/isdn4k-utils-CVS-2006-02-13-cleanup.patch [deleted file]
src/patches/isdn4k-utils-CVS-2006-07-20-pppd-2.4.4.patch [deleted file]
src/patches/isdn4k-utils-CVS-2006-07-20-redhat.patch [deleted file]
src/patches/isdn4k-utils-capiinit.patch [deleted file]
src/patches/isdn4k-utils-statfs.patch [deleted file]
src/patches/libpri.patch [deleted file]
src/patches/zaphfc_0.3.0-PRE-1o_florz-12.diff [deleted file]
src/patches/zaptel.patch [deleted file]

index f1c0f8a303c8d3e6f8a4d6faa1a62e89bbb8a87e..8be1328ee3a5b14f53b8497acd14ee9595772c6a 100644 (file)
@@ -2,7 +2,7 @@
 #etc/rc.d/helper
 etc/rc.d/helper/getdnsfromdhcpc.pl
 etc/rc.d/helper/writeipac.pl
-#etc/rc.d/init.d
+etc/rc.d/init.d
 #etc/rc.d/init.d/alsa
 etc/rc.d/init.d/apache
 #etc/rc.d/init.d/applejuice
@@ -34,7 +34,7 @@ etc/rc.d/init.d/networking/any
 etc/rc.d/init.d/networking/blue
 etc/rc.d/init.d/networking/green
 etc/rc.d/init.d/networking/orange
-#etc/rc.d/init.d/networking/red
+etc/rc.d/init.d/networking/red
 #etc/rc.d/init.d/networking/red.down
 etc/rc.d/init.d/networking/red.down/05-RS-dnsmasq
 etc/rc.d/init.d/networking/red.down/10-ipsec
index 579cbe02619fe039c4465d37c562e99d54977081..e4f2a1b5b17149bd3e51794bf593a7a5e189700b 100644 (file)
 . ${rc_functions}
 eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
 
+init_networking() {
+
+       boot_mesg "Loading firewall modules into the kernel"
+       modprobe iptable_nat || failed=1
+       for i in $(find /lib/modules/$(uname -r) -name ip_conntrack*); do
+               modprobe $i || failed=1
+       done
+       for i in $(find /lib/modules/$(uname -r) -name ip_nat*); do
+               modprobe $i || failed=1
+       done
+       (exit ${failed})
+       evaluate_retval
+                        
+       boot_mesg "Setting up firewall"
+       /etc/rc.d/init.d/firewall start; evaluate_retval
+
+       boot_mesg "Setting up traffic accounting"
+       /etc/rc.d/helper/writeipac.pl || failed=1
+       /usr/sbin/fetchipac -S || failed=1
+       (exit ${failed})
+       evaluate_retval
+
+       boot_mesg "Setting up DMZ pinholes"
+       /usr/local/bin/setdmzholes; evaluate_retval
+
+       if [ "$CONFIG_TYPE" = "3" -o "$CONFIG_TYPE" = "4" ]; then
+               boot_mesg "Setting up wireless firewall rules"
+               /usr/local/bin/restartwireless; evaluate_retval
+       fi
+
+       /etc/rc.d/init.d/dnsmasq start
+}
+
 DO="${1}"
 shift
 
@@ -104,37 +137,4 @@ case "${DO}" in
                ;;
 esac
 
-init_networking() {
-
-       boot_mesg "Loading firewall modules into the kernel"
-       modprobe iptable_nat || failed=1
-       for i in $(find /lib/modules/$(uname -r) -name ip_conntrack*); do
-               modprobe $i || failed=1
-       done
-       for i in $(find /lib/modules/$(uname -r) -name ip_nat*); do
-               modprobe $i || failed=1
-       done
-       (exit ${failed})
-       evaluate_retval
-                        
-       boot_mesg "Setting up firewall"
-       /etc/rc.d/init.d/firewall start; evaluate_retval
-
-       boot_mesg "Setting up traffic accounting"
-       /etc/rc.d/helper/writeipac.pl || failed=1
-       /usr/sbin/fetchipac -S || failed=1
-       (exit ${failed})
-       evaluate_retval
-
-       boot_mesg "Setting up DMZ pinholes"
-       /usr/local/bin/setdmzholes; evaluate_retval
-
-       if [ "$CONFIG_TYPE" = "3" -o "$CONFIG_TYPE" = "4" ]; then
-               boot_mesg "Setting up wireless firewall rules"
-               /usr/local/bin/restartwireless; evaluate_retval
-       fi
-
-       /etc/rc.d/init.d/dnsmasq start
-}
-
 # End /etc/rc.d/init.d/network
index 6bac6b60844ef9cb1e754b4e7788bf212f8c8054..ed18f40293b7682e4124b32f1015ae7ddf45d0f6 100644 (file)
@@ -41,7 +41,7 @@ int configtypecards[] = {
        2,      // "GREEN + RED",
        3,      // "GREEN + RED + ORANGE",
        3,      // "GREEN + RED + BLUE",
-       4       // "GREEN + RED + ORANGE + BLUE",
+       4         // "GREEN + RED + ORANGE + BLUE",
 };
 
 
@@ -282,6 +282,7 @@ int configtypemenu(void)
        found = scan_network_cards();
        
        findkey(kv, "CONFIG_TYPE", temp); choise = atol(temp);
+       choise--;
 
        do
        {
diff --git a/src/patches/asterisk.patch b/src/patches/asterisk.patch
deleted file mode 100644 (file)
index 8331701..0000000
+++ /dev/null
@@ -1,14804 +0,0 @@
-diff -urN asterisk-1.2.10.orig/.version asterisk-1.2.10/.version
---- asterisk-1.2.10.orig/.version      2006-07-14 23:29:33.000000000 +0200
-+++ asterisk-1.2.10/.version   2006-07-31 14:13:27.000000000 +0200
-@@ -1 +1 @@
--1.2.10
-+1.2.10-BRIstuffed-0.3.0-PRE-1s
-diff -urN asterisk-1.2.10.orig/HARDWARE asterisk-1.2.10/HARDWARE
---- asterisk-1.2.10.orig/HARDWARE      2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/HARDWARE   2006-07-31 14:13:08.000000000 +0200
-@@ -37,6 +37,19 @@
-    * 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
- ==============================
-diff -urN asterisk-1.2.10.orig/LICENSE asterisk-1.2.10/LICENSE
---- asterisk-1.2.10.orig/LICENSE       2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/LICENSE    2006-07-31 14:13:08.000000000 +0200
-@@ -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.
-diff -urN asterisk-1.2.10.orig/Makefile asterisk-1.2.10/Makefile
---- asterisk-1.2.10.orig/Makefile      2006-06-29 21:23:18.000000000 +0200
-+++ asterisk-1.2.10/Makefile   2006-08-10 11:07:53.000000000 +0200
-@@ -772,6 +772,9 @@
-               echo ";astctlowner = root" ; \
-               echo ";astctlgroup = apache" ; \
-               echo ";astctl = asterisk.ctl" ; \
-+              echo "[options]" ; \
-+              echo "uniquename = `hostname`" ;\
-+              echo "silence_suppression = yes" ;\
-               ) > $(DESTDIR)$(ASTCONFPATH) ; \
-       else \
-               echo "Skipping asterisk.conf creation"; \
-diff -urN asterisk-1.2.10.orig/README asterisk-1.2.10/README
---- asterisk-1.2.10.orig/README        2006-03-03 09:12:33.000000000 +0100
-+++ asterisk-1.2.10/README     2006-07-31 14:13:08.000000000 +0200
-@@ -4,6 +4,8 @@
- Copyright (C) 2001-2005 Digium, Inc.
- and other copyright holders.
-+Copyright (C) 2002-2005 Junghanns.NET GmbH 
-+and other copyright holders.
- ================================================================
- * SECURITY
-diff -urN asterisk-1.2.10.orig/README.chan_capi asterisk-1.2.10/README.chan_capi
---- asterisk-1.2.10.orig/README.chan_capi      1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/README.chan_capi   2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,146 @@
-+(CAPI*) chan_capi a Common ISDN API 2.0 implementation for Asterisk
-+(C) 2002, 2003, 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 Public License. There is _NO_ warranty for this!
-+
-+Thanks go to the debuggers and bugfixers (listed in chronological order) :)
-+===========================================================================
-+Lele Forzani <lele@windmill.it>
-+Florian Overkamp <florian@obsimref.com>
-+Gareth Watts <gareth@omnipotent.net>
-+Jeff Noxon <jeff@planetfall.com>
-+Petr Michalek <petr.michalek@aca.cz>
-+Jan Stocker
-+(...and all the others that i forgot..) :-)
-+
-+chan_capi version 0.4.0-PRE1 includes:
-+======================================
-+
-+- multiple controller support
-+- CID,DNID (callling party, called party)
-+- CLIR/CLIP
-+- supplementary services, CD,HOLD,RETRIEVE,ECT
-+- DTMF (dependend on card) + software DTMF support
-+- early B3 connects (always,success,never)
-+- digital audio (what did you think?)
-+- incoming/outgoing calls
-+- overlap sending (dialtone)
-+- E(xplicit) C(all) T(ransfer) (...although it's done implicit .. but dont tell!)
-+- tuneable latency ;) you can configure the size of B3 blocks at compile time
-+  (in chan_capi_pvt.h, AST_CAPI_MAX_B3_BLOCK_SIZE)
-+  the default is 160 samples, for non-VoIP use you can tune it down to 130
-+- use asterisk's internal dsp functions for dtmf
-+- alaw support 
-+- ulaw support! 
-+- Eicon CAPI echo cancelation (echocancel=1)
-+- reject call waiting (ACO)
-+- DID for Point to Point mode (a.k.a overlap receiving)
-+- experimental echo squelching (echosquelch=1)
-+- call progress, no need to add ||r to your dialstring anymore
-+- rx/tx gains (rxgain=1.0)
-+- call deflection on circuitbusy (makefile option) (deflect=12345678)
-+- (inter)national dialing prefix (for callerid) configurable in capi.conf
-+- CLI command "capi info" shows B channel status
-+- capiECT will announce the callerID since it gets lost on most isdn pbxes
-+  the called party can press # to drop the call
-+- audio syncing (timing outgoing dataB3 on incoming dataB3), supposed to fix
-+  the DATA_B3_REQ (error = 0x1103) problem
-+- catch all MSN (incomingmsn=*)
-+- some configuration enhancements (msn=123,124,125 and controller=1,2,3,4)
-+- accountcode= added.
-+- finally the echo squelching works!
-+- callgroup support
-+- fixed pipe leak
-+- updated to support the new frame->delivery field
-+- compiles with latest cvs with a makefile option (LOOK AT THE MAKEFILE)
-+- fixed channel name bug in p2p mode
-+- added app_capiNoES for disabling the primitive echo suppressor, use this before
-+  you start recording voicemail or your files may get choppy
-+- fixed for latest cvs (AST_MUTEX_DEFINE_STATIC)
-+- fixed for latest cvs (asterisk/parking.h -> asterisk/features.h)
-+- fixed for latest cvs ast_pthread_create
-+
-+- ATTENTION! the dialstring syntax now uses the zaptel dialstring syntax 
-+  it used to be:  Dial(CAPI/[@]<outgoingMSN>:[b|B]<destination>)
-+ 
-+  now it is:      Dial(CAPI/g<group>/[b|B]<destination>)
-+  or:             Dial(CAPI/contr<controller>/[b|B]<destination>)
-+ 
-+  CLIP/CLIR is now uses the calling presentation of the calling channel, this can
-+  be modified using the CallingPres() application. Use CallinPres(32) for CLIR.
-+  That is why the msn= param in capi.conf is now obsolete. The callerID is also
-+  taken from the calling channel.
-+
-+- fixes for BSD (Jan Stocker)
-+
-+Helper applications
-+===================
-+kapejod says: "No No No, dont use those yet....!" (except maybe HOLD,ECT...)
-+
-+app_capiCD.c          forwards an unanswered call to another phone (does not rely on sservice CD)
-+                      example:
-+                      exten => s,1,Wait,1
-+                      exten => s,2,capiCD,12345678
-+                      
-+app_capiHOLD.c                puts an answered call on hold, this has nothing to do with asterisk's onhold thingie (music et al)
-+                      after putting a call onhold, never use the Wait application!
-+
-+app_capiRETRIEVE.c    gets the holded call back
-+
-+app_capiECT.c         explicit call transfer of the holded call (must put call on hold first!)
-+                      example:
-+                      exten => s,1,Answer
-+                      exten => s,2,capiHOLD
-+                      exten => s,3,capiECT,55:50
-+                      will ECT the call to 50 using 55 as the callerid/outgoing msn
-+
-+
-+Using CLIR
-+==========
-+Use the CallingPres() application before you dial:
-+exten => _X.,1,CallingPres(32)
-+exten => _X.,2,Dial(CAPI/contr1/${EXTEN})    
-+
-+Enjoying early B3 connects (inband call progress, tones and announcements)
-+==========================================================================
-+early B3 is now configurable in the dialstring :)
-+if you prefix the destination number with a 'b' early B3 will always be used, also if the call fails
-+because the number is unprovisioned, etc ...
-+if you prefix it with a 'B' early B3 will only be used on successful calls, giving you ring indication,etc...
-+
-+dont use indications in the Dial command, your local exchange will do that for you:
-+exten => _X.,1,Dial(CAPI/contr1/B${EXTEN},30)         (early B3 on success)
-+exten => _X.,1,Dial(CAPI/contr1/b${EXTEN},30)         (always early B3)
-+exten => _X.,1,Dial(CAPI/contr1/${EXTEN},30,r)                (no early B3, fake ring indication)
-+
-+exten => _X.,1,Dial(CAPI/contr1/b${EXTEN},30,r)               (always early B3, fake indicatons if the exchange
-+                                                      does not give us indications)
-+exten => _X.,1,Dial(CAPI/contr1/B${EXTEN},30,r)               (early B3 on success, fake indicatons if the exchange
-+                                                      does not give us indications)
-+    
-+you can totally turn B3 off in the Makefile at buildtime (-DNEVER_EVER_EARLY_B3_CONNECTS).
-+
-+For normal PBX usage you would use the "b" option, always early B3.
-+
-+Overlap sending (a.k.a. real dialtone)
-+======================================
-+when you dial an empty number, and have early B3 enabled, with:
-+    Dial(CAPI/g1/b)
-+the channel will come up at once and give you the dialtone it gets from the local exchange.
-+at this point the channel is like a legacy phone, now you can send dtmf digits to dial.    
-+
-+Example context for incoming calls on MSN 12345678:
-+===================================================
-+
-+[capi-in]
-+exten => 12345678,1,Dial(SIP/phone1)
-+exten => 12345678,2,Hangup
-+
-+
-+More information/documentation and commercial support can be found at:
-+      http://www.junghanns.net/asterisk/
-+      
-+
-+
-diff -urN asterisk-1.2.10.orig/agi/Makefile asterisk-1.2.10/agi/Makefile
---- asterisk-1.2.10.orig/agi/Makefile  2006-03-28 22:22:05.000000000 +0200
-+++ asterisk-1.2.10/agi/Makefile       2006-07-31 14:13:08.000000000 +0200
-@@ -11,7 +11,7 @@
- # the GNU General Public License
- #
--AGIS=agi-test.agi eagi-test eagi-sphinx-test
-+AGIS=agi-test.agi eagi-test eagi-sphinx-test xagi-test
- CFLAGS+=-DNO_AST_MM
-@@ -37,7 +37,7 @@
-       $(CC) $(CFLAGS) -o eagi-sphinx-test eagi-sphinx-test.o $(LIBS) 
- clean:
--      rm -f *.so *.o look .depend eagi-test eagi-sphinx-test
-+      rm -f *.so *.o look .depend eagi-test eagi-sphinx-test xagi-test
- %.so : %.o
-       $(CC) -shared -Xlinker -x -o $@ $<
-diff -urN asterisk-1.2.10.orig/agi/xagi-test.c asterisk-1.2.10/agi/xagi-test.c
---- asterisk-1.2.10.orig/agi/xagi-test.c       1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/agi/xagi-test.c    2006-07-31 14:13:08.000000000 +0200
-@@ -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);
-+}
-diff -urN asterisk-1.2.10.orig/apps/Makefile asterisk-1.2.10/apps/Makefile
---- asterisk-1.2.10.orig/apps/Makefile 2006-04-30 15:38:22.000000000 +0200
-+++ asterisk-1.2.10/apps/Makefile      2006-07-31 14:13:08.000000000 +0200
-@@ -28,8 +28,15 @@
-      app_test.so app_forkcdr.so app_math.so app_realtime.so \
-      app_dumpchan.so app_waitforsilence.so app_while.so app_setrdnis.so \
-      app_md5.so app_readfile.so app_chanspy.so app_settransfercapability.so \
-+     app_pickup.so app_segfault.so app_callingpres.so app_devstate.so \
-      app_dictate.so app_externalivr.so app_directed_pickup.so \
--     app_mixmonitor.so app_stack.so
-+     app_mixmonitor.so app_stack.so 
-+
-+
-+ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/capi20.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/capi20.h),)
-+  APPS+= app_capiNoES.so app_capiCD.so app_capiECT.so
-+endif
-+    
- #
- # Obsolete things...
-diff -urN asterisk-1.2.10.orig/apps/app_callingpres.c asterisk-1.2.10/apps/app_callingpres.c
---- asterisk-1.2.10.orig/apps/app_callingpres.c        1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/apps/app_callingpres.c     2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,70 @@
-+/*
-+ * An application to change the CallingPresentation for an Asterisk channel.
-+ *
-+ * 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 <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 *synopsis_callingpres = "Change the presentation for the callerid";
-+static char *descrip_callingpres = "Callingpres(number): Changes the presentation for the callerid. Should be called before placing an outgoing call\n";
-+static char *app_callingpres = "CallingPres";
-+STANDARD_LOCAL_USER;
-+LOCAL_USER_DECL;
-+
-+
-+static int change_callingpres(struct ast_channel *chan, void *data)
-+{
-+    int mode = 0;
-+    struct localuser *u;
-+    LOCAL_USER_ADD(u);
-+    if (data) {
-+        mode = atoi((char *)data);
-+        chan->cid.cid_pres = mode;
-+    } else
-+        ast_log(LOG_NOTICE, "Application %s requres an argument: %s(number)\n", app_callingpres,app_callingpres);
-+    LOCAL_USER_REMOVE(u);
-+    return 0;
-+}    
-+
-+int unload_module(void)
-+{
-+    STANDARD_HANGUP_LOCALUSERS;
-+    return ast_unregister_application(app_callingpres);
-+}
-+
-+int load_module(void)
-+{
-+    return ast_register_application(app_callingpres, change_callingpres, synopsis_callingpres, descrip_callingpres);
-+}
-+
-+char *description(void)
-+{
-+    return descrip_callingpres;
-+}
-+
-+int usecount(void)
-+{
-+    int res;
-+    STANDARD_USECOUNT(res);
-+    return res;
-+}
-+
-+char *key()
-+{
-+    return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/apps/app_capiCD.c asterisk-1.2.10/apps/app_capiCD.c
---- asterisk-1.2.10.orig/apps/app_capiCD.c     1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/apps/app_capiCD.c  2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,172 @@
-+/*
-+ * (CAPI*)
-+ *
-+ * An implementation of Common ISDN API 2.0 for Asterisk
-+ *
-+ * Call Deflection, inspired by capircvd by Alexander Brickwedde
-+ *
-+ * Copyright (C) 2002,2003,2004,2005 Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
-+ *
-+ * This program is free software and may be modified and 
-+ * distributed under the terms of the GNU Public License.
-+ */
-+
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdio.h>
-+#include <linux/capi.h>
-+#include <capi20.h>
-+
-+#include <asterisk/file.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/module.h>
-+#include <asterisk/chan_capi.h>
-+#include <asterisk/chan_capi_app.h>
-+
-+
-+
-+static char *tdesc = "(CAPI*) Call Deflection, the magic thing.";
-+static char *app = "capiCD";
-+static char *synopsis = "call deflection";
-+
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+static int capiCD_exec(struct ast_channel *chan, void *data)
-+{
-+    struct ast_capi_pvt *i = chan->tech_pvt;
-+    MESSAGE_EXCHANGE_ERROR Info;
-+    _cmsg     CMSG;
-+    char      bchaninfo[1];
-+    char      fac[60];
-+    int res=0;
-+    int ms=3000;
-+    struct localuser *u;
-+
-+    if (!data) {
-+      ast_log(LOG_WARNING, "cd requires an argument (destination phone number)\n");
-+      return -1;
-+    }
-+    LOCAL_USER_ADD(u);
-+    /* Do our thing here */
-+
-+    if ((i->state == CAPI_STATE_CONNECTED) || (i->state == CAPI_STATE_BCONNECTED)) {
-+      ast_log(LOG_ERROR, "call deflection does not work with calls that are already connected!\n");
-+      LOCAL_USER_REMOVE(u);
-+      return -1;
-+    }
-+    // wait until the channel is alerting, so we dont drop the call and interfer with msgs
-+    while ((ms > 0) && (i->state != CAPI_STATE_ALERTING)) {
-+      sleep(100);
-+      ms -= 100;
-+    }
-+
-+    // make sure we hang up correctly
-+    i->state = CAPI_STATE_CONNECTPENDING;
-+
-+    fac[0]=0; // len 
-+    fac[1]=0; //len 
-+    fac[2]=0x01; // Use D-Chan
-+    fac[3]=0; // Keypad len
-+    fac[4]=31;        // user user data? len = 31 = 29 + 2
-+    fac[5]=0x1c;      // magic?
-+    fac[6]=0x1d;      // strlen destination + 18 = 29
-+    fac[7]=0x91;      // ..
-+    fac[8]=0xA1;
-+    fac[9]=0x1A;      // strlen destination + 15 = 26
-+    fac[10]=0x02;
-+    fac[11]=0x01;
-+    fac[12]=0x70;
-+    fac[13]=0x02;
-+    fac[14]=0x01;
-+    fac[15]=0x0d;
-+    fac[16]=0x30;
-+    fac[17]=0x12;     // strlen destination + 7 = 18
-+    fac[18]=0x30;     // ...hm 0x30
-+    fac[19]=0x0d;     // strlen destination + 2       
-+    fac[20]=0x80;     // CLIP
-+    fac[21]=0x0b;     //  strlen destination 
-+    fac[22]=0x01;     //  destination start
-+    fac[23]=0x01;     //  
-+    fac[24]=0x01;     //  
-+    fac[25]=0x01;     //  
-+    fac[26]=0x01;     //  
-+    fac[27]=0x01;     //  
-+    fac[28]=0x01;     //  
-+    fac[29]=0x01;     //  
-+    fac[30]=0x01;     //  
-+    fac[31]=0x01;     //  
-+    fac[32]=0x01;     //  
-+    fac[33]=0x01;     // 0x1 = sending complete
-+    fac[34]=0x01;
-+    fac[35]=0x01;
-+                                 
-+    memcpy((unsigned char *)fac+22,data,strlen(data));
-+    fac[22+strlen(data)]=0x01;        // fill with 0x01 if number is only 6 numbers (local call)
-+    fac[23+strlen(data)]=0x01;
-+    fac[24+strlen(data)]=0x01;
-+    fac[25+strlen(data)]=0x01;
-+    fac[26+strlen(data)]=0x01;
-+     
-+    fac[6]=18+strlen(data);
-+    fac[9]=15+strlen(data);
-+    fac[17]=7+strlen(data);
-+    fac[19]=2+strlen(data);
-+    fac[21]=strlen(data);
-+
-+    bchaninfo[0] = 0x1;
-+    INFO_REQ_HEADER(&CMSG,ast_capi_ApplID,ast_capi_MessageNumber++,0);
-+    INFO_REQ_CONTROLLER(&CMSG) = i->controller;
-+    INFO_REQ_PLCI(&CMSG) = i->PLCI;
-+    INFO_REQ_BCHANNELINFORMATION(&CMSG) = (unsigned char*)bchaninfo; // use D-Channel
-+    INFO_REQ_KEYPADFACILITY(&CMSG) = 0;
-+    INFO_REQ_USERUSERDATA(&CMSG) = 0;
-+    INFO_REQ_FACILITYDATAARRAY(&CMSG) = (unsigned char*) fac + 4;
-+
-+    if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
-+      ast_log(LOG_ERROR,"Error sending INFO_REQ\n");
-+      return Info;
-+    } else {
-+      if (capidebug) {
-+          // ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(&CMSG));
-+          ast_log(LOG_NOTICE,"sent INFO_REQ PLCI = %#x\n",i->PLCI);
-+      }
-+    }
-+
-+    LOCAL_USER_REMOVE(u);
-+    return res;
-+}
-+
-+int unload_module(void)
-+{
-+      STANDARD_HANGUP_LOCALUSERS;
-+      return ast_unregister_application(app);
-+}
-+
-+int load_module(void)
-+{
-+      return ast_register_application(app, capiCD_exec,synopsis,tdesc);
-+}
-+
-+char *description(void)
-+{
-+      return tdesc;
-+}
-+
-+int usecount(void)
-+{
-+      int res;
-+      STANDARD_USECOUNT(res);
-+      return res;
-+}
-+
-+char *key()
-+{
-+      return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/apps/app_capiECT.c asterisk-1.2.10/apps/app_capiECT.c
---- asterisk-1.2.10.orig/apps/app_capiECT.c    1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/apps/app_capiECT.c 2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,210 @@
-+/*
-+ * (CAPI*)
-+ *
-+ * An implementation of Common ISDN API 2.0 for Asterisk
-+ *
-+ * ECT transfer the held call 
-+ *
-+ * Copyright (C) 2002,2003,2004,2005 Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
-+ *
-+ * This program is free software and may be modified and 
-+ * distributed under the terms of the GNU Public License.
-+ */
-+
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdio.h>
-+#include <linux/capi.h>
-+#include <capi20.h>
-+#include <asterisk/file.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/module.h>
-+#include <asterisk/say.h>
-+#include <asterisk/chan_capi.h>
-+#include <asterisk/chan_capi_app.h>
-+
-+
-+static char *tdesc = "(CAPI*) ECT";
-+static char *app = "capiECT";
-+static char *synopsis = "transfer the call that is on hold";
-+
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+
-+static int capiECT_exec(struct ast_channel *chan, void *data)
-+{
-+    struct ast_capi_pvt *i = chan->tech_pvt;
-+    MESSAGE_EXCHANGE_ERROR Info;
-+    _cmsg     CMSG;
-+    unsigned char fac[8];
-+    int res=0;
-+    struct localuser *u;
-+    char *ecodes = "*#";
-+
-+    if (!data) {
-+      ast_log(LOG_WARNING, "ECT requires an argument (destination phone number)\n");
-+      return -1;
-+    }
-+    LOCAL_USER_ADD(u);
-+    /* Do our thing here */
-+    if (i->onholdPLCI <= 0) {
-+      ast_log(LOG_WARNING, "no call on hold that could be transfered\n");
-+      return -1;
-+    }
-+
-+    ast_log(LOG_NOTICE,"ECT to %s\n",(char *)data);
-+    capi_call(chan,data,0);
-+
-+    while ((i->state != CAPI_STATE_BCONNECTED) && (i->onholdPLCI != 0)) {
-+      usleep(10000);
-+    }
-+
-+
-+    if (i->state == CAPI_STATE_BCONNECTED) {
-+      ast_log(LOG_NOTICE,"call was answered\n");
-+
-+      capi_detect_dtmf(chan,1);
-+
-+      // put the stuff to play announcement message here --->   <-----
-+      res = ast_say_digit_str(chan,i->cid,ecodes,chan->language);
-+      if ( res == '#') {
-+          ast_log(LOG_NOTICE,"res = %d\n",res);
-+          // user pressed #, hangup
-+              // first the holded user
-+//            ast_exec("capiRETRIEVE",chan);
-+
-+              DISCONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+              DISCONNECT_REQ_PLCI(&CMSG) = i->onholdPLCI;
-+
-+              if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
-+                  ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",i->onholdPLCI);
-+              } else {
-+                  ast_log(LOG_NOTICE, "sent DISCONNECT_REQ PLCI=%#x\n",i->onholdPLCI);
-+              }
-+              
-+              // then the destination
-+
-+              DISCONNECT_B3_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+              DISCONNECT_B3_REQ_NCCI(&CMSG) = i->NCCI;
-+
-+              if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
-+                  ast_log(LOG_NOTICE, "error sending DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
-+              } else {
-+                  ast_log(LOG_NOTICE, "sent DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
-+              }
-+
-+              // wait for the B3 layer to go down
-+              while (i->state != CAPI_STATE_CONNECTED) {
-+                  usleep(10000);
-+              }
-+
-+              DISCONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+              DISCONNECT_REQ_PLCI(&CMSG) = i->PLCI;
-+
-+              if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
-+                  ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
-+              } else {
-+                  ast_log(LOG_NOTICE, "sent DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
-+              }
-+              
-+              
-+              LOCAL_USER_REMOVE(u);
-+              return -1;
-+
-+      } else {
-+          // now drop the bchannel
-+          DISCONNECT_B3_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+          DISCONNECT_B3_REQ_NCCI(&CMSG) = i->NCCI;
-+
-+          if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
-+              ast_log(LOG_NOTICE, "error sending DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
-+          } else {
-+              ast_log(LOG_NOTICE, "sent DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
-+          }
-+
-+          // wait for the B3 layer to go down
-+          while (i->state != CAPI_STATE_CONNECTED) {
-+              usleep(10000);
-+          } 
-+      }
-+    }
-+
-+    // the caller onhold hungup or died away, drop the answered call
-+    if (i->onholdPLCI == 0) {
-+      DISCONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+      DISCONNECT_REQ_PLCI(&CMSG) = i->PLCI;
-+
-+      if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
-+          ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
-+      } else {
-+          ast_log(LOG_NOTICE, "sent DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
-+      }
-+      return -1;
-+    }
-+
-+    ast_log(LOG_NOTICE,"onholdPLCI = %d\n",i->onholdPLCI);
-+
-+
-+    fac[0] = 7;       // len
-+    fac[1] = 0x06; // ECT (function)
-+    fac[2] = 0x00;
-+    fac[3] = 4; //len //sservice specific parameter , cstruct
-+    fac[4] = (i->onholdPLCI << 8 ) >> 8;
-+    fac[5] = i->onholdPLCI >> 8;
-+    fac[6] = 0;
-+    fac[7] = 0;
-+
-+    FACILITY_REQ_HEADER(&CMSG,ast_capi_ApplID,ast_capi_MessageNumber++,0);
-+    FACILITY_REQ_CONTROLLER(&CMSG) = i->controller;
-+    FACILITY_REQ_PLCI(&CMSG) = i->onholdPLCI;
-+    FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 0x0003; // sservices
-+    FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (unsigned char *)&fac;
-+
-+    if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
-+      ast_log(LOG_ERROR,"Error sending FACILITY_REQ\n");
-+      return Info;
-+    } else {
-+      ast_log(LOG_NOTICE,"sent FACILITY_REQ PLCI = %#x (%#x %#x) onholdPLCI = %#x\n ",i->PLCI,fac[4],fac[5],i->onholdPLCI);
-+      ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(&CMSG));
-+    }
-+
-+//    i->outgoing = -1; // incoming + outgoing, this is a magic channel :)
-+
-+    LOCAL_USER_REMOVE(u);
-+    return res;
-+}
-+
-+int unload_module(void)
-+{
-+      STANDARD_HANGUP_LOCALUSERS;
-+      return ast_unregister_application(app);
-+}
-+
-+int load_module(void)
-+{
-+      return ast_register_application(app, capiECT_exec,synopsis,tdesc);
-+}
-+
-+char *description(void)
-+{
-+      return tdesc;
-+}
-+
-+int usecount(void)
-+{
-+      int res;
-+      STANDARD_USECOUNT(res);
-+      return res;
-+}
-+
-+char *key()
-+{
-+      return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/apps/app_capiNoES.c asterisk-1.2.10/apps/app_capiNoES.c
---- asterisk-1.2.10.orig/apps/app_capiNoES.c   1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/apps/app_capiNoES.c        2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,96 @@
-+/*
-+ * (CAPI*)
-+ *
-+ * An implementation of Common ISDN API 2.0 for Asterisk
-+ *
-+ * Disable echo suppression (useful for fax and voicemail!)
-+ *
-+ * Copyright (C) 2004,2005 Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
-+ *
-+ * This program is free software and may be modified and 
-+ * distributed under the terms of the GNU Public License.
-+ */
-+
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdio.h>
-+#include <linux/capi.h>
-+#include <capi20.h>
-+
-+#include <asterisk/file.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/module.h>
-+#include <asterisk/chan_capi_app.h>
-+
-+
-+
-+#ifdef CAPI_ES
-+static char *tdesc = "(CAPI*) No Echo Suppression.";
-+static char *app = "capiNoES";
-+static char *synopsis = "Disable Echo Suppression";
-+#else
-+static char *tdesc = "(CAPI*) No Echo Suppression at all!";
-+static char *app = "capiNoES";
-+static char *synopsis = "Bogus Application";
-+#endif
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+static int capiNoES_exec(struct ast_channel *chan, void *data)
-+{
-+    int res=0;
-+    struct localuser *u;
-+    LOCAL_USER_ADD(u);
-+
-+#ifdef CAPI_ES
-+    if (strcasecmp("CAPI",chan->type) == 0) {
-+#ifdef CVS_HEAD
-+      struct ast_capi_pvt *i = chan->tech_pvt;
-+#else
-+      struct ast_capi_pvt *i = chan->pvt->pvt;
-+#endif
-+      if (i->doES == 1) {
-+          i->doES = 0;
-+      }
-+    } else {
-+      ast_log(LOG_WARNING, "capiNoES only works on CAPI channels, check your extensions.conf!\n");
-+    }
-+#endif
-+
-+    LOCAL_USER_REMOVE(u);
-+    return res;
-+}
-+
-+int unload_module(void)
-+{
-+      STANDARD_HANGUP_LOCALUSERS;
-+      return ast_unregister_application(app);
-+}
-+
-+int load_module(void)
-+{
-+      return ast_register_application(app, capiNoES_exec,synopsis,tdesc);
-+}
-+
-+char *description(void)
-+{
-+      return tdesc;
-+}
-+
-+int usecount(void)
-+{
-+      int res;
-+      STANDARD_USECOUNT(res);
-+      return res;
-+}
-+
-+char *key()
-+{
-+      return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/apps/app_chanisavail.c asterisk-1.2.10/apps/app_chanisavail.c
---- asterisk-1.2.10.orig/apps/app_chanisavail.c        2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/apps/app_chanisavail.c     2006-07-31 14:13:08.000000000 +0200
-@@ -118,7 +118,7 @@
-                               snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
-                               status = inuse = ast_device_state(trychan);
-                       }
--                      if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
-+                      if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status, NULL))) {
-                                       pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
-                                       /* Store the originally used channel too */
-                                       snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
-diff -urN asterisk-1.2.10.orig/apps/app_chanspy.c asterisk-1.2.10/apps/app_chanspy.c
---- asterisk-1.2.10.orig/apps/app_chanspy.c    2006-06-14 16:07:53.000000000 +0200
-+++ asterisk-1.2.10/apps/app_chanspy.c 2006-07-31 14:13:08.000000000 +0200
-@@ -55,6 +55,7 @@
- static const char *synopsis = "Listen to the audio of an active channel\n";
- static const char *app = "ChanSpy";
-+static const char *app2 = "ChanSpyChan";
- static const char *desc = 
- "  ChanSpy([chanprefix][|options]): This application is used to listen to the\n"
- "audio from an active Asterisk channel. This includes the audio coming in and\n"
-@@ -142,6 +143,19 @@
-       return ret;
- }
-+static struct ast_channel *local_get_channel_uniqueid(char *uniqueid) 
-+{
-+      struct ast_channel *chan = NULL;
-+      if (uniqueid) {
-+          ast_mutex_lock(&modlock);
-+          if ((chan = ast_get_channel_by_uniqueid_locked(uniqueid))) {
-+              ast_mutex_unlock(&chan->lock);
-+          }
-+          ast_mutex_unlock(&modlock);
-+      }       
-+      return chan;
-+}
-+
- static void *spy_alloc(struct ast_channel *chan, void *data)
- {
-       /* just store the data pointer in the channel structure */
-@@ -554,11 +568,87 @@
-       ALL_DONE(u, res);
- }
-+static int chanspychan_exec(struct ast_channel *chan, void *data)
-+{
-+      struct localuser *u;
-+      struct ast_channel *peer=NULL;
-+      char    *args,
-+              *uniqueid = NULL,
-+              *argv[5];
-+      int res = -1,
-+              volfactor = 0,
-+              argc = 0,
-+              oldrf = 0,
-+              oldwf = 0,
-+              fd = 0;
-+      signed char zero_volume = 0;
-+
-+      if (!(args = ast_strdupa((char *)data))) {
-+              ast_log(LOG_ERROR, "Out of memory!\n");
-+              return -1;
-+      }
-+
-+      LOCAL_USER_ADD(u);
-+
-+      oldrf = chan->readformat;
-+      oldwf = chan->writeformat;
-+      if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) {
-+              ast_log(LOG_ERROR, "Could Not Set Read Format.\n");
-+              LOCAL_USER_REMOVE(u);
-+              return -1;
-+      }
-+      
-+      if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
-+              ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
-+              LOCAL_USER_REMOVE(u);
-+              return -1;
-+      }
-+
-+
-+      if ((argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
-+              uniqueid = argv[0];
-+              if (ast_strlen_zero(uniqueid)) {
-+                  LOCAL_USER_REMOVE(u);
-+                  return -1;
-+              }
-+      }
-+      
-+      ast_answer(chan);
-+
-+      ast_set_flag(chan, AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
-+
-+      peer = local_get_channel_uniqueid(uniqueid);
-+      if (peer && (peer != chan) && !ast_check_hangup(peer) && !ast_test_flag(peer, AST_FLAG_SPYING)) {
-+          res = channel_spy(chan, peer, &volfactor, fd);
-+      } else {
-+          ast_log(LOG_NOTICE, "no channel found with uniqueid %s\n", uniqueid);
-+      }
-+
-+      if (fd > 0) {
-+              close(fd);
-+      }
-+
-+      if (oldrf && ast_set_read_format(chan, oldrf) < 0) {
-+              ast_log(LOG_ERROR, "Could Not Set Read Format.\n");
-+      }
-+      
-+      if (oldwf && ast_set_write_format(chan, oldwf) < 0) {
-+              ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
-+      }
-+
-+      ast_clear_flag(chan, AST_FLAG_SPYING);
-+
-+      ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
-+
-+      ALL_DONE(u, res);
-+}
-+
- int unload_module(void)
- {
-       int res;
--      res = ast_unregister_application(app);
-+      ast_unregister_application(app);
-+      res = ast_unregister_application(app2);
-       STANDARD_HANGUP_LOCALUSERS;
-@@ -567,7 +657,8 @@
- int load_module(void)
- {
--      return ast_register_application(app, chanspy_exec, synopsis, desc);
-+      ast_register_application(app, chanspy_exec, synopsis, desc);
-+      return ast_register_application(app2, chanspychan_exec, synopsis, desc);
- }
- char *description(void)
-diff -urN asterisk-1.2.10.orig/apps/app_devstate.c asterisk-1.2.10/apps/app_devstate.c
---- asterisk-1.2.10.orig/apps/app_devstate.c   1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/apps/app_devstate.c        2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,225 @@
-+/*
-+ * 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 <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>
-+#include <asterisk/astdb.h>
-+#include <asterisk/utils.h>
-+#include <asterisk/cli.h>
-+#include <asterisk/manager.h>
-+#include <asterisk/devicestate.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 };
-+
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+
-+static int devstate_cli(int fd, int argc, char *argv[])
-+{
-+    char devName[128];
-+    if ((argc != 3) && (argc != 4) && (argc != 5))
-+        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]);
-+    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;
-+}
-+
-+static int devstate_exec(struct ast_channel *chan, void *data)
-+{
-+    struct localuser *u;
-+    char *device, *state, *info;
-+    char devName[128];
-+    if (!(info = ast_strdupa(data))) {
-+            ast_log(LOG_WARNING, "Unable to dupe data :(\n");
-+            return -1;
-+    }
-+    LOCAL_USER_ADD(u);
-+    
-+    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, NULL, NULL);
-+
-+    LOCAL_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 = 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, struct message *m)
-+{
-+        char *devstate = astman_get_header(m, "Devstate");
-+        char *value = astman_get_header(m, "Value");
-+      char *id = astman_get_header(m,"ActionID");
-+        char *cid_num = astman_get_header(m, "CallerID");
-+        char *cid_name = astman_get_header(m, "CallerIDName");
-+      char devName[128];
-+
-+      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_db_put("DEVSTATES", devstate, value)) {
-+          snprintf(devName, sizeof(devName), "DS/%s", devstate);
-+//        ast_device_state_changed(devName);
-+          ast_device_state_changed_literal(devName, cid_num, cid_name);
-+          ast_cli(s->fd, "Response: Success\r\n");
-+      } else {
-+          ast_log(LOG_DEBUG, "ast_db_put failed\n");
-+          ast_cli(s->fd, "Response: Failed\r\n");
-+      }
-+      if (id && !ast_strlen_zero(id))
-+              ast_cli(s->fd, "ActionID: %s\r\n",id);
-+      ast_cli(s->fd, "\r\n");
-+      return 0;
-+}
-+
-+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);
-+}
-+
-+int unload_module(void)
-+{
-+    int res = 0;
-+    STANDARD_HANGUP_LOCALUSERS;
-+    ast_manager_unregister( "Devstate");
-+    ast_cli_unregister(&cli_dev_state);
-+    res = ast_unregister_application(app);
-+    ast_channel_unregister(&devstate_tech);    
-+    return res;
-+}
-+
-+char *description(void)
-+{
-+    return tdesc;
-+}
-+
-+int usecount(void)
-+{
-+    int res;
-+    STANDARD_USECOUNT(res);
-+    return res;
-+}
-+
-+char *key()
-+{
-+    return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/apps/app_dial.c asterisk-1.2.10/apps/app_dial.c
---- asterisk-1.2.10.orig/apps/app_dial.c       2006-06-09 20:08:00.000000000 +0200
-+++ asterisk-1.2.10/apps/app_dial.c    2006-08-04 11:23:28.000000000 +0200
-@@ -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.
-@@ -55,6 +59,7 @@
- #include "asterisk/causes.h"
- #include "asterisk/manager.h"
- #include "asterisk/privacy.h"
-+#include "asterisk/transcap.h"
- static char *tdesc = "Dialing Application";
-@@ -115,7 +120,8 @@
- "           action post answer options in conjunction with this option.\n" 
- "    h    - Allow the called party to hang up by sending the '*' DTMF digit.\n"
- "    H    - Allow the calling party to hang up by hitting the '*' DTMF digit.\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"
- "    L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
- "           left. Repeat the warning every 'z' ms. The following special\n"
- "           variables can be used with this option:\n"
-@@ -162,8 +168,11 @@
- "           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"     
-+"           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"
-@@ -214,6 +223,8 @@
-       OPT_CALLEE_MONITOR = (1 << 21),
-       OPT_CALLER_MONITOR = (1 << 22),
-       OPT_GOTO = (1 << 23),
-+      OPT_NOINBAND = (1 << 24),
-+      OPT_CALLBACK_INIT = (1 << 25),
- } dial_exec_option_flags;
- #define DIAL_STILLGOING                       (1 << 30)
-@@ -252,6 +263,8 @@
-       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('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),
-@@ -389,7 +402,7 @@
-       char *context = NULL;
-       char cidname[AST_MAX_EXTENSION];
--      single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK));
-+      single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK | OPT_NOINBAND));
-       
-       if (single) {
-               /* Turn off hold music, etc */
-@@ -468,7 +481,7 @@
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
-                                               /* Setup parameters */
--                                              o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
-+                                              o->chan = ast_request(tech, in->nativeformats, stuff, &cause, NULL);
-                                               if (!o->chan)
-                                                       ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
-                                               else
-@@ -586,12 +599,18 @@
-                                                       HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
-                                                       break;
-                                               case AST_CONTROL_RINGING:
--                                                      if (option_verbose > 2)
--                                                              ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
--                                                      if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
--                                                              ast_indicate(in, AST_CONTROL_RINGING);
--                                                              (*sentringing)++;
--                                                      }
-+                                                        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", o->chan->name);
-+                                                            if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
-+                                                                ast_indicate(in, AST_CONTROL_RINGING);
-+                                                                (*sentringing)++;
-+                                                            }
-+                                                        }
-                                                       break;
-                                               case AST_CONTROL_PROGRESS:
-                                                       if (option_verbose > 2)
-@@ -766,6 +785,7 @@
-       int digit = 0, result = 0;
-       time_t start_time, answer_time, end_time;
-       struct ast_app *app = NULL;
-+/*    char *aoceunits; */
-       char *parse;
-       AST_DECLARE_APP_ARGS(args,
-@@ -939,13 +959,13 @@
-               }
-               
-               if( privdb_val == AST_PRIVACY_DENY ) {
--                      strcpy(status, "NOANSWER");
-+                      ast_copy_string(status, "NOANSWER", sizeof(status));
-                       ast_verbose( VERBOSE_PREFIX_3  "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
-                       res=0;
-                       goto out;
-               }
-               else if( privdb_val == AST_PRIVACY_KILL ) {
--                      strcpy(status, "DONTCALL");
-+                      ast_copy_string(status, "DONTCALL", sizeof(status));
-                       if (option_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
-                               ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
-                       }
-@@ -953,7 +973,7 @@
-                       goto out; /* Is this right? */
-               }
-               else if( privdb_val == AST_PRIVACY_TORTURE ) {
--                      strcpy(status, "TORTURE");
-+                      ast_copy_string(status, "TORTURE", sizeof(status));
-                       if (option_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
-                               ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
-                       }
-@@ -1001,7 +1021,7 @@
-       /* If a channel group has been specified, get it for use when we create peer channels */
-       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);
-+      ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP| OPT_CALLBACK_INIT | OPT_NOINBAND);
-       cur = args.peers;
-       do {
-               /* Remember where to start next time */
-@@ -1043,7 +1063,7 @@
-                               ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
-               }
-               /* Request the peer */
--              tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
-+              tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause, NULL);
-               if (!tmp->chan) {
-                       /* If we can't, just go on to the next call */
-                       ast_log(LOG_NOTICE, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
-@@ -1074,7 +1094,7 @@
-                                       ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
-                               ast_hangup(tmp->chan);
-                               /* Setup parameters */
--                              tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
-+                              tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause, NULL);
-                               if (!tmp->chan)
-                                       ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
-                               else
-@@ -1187,7 +1207,7 @@
-       if (outgoing) {
-               /* 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;
-                       ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
-@@ -1195,8 +1215,11 @@
-                       ast_indicate(chan, AST_CONTROL_RINGING);
-                       sentringing++;
-               }
--      } else
--              strcpy(status, "CHANUNAVAIL");
-+      } else {
-+              ast_copy_string(status, "CHANUNAVAIL", sizeof(status));
-+              /* See if there is a special message */
-+              ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
-+      }
-       time(&start_time);
-       peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
-@@ -1561,18 +1584,22 @@
-                               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);
-+                      }
-                       config.timelimit = timelimit;
-                       config.play_warning = play_warning;
-@@ -1608,7 +1635,15 @@
-               }
-               snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
-               pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
--              
-+
-+              /* forward AOC-E units from peer, if possible */
-+/*            aoceunits = pbx_builtin_getvar_helper(peer, "AOCEUNITS");
-+
-+              if (aoceunits) {
-+                  snprintf(toast, sizeof(toast), "%d", atoi(aoceunits));
-+                  pbx_builtin_setvar_helper(chan, "AOCEUNITS", toast);
-+              }  */
-+
-               if (res != AST_PBX_NO_HANGUP_PEER) {
-                       if (!chan->_softhangup)
-                               chan->hangupcause = peer->hangupcause;
-diff -urN asterisk-1.2.10.orig/apps/app_directed_pickup.c asterisk-1.2.10/apps/app_directed_pickup.c
---- asterisk-1.2.10.orig/apps/app_directed_pickup.c    2006-04-06 19:00:10.000000000 +0200
-+++ asterisk-1.2.10/apps/app_directed_pickup.c 2006-07-31 14:13:08.000000000 +0200
-@@ -41,7 +41,7 @@
- #include "asterisk/app.h"
- static const char *tdesc = "Directed Call Pickup Application";
--static const char *app = "Pickup";
-+static const char *app = "DPickup";
- static const char *synopsis = "Directed Call Pickup";
- static const char *descrip =
- "  Pickup(extension[@context]): This application can pickup any ringing channel\n"
-diff -urN asterisk-1.2.10.orig/apps/app_meetme.c asterisk-1.2.10/apps/app_meetme.c
---- asterisk-1.2.10.orig/apps/app_meetme.c     2006-06-11 23:08:04.000000000 +0200
-+++ asterisk-1.2.10/apps/app_meetme.c  2006-07-31 14:13:08.000000000 +0200
-@@ -453,7 +453,7 @@
-                       ast_copy_string(cnf->pin, pin, sizeof(cnf->pin));
-                       ast_copy_string(cnf->pinadmin, pinadmin, sizeof(cnf->pinadmin));
-                       cnf->markedusers = 0;
--                      cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo", NULL);
-+                      cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo", NULL, NULL);
-                       if (cnf->chan) {
-                               cnf->fd = cnf->chan->fds[0];    /* for use by conf_play() */
-                       } else {
-@@ -823,8 +823,9 @@
-       char exitcontext[AST_MAX_CONTEXT] = "";
-       char recordingtmp[AST_MAX_EXTENSION] = "";
-       int dtmf;
-+      int dyna_buff = CONF_SIZE;
-       ZT_BUFFERINFO bi;
--      char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
-+      char __buf[ZT_MAX_BUF_SPACE / ZT_DEFAULT_NUM_BUFS + AST_FRIENDLY_OFFSET];
-       char *buf = __buf + AST_FRIENDLY_OFFSET;
-       
-       if (!user) {
-@@ -990,7 +991,7 @@
-               }
-               /* Setup buffering information */
-               memset(&bi, 0, sizeof(bi));
--              bi.bufsize = CONF_SIZE/2;
-+              bi.bufsize = dyna_buff / 2;
-               bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
-               bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
-               bi.numbufs = audio_buffers;
-@@ -1275,6 +1276,14 @@
-                               f = ast_read(c);
-                               if (!f)
-                                       break;
-+                              if (f->datalen && f->datalen != dyna_buff) {
-+                                      ast_log(LOG_NOTICE, "Audio bytes: %d  Buffer size: %d\n", f->datalen, dyna_buff);
-+                                      if (f->datalen < ZT_MAX_BUF_SPACE/audio_buffers) { /* skip too large frame to avoid overflow */
-+                                              dyna_buff = f->datalen;
-+                                              close(fd);
-+                                              goto zapretry;
-+                                      }
-+                              }
-                               if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
-                                       if (user->talk.actual)
-                                               ast_frame_adjust_volume(f, user->talk.actual);
-@@ -1509,7 +1518,7 @@
-                               }
-                               ast_frfree(f);
-                       } else if (outfd > -1) {
--                              res = read(outfd, buf, CONF_SIZE);
-+                              res = read(outfd, buf, dyna_buff);
-                               if (res > 0) {
-                                       memset(&fr, 0, sizeof(fr));
-                                       fr.frametype = AST_FRAME_VOICE;
-diff -urN asterisk-1.2.10.orig/apps/app_milliwatt.c asterisk-1.2.10/apps/app_milliwatt.c
---- asterisk-1.2.10.orig/apps/app_milliwatt.c  2006-01-19 05:17:45.000000000 +0100
-+++ asterisk-1.2.10/apps/app_milliwatt.c       2006-07-31 14:13:08.000000000 +0200
-@@ -74,20 +74,28 @@
- {
-       struct ast_frame wf;
-       unsigned char buf[AST_FRIENDLY_OFFSET + 640];
-+      const int maxsamples = (sizeof (buf) - AST_FRIENDLY_OFFSET) / sizeof (buf[0]);
-       int i,*indexp = (int *) data;
--      if (len + AST_FRIENDLY_OFFSET > sizeof(buf))
--      {
--              ast_log(LOG_WARNING,"Only doing %d bytes (%d bytes requested)\n",(int)(sizeof(buf) - AST_FRIENDLY_OFFSET),len);
--              len = sizeof(buf) - AST_FRIENDLY_OFFSET;
--      }
-+      /* Instead of len, use samples, because channel.c generator_force 
-+       * generate(chan, tmp, 0, 160) ignores len. In any case, len is  
-+       * a multiple of samples, given by number of samples times bytes per
-+       * sample. In the case of ulaw, len = samples. for signed linear 
-+       * len = 2 * samples                                                 */
-+ 
-+      if (samples > maxsamples)
-+      {
-+              ast_log(LOG_WARNING, "Only doing %d samples (%d requested)\n", maxsamples, samples);
-+              samples = maxsamples;
-+      }
-+      len = samples * sizeof (buf[0]);
-       wf.frametype = AST_FRAME_VOICE;
-       wf.subclass = AST_FORMAT_ULAW;
-       wf.offset = AST_FRIENDLY_OFFSET;
-       wf.mallocd = 0;
-       wf.data = buf + AST_FRIENDLY_OFFSET;
-       wf.datalen = len;
--      wf.samples = wf.datalen;
-+      wf.samples = samples;
-       wf.src = "app_milliwatt";
-       wf.delivery.tv_sec = 0;
-       wf.delivery.tv_usec = 0;
-diff -urN asterisk-1.2.10.orig/apps/app_page.c asterisk-1.2.10/apps/app_page.c
---- asterisk-1.2.10.orig/apps/app_page.c       2006-04-13 19:40:21.000000000 +0200
-+++ asterisk-1.2.10/apps/app_page.c    2006-07-31 14:13:08.000000000 +0200
-@@ -85,7 +85,7 @@
- {
-       struct calloutdata *cd = data;
-       ast_pbx_outgoing_app(cd->tech, AST_FORMAT_SLINEAR, cd->resource, 30000,
--              "MeetMe", cd->meetmeopts, NULL, 0, cd->cidnum, cd->cidname, cd->variables, NULL, NULL);
-+              "MeetMe", cd->meetmeopts, NULL, 0, 0, cd->cidnum, cd->cidname, cd->variables, NULL, NULL, NULL);
-       free(cd);
-       return NULL;
- }
-diff -urN asterisk-1.2.10.orig/apps/app_parkandannounce.c asterisk-1.2.10/apps/app_parkandannounce.c
---- asterisk-1.2.10.orig/apps/app_parkandannounce.c    2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/apps/app_parkandannounce.c 2006-07-31 14:13:08.000000000 +0200
-@@ -183,7 +183,7 @@
-       memset(&oh, 0, sizeof(oh));
-       oh.parent_channel = chan;
--      dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, chan->cid.cid_num, chan->cid.cid_name, &oh);
-+      dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, 0, chan->cid.cid_num, chan->cid.cid_name, &oh, NULL);
-       if(dchan) {
-               if(dchan->_state == AST_STATE_UP) {
-diff -urN asterisk-1.2.10.orig/apps/app_pickup.c asterisk-1.2.10/apps/app_pickup.c
---- asterisk-1.2.10.orig/apps/app_pickup.c     1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/apps/app_pickup.c  2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,319 @@
-+/*
-+ * 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 <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 *tdesc = "PickUp/PickDown/Steal/PickupChan/StealChan";
-+
-+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";
-+
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+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';
-+                               }
-+                               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 localuser *u;
-+      if (!data || !strlen(data)) {
-+          pickupgroup = chan->pickupgroup;
-+      } else {
-+          pickupgroup = ast_get_group(data);
-+      }
-+      LOCAL_USER_ADD(u);
-+      if (!res) {
-+              res = my_pickup_call(chan, pickupgroup, AST_STATE_RINGING, 1);
-+      }
-+      if (res > 0)
-+              res = 0;
-+      LOCAL_USER_REMOVE(u);
-+      return res;
-+}
-+
-+static int steal_exec(struct ast_channel *chan, void *data)
-+{
-+      int res=0;
-+      unsigned int pickupgroup=0;
-+      struct localuser *u;
-+      if (!data || !strlen(data)) {
-+          pickupgroup = chan->pickupgroup;
-+      } else {
-+          pickupgroup = ast_get_group(data);
-+      }
-+      LOCAL_USER_ADD(u);
-+      if (!res) {
-+              res = my_pickup_call(chan, pickupgroup, AST_STATE_UP, 1);
-+      }
-+      if (res > 0)
-+              res = 0;
-+      LOCAL_USER_REMOVE(u);
-+      return res;
-+}
-+
-+static int pickdown_exec(struct ast_channel *chan, void *data)
-+{
-+      int res=0;
-+      unsigned int pickupgroup=0;
-+      struct localuser *u;
-+      if (!data || !strlen(data)) {
-+          pickupgroup = chan->pickupgroup;
-+      } else {
-+          pickupgroup = ast_get_group(data);
-+      }
-+      LOCAL_USER_ADD(u);
-+      if (!res) {
-+              res = my_pickup_call(chan, pickupgroup, AST_STATE_RINGING, 0);
-+      }
-+      if (res > 0)
-+              res = 0;
-+      LOCAL_USER_REMOVE(u);
-+      return res;
-+}
-+
-+static int pickupchan_exec(struct ast_channel *chan, void *data) {
-+       int res=0;
-+       struct localuser *u;
-+        if (!data) {
-+                ast_log(LOG_WARNING, "PickupChan requires an argument (technology1/number1&technology2/number2...)\n");
-+                return -1;
-+        }
-+       LOCAL_USER_ADD(u);
-+       if (!res) {
-+               res = my_pickup_channel(chan, data, AST_STATE_RINGING, 1);
-+       }
-+       if (res > 0)
-+               res = 0;
-+       LOCAL_USER_REMOVE(u);
-+       return res;
-+}
-+
-+static int stealchan_exec(struct ast_channel *chan, void *data)
-+{
-+      int res=0;
-+      struct localuser *u;
-+        if (!data) {
-+                ast_log(LOG_WARNING, "StealChan requires an argument (technology1/number1&technology2/number2...)\n");
-+                return -1;
-+        }
-+
-+      LOCAL_USER_ADD(u);
-+      if (!res) {
-+              res = my_pickup_channel(chan, data, AST_STATE_UP, 1);
-+      }
-+      if (res > 0)
-+              res = 0;
-+      LOCAL_USER_REMOVE(u);
-+      return res;
-+}
-+
-+
-+int unload_module(void)
-+{
-+      STANDARD_HANGUP_LOCALUSERS;
-+      ast_unregister_application(app5);
-+      ast_unregister_application(app4);
-+      ast_unregister_application(app3);
-+      ast_unregister_application(app2);
-+      return ast_unregister_application(app);
-+}
-+
-+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);
-+}
-+
-+char *description(void)
-+{
-+      return tdesc;
-+}
-+
-+int usecount(void)
-+{
-+      int res;
-+      STANDARD_USECOUNT(res);
-+      return res;
-+}
-+
-+char *key()
-+{
-+      return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/apps/app_queue.c asterisk-1.2.10/apps/app_queue.c
---- asterisk-1.2.10.orig/apps/app_queue.c      2006-06-23 13:30:17.000000000 +0200
-+++ asterisk-1.2.10/apps/app_queue.c   2006-07-31 14:13:08.000000000 +0200
-@@ -526,7 +526,7 @@
-       return NULL;
- }
--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)
- {
-       /* Avoid potential for deadlocks by spawning a new thread to handle
-          the event */
-@@ -1509,7 +1509,7 @@
-               location = "";
-       /* Request the peer */
--      tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
-+      tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status, NULL);
-       if (!tmp->chan) {                       /* If we can't, just go on to the next call */
- #if 0
-               ast_log(LOG_NOTICE, "Unable to create channel of type '%s' for Queue\n", cur->tech);
-@@ -1816,7 +1816,7 @@
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
-                                       /* Setup parameters */
--                                      o->chan = ast_request(tech, in->nativeformats, stuff, &status);
-+                                      o->chan = ast_request(tech, in->nativeformats, stuff, &status, NULL);
-                                       if (status != o->oldstatus) 
-                                               update_dial_status(qe->parent, o->member, status);                                              
-                                       if (!o->chan) {
-@@ -2360,14 +2360,14 @@
-                       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 */
-                               char tmpid[256];
-                               snprintf(tmpid, sizeof(tmpid), "chan-%x", rand());
--                              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);
-diff -urN asterisk-1.2.10.orig/apps/app_readfile.c asterisk-1.2.10/apps/app_readfile.c
---- asterisk-1.2.10.orig/apps/app_readfile.c   2006-03-23 21:13:48.000000000 +0100
-+++ asterisk-1.2.10/apps/app_readfile.c        2006-07-31 14:13:08.000000000 +0200
-@@ -40,7 +40,7 @@
- #include "asterisk/app.h"
- #include "asterisk/module.h"
--static char *tdesc = "Stores output of file into a variable";
-+static char *tdesc = "Stores content of file into a variable";
- static char *app_readfile = "ReadFile";
-diff -urN asterisk-1.2.10.orig/apps/app_segfault.c asterisk-1.2.10/apps/app_segfault.c
---- asterisk-1.2.10.orig/apps/app_segfault.c   1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/apps/app_segfault.c        2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,75 @@
-+/*
-+ * 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 <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 *tdesc = "Application for crashing Asterisk with a segmentation fault";
-+
-+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";
-+
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+static int segfault_exec(struct ast_channel *chan, void *data)
-+{
-+    struct localuser *u;
-+    LOCAL_USER_ADD(u);
-+    ((char *)0)[0] = 0;
-+    LOCAL_USER_REMOVE(u);
-+    return 0;
-+}
-+
-+int unload_module(void)
-+{
-+    STANDARD_HANGUP_LOCALUSERS;
-+    return ast_unregister_application(app);
-+}
-+
-+int load_module(void)
-+{
-+    return ast_register_application(app, segfault_exec, synopsis, descrip);
-+}
-+
-+char *description(void)
-+{
-+    return tdesc;
-+}
-+
-+int usecount(void)
-+{
-+    int res;
-+    STANDARD_USECOUNT(res);
-+    return res;
-+}
-+
-+char *key()
-+{
-+    return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/apps/app_zapras.c asterisk-1.2.10/apps/app_zapras.c
---- asterisk-1.2.10.orig/apps/app_zapras.c     2006-07-12 15:54:10.000000000 +0200
-+++ asterisk-1.2.10/apps/app_zapras.c  2006-07-31 14:13:08.000000000 +0200
-@@ -180,7 +180,7 @@
-                               }
-                       }
-                       /* Throw back into audio mode */
--                      x = 1;
-+                      x = 0;
-                       ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
-                       /* Restore saved values */
-diff -urN asterisk-1.2.10.orig/apps/app_zapras.c.orig asterisk-1.2.10/apps/app_zapras.c.orig
---- asterisk-1.2.10.orig/apps/app_zapras.c.orig        1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/apps/app_zapras.c.orig     2006-07-12 15:54:10.000000000 +0200
-@@ -0,0 +1,274 @@
-+/*
-+ * Asterisk -- An open source telephony toolkit.
-+ *
-+ * Copyright (C) 1999 - 2005, Digium, Inc.
-+ *
-+ * Mark Spencer <markster@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 Execute an ISDN RAS
-+ * 
-+ * \ingroup applications
-+ */
-+
-+#include <sys/ioctl.h>
-+#include <sys/wait.h>
-+#ifdef __linux__
-+#include <sys/signal.h>
-+#else
-+#include <signal.h>
-+#endif /* __linux__ */
-+
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <stdio.h>
-+#include <fcntl.h>
-+
-+/* Need some zaptel help here */
-+#ifdef __linux__
-+#include <linux/zaptel.h>
-+#else
-+#include <zaptel.h>
-+#endif /* __linux__ */
-+
-+#include "asterisk.h"
-+
-+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 37419 $")
-+
-+#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/options.h"
-+
-+static char *tdesc = "Zap RAS Application";
-+
-+static char *app = "ZapRAS";
-+
-+static char *synopsis = "Executes Zaptel ISDN RAS application";
-+
-+static char *descrip =
-+"  ZapRAS(args): Executes a RAS server using pppd on the given channel.\n"
-+"The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
-+"channel to be able to use this function (No modem emulation is included).\n"
-+"Your pppd must be patched to be zaptel aware. Arguments should be\n"
-+"separated by | characters.\n";
-+
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+#define PPP_MAX_ARGS  32
-+#define PPP_EXEC      "/usr/sbin/pppd"
-+
-+static pid_t spawn_ras(struct ast_channel *chan, char *args)
-+{
-+      pid_t pid;
-+      int x;  
-+      char *c;
-+
-+      char *argv[PPP_MAX_ARGS];
-+      int argc = 0;
-+      char *stringp=NULL;
-+
-+      /* Start by forking */
-+      pid = fork();
-+      if (pid)
-+              return pid;
-+
-+      /* Execute RAS on File handles */
-+      dup2(chan->fds[0], STDIN_FILENO);
-+
-+      /* Drop high priority */
-+      if (option_highpriority)
-+              ast_set_priority(0);
-+
-+      /* Close other file descriptors */
-+      for (x=STDERR_FILENO + 1;x<1024;x++) 
-+              close(x);
-+
-+      /* Restore original signal handlers */
-+      for (x=0;x<NSIG;x++)
-+              signal(x, SIG_DFL);
-+
-+      /* Reset all arguments */
-+      memset(argv, 0, sizeof(argv));
-+
-+      /* First argument is executable, followed by standard
-+         arguments for zaptel PPP */
-+      argv[argc++] = PPP_EXEC;
-+      argv[argc++] = "nodetach";
-+
-+      /* And all the other arguments */
-+      stringp=args;
-+      c = strsep(&stringp, "|");
-+      while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
-+              argv[argc++] = c;
-+              c = strsep(&stringp, "|");
-+      }
-+
-+      argv[argc++] = "plugin";
-+      argv[argc++] = "zaptel.so";
-+      argv[argc++] = "stdin";
-+
-+      /* Finally launch PPP */
-+      execv(PPP_EXEC, argv);
-+      fprintf(stderr, "Failed to exec PPPD!\n");
-+      exit(1);
-+}
-+
-+static void run_ras(struct ast_channel *chan, char *args)
-+{
-+      pid_t pid;
-+      int status;
-+      int res;
-+      int signalled = 0;
-+      struct zt_bufferinfo savebi;
-+      int x;
-+      
-+      res = ioctl(chan->fds[0], ZT_GET_BUFINFO, &savebi);
-+      if(res) {
-+              ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
-+              return;
-+      }
-+
-+      pid = spawn_ras(chan, args);
-+      if (pid < 0) {
-+              ast_log(LOG_WARNING, "Failed to spawn RAS\n");
-+      } else {
-+              for (;;) {
-+                      res = wait4(pid, &status, WNOHANG, NULL);
-+                      if (!res) {
-+                              /* Check for hangup */
-+                              if (chan->_softhangup && !signalled) {
-+                                      ast_log(LOG_DEBUG, "Channel '%s' hungup.  Signalling RAS at %d to die...\n", chan->name, pid);
-+                                      kill(pid, SIGTERM);
-+                                      signalled=1;
-+                              }
-+                              /* Try again */
-+                              sleep(1);
-+                              continue;
-+                      }
-+                      if (res < 0) {
-+                              ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
-+                      }
-+                      if (option_verbose > 2) {
-+                              if (WIFEXITED(status)) {
-+                                      ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
-+                              } else if (WIFSIGNALED(status)) {
-+                                      ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with signal %d\n", 
-+                                               chan->name, WTERMSIG(status));
-+                              } else {
-+                                      ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated weirdly.\n", chan->name);
-+                              }
-+                      }
-+                      /* Throw back into audio mode */
-+                      x = 1;
-+                      ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
-+
-+                      /* Restore saved values */
-+                      res = ioctl(chan->fds[0], ZT_SET_BUFINFO, &savebi);
-+                      if (res < 0) {
-+                              ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
-+                      }
-+                      break;
-+              }
-+      }
-+}
-+
-+static int zapras_exec(struct ast_channel *chan, void *data)
-+{
-+      int res=-1;
-+      char *args;
-+      struct localuser *u;
-+      ZT_PARAMS ztp;
-+
-+      if (!data) 
-+              data = "";
-+
-+      LOCAL_USER_ADD(u);
-+
-+      args = ast_strdupa(data);
-+      if (!args) {
-+              ast_log(LOG_ERROR, "Out of memory\n");
-+              LOCAL_USER_REMOVE(u);
-+              return -1;
-+      }
-+      
-+      /* Answer the channel if it's not up */
-+      if (chan->_state != AST_STATE_UP)
-+              ast_answer(chan);
-+      if (strcasecmp(chan->type, "Zap")) {
-+              /* If it's not a zap channel, we're done.  Wait a couple of
-+                 seconds and then hangup... */
-+              if (option_verbose > 1)
-+                      ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a Zap channel\n", chan->name);
-+              sleep(2);
-+      } else {
-+              memset(&ztp, 0, sizeof(ztp));
-+              if (ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp)) {
-+                      ast_log(LOG_WARNING, "Unable to get zaptel parameters\n");
-+              } else if (ztp.sigtype != ZT_SIG_CLEAR) {
-+                      if (option_verbose > 1)
-+                              ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name);
-+              } else {
-+                      /* Everything should be okay.  Run PPP. */
-+                      if (option_verbose > 2)
-+                              ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name);
-+                      /* Execute RAS */
-+                      run_ras(chan, args);
-+              }
-+      }
-+      LOCAL_USER_REMOVE(u);
-+      return res;
-+}
-+
-+int unload_module(void)
-+{
-+      int res;
-+
-+      res = ast_unregister_application(app);
-+      
-+      STANDARD_HANGUP_LOCALUSERS;
-+
-+      return res;
-+}
-+
-+int load_module(void)
-+{
-+      return ast_register_application(app, zapras_exec, synopsis, descrip);
-+}
-+
-+char *description(void)
-+{
-+      return tdesc;
-+}
-+
-+int usecount(void)
-+{
-+      int res;
-+      STANDARD_USECOUNT(res);
-+      return res;
-+}
-+
-+char *key()
-+{
-+      return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/asterisk.c asterisk-1.2.10/asterisk.c
---- asterisk-1.2.10.orig/asterisk.c    2006-07-12 15:54:10.000000000 +0200
-+++ asterisk-1.2.10/asterisk.c 2006-07-31 14:13:08.000000000 +0200
-@@ -228,6 +228,7 @@
- char ast_config_AST_CTL_OWNER[AST_CONFIG_MAX_PATH] = "\0";
- char ast_config_AST_CTL_GROUP[AST_CONFIG_MAX_PATH] = "\0";
- char ast_config_AST_CTL[AST_CONFIG_MAX_PATH] = "asterisk.ctl";
-+char ast_config_AST_SYMBOLIC_NAME[20];
- static char *_argv[256];
- static int shuttingdown = 0;
-@@ -1877,6 +1878,7 @@
-       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_SYMBOLIC_NAME, AST_SYMBOLIC_NAME, sizeof(ast_config_AST_SYMBOLIC_NAME));
-       /* no asterisk.conf? no problem, use buildtime config! */
-       if (!cfg) {
-@@ -1991,6 +1993,8 @@
-               /* What group to run as */
-               } else if (!strcasecmp(v->name, "rungroup")) {
-                       ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP));
-+              } else if (!strcasecmp(v->name, "uniquename")) {
-+                      strncpy(ast_config_AST_SYMBOLIC_NAME,v->value,sizeof(ast_config_AST_SYMBOLIC_NAME));
-               }
-               v = v->next;
-       }
-diff -urN asterisk-1.2.10.orig/build_tools/make_defaults_h asterisk-1.2.10/build_tools/make_defaults_h
---- asterisk-1.2.10.orig/build_tools/make_defaults_h   2005-06-20 19:26:08.000000000 +0200
-+++ asterisk-1.2.10/build_tools/make_defaults_h        2006-07-31 14:13:08.000000000 +0200
-@@ -16,6 +16,7 @@
- #define AST_KEY_DIR    "${INSTALL_PATH}${ASTVARLIBDIR}/keys"
- #define AST_DB         "${INSTALL_PATH}${ASTVARLIBDIR}/astdb"
- #define AST_TMP_DIR    "${INSTALL_PATH}${ASTSPOOLDIR}/tmp"
-+#define AST_SYMBOLIC_NAME     "asterisk"
- #define AST_CONFIG_FILE "${INSTALL_PATH}${ASTCONFPATH}"
-diff -urN asterisk-1.2.10.orig/channel.c asterisk-1.2.10/channel.c
---- asterisk-1.2.10.orig/channel.c     2006-07-10 23:01:35.000000000 +0200
-+++ asterisk-1.2.10/channel.c  2006-07-31 14:13:08.000000000 +0200
-@@ -94,8 +94,8 @@
-  */
- static int shutting_down = 0;
--AST_MUTEX_DEFINE_STATIC(uniquelock);
- static int uniqueint = 0;
-+AST_MUTEX_DEFINE_EXPORTED(uniquelock);
- unsigned long global_fin = 0, global_fout = 0;
-@@ -512,6 +512,17 @@
-       .description = "Null channel (should not see this)",
- };
-+char *ast_alloc_uniqueid(void) {
-+      char *uniqueid;
-+      uniqueid = malloc(64);
-+      if (!uniqueid) return NULL;
-+      ast_mutex_lock(&uniquelock);
-+      snprintf(uniqueid, 63, "%s-%d-%li.%d", ast_config_AST_SYMBOLIC_NAME, ast_mainpid, (long)time(NULL), uniqueint++);
-+      ast_mutex_unlock(&uniquelock);
-+      return uniqueid;
-+}
-+
-+
- /*--- ast_channel_alloc: Create a new channel structure */
- struct ast_channel *ast_channel_alloc(int needqueue)
- {
-@@ -519,6 +530,7 @@
-       int x;
-       int flags;
-       struct varshead *headp;        
-+      char *tmpuniqueid;
-               
-       /* If shutting down, don't allocate any new channels */
-@@ -584,9 +596,12 @@
-       tmp->data = NULL;
-       tmp->fin = global_fin;
-       tmp->fout = global_fout;
--      ast_mutex_lock(&uniquelock);
--      snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long) time(NULL), uniqueint++);
--      ast_mutex_unlock(&uniquelock);
-+      tmpuniqueid = ast_alloc_uniqueid();
-+      snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), tmpuniqueid);
-+      if (tmpuniqueid) { 
-+          free(tmpuniqueid);
-+          tmpuniqueid = NULL;
-+      }
-       headp = &tmp->varshead;
-       ast_mutex_init(&tmp->lock);
-       AST_LIST_HEAD_INIT_NOLOCK(headp);
-@@ -729,7 +744,7 @@
-  */
- 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, done;
-@@ -740,9 +755,14 @@
-               for (c = channels; c; c = c->next) {
-                       if (!prev) {
-                               /* want head of list */
--                              if (!name && !exten)
-+                              if (!name && !exten && !uniqueid)
-                                       break;
--                              if (name) {
-+                              if (uniqueid) {
-+                                  if (!strcasecmp(c->uniqueid, uniqueid))
-+                                      break;
-+                                  else
-+                                      continue;
-+                              } else if (name) {
-                                       /* want match by full name */
-                                       if (!namelen) {
-                                               if (!strcasecmp(c->name, name))
-@@ -793,33 +813,39 @@
- /*--- ast_channel_walk_locked: 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);
- }
- /*--- ast_get_channel_by_name_locked: 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);
- }
- /*--- ast_get_channel_by_name_prefix_locked: 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);
- }
- /*--- ast_walk_channel_by_name_prefix_locked: Get next channel by name prefix and lock it */
- struct ast_channel *ast_walk_channel_by_name_prefix_locked(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);
- }
- /*--- ast_get_channel_by_exten_locked: 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);
- }
-+struct ast_channel *ast_get_channel_by_uniqueid_locked(const char *uniqueid)
-+{
-+      return channel_find_locked(NULL, NULL, 0, NULL, NULL, uniqueid);
-+}
-+
-+
- /*--- ast_safe_sleep_conditional: Wait, look for hangups and condition arg */
- int ast_safe_sleep_conditional(       struct ast_channel *chan, int ms,
-       int (*cond)(void*), void *data )
-@@ -912,8 +938,10 @@
-               free(chan->tech_pvt);
-       }
--      if (chan->sched)
--              sched_context_destroy(chan->sched);
-+      if (chan->sched) {
-+              sched_context_destroy(chan->sched);     
-+              chan->sched = NULL;
-+      }
-       ast_copy_string(name, chan->name, sizeof(name));
-@@ -956,10 +984,11 @@
-       while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
-               ast_var_delete(vardata);
-+
-       free(chan);
-       ast_mutex_unlock(&chlock);
--      ast_device_state_changed_literal(name);
-+      ast_device_state_changed_literal(name, NULL, NULL);
- }
- int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy)
-@@ -2377,7 +2406,7 @@
-                         &chan->writetrans, 1);
- }
--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)
-+struct ast_channel *__ast_request_and_dial(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 state = 0;
-       int cause = 0;
-@@ -2385,7 +2414,7 @@
-       struct ast_frame *f;
-       int res = 0;
-       
--      chan = ast_request(type, format, data, &cause);
-+      chan = ast_request(type, format, data, &cause, uniqueid);
-       if (chan) {
-               if (oh) {
-                       if (oh->vars)   
-@@ -2399,6 +2428,7 @@
-               }
-               ast_set_callerid(chan, cid_num, cid_name, cid_num);
-+              chan->cid.cid_pres = callingpres;
-               if (!ast_call(chan, data, 0)) {
-                       res = 1;        /* in case chan->_state is already AST_STATE_UP */
-                       while (timeout && (chan->_state != AST_STATE_UP)) {
-@@ -2422,6 +2452,7 @@
-                                       if (f->subclass == AST_CONTROL_RINGING)
-                                               state = AST_CONTROL_RINGING;
-                                       else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
-+                                              res = 0;
-                                               state = f->subclass;
-                                               ast_frfree(f);
-                                               break;
-@@ -2491,12 +2522,12 @@
-       return chan;
- }
--struct ast_channel *ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
-+struct ast_channel *ast_request_and_dial(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(type, format, data, timeout, outstate, cidnum, cidname, NULL);
-+      return __ast_request_and_dial(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(const char *type, int format, void *data, int *cause, char *uniqueid)
- {
-       struct chanlist *chan;
-       struct ast_channel *c;
-@@ -2533,6 +2564,7 @@
-               if (!(c = chan->tech->requester(type, capabilities, data, cause)))
-                       return NULL;
-+              if (uniqueid) strncpy(c->uniqueid, uniqueid, sizeof(c->uniqueid));
-               if (c->_state == AST_STATE_DOWN) {
-                       manager_event(EVENT_FLAG_CALL, "Newchannel",
-                                     "Channel: %s\r\n"
-@@ -2808,6 +2840,29 @@
-       return res;
- }
-+int ast_channel_masquerade_locked(struct ast_channel *original, struct ast_channel *clone)
-+{
-+      struct ast_frame null = { AST_FRAME_NULL, };
-+      int res = -1;
-+      ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
-+              clone->name, original->name);
-+      if (original->masq) {
-+              ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
-+                      original->masq->name, original->name);
-+      } else if (clone->masqr) {
-+              ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
-+                      clone->name, clone->masqr->name);
-+      } else {
-+              original->masq = clone;
-+              clone->masqr = original;
-+              ast_queue_frame(original, &null);
-+              ast_queue_frame(clone, &null);
-+              ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
-+              res = 0;
-+      }
-+      return res;
-+}
-+
- void ast_change_name(struct ast_channel *chan, char *newname)
- {
-       char tmp[256];
-@@ -2947,7 +3002,7 @@
-       ast_copy_string(clone->name, masqn, sizeof(clone->name));
-       
-       /* Notify any managers of the change, first the masq then the other */
--      manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
-+      manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\nNewUniqueid: %s\r\n", newn, masqn, clone->uniqueid, original->uniqueid);
-       manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
-       /* Swap the technlogies */      
-@@ -3174,15 +3229,14 @@
-                               );
- }
--int ast_setstate(struct ast_channel *chan, int state)
--{
-+int ast_setstate_and_cid(struct ast_channel *chan, int state, char *cid_num, char *cid_name) {
-       int oldstate = chan->_state;
-       if (oldstate == state)
-               return 0;
-       chan->_state = state;
--      ast_device_state_changed_literal(chan->name);
-+      ast_device_state_changed_literal(chan->name, cid_num, cid_name);
-       manager_event(EVENT_FLAG_CALL,
-                     (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate",
-                     "Channel: %s\r\n"
-@@ -3198,6 +3252,10 @@
-       return 0;
- }
-+int ast_setstate(struct ast_channel *chan, int state) {
-+    return ast_setstate_and_cid(chan, state, NULL, NULL);
-+}
-+
- /*--- Find bridged channel */
- struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
- {
-@@ -3375,6 +3433,7 @@
-       char callee_warning = 0;
-       int to;
-+
-       if (c0->_bridge) {
-               ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
-                       c0->name, c0->_bridge->name);
-@@ -3385,6 +3444,10 @@
-                       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) ||
-diff -urN asterisk-1.2.10.orig/channels/Makefile asterisk-1.2.10/channels/Makefile
---- asterisk-1.2.10.orig/channels/Makefile     2006-04-30 16:27:56.000000000 +0200
-+++ asterisk-1.2.10/channels/Makefile  2006-07-31 14:13:08.000000000 +0200
-@@ -102,6 +102,11 @@
-   ZAPR2=-lmfcr2
- endif
-+ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/lib/libgsmat.so.1)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/lib/libgsmat.so.1),)
-+  CFLAGS+=-DZAPATA_GSM
-+  ZAPGSM=-lgsmat
-+endif
-+
- ALSA_SRC=chan_alsa.c
- ifneq ($(wildcard alsa-monitor.h),)
-@@ -122,6 +127,35 @@
- endif
- endif # WITHOUT_ZAPTEL
-+ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/capi20.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/capi20.h),)
-+  CHANNEL_LIBS+=chan_capi.so
-+# uncomment the following line if you really never ever want early b3 connects,
-+# you can also configure it in the dialstring, this is just for performance
-+# NOTE: this is probably obsolete by using the "R" dial option
-+#CFLAGS+=-DCAPI_NEVER_EVER_EARLY_B3_CONNECTS
-+
-+# uncommnet next line to force dtmf software detection/generation, can also be configured
-+# in capi.conf on a perdevice basis (softdtmf=1)
-+#CFLAGS+=-DCAPI_FORCE_SOFTWARE_DTMF
-+
-+# uncomment the next line if you are in the ulaw world
-+#CFLAGS+=-DCAPI_ULAW
-+
-+# very experimental echo squelching
-+CFLAGS+=-DCAPI_ES
-+
-+#gains
-+CFLAGS+=-DCAPI_GAIN
-+
-+# what do to with call waiting connect indications?
-+# uncomment the next line for call deflection in that case
-+CFLAGS+=-DCAPI_DEFLECT_ON_CIRCUITBUSY
-+
-+# audio sync
-+CFLAGS+=-DCAPI_SYNC
-+
-+endif
-+
- ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/vpbapi.h),)
-   CHANNEL_LIBS+=chan_vpb.so
-   CFLAGS+=-DLINUX
-@@ -204,7 +238,7 @@
-       $(CC) -c $(CFLAGS) -o chan_zap.o chan_zap.c
- chan_zap.so: chan_zap.o
--      $(CC) $(SOLINK) -o $@ $<  $(ZAPPRI) $(ZAPR2) -ltonezone
-+      $(CC) $(SOLINK) -o $@ $<  $(ZAPPRI) $(ZAPGSM) $(ZAPR2) -ltonezone
- chan_sip.so: chan_sip.o
-       $(CC) $(SOLINK) -o $@ ${CYGSOLINK} chan_sip.o ${CYGSOLIB}
-@@ -220,6 +254,9 @@
- chan_nbs.so: chan_nbs.o
-       $(CC) $(SOLINK) -o $@ $< -lnbs
-+chan_capi.so: chan_capi.o
-+      $(CC) $(SOLINK) -o $@ $< -lcapi20
-+
- chan_vpb.o: chan_vpb.c
-       $(CXX) -c $(CFLAGS) -o $@ chan_vpb.c
-diff -urN asterisk-1.2.10.orig/channels/chan_agent.c asterisk-1.2.10/channels/chan_agent.c
---- asterisk-1.2.10.orig/channels/chan_agent.c 2006-07-06 22:38:45.000000000 +0200
-+++ asterisk-1.2.10/channels/chan_agent.c      2006-07-31 14:13:08.000000000 +0200
-@@ -440,7 +440,7 @@
-               if ((pointer = strchr(filename, '.')))
-                       *pointer = '-';
-               snprintf(tmp, sizeof(tmp), "%s%s",savecallsin ? 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 ? urlprefix : "", filename, recordformatext);
- #if 0
-@@ -1323,7 +1323,7 @@
-                                               chan = agent_new(p, AST_STATE_DOWN);
-                                       } else if (!p->owner && !ast_strlen_zero(p->loginchan)) {
-                                               /* Adjustable agent */
--                                              p->chan = ast_request("Local", format, p->loginchan, cause);
-+                                              p->chan = ast_request("Local", format, p->loginchan, cause, NULL);
-                                               if (p->chan)
-                                                       chan = agent_new(p, AST_STATE_DOWN);
-                                       }
-diff -urN asterisk-1.2.10.orig/channels/chan_capi.c asterisk-1.2.10/channels/chan_capi.c
---- asterisk-1.2.10.orig/channels/chan_capi.c  1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/channels/chan_capi.c       2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,2888 @@
-+/*
-+ * (CAPI*)
-+ *
-+ * An implementation of Common ISDN API 2.0 for Asterisk
-+ *
-+ * Copyright (C) 2002, 2003, 2004, 2005 Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
-+ *
-+ * This program is free software and may be modified and 
-+ * distributed under the terms of the GNU Public License.
-+ */
-+
-+#include <sys/time.h>
-+#include <sys/signal.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <fcntl.h>
-+#include <sys/types.h>
-+#include <asterisk/lock.h>
-+#include <asterisk/frame.h> 
-+#include <asterisk/channel.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/module.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/config.h>
-+#include <asterisk/options.h>
-+#include <asterisk/features.h>
-+#include <asterisk/utils.h>
-+#include <asterisk/cli.h>
-+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
-+#include <capi_bsd.h>
-+#else
-+#include <linux/capi.h>
-+#endif
-+#include <capi20.h>
-+#include <asterisk/dsp.h>
-+#include <asterisk/xlaw.h>
-+#include <asterisk/chan_capi.h>
-+
-+unsigned ast_capi_ApplID;
-+_cword ast_capi_MessageNumber=1;
-+static char desc[] = "Common ISDN API for Asterisk";
-+#ifdef CAPI_ULAW
-+static char tdesc[] = "Common ISDN API Driver (0.4.0) muLaw";
-+#else
-+static char tdesc[] = "Common ISDN API Driver (0.4.0) aLaw ";
-+#endif
-+static char type[] = "CAPI";
-+
-+
-+static int usecnt;
-+AST_MUTEX_DEFINE_STATIC(usecnt_lock);
-+AST_MUTEX_DEFINE_STATIC(iflock);
-+AST_MUTEX_DEFINE_STATIC(pipelock);
-+AST_MUTEX_DEFINE_STATIC(monlock);
-+AST_MUTEX_DEFINE_STATIC(contrlock);
-+AST_MUTEX_DEFINE_STATIC(capi_send_buffer_lock);
-+AST_MUTEX_DEFINE_STATIC(capi_put_lock);
-+
-+#ifdef CAPI_ULAW
-+static int capi_capability = AST_FORMAT_ULAW;
-+#else
-+static int capi_capability = AST_FORMAT_ALAW;
-+#endif
-+
-+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
-+static CAPIProfileBuffer_t profile;
-+#else
-+static struct ast_capi_profile profile;
-+#endif
-+static pthread_t monitor_thread = -1;
-+
-+static struct ast_capi_pvt *iflist = NULL;
-+static struct capi_pipe *pipelist = NULL;
-+static int capi_last_plci = 0;
-+static struct ast_capi_controller *capi_controllers[AST_CAPI_MAX_CONTROLLERS];
-+static int capi_num_controllers = 0;
-+static int capi_counter = 0;
-+static unsigned long capi_used_controllers=0;
-+
-+static char capi_send_buffer[AST_CAPI_MAX_B3_BLOCKS * AST_CAPI_MAX_B3_BLOCK_SIZE];
-+static int capi_send_buffer_handle = 0;
-+
-+char capi_national_prefix[AST_MAX_EXTENSION];
-+char capi_international_prefix[AST_MAX_EXTENSION];
-+
-+int capidebug = 0;
-+
-+static const struct ast_channel_tech capi_tech;
-+
-+MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG) {
-+    MESSAGE_EXCHANGE_ERROR error;
-+    if (ast_mutex_lock(&capi_put_lock)) {
-+        ast_log(LOG_WARNING,"Unable to lock capi put!\n");
-+        return -1;
-+    } 
-+    error = capi20_put_cmsg(CMSG);    
-+    if (ast_mutex_unlock(&capi_put_lock)) {
-+      ast_log(LOG_WARNING,"Unable to unlock capi put!\n");
-+        return -1;
-+    }
-+    return error;
-+}
-+
-+
-+MESSAGE_EXCHANGE_ERROR check_wait_get_cmsg(_cmsg *CMSG) {
-+    MESSAGE_EXCHANGE_ERROR Info;
-+    struct timeval tv;
-+    tv.tv_sec = 0;
-+    tv.tv_usec = 10000;
-+    Info = capi20_waitformessage(ast_capi_ApplID,&tv);
-+    if ((Info != 0x0000) && (Info != 0x1104)) {
-+      if (capidebug) {
-+          ast_log(LOG_DEBUG, "Error waiting for cmsg... INFO = %#x\n", Info);
-+      }
-+      return Info;
-+    }
-+    
-+    if (Info == 0x0000) {
-+        Info = capi_get_cmsg(CMSG,ast_capi_ApplID);
-+    }
-+    return Info;
-+}
-+
-+
-+unsigned ListenOnController(unsigned long CIPmask,unsigned controller) {
-+    MESSAGE_EXCHANGE_ERROR  error;
-+    _cmsg                 CMSG,CMSG2;
-+
-+    LISTEN_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, controller);
-+#ifdef CAPI_NEVER_EVER_EARLY_B3_CONNECTS
-+    LISTEN_REQ_INFOMASK(&CMSG) = 0x00ff; // lots of info ;)
-+#else
-+    LISTEN_REQ_INFOMASK(&CMSG) = 0x03ff; // lots of info ;) + early B3 connect
-+#endif
-+    LISTEN_REQ_CIPMASK(&CMSG) = CIPmask;
-+    if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+      return error;
-+    }
-+    while (!IS_LISTEN_CONF(&CMSG2)) {
-+      error = check_wait_get_cmsg(&CMSG2);
-+    }
-+    return 0;
-+}
-+
-+// Echo cancellation is for cards w/ integrated echo cancellation only
-+// (i.e. Eicon active cards support it)
-+
-+#define EC_FUNCTION_ENABLE            1
-+#define EC_FUNCTION_DISABLE           2
-+#define EC_FUNCTION_FREEZE            3
-+#define EC_FUNCTION_RESUME            4
-+#define EC_FUNCTION_RESET             5
-+#define EC_OPTION_DISABLE_NEVER               0
-+#define EC_OPTION_DISABLE_G165                (1<<1)
-+#define EC_OPTION_DISABLE_G164_OR_G165        (1<<1 | 1<<2)
-+#define EC_DEFAULT_TAIL                       64
-+
-+static int capi_echo_canceller(struct ast_channel *c, int function) {
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+    MESSAGE_EXCHANGE_ERROR  error;
-+    _cmsg                 CMSG;
-+    unsigned char   buf[7];
-+
-+      /* If echo cancellation is not requested or supported, don't attempt to enable it */
-+      ast_mutex_lock(&contrlock);
-+      if (!capi_controllers[i->controller]->echocancel || !i->doEC) {
-+              ast_mutex_unlock(&contrlock);
-+              return 0;
-+      }
-+      ast_mutex_unlock(&contrlock);
-+
-+      if (option_verbose > 2) 
-+              ast_verbose(VERBOSE_PREFIX_3 "Setting up echo canceller (PLCI=%#x, function=%d, options=%d, tail=%d)\n",i->PLCI,function,i->ecOption,i->ecTail);
-+
-+      FACILITY_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+      FACILITY_REQ_NCCI(&CMSG) = i->NCCI;
-+      FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 6; /* Echo canceller */
-+
-+        buf[0]=6; /* msg size */
-+        buf[1]=function;
-+      if (function == EC_FUNCTION_ENABLE) {
-+              buf[3]=i->ecOption; /* bit field - ignore echo canceller disable tone */
-+              buf[5]=i->ecTail;   /* Tail length, ms */
-+      }
-+      else {
-+              buf[3]=0;
-+              buf[5]=0;
-+      }
-+
-+      // Always null:
-+        buf[2]=0;
-+        buf[4]=0;
-+        buf[6]=0;
-+
-+      FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = buf;
-+        
-+      if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+          ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
-+          return error;
-+      }
-+
-+      if (option_verbose > 5) 
-+         ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_REQ (PLCI=%#x)\n",i->PLCI);
-+
-+    return 0;
-+}
-+
-+int capi_detect_dtmf(struct ast_channel *c, int flag) {
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+#ifndef CAPI_FORCE_SOFTWARE_DTMF
-+    MESSAGE_EXCHANGE_ERROR  error;
-+    _cmsg                 CMSG;
-+    unsigned char buf[9];
-+    // does the controller support dtmf? and do we want to use it?
-+    ast_mutex_lock(&contrlock);
-+    if ((capi_controllers[i->controller]->dtmf == 1) && (i->doDTMF == 0)) {
-+      ast_mutex_unlock(&contrlock);
-+      FACILITY_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+      FACILITY_REQ_PLCI(&CMSG) = i->PLCI;
-+      FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 1;
-+      buf[0] = 8;
-+      if (flag == 1) {
-+          buf[1] = 1;
-+      } else {
-+          buf[1] = 2;
-+      }
-+      buf[2] = 0;
-+      buf[3] = AST_CAPI_DTMF_DURATION;
-+      buf[4] = 0;
-+      buf[5] = AST_CAPI_DTMF_DURATION;
-+      buf[6] = 0;
-+      buf[7] = 0;
-+      buf[8] = 0;
-+      FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = buf;
-+        
-+      if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+          ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
-+          return error;
-+      } else {
-+          if (option_verbose > 5) {
-+              ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_REQ (PLCI=%#x)\n",i->PLCI);
-+          }
-+      }
-+    } else {
-+      ast_mutex_unlock(&contrlock);
-+
-+#endif
-+      // do software dtmf detection
-+      i->doDTMF = 1; // just being paranoid again...
-+#ifndef CAPI_FORCE_SOFTWARE_DTMF
-+    }
-+#endif
-+    return 0;
-+}
-+static int capi_send_digit(struct ast_channel *c,char digit) {
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+    MESSAGE_EXCHANGE_ERROR  error;
-+    _cmsg                 CMSG;
-+    unsigned char     buf[10];
-+    
-+    if (i->state != CAPI_STATE_BCONNECTED) {
-+      return 0;
-+    }
-+    
-+    
-+#ifndef CAPI_NEVER_EVER_EARLY_B3_CONNECTS
-+    if(i->earlyB3 == 1)
-+    /* we should really test for the network saying the number is incomplete
-+    since i'm only doing a test and this is true at the right time
-+    i'm going with this */
-+    {
-+
-+      INFO_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+      INFO_REQ_PLCI(&CMSG) = i->PLCI;
-+      buf[0] = 2;
-+      buf[1] = 0x80;
-+      buf[2] = digit;
-+      INFO_REQ_CALLEDPARTYNUMBER(&CMSG) = buf;
-+
-+
-+      if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+          ast_log(LOG_ERROR,"error sending CALLEDPARTYNUMBER INFO (error=%#x)\n",error);
-+          return error;
-+      } else {
-+          if (option_verbose > 5) {
-+              ast_verbose(VERBOSE_PREFIX_4 "sent CALLEDPARTYNUMBER INFO digit = %c (PLCI=%#x)\n", digit, i->PLCI);
-+          }
-+      }
-+
-+    } else {
-+#endif
-+#ifndef CAPI_FORCE_SOFTWARE_DTMF
-+      ast_mutex_lock(&contrlock);
-+      if ((capi_controllers[i->controller]->dtmf == 0) || (i->doDTMF == 1)) {
-+#endif
-+          // let * fake it
-+#ifndef CAPI_FORCE_SOFTWARE_DTMF
-+          ast_mutex_unlock(&contrlock);
-+#endif
-+          return -1;
-+#ifndef CAPI_FORCE_SOFTWARE_DTMF
-+      }
-+      ast_mutex_unlock(&contrlock);
-+      
-+      FACILITY_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+      FACILITY_REQ_PLCI(&CMSG) = i->NCCI;
-+        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 1;
-+        buf[0] = 8;
-+    
-+        buf[1] = 3;
-+        buf[2] = 0;
-+    
-+        buf[3] = AST_CAPI_DTMF_DURATION;
-+        buf[4] = 0;
-+    
-+        buf[5] = AST_CAPI_DTMF_DURATION;
-+        buf[6] = 0;
-+    
-+        buf[7] = 1;
-+      buf[8] = digit;
-+        buf[9] = 0;
-+      FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = buf;
-+        
-+        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+          ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
-+          return error;
-+        } else {
-+          if (option_verbose > 4) {
-+              ast_verbose(VERBOSE_PREFIX_3 "sent dtmf '%c'\n",digit);
-+          }
-+      }
-+#endif
-+#ifndef CAPI_NEVER_EVER_EARLY_B3_CONNECTS
-+    }
-+#endif
-+    return 0;
-+}
-+
-+static int capi_alert(struct ast_channel *c) {
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+    MESSAGE_EXCHANGE_ERROR  error;
-+    _cmsg     CMSG;
-+    
-+    ALERT_REQ_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, 0);
-+    ALERT_REQ_PLCI(&CMSG) = i->PLCI;
-+
-+    if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+      ast_log(LOG_ERROR,"error sending ALERT_REQ PLCI = %#x\n",i->PLCI);
-+      return -1;
-+    } else {
-+      if (option_verbose > 5) {
-+          ast_verbose(VERBOSE_PREFIX_4 "sent ALERT_REQ PLCI = %#x\n",i->PLCI);
-+      }
-+    }
-+
-+    i->state = CAPI_STATE_ALERTING;
-+    return 0;
-+}
-+
-+#ifdef CAPI_DEFLECT_ON_CIRCUITBUSY
-+static int capi_deflect(struct ast_channel *chan, void *data)
-+{
-+    struct ast_capi_pvt *i = chan->tech_pvt;
-+    MESSAGE_EXCHANGE_ERROR Info;
-+    _cmsg     CMSG;
-+    char      bchaninfo[1];
-+    char      fac[60];
-+    int res=0;
-+    int ms=3000;
-+
-+    if (!data) {
-+      ast_log(LOG_WARNING, "cd requires an argument (destination phone number)\n");
-+      return -1;
-+    }
-+
-+    if ((i->state == CAPI_STATE_CONNECTED) || (i->state == CAPI_STATE_BCONNECTED)) {
-+      ast_log(LOG_ERROR, "call deflection does not work with calls that are already connected!\n");
-+      return -1;
-+    }
-+    // wait until the channel is alerting, so we dont drop the call and interfer with msgs
-+    while ((ms > 0) && (i->state != CAPI_STATE_ALERTING)) {
-+      sleep(100);
-+      ms -= 100;
-+    }
-+
-+    // make sure we hang up correctly
-+    i->state = CAPI_STATE_CONNECTPENDING;
-+
-+    fac[0]=0; // len 
-+    fac[1]=0; //len 
-+    fac[2]=0x01; // Use D-Chan
-+    fac[3]=0; // Keypad len
-+    fac[4]=31;        // user user data? len = 31 = 29 + 2
-+    fac[5]=0x1c;      // magic?
-+    fac[6]=0x1d;      // strlen destination + 18 = 29
-+    fac[7]=0x91;      // ..
-+    fac[8]=0xA1;
-+    fac[9]=0x1A;      // strlen destination + 15 = 26
-+    fac[10]=0x02;
-+    fac[11]=0x01;
-+    fac[12]=0x70;
-+    fac[13]=0x02;
-+    fac[14]=0x01;
-+    fac[15]=0x0d;
-+    fac[16]=0x30;
-+    fac[17]=0x12;     // strlen destination + 7 = 18
-+    fac[18]=0x30;     // ...hm 0x30
-+    fac[19]=0x0d;     // strlen destination + 2       
-+    fac[20]=0x80;     // CLIP
-+    fac[21]=0x0b;     //  strlen destination 
-+    fac[22]=0x01;     //  destination start
-+    fac[23]=0x01;     //  
-+    fac[24]=0x01;     //  
-+    fac[25]=0x01;     //  
-+    fac[26]=0x01;     //  
-+    fac[27]=0x01;     //  
-+    fac[28]=0x01;     //  
-+    fac[29]=0x01;     //  
-+    fac[30]=0x01;     //  
-+    fac[31]=0x01;     //  
-+    fac[32]=0x01;     //  
-+    fac[33]=0x01;     // 0x1 = sending complete
-+    fac[34]=0x01;
-+    fac[35]=0x01;
-+                                 
-+    memcpy((unsigned char *)fac+22,data,strlen(data));
-+    fac[22+strlen(data)]=0x01;        // fill with 0x01 if number is only 6 numbers (local call)
-+    fac[23+strlen(data)]=0x01;
-+    fac[24+strlen(data)]=0x01;
-+    fac[25+strlen(data)]=0x01;
-+    fac[26+strlen(data)]=0x01;
-+     
-+    fac[6]=18+strlen(data);
-+    fac[9]=15+strlen(data);
-+    fac[17]=7+strlen(data);
-+    fac[19]=2+strlen(data);
-+    fac[21]=strlen(data);
-+
-+    bchaninfo[0] = 0x1;
-+    INFO_REQ_HEADER(&CMSG,ast_capi_ApplID,ast_capi_MessageNumber++,0);
-+    INFO_REQ_CONTROLLER(&CMSG) = i->controller;
-+    INFO_REQ_PLCI(&CMSG) = i->PLCI;
-+    INFO_REQ_BCHANNELINFORMATION(&CMSG) = (unsigned char*)bchaninfo; // use D-Channel
-+    INFO_REQ_KEYPADFACILITY(&CMSG) = 0;
-+    INFO_REQ_USERUSERDATA(&CMSG) = 0;
-+    INFO_REQ_FACILITYDATAARRAY(&CMSG) = (unsigned char*) fac + 4;
-+
-+    if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
-+      ast_log(LOG_ERROR,"Error sending INFO_REQ\n");
-+      return Info;
-+    } else {
-+      if (capidebug) {
-+          // ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(&CMSG));
-+          ast_log(LOG_NOTICE,"sent INFO_REQ PLCI = %#x\n",i->PLCI);
-+      }
-+    }
-+
-+    return res;
-+}
-+#endif
-+
-+void remove_pipe(int PLCI) {
-+    struct capi_pipe *p,*ptmp;
-+
-+    ast_mutex_lock(&pipelock);
-+    p = pipelist;
-+    ptmp = NULL;
-+    while (p) {
-+      if (p->PLCI == PLCI) {
-+          if (ptmp == NULL) {
-+              // mypipe == head of pipelist
-+              pipelist = p->next;
-+              if(p->fd > -1) close(p->fd);
-+              if(p->i != NULL && p->i->fd > -1) close(p->i->fd);
-+              free(p);
-+              if (option_verbose > 4) {
-+                  ast_verbose(VERBOSE_PREFIX_3 "removed pipe for PLCI = %#x\n",PLCI);
-+              }
-+              break;
-+          } else {
-+              // somehwere inbetween or at the end
-+              ptmp->next = p->next;
-+              if (p->next == NULL) {
-+                  capi_last_plci = p->PLCI;
-+              }
-+              if(p->fd > -1) close(p->fd);
-+              if(p->i != NULL && p->i->fd > -1) close(p->i->fd);
-+              free(p);
-+              if (option_verbose > 4) {
-+                  ast_verbose(VERBOSE_PREFIX_3 "removed pipe for PLCI = %#x\n",PLCI);
-+              }
-+              break;
-+          }
-+      }
-+      ptmp = p;
-+      p = p->next;
-+    }
-+    ast_mutex_unlock(&pipelock);
-+}
-+
-+static int capi_activehangup(struct ast_channel *c) {
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+    MESSAGE_EXCHANGE_ERROR  error;
-+    _cmsg     CMSG;
-+
-+    if (option_verbose > 2) {
-+      if (capidebug)
-+            ast_verbose(VERBOSE_PREFIX_4 "activehangingup\n");
-+    }
-+
-+    if (i == NULL) {
-+      return 0;
-+    }
-+
-+    if (c->_state == AST_STATE_RING) {
-+      CONNECT_RESP_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, 0);
-+      CONNECT_RESP_PLCI(&CMSG) = i->PLCI;
-+      CONNECT_RESP_REJECT(&CMSG) = 2;
-+      if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+          ast_log(LOG_ERROR,"error sending CONNECT_RESP for PLCI = %#x\n",i->PLCI);
-+      } else {
-+          if (option_verbose > 5) {
-+              ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",i->PLCI);
-+          }
-+      }
-+      return 0;
-+    }
-+
-+    // active disconnect
-+    if (i->state == CAPI_STATE_BCONNECTED) {
-+      DISCONNECT_B3_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+      DISCONNECT_B3_REQ_NCCI(&CMSG) = i->NCCI;
-+
-+      if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+          ast_log(LOG_ERROR, "error sending DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
-+      } else {
-+          if (option_verbose > 5) {
-+              ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
-+          }
-+      }
-+      // wait for the B3 layer to go down
-+      while (i->state != CAPI_STATE_CONNECTED) {
-+          usleep(10000);
-+      }
-+    }
-+    if ((i->state == CAPI_STATE_CONNECTED) || (i->state == CAPI_STATE_CONNECTPENDING)){
-+      DISCONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+      DISCONNECT_REQ_PLCI(&CMSG) = i->PLCI;
-+
-+      if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+          ast_log(LOG_ERROR, "error sending DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
-+      } else {
-+          if (option_verbose > 5) {
-+              ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
-+          }
-+      }
-+      // wait for the B1 layer to go down
-+      while (i->state != CAPI_STATE_DISCONNECTED) {
-+          usleep(10000);
-+      }
-+    }
-+    return 0;
-+}
-+
-+static int capi_hangup(struct ast_channel *c) {
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+
-+    // hmm....ok...this is called to free the capi interface (passive disconnect)
-+    // or to bring down the channel (active disconnect)
-+    
-+    if (option_verbose > 3)
-+          ast_verbose(VERBOSE_PREFIX_3 "CAPI Hangingup\n");
-+
-+    if (i == NULL) {
-+      ast_log(LOG_ERROR,"channel has no interface!\n");
-+      return -1;
-+    }
-+    
-+    // are we down, yet?
-+    if (i->state != CAPI_STATE_DISCONNECTED) {
-+      // no
-+      capi_activehangup(c);
-+    }
-+
-+    remove_pipe(i->PLCI);
-+    i->PLCI = 0;
-+    i->NCCI = 0;
-+    if ((i->doDTMF == 1) && (i->vad != NULL)) {
-+      ast_dsp_free(i->vad);
-+    }
-+    ast_smoother_free(i->smoother); // discard any frames left hanging
-+    i->smoother=ast_smoother_new(AST_CAPI_MAX_B3_BLOCK_SIZE * 2);
-+    memset(i->cid,0,sizeof(i->cid));
-+    i->owner=NULL;
-+    ast_mutex_lock(&usecnt_lock);
-+      usecnt--;
-+    ast_mutex_unlock(&usecnt_lock);
-+    ast_update_use_count();
-+    i->mypipe = NULL;
-+    i = NULL;
-+    c->tech_pvt = NULL;
-+    ast_setstate(c,AST_STATE_DOWN);
-+    return 0;
-+}
-+
-+static char *capi_number(char *data,int strip) {
-+    unsigned len = *data;
-+    // XXX fix me
-+    // convert a capi struct to a \0 terminated string
-+    if (!len || len < (unsigned int) strip) return NULL;
-+    len = len - strip;
-+    data = (char *)(data + 1 + strip);
-+    return strndup((char *)data,len);
-+}
-+
-+int capi_call(struct ast_channel *c, char *idest, int timeout)
-+{
-+      struct ast_capi_pvt *i;
-+      struct capi_pipe *p = NULL;
-+      int fds[2];
-+      char *dest,*interface;
-+      char buffer[AST_MAX_EXTENSION];
-+      char called[AST_MAX_EXTENSION],calling[AST_MAX_EXTENSION];
-+      char bchaninfo[3];
-+      long flags;
-+              
-+      _cmsg CMSG;
-+      MESSAGE_EXCHANGE_ERROR  error;
-+      
-+      strncpy(buffer,idest,sizeof(buffer)-1);
-+      interface = strtok(buffer, "/");
-+      dest = strtok(NULL, "/");
-+
-+
-+      if (!dest) {
-+              ast_log(LOG_WARNING, "Destination %s requires a real destination\n", idest);
-+              return -1;
-+      }
-+      i = c->tech_pvt;
-+      i->doB3 = AST_CAPI_B3_DONT; // <homer>DOH</homer>
-+
-+      // always B3
-+      if (((char *)dest)[0] == 'b') {
-+          i->doB3 = AST_CAPI_B3_ALWAYS;
-+      }
-+      // only do B3 on successfull calls
-+      if (((char *)dest)[0] == 'B') {
-+          i->doB3 = AST_CAPI_B3_ON_SUCCESS;
-+      } 
-+      
-+      if (i->doB3 != AST_CAPI_B3_DONT) {
-+          dest++;
-+      }
-+
-+      if (option_verbose > 1) {
-+          if (capidebug)
-+              ast_verbose(VERBOSE_PREFIX_2 "CAPI Call %s %s", c->name, i->doB3?"with B3":"");
-+      }
-+      switch (c->cid.cid_pres) {
-+          case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
-+          case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
-+          case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
-+          case PRES_ALLOWED_NETWORK_NUMBER:
-+          case PRES_NUMBER_NOT_AVAILABLE:
-+              i->CLIR = 0;
-+              break;
-+          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:
-+              i->CLIR = 1;
-+              break;
-+          default:
-+              i->CLIR = 0;
-+      }
-+    
-+      if (pipe(fds) == 0) {
-+          ast_mutex_lock(&pipelock);
-+          i->fd = fds[0];
-+          flags = fcntl(i->fd,F_GETFL);
-+          fcntl(i->fd,F_SETFL,flags | O_SYNC | O_DIRECT);
-+          p = malloc(sizeof(struct capi_pipe));
-+          memset(p, 0, sizeof(struct capi_pipe));
-+          p->fd = fds[1];
-+          flags = fcntl(i->fd,F_GETFL);
-+          fcntl(p->fd,F_SETFL,flags | O_SYNC | O_DIRECT);
-+          c->fds[0] = i->fd;
-+          p->PLCI = -1;
-+          p->i = i;
-+          p->c = c;
-+          i->mypipe = p;
-+          p->next = pipelist;
-+          pipelist = p;
-+          if (option_verbose > 4) {
-+              ast_verbose(VERBOSE_PREFIX_3 "creating pipe for PLCI=-1\n");
-+          }
-+          ast_mutex_unlock(&pipelock);
-+      }
-+      i->outgoing = 1;
-+      
-+      i->MessageNumber = ast_capi_MessageNumber++;
-+      CONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, i->controller);
-+      CONNECT_REQ_CONTROLLER(&CMSG) = i->controller;
-+      CONNECT_REQ_CIPVALUE(&CMSG) = 0x10;     // Telephony, could also use 0x04 (3.1Khz audio)
-+      called[0] = strlen(dest)+1;
-+      called[1] = 0x80;
-+      strncpy(&called[2],dest,sizeof(called)-2);
-+      CONNECT_REQ_CALLEDPARTYNUMBER(&CMSG) = (unsigned char *)called;
-+      CONNECT_REQ_CALLEDPARTYSUBADDRESS(&CMSG) = NULL;
-+
-+      if (c->cid.cid_num) {
-+          calling[0] = strlen(c->cid.cid_num)+2;
-+          calling[1] = 0x0;
-+      } else {
-+          calling[0] = 0x0;
-+          calling[1] = 0x0;
-+      }
-+
-+      if (i->CLIR == 1) {
-+          calling[2] = 0xA0; // CLIR
-+      } else {
-+          calling[2] = 0x80; // CLIP
-+      }
-+
-+      if (c->cid.cid_num) {
-+          strncpy(&calling[3],c->cid.cid_num,sizeof(calling)-3);
-+      }
-+      CONNECT_REQ_CALLINGPARTYNUMBER(&CMSG) = (unsigned char *)calling;
-+      CONNECT_REQ_CALLINGPARTYSUBADDRESS(&CMSG) = NULL;
-+
-+      CONNECT_REQ_B1PROTOCOL(&CMSG) = 1;
-+      CONNECT_REQ_B2PROTOCOL(&CMSG) = 1; // 1
-+      CONNECT_REQ_B3PROTOCOL(&CMSG) = 0;
-+
-+      bchaninfo[0] = 2;
-+      bchaninfo[1] = 0x0;
-+      bchaninfo[2] = 0x0;
-+      CONNECT_REQ_BCHANNELINFORMATION(&CMSG) = (unsigned char *)bchaninfo; // 0
-+
-+        if ((error = _capi_put_cmsg(&CMSG))) {
-+          ast_log(LOG_ERROR,"error sending CONNECT_REQ (error=%#x)\n",error);
-+          return error;
-+      } else {
-+          if (option_verbose > 5) {
-+              ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_REQ MN =%#x\n",CMSG.Messagenumber);
-+          }
-+      }
-+
-+      i->state = CAPI_STATE_CONNECTPENDING;
-+
-+      ast_setstate(c, AST_STATE_DIALING);
-+
-+      // XXX fixme, not nice:
-+/*    if (i->controller > 0) {
-+          capi_controllers[i->controller]->nfreebchannels--;
-+      } */
-+
-+      // now we shall return .... the rest has to be done by handle_msg
-+    return 0;
-+}
-+
-+
-+static int capi_answer(struct ast_channel *c) {
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+    MESSAGE_EXCHANGE_ERROR  error;
-+    _cmsg                 CMSG;
-+    char buf[AST_MAX_EXTENSION];
-+    char *dnid;
-+    
-+    if (i->isdnmode && (strlen(i->incomingmsn)<strlen(i->dnid)))
-+      dnid = i->dnid + strlen(i->incomingmsn);
-+    else
-+      dnid = i->dnid;
-+
-+    CONNECT_RESP_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, 0);
-+    CONNECT_RESP_PLCI(&CMSG) = i->PLCI;
-+    CONNECT_RESP_REJECT(&CMSG) = 0;
-+    buf[0] = strlen(dnid)+2;
-+    buf[1] = 0x0;
-+    buf[2] = 0x80;
-+    strncpy(&buf[3],dnid,sizeof(buf)-4);
-+    CONNECT_RESP_CONNECTEDNUMBER(&CMSG) = (unsigned char *)buf;
-+    CONNECT_RESP_CONNECTEDSUBADDRESS(&CMSG) = NULL;
-+    CONNECT_RESP_LLC(&CMSG) = NULL;
-+    CONNECT_RESP_B1PROTOCOL(&CMSG) = 1;
-+    CONNECT_RESP_B2PROTOCOL(&CMSG) = 1;
-+    CONNECT_RESP_B3PROTOCOL(&CMSG) = 0;
-+
-+    if (option_verbose > 3)
-+      ast_verbose(VERBOSE_PREFIX_3 "CAPI Answering for MSN %s\n", dnid);
-+    if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+      return -1;      
-+    } else {
-+      if (option_verbose > 5) {
-+          if (capidebug) 
-+              ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP PLCI = %#x DNID = %s\n",i->PLCI,i->dnid);
-+      }
-+    }
-+    
-+    i->state = CAPI_STATE_ANSWERING;
-+    i->doB3 = AST_CAPI_B3_DONT;
-+    i->outgoing = 0;
-+    i->earlyB3 = -1;
-+
-+    return 0;
-+}
-+
-+struct ast_frame *capi_read(struct ast_channel *c) {
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+      int readsize = 0;
-+
-+      if ((i->state == CAPI_STATE_REMOTE_HANGUP)) {
-+          ast_log(LOG_ERROR,"this channel is not connected\n");
-+          return NULL;
-+      }
-+      if (i->state == CAPI_STATE_ONHOLD) {
-+          i->fr.frametype = AST_FRAME_NULL;
-+          return &i->fr;
-+      }
-+      
-+      if (i == NULL) {
-+          ast_log(LOG_ERROR,"channel has no interface\n");
-+          return NULL;
-+      }
-+      i->fr.frametype = AST_FRAME_NULL;
-+      i->fr.subclass = 0;
-+      i->fr.delivery.tv_sec = 0;
-+      i->fr.delivery.tv_usec = 0;
-+      readsize = read(i->fd,&i->fr,sizeof(struct ast_frame));
-+      if (readsize != sizeof(struct ast_frame)) {
-+          ast_log(LOG_ERROR,"did not read a whole frame\n");
-+      }
-+      if (i->fr.frametype == AST_FRAME_VOICE) {
-+          readsize = read(i->fd,i->fr.data,i->fr.datalen);
-+          if (readsize != i->fr.datalen) {
-+              ast_log(LOG_ERROR,"did not read whole frame data\n");
-+          }
-+      }
-+      i->fr.mallocd = 0;      
-+      if (i->fr.frametype == AST_FRAME_NULL) {
-+          return NULL;
-+      }
-+      if ((i->fr.frametype == AST_FRAME_DTMF) && (i->fr.subclass == 'f')) {
-+          if (strcmp(c->exten, "fax")) {
-+              if (ast_exists_extension(c, ast_strlen_zero(c->macrocontext) ? c->context : c->macrocontext, "fax", 1, c->cid.cid_num)) {
-+                  if (option_verbose > 2)
-+                      ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", c->name);
-+                      /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
-+                      pbx_builtin_setvar_helper(c,"FAXEXTEN",c->exten);
-+                      if (ast_async_goto(c, c->context, "fax", 1))
-+                          ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", c->name, c->context);
-+                      } else {
-+                          ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
-+                      }
-+          } else {
-+              ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
-+          }
-+      }
-+      return &i->fr;
-+}
-+
-+int capi_write(struct ast_channel *c, struct ast_frame *f) {
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+      _cmsg CMSG;
-+      MESSAGE_EXCHANGE_ERROR  error;
-+      int j=0;
-+      char buf[1000];
-+      struct ast_frame *fsmooth;
-+#ifdef CAPI_ES
-+      int txavg=0;
-+#endif
-+
-+#ifndef CAPI_NEVER_EVER_EARLY_B3_CONNECTS
-+      // dont send audio to the local exchange!
-+      if (i->earlyB3 == 1 || !i->NCCI) {
-+          return 0;
-+      }
-+#endif
-+
-+      if (!i) {
-+          ast_log(LOG_ERROR,"channel has no interface\n");
-+          return -1;
-+      } 
-+
-+      if (f->frametype == AST_FRAME_NULL) {
-+          return 0;
-+      }
-+      if (f->frametype == AST_FRAME_DTMF) {
-+          ast_log(LOG_ERROR,"dtmf frame should be written\n");
-+          return 0;
-+      }
-+      if (f->frametype != AST_FRAME_VOICE) {
-+          ast_log(LOG_ERROR,"not a voice frame\n");
-+          return -1;
-+      }
-+      if (f->subclass != capi_capability) {
-+          ast_log(LOG_ERROR,"dont know how to write subclass %d\n",f->subclass);
-+          return -1;
-+      }
-+//    ast_log(LOG_NOTICE,"writing frame %d %d\n",f->frametype,f->subclass);
-+
-+    if (ast_smoother_feed(i->smoother, f)!=0) {
-+        ast_log(LOG_ERROR,"failed to fill smoother\n");
-+        return -1;
-+    }
-+
-+    fsmooth=ast_smoother_read(i->smoother);
-+    while(fsmooth != NULL) {
-+        DATA_B3_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+        DATA_B3_REQ_NCCI(&CMSG) = i->NCCI;
-+        DATA_B3_REQ_DATALENGTH(&CMSG) = fsmooth->datalen;
-+        DATA_B3_REQ_FLAGS(&CMSG) = 0; 
-+
-+        if (ast_mutex_lock(&capi_send_buffer_lock)) {
-+            ast_log(LOG_WARNING,"Unable to lock B3 send buffer!\n");
-+            return -1;
-+        }
-+#ifndef CAPI_ES
-+#ifdef CAPI_GAIN
-+        for (j=0;j<fsmooth->datalen;j++) {
-+          buf[j] = i->g.txgains[reversebits[((unsigned char *)fsmooth->data)[j]]]; 
-+        }
-+#else
-+        for (j=0;j<fsmooth->datalen;j++) {
-+          buf[j] = reversebits[ ((unsigned char *)fsmooth->data)[j] ]; 
-+        }
-+#endif
-+#else
-+      if ((i->doES == 1)) {
-+          for (j=0;j<fsmooth->datalen;j++) {
-+              buf[j] = reversebits[ ((unsigned char *)fsmooth->data)[j] ]; 
-+              txavg += abs( capiXLAW2INT(reversebits[ ((unsigned char*)fsmooth->data)[j]]) );
-+          }
-+          txavg = txavg/j;
-+          for(j=0;j<ECHO_TX_COUNT-1;j++) {
-+              i->txavg[j] = i->txavg[j+1];
-+          }
-+          i->txavg[ECHO_TX_COUNT-1] = txavg;
-+          
-+//        ast_log(LOG_NOTICE,"txavg = %d\n",txavg);
-+      } else {
-+#ifdef CAPI_GAIN
-+          for (j=0;j<fsmooth->datalen;j++) {
-+              buf[j] = i->g.txgains[reversebits[((unsigned char *)fsmooth->data)[j]]]; 
-+          }
-+#else
-+          for (j=0;j<fsmooth->datalen;j++) {
-+              buf[j] = reversebits[ ((unsigned char *)fsmooth->data)[j] ]; 
-+          }
-+#endif
-+      }
-+#endif
-+    
-+        DATA_B3_REQ_DATAHANDLE(&CMSG) = capi_send_buffer_handle;
-+      memcpy((char *)&capi_send_buffer[(capi_send_buffer_handle % AST_CAPI_MAX_B3_BLOCKS) * AST_CAPI_MAX_B3_BLOCK_SIZE],&buf,fsmooth->datalen);
-+        DATA_B3_REQ_DATA(&CMSG) = (unsigned char *)&capi_send_buffer[(capi_send_buffer_handle % AST_CAPI_MAX_B3_BLOCKS) * AST_CAPI_MAX_B3_BLOCK_SIZE];
-+      capi_send_buffer_handle++;
-+    
-+        if (ast_mutex_unlock(&capi_send_buffer_lock)) {
-+            ast_log(LOG_WARNING,"Unable to unlock B3 send buffer!\n");
-+            return -1;
-+        }
-+
-+
-+#ifdef CAPI_SYNC    
-+    ast_mutex_lock(&i->lockB3in);
-+    if ((i->B3in >= 1) && (i->B3in <= AST_CAPI_MAX_B3_BLOCKS)) {
-+      i->B3in--;
-+      ast_mutex_unlock(&i->lockB3in);
-+        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+            ast_log(LOG_ERROR,"error sending DATA_B3_REQ (error=%#x, datalen=%d) B3in=%d\n",error,fsmooth->datalen,i->B3in);
-+//            ast_log(LOG_NOTICE,"f: timelen %d b = %d MN = %d \n",fsmooth->timelen,b,CMSG.Messagenumber);
-+      } else {
-+                  if (option_verbose > 5) {
-+              if (capidebug) 
-+                  ast_verbose(VERBOSE_PREFIX_4 "sent DATA_B3_REQ (NCCI=%#x) (%d bytes)\n",i->NCCI,fsmooth->datalen);
-+                  }
-+      }
-+    } else {
-+      if (i->B3in > 0) i->B3in--;
-+      ast_mutex_unlock(&i->lockB3in);
-+    }
-+#else
-+        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
-+            ast_log(LOG_ERROR,"error sending DATA_B3_REQ (error=%#x, datalen=%d)\n",error,fsmooth->datalen);
-+//            ast_log(LOG_NOTICE,"f: timelen %d b = %d MN = %d \n",fsmooth->timelen,b,CMSG.Messagenumber);
-+      } else {
-+                  if (option_verbose > 5) {
-+              if (capidebug) 
-+                  ast_verbose(VERBOSE_PREFIX_4 "sent DATA_B3_REQ (NCCI=%#x) (%d bytes)\n",i->NCCI,fsmooth->datalen);
-+                  }
-+      }
-+#endif
-+    
-+//    ast_frfree(fsmooth);
-+
-+        fsmooth=ast_smoother_read(i->smoother);
-+    }
-+      return 0;
-+}
-+
-+static int capi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan) {
-+    struct ast_capi_pvt *p = newchan->tech_pvt;
-+      p->owner = newchan;
-+      return 0;
-+}
-+
-+int capi_indicate(struct ast_channel *c,int condition) {
-+    return -1;
-+}
-+
-+int capi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc) {
-+    return -1;
-+}
-+
-+
-+struct ast_channel *capi_new(struct ast_capi_pvt *i,int state) {
-+    struct ast_channel *tmp;
-+    int fmt;
-+
-+    tmp = ast_channel_alloc(1);
-+    if (tmp != NULL) {
-+      snprintf(tmp->name,sizeof(tmp->name),"CAPI/contr%d/%s-%d",i->controller,i->dnid,capi_counter++);
-+      tmp->type = type;
-+      tmp->tech = &capi_tech;
-+      tmp->nativeformats = capi_capability;
-+      ast_setstate(tmp,state);
-+      tmp->fds[0] = i->fd;
-+      i->smoother = ast_smoother_new(AST_CAPI_MAX_B3_BLOCK_SIZE);
-+      if (i->smoother == NULL) {
-+          ast_log(LOG_ERROR, "smoother NULL!\n");
-+      }
-+      i->fr.frametype = 0;
-+      i->fr.subclass = 0;
-+      i->fr.delivery.tv_sec = 0;
-+      i->fr.delivery.tv_usec = 0;
-+      i->state = CAPI_STATE_DISCONNECTED;
-+      i->CLIR = 0;
-+      i->calledPartyIsISDN = 0; // let's be pessimistic
-+      i->earlyB3 = -1;
-+      i->doB3 = AST_CAPI_B3_DONT;
-+      i->outgoing = 0;
-+      i->onholdPLCI = 0;
-+#ifdef CAPI_SYNC
-+      i->B3in = 0;
-+      ast_mutex_init(&i->lockB3in);
-+#endif                
-+#ifdef CAPI_ES
-+      memset(i->txavg,0,ECHO_TX_COUNT);
-+#endif
-+
-+#ifndef CAPI_FORCE_SOFTWARE_DTMF
-+          if (i->doDTMF == 1) {
-+#endif
-+              i->vad = ast_dsp_new();
-+              ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
-+#ifndef CAPI_FORCE_SOFTWARE_DTMF
-+          }
-+#endif
-+
-+      tmp->tech_pvt = i;
-+      tmp->callgroup = i->callgroup;
-+      tmp->nativeformats = capi_capability;
-+      fmt = ast_best_codec(tmp->nativeformats);
-+//    fmt = capi_capability;
-+      tmp->readformat = fmt;
-+      tmp->writeformat = fmt;
-+      tmp->rawreadformat = fmt;
-+      tmp->rawwriteformat = fmt;
-+      strncpy(tmp->context,i->context,sizeof(tmp->context)-1);
-+      tmp->cid.cid_num = strdup(i->cid);
-+      tmp->cid.cid_dnid = strdup(i->dnid);
-+      strncpy(tmp->exten,i->dnid,sizeof(tmp->exten)-1);
-+      strncpy(tmp->accountcode,i->accountcode,sizeof(tmp->accountcode)-1);
-+      i->owner = tmp;
-+      ast_mutex_lock(&usecnt_lock);
-+      usecnt++;
-+      ast_mutex_unlock(&usecnt_lock);
-+      ast_update_use_count();
-+      if (state != AST_STATE_DOWN) {
-+          // we are alerting (phones ringing)
-+          if (state == AST_STATE_RING)
-+              capi_alert(tmp);
-+          if (ast_pbx_start(tmp)) {
-+              ast_log(LOG_ERROR,"Unable to start pbx on channel!\n");
-+              ast_hangup(tmp);
-+              tmp = NULL;
-+          } else {
-+              if (option_verbose > 2) {
-+                  ast_verbose(VERBOSE_PREFIX_3 "started pbx on channel (callgroup=%d)!\n",tmp->callgroup);
-+              }
-+          }
-+      }
-+    } else {
-+      ast_log(LOG_ERROR,"Unable to allocate channel!\n");
-+    }
-+    return tmp;
-+}
-+
-+
-+struct ast_channel *capi_request(const char *type, int format, void *data, int *cause)
-+{
-+      struct ast_capi_pvt *i;
-+      struct ast_channel *tmp = NULL;
-+      char *dest,*interface;
-+      char buffer[AST_MAX_EXTENSION];
-+      unsigned int capigroup=0, controller=0;
-+      int notfound = 1;
-+
-+      if (option_verbose > 1) {
-+          if (capidebug)
-+              ast_verbose(VERBOSE_PREFIX_3 "data = %s\n",(char *)data);
-+      }
-+      strncpy(buffer,(char *)data,sizeof(buffer)-1);
-+
-+      interface = strtok(buffer, "/");
-+      dest = strtok(NULL, "/");
-+
-+      
-+      if (((char *)interface)[0] == 'g') {
-+          interface++;
-+          capigroup = atoi(interface);
-+          if (option_verbose > 1) {
-+              if (capidebug)
-+                  ast_verbose(VERBOSE_PREFIX_3 "capi request group = %d\n",capigroup);
-+          }
-+      } else if (!strncmp(interface,"contr",5)) {
-+          interface += 5;
-+          controller = atoi(interface);
-+          if (option_verbose > 1) {
-+              if (capidebug)
-+                  ast_verbose(VERBOSE_PREFIX_3 "capi request controller = %d\n",controller);
-+          }
-+      } else {
-+          ast_log(LOG_ERROR,"Syntax error in dialstring. read the docs!\n");
-+      }
-+
-+      ast_mutex_lock(&iflock);
-+      i = iflist;
-+      while (i && notfound) {
-+          // unused channel
-+          if (!i->owner) {
-+              if (controller && (i->controllers & (1 << controller))) {
-+                  // DIAL(CAPI/contrX/...)
-+                  ast_mutex_lock(&contrlock);
-+                  if (capi_controllers[controller]->nfreebchannels > 0) {
-+                      strncpy(i->dnid,dest,sizeof(i->dnid)-1);
-+                      i->controller = controller;
-+                      tmp = capi_new(i, AST_STATE_DOWN);
-+                      i->PLCI = -1;
-+                      i->datahandle = 0;
-+                      i->outgoing = 1;        // this is an outgoing line
-+                      i->earlyB3 = -1;
-+                      // capi_detect_dtmf(tmp,1);
-+                      ast_mutex_unlock(&contrlock);
-+                      ast_mutex_unlock(&iflock);
-+                      return tmp;
-+                  } else {
-+                      // keep on running!
-+                      ast_mutex_unlock(&contrlock);
-+                  }
-+              } else if (capigroup && (i->group & (1 << capigroup))) {
-+                  int c;
-+                  // DIAL(CAPI/gX/...)
-+                  ast_mutex_lock(&contrlock);
-+                  for (c=1;c<=capi_num_controllers;c++) {
-+                      if (i->controllers & (1 << c)) {
-+                          if (capi_controllers[c]->nfreebchannels > 0) {
-+                              strncpy(i->dnid,dest,sizeof(i->dnid)-1);
-+                              i->controller = c;
-+                              tmp = capi_new(i, AST_STATE_DOWN);
-+                              i->PLCI = -1;
-+                              i->datahandle = 0;
-+                              i->outgoing = 1;        // this is an outgoing line
-+                              i->earlyB3 = -1;
-+                              // capi_detect_dtmf(tmp,1);
-+                              ast_mutex_unlock(&contrlock);
-+                              ast_mutex_unlock(&iflock);
-+                              return tmp;
-+                          } else {
-+                              // keep on running!
-+                          }
-+                      }
-+                  }
-+                  ast_mutex_unlock(&contrlock);
-+              }
-+          }
-+//        ast_log(LOG_NOTICE,"not contr %d group %d\n",i->controllers, i->group);
-+          i = i->next;
-+      }
-+      ast_mutex_unlock(&iflock);
-+      ast_log(LOG_NOTICE,"didn't find capi device with controller = %d or group = %d.\n",controller, capigroup);
-+      return NULL;
-+}
-+
-+
-+struct capi_pipe *find_pipe(int PLCI,int MN) {
-+    struct capi_pipe *p;
-+    // find a pipe by PLCI or by MessageNumber (in case this is a CONNECT_CONF)
-+    ast_mutex_lock(&pipelock);
-+    p = pipelist;
-+    if ((p == NULL) && (capi_last_plci != PLCI)){
-+      if (capidebug) {
-+      ast_log(LOG_NOTICE,"PLCI doesnt match last pipe (PLCI = %#x)\n",PLCI);
-+      }
-+      ast_mutex_unlock(&pipelock);
-+      return NULL;
-+    }
-+    while(p != NULL) {
-+      if ((p->PLCI == PLCI) || ( (p->PLCI == -1) && (p->i->MessageNumber == MN) ) ){
-+          ast_mutex_unlock(&pipelock);
-+          return p;
-+      }
-+      p = p->next;
-+    }
-+    if (capidebug) {
-+      ast_log(LOG_ERROR,"unable to find a pipe for PLCI = %#x MN = %#x\n",PLCI,MN);
-+    }
-+    ast_mutex_unlock(&pipelock);
-+    return NULL;
-+}
-+
-+int pipe_frame(struct capi_pipe *p,struct ast_frame *f) {
-+      fd_set wfds;
-+      int written=0;
-+      struct timeval tv;
-+      FD_ZERO(&wfds);
-+      FD_SET(p->fd,&wfds);
-+      tv.tv_sec = 0;
-+      tv.tv_usec = 10;
-+      if ((f->frametype == AST_FRAME_VOICE) && (p->i->doDTMF == 1) && (p->i->vad != NULL)) {
-+          f = ast_dsp_process(p->c,p->i->vad,f);
-+          if (f->frametype == AST_FRAME_NULL) {
-+              return 0;
-+          }
-+      }
-+      // we dont want the monitor thread to block
-+      if (select(p->fd + 1,NULL,&wfds,NULL,&tv) == 1) {
-+          written = write(p->fd,f,sizeof(struct ast_frame));
-+          if (written < (signed int) sizeof(struct ast_frame)) {
-+              ast_log(LOG_ERROR,"wrote %d bytes instead of %d\n", written, (int)sizeof(struct ast_frame));
-+              return -1;
-+          }
-+          if (f->frametype == AST_FRAME_VOICE) {
-+              written = write(p->fd,f->data,f->datalen);
-+              if (written < f->datalen) {
-+                  ast_log(LOG_ERROR,"wrote %d bytes instead of %d\n",written,f->datalen);
-+                  return -1;
-+              }
-+          }
-+      } else {
-+          return 0;
-+      }
-+      return -1;
-+}
-+
-+static int search_did(struct ast_channel *c)
-+{
-+    // Returns 
-+    // -1 = Failure 
-+    //  0 = Match
-+    //  1 = possible match 
-+    struct ast_capi_pvt *i = c->tech_pvt;
-+    char *exten;
-+    
-+    if (strlen(i->dnid)<strlen(i->incomingmsn))
-+      return -1;
-+      
-+//    exten = i->dnid + strlen(i->incomingmsn);
-+    exten = i->dnid;
-+
-+    if (ast_exists_extension(NULL, c->context, exten, 1, NULL)) {
-+          c->priority = 1;
-+          strncpy(c->exten, exten, sizeof(c->exten) - 1);
-+      return 0;
-+    }
-+
-+    if (ast_canmatch_extension(NULL, c->context, exten, 1, NULL)) {
-+      return 1;
-+    }
-+
-+
-+    return -1;
-+}
-+
-+int pipe_msg(int PLCI,_cmsg *CMSG) {
-+      struct capi_pipe *p;
-+      _cmsg CMSG2;
-+      MESSAGE_EXCHANGE_ERROR  error;
-+      struct ast_frame fr;
-+      char b3buf[1024];
-+      int j;
-+      int b3len=0;
-+      char dtmf;
-+      unsigned dtmflen;
-+#ifdef CAPI_ES
-+      int rxavg = 0;
-+      int txavg = 0;
-+#endif    
-+
-+      p = find_pipe(PLCI,CMSG->Messagenumber);
-+      if (p == NULL) {
-+          if (IS_DISCONNECT_IND(CMSG)) {
-+              DISCONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber , 0);
-+              DISCONNECT_RESP_PLCI(&CMSG2) = PLCI;
-+              if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                  ast_log(LOG_NOTICE, "error sending DISCONNECT_RESP PLCI=%#x\n",PLCI);
-+              } else {
-+                  if (option_verbose > 5) {
-+                      if (capidebug)
-+                          ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_RESP PLCI=%#x\n",PLCI);
-+                  }
-+              }           
-+              return 0;
-+          }
-+          if (capidebug) {
-+              ast_log(LOG_NOTICE,"%s",capi_cmsg2str(CMSG));
-+          } 
-+          return -1;
-+      }
-+
-+      if (CMSG != NULL) {
-+          switch (CMSG->Subcommand) {
-+              case CAPI_IND:
-+                  switch (CMSG->Command) {
-+                      case CAPI_DISCONNECT_B3:
-+//                        ast_log(LOG_NOTICE,"DISCONNECT_B3_IND\n");
-+
-+                          DISCONNECT_B3_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
-+                          DISCONNECT_B3_RESP_NCCI(&CMSG2) = DISCONNECT_B3_IND_NCCI(CMSG);
-+
-+                          if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                              ast_log(LOG_NOTICE, "error sending DISCONNECT_B3_RESP NCCI=%#x\n",(int)DISCONNECT_B3_IND_NCCI(CMSG));
-+                          } else {
-+                              if (option_verbose > 5) {
-+                                  if (capidebug)
-+                                      ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_B3_RESP NCCI=%#x\n",(int)DISCONNECT_B3_IND_NCCI(CMSG));
-+                              }
-+                          }
-+                          if (p->i->state == CAPI_STATE_BCONNECTED) {
-+                              // passive disconnect
-+                              p->i->state = CAPI_STATE_CONNECTED;
-+                          } else
-+                          if (p->i->state == CAPI_STATE_DISCONNECTING) {
-+                              // active disconnect
-+                              memset(&CMSG2,0,sizeof(_cmsg));
-+                              DISCONNECT_REQ_HEADER(&CMSG2, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+                              DISCONNECT_REQ_PLCI(&CMSG2) = PLCI;
-+
-+                              if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                                  ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",PLCI);
-+                              } else {
-+                                  if (option_verbose > 5) {
-+                                      if (capidebug)
-+                                          ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_REQ PLCI=%#x\n",PLCI);
-+                                  }
-+                              }                               
-+                          } else 
-+                          if (p->i->state == CAPI_STATE_ONHOLD) {
-+                                  // no hangup
-+                          }
-+                          ast_mutex_lock(&contrlock);
-+                          if (p->i->controller > 0) {
-+                              capi_controllers[p->i->controller]->nfreebchannels++;
-+                          }
-+                          ast_mutex_unlock(&contrlock);
-+                          break;
-+                      case CAPI_DISCONNECT:
-+//                        ast_log(LOG_NOTICE,"DISCONNECT_IND\n");
-+                          DISCONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber , 0);
-+                          DISCONNECT_RESP_PLCI(&CMSG2) = PLCI;
-+/*                        if (p->i->controller > 0) {
-+                              capi_controllers[p->i->controller]->nfreebchannels++;
-+                          } */
-+
-+                          if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                              ast_log(LOG_NOTICE, "error sending DISCONNECT_RESP PLCI=%#x\n",PLCI);
-+                          } else {
-+                              if (option_verbose > 5) {
-+                                  if (capidebug)
-+                                      ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_RESP PLCI=%#x\n",PLCI);
-+                              }
-+                          }
-+                          if (p->c) {
-+                              p->c->hangupcause = DISCONNECT_IND_REASON(CMSG) - 0x3480;
-+                          }
-+                          
-+                          if (PLCI == p->i->onholdPLCI) {
-+                              // the caller onhold hung up (or ECTed away)
-+                              p->i->onholdPLCI = 0;
-+                              remove_pipe(PLCI);
-+                              return 0;
-+                          }
-+                          
-+                          if (p->i->state == CAPI_STATE_DID) {
-+                              if ((p->c) != NULL) {
-+                                  ast_hangup(p->c);
-+                              } else {    
-+                                  ast_log(LOG_WARNING, "unable to hangup channel on DID. Channel is NULL.\n");
-+                              }
-+                              return 0;                               
-+                          }
-+                          
-+                          p->i->state = CAPI_STATE_DISCONNECTED;
-+
-+                          fr.frametype = AST_FRAME_CONTROL;
-+                          if (DISCONNECT_IND_REASON(CMSG) == 0x34a2) {
-+                              fr.subclass = AST_CONTROL_BUSY;
-+                          } else {
-+                              fr.frametype = AST_FRAME_NULL;
-+                          }
-+                          fr.datalen = 0;
-+                          if (pipe_frame(p,(struct ast_frame *)&fr) == -1) {
-+              // printf("STATE = %#x\n",p->i->state);
-+                              // in this case * did not read our hangup control frame
-+                              // so we must hangup the channel!
-+                              if ( (p->i->state != CAPI_STATE_DISCONNECTED) && (ast_check_hangup(p->c) == 0)) {
-+                                  if (option_verbose > 1) {
-+                                      ast_verbose(VERBOSE_PREFIX_3 "soft hangup by capi\n");
-+                                  }
-+                                  ast_softhangup(p->c,AST_SOFTHANGUP_DEV);
-+                              } else {
-+                                  // dont ever hangup while hanging up!
-+//                                ast_log(LOG_NOTICE,"no soft hangup by capi\n");
-+                              }
-+                              return -1;
-+                          } else {
-+                              return 0;
-+                          }
-+
-+/*                        fr.frametype = AST_FRAME_NULL;
-+                          fr.datalen = 0;
-+                          pipe_frame(p,(struct ast_frame *)&fr); */
-+                          break;
-+                      case CAPI_DATA_B3:
-+
-+                          memcpy(&b3buf[AST_FRIENDLY_OFFSET],(char *)DATA_B3_IND_DATA(CMSG),DATA_B3_IND_DATALENGTH(CMSG));
-+                          b3len = DATA_B3_IND_DATALENGTH(CMSG);
-+                      
-+                          // send a DATA_B3_RESP very quickly to free the buffer in capi
-+                          DATA_B3_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber,0);
-+                          DATA_B3_RESP_NCCI(&CMSG2) = DATA_B3_IND_NCCI(CMSG);
-+                          DATA_B3_RESP_DATAHANDLE(&CMSG2) = DATA_B3_IND_DATAHANDLE(CMSG);
-+                          if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                              ast_log(LOG_ERROR,"error sending DATA_B3_RESP (error=%#x)\n",error);
-+                          } else {
-+                              if (option_verbose > 6) {
-+                                  if (capidebug)
-+                                      ast_verbose(VERBOSE_PREFIX_4 "sent DATA_B3_RESP (NCCI=%#x)\n",(int)DATA_B3_IND_NCCI(CMSG));
-+                              }
-+                          }
-+#ifdef CAPI_SYNC
-+                          ast_mutex_lock(&p->i->lockB3in);
-+                          p->i->B3in++;
-+                          if (p->i->B3in > AST_CAPI_MAX_B3_BLOCKS) p->i->B3in = AST_CAPI_MAX_B3_BLOCKS;
-+                          ast_mutex_unlock(&p->i->lockB3in);
-+#endif                            
-+#ifdef CAPI_ES
-+                          if ((p->i->doES == 1)) {
-+                              for (j=0;j<b3len;j++) {
-+                                  b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]; 
-+                                  rxavg += abs(capiXLAW2INT( reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]));
-+                              }
-+                              rxavg = rxavg/j;
-+                              for(j=0;j<ECHO_EFFECTIVE_TX_COUNT;j++) {
-+                                  txavg += p->i->txavg[j];
-+                              }
-+                              txavg = txavg/j;
-+                          
-+                              if( (txavg/ECHO_TXRX_RATIO) > rxavg) { 
-+#ifdef CAPI_ULAW
-+                                  memset(&b3buf[AST_FRIENDLY_OFFSET],255,b3len);
-+#else
-+                                  memset(&b3buf[AST_FRIENDLY_OFFSET],84,b3len);
-+#endif
-+                                  if (capidebug) {
-+                                      ast_log(LOG_NOTICE,"SUPPRESSING ECHOrx=%d, tx=%d\n",rxavg,txavg);
-+                                  }
-+                              }
-+                          } else {
-+#ifdef CAPI_GAIN
-+                              for (j=0;j<b3len;j++) {
-+                                  b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[p->i->g.rxgains[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]]; 
-+                              }
-+#else
-+                              for (j=0;j<b3len;j++) {
-+                                  b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]; 
-+                              }
-+#endif
-+                          }
-+#else
-+
-+#ifdef CAPI_GAIN
-+                          for (j=0;j<b3len;j++) {
-+                              b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[p->i->g.rxgains[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]]; 
-+                          }
-+#else
-+                          for (j=0;j<b3len;j++) {
-+                              b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]; 
-+                          }
-+#endif
-+
-+#endif
-+                          // just being paranoid ...
-+              /*          if (p->c->_state != AST_STATE_UP) {
-+                              ast_setstate(p->c,AST_STATE_UP);
-+                          } */
-+                          
-+                          fr.frametype = AST_FRAME_VOICE;
-+                          fr.subclass = capi_capability;
-+                          fr.data = (char *)&b3buf[AST_FRIENDLY_OFFSET];
-+                          fr.datalen = b3len;
-+                          fr.samples = b3len;
-+                          fr.offset = AST_FRIENDLY_OFFSET;
-+                          fr.mallocd = 0;
-+                          fr.delivery.tv_sec = 0;
-+                          fr.delivery.tv_usec = 0;
-+                          fr.src = NULL;
-+                      //          ast_verbose(VERBOSE_PREFIX_3 "DATA_B3_IND (len=%d) fr.datalen=%d fr.subclass=%d\n",(int)DATA_B3_IND_DATALENGTH(CMSG),fr.datalen,fr.subclass);
-+                          return pipe_frame(p,(struct ast_frame *)&fr);
-+                          break;
-+                      case CAPI_FACILITY:
-+                          if (FACILITY_IND_FACILITYSELECTOR(CMSG) == 0x0001) {
-+                      // DTMF received
-+                              if (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0] != (0xff)) {
-+                                  dtmflen = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0];
-+                                  FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 1;
-+                              } else {
-+                                  dtmflen = ((__u16 *) (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) + 1))[0];
-+                                  FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 3;
-+                              }
-+                              if (dtmflen == 1) {
-+                                  dtmf = (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG))[0];
-+                                  fr.frametype = AST_FRAME_DTMF;
-+                                  fr.subclass = dtmf;
-+                                  if (option_verbose > 1) {
-+                                      if (capidebug)
-+                                          ast_verbose(VERBOSE_PREFIX_3 "c_dtmf = %c\n",dtmf);
-+                                  }
-+                                  pipe_frame(p,(struct ast_frame *)&fr);
-+                              } 
-+                          }
-+                          if (FACILITY_IND_FACILITYSELECTOR(CMSG) == 0x0003) {
-+                          // sservices
-+                      /*       ast_log(LOG_NOTICE,"FACILITY_IND PLCI = %#x\n",(int)FACILITY_IND_PLCI(CMSG));
-+                               ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0]);
-+                               ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1]);
-+                               ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[2]);
-+                               ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[3]);
-+                               ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]);
-+                               ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5]);  */
-+                              // RETRIEVE
-+                              if ( (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1] == 0x3) && (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[3] == 0x2)) {
-+                                  p->i->state = CAPI_STATE_CONNECTED;
-+                                  p->i->PLCI = p->i->onholdPLCI;
-+                                  p->i->onholdPLCI = 0;
-+                              }
-+                              if ( (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1] == 0x2) && (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[3] == 0x2)) {
-+                                  if ((FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5] != 0) && (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4] != 0)) { 
-+                                      // reason != 0x0000 == problem
-+                                      p->i->onholdPLCI = 0;
-+                                      p->i->state = CAPI_STATE_ONHOLD;
-+                                      ast_log(LOG_WARNING, "unable to put PLCI=%#x onhold, REASON = %#x%#x, maybe you need to subscribe for this...\n",(int)FACILITY_IND_PLCI(CMSG),FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5],FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]);
-+                                  } else {
-+                                      // reason = 0x0000 == call on hold
-+                                      p->i->state = CAPI_STATE_ONHOLD;
-+                                      if (capidebug) 
-+                                          ast_log(LOG_NOTICE, "PLCI=%#x put onhold\n",(int)FACILITY_IND_PLCI(CMSG));
-+                                  }
-+                              }
-+                          }
-+                          
-+                          error = FACILITY_RESP(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber,FACILITY_IND_PLCI(CMSG),FACILITY_IND_FACILITYSELECTOR(CMSG),FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG));
-+
-+                          if (error != 0) {
-+                              ast_log(LOG_ERROR,"error sending FACILITY_RESP (error=%#x)\n",error);
-+                          } else {
-+                              if (option_verbose > 5) {
-+                                  if (capidebug)
-+                                      ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_RESP (PLCI=%#x)\n",(int)FACILITY_IND_PLCI(CMSG));
-+                              }
-+                          }
-+                          break;
-+                      case CAPI_INFO:
-+                          // ast_log(LOG_ERROR,"INFO_IND PLCI=%#x INFO# = %#x\n",PLCI,INFO_IND_INFONUMBER(CMSG));
-+
-+                          memset(&CMSG2,0,sizeof(_cmsg));
-+                          error = INFO_RESP(&CMSG2,ast_capi_ApplID,CMSG->Messagenumber,PLCI);
-+                          if (error != 0) {
-+                              ast_log(LOG_ERROR,"error sending INFO_RESP (error=%#x)\n",error);
-+                              return -1;
-+                          } else {
-+                              if (option_verbose > 5) {
-+                                  if (capidebug)
-+                                      ast_verbose(VERBOSE_PREFIX_4 "sent INFO_RESP (PLCI=%#x)\n",PLCI);
-+                              }
-+                          }
-+/*                        if ((INFO_IND_INFONUMBER(CMSG) >> 8) == 0x00) {
-+                              ast_log(LOG_ERROR,"%#x\n",INFO_IND_INFOELEMENT(CMSG)[0]);
-+                              ast_log(LOG_ERROR,"%#x\n",INFO_IND_INFOELEMENT(CMSG)[1]);
-+                              ast_log(LOG_ERROR,"%#x\n",INFO_IND_INFOELEMENT(CMSG)[2]);
-+                              ast_log(LOG_ERROR,"%#x\n",INFO_IND_INFOELEMENT(CMSG)[3]);
-+                          } */
-+#ifndef CAPI_NEVER_EVER_EARLY_B3_CONNECTS
-+                          if ((INFO_IND_INFONUMBER(CMSG) == 0x001e) && (p->i->doB3 != AST_CAPI_B3_DONT) && (p->i->earlyB3 == -1) && (p->i->state != CAPI_STATE_BCONNECTED)){
-+                              // ETSI 300 102-1 Progress Indicator
-+                              // we do early B3 Connect
-+                                if(INFO_IND_INFOELEMENT(CMSG)[0] >= 2) {
-+                                  if(INFO_IND_INFOELEMENT(CMSG)[2] & 0x2) {
-+                                      p->i->calledPartyIsISDN = 0;
-+                                      // ast_log(LOG_NOTICE,"A N A L O G \n");
-+                                  } else {
-+                                      p->i->calledPartyIsISDN = 1;
-+                                      // ast_log(LOG_NOTICE,"I S D N\n");
-+                                  }
-+                                  if(INFO_IND_INFOELEMENT(CMSG)[2] & 0x88) {
-+                                       // in-band info available
-+                                      p->i->earlyB3 = 1;
-+                                      memset(&CMSG2,0,sizeof(_cmsg));
-+                                      CONNECT_B3_REQ_HEADER(&CMSG2, ast_capi_ApplID, ast_capi_MessageNumber++,0);
-+                                      CONNECT_B3_REQ_PLCI(&CMSG2) = PLCI;
-+                                      if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                                          ast_log(LOG_ERROR,"error sending early CONNECT_B3_REQ (error=%#x)\n",error);
-+                                          return -1;
-+                                      } else {
-+                                          if (option_verbose > 1) {
-+                                              if (capidebug)
-+                                                  ast_verbose(VERBOSE_PREFIX_4 "sent early CONNECT_B3_REQ (PLCI=%#x)\n",PLCI);
-+                                          }
-+                                      }
-+                                  }
-+                              }
-+                          }
-+                          // DISCONNECT
-+                          if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (PLCI == p->i->onholdPLCI)) {
-+                              // the caller onhold hung up (or ECTed away)
-+                              // send a disconnect_req , we cannot hangup the channel here!!!
-+                              memset(&CMSG2,0,sizeof(_cmsg));
-+                              DISCONNECT_REQ_HEADER(&CMSG2, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+                              DISCONNECT_REQ_PLCI(&CMSG2) = p->i->onholdPLCI;
-+
-+                              if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                                  ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",PLCI);
-+                              } else {
-+                                  if (option_verbose > 1) {
-+                                      if (capidebug)
-+                                          ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_REQ for onholdPLCI=%#x\n",PLCI);
-+                                  }
-+                              }                               
-+                              return 0;
-+                          }
-+
-+                          // case 1: B3 on success or no B3 at all
-+                          if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (p->i->doB3 != AST_CAPI_B3_ALWAYS) && (p->i->outgoing == 1)) {
-+                              p->i->earlyB3 = 0; // !!!
-+                              fr.frametype = AST_FRAME_NULL;
-+                              fr.datalen = 0;
-+                              return pipe_frame(p,(struct ast_frame *)&fr);
-+                          }
-+                          // case 2: we are doing B3, and receive the 0x8045 after a successful call
-+                          if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (p->i->doB3 != AST_CAPI_B3_DONT) && (p->i->earlyB3 == 0) && (p->i->outgoing == 1)) {
-+                              fr.frametype = AST_FRAME_NULL;
-+                              fr.datalen = 0;
-+                              return pipe_frame(p,(struct ast_frame *)&fr);
-+                          }
-+                          // case 3: this channel is an incoming channel! the user hung up!
-+                          // it is much better to hangup now instead of waiting for a timeout and
-+                          // network caused DISCONNECT_IND!
-+                          if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (p->i->outgoing == 0)) {
-+                          // ast_log(LOG_NOTICE,"case 3\n");
-+                              fr.frametype = AST_FRAME_NULL;
-+                              fr.datalen = 0;
-+                              return pipe_frame(p,(struct ast_frame *)&fr);
-+                          }
-+                          // case 4 (a.k.a. the italian case): B3 always. call is unsuccessful
-+                          if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (p->i->doB3 == AST_CAPI_B3_ALWAYS) && (p->i->earlyB3 == -1) && (p->i->outgoing == 1)) {
-+                              // wait for the 0x001e (PROGRESS), play audio and wait for a timeout from the network
-+                              return 0;
-+                          }
-+#endif
-+                          // Handle DID digits
-+                          if ((INFO_IND_INFONUMBER(CMSG) == 0x0070) && p->i->isdnmode && (p->c != NULL)) {
-+                              int search = -1;
-+                              char name[AST_CHANNEL_NAME] = "";
-+                              char *did;
-+
-+                              did = capi_number((char *)INFO_IND_INFOELEMENT(CMSG),1);
-+                              if (strcasecmp(p->i->dnid, did)) {
-+                                  strncat(p->i->dnid, did, sizeof(p->i->dnid)-1);
-+                              }
-+                              
-+                              snprintf(name,sizeof(name),"CAPI/contr%d/%s/-%d",p->i->controller,p->i->dnid,capi_counter++);
-+                              ast_change_name(p->c, name);
-+                              
-+                              search = search_did(p->c);
-+                              if (search != -1) {
-+                                  if (!search) {
-+                                      ast_setstate(p->c, AST_STATE_RING);
-+                                      // we are alerting (phones ringing)
-+                                      capi_alert(p->c); // Do this here after pbx_start the Channel can be destroyed
-+                                      if (ast_pbx_start(p->c)) {
-+                                          ast_log(LOG_ERROR,"Unable to start pbx on channel!\n");
-+                                          ast_hangup(p->c);
-+                                      } else {
-+                                          if (option_verbose > 2) {
-+                                              if (capidebug)
-+                                                  ast_verbose(VERBOSE_PREFIX_3 "started pbx on channel!\n");
-+                                          }
-+                                      }
-+                                  }
-+                              } else {
-+                                  ast_log(LOG_ERROR,"did not find device for msn = %s\n",p->i->dnid);
-+                                  CONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
-+                                  CONNECT_RESP_PLCI(&CMSG2) = PLCI;
-+                                  CONNECT_RESP_REJECT(&CMSG2) = 1; // ignore
-+                                  if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                                      ast_log(LOG_ERROR,"error sending CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
-+                                  } else {
-+                                      if (option_verbose > 5) {
-+                                          if (capidebug)
-+                                              ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
-+                                      }
-+                                  }
-+                                  
-+                                  return 0;
-+                              }
-+                          }
-+                          if (INFO_IND_INFONUMBER(CMSG) == 0x8001) {
-+                              fr.frametype = AST_FRAME_CONTROL;
-+                              fr.subclass = AST_CONTROL_RINGING;
-+                              return pipe_frame(p,(struct ast_frame *)&fr);
-+                          }
-+                          if (INFO_IND_INFONUMBER(CMSG) == 0x800d) {
-+                              fr.frametype = AST_FRAME_CONTROL;
-+                              fr.subclass = AST_CONTROL_PROGRESS;
-+                              return pipe_frame(p,(struct ast_frame *)&fr);
-+                          }
-+                          if (INFO_IND_INFONUMBER(CMSG) == 0x74) {
-+                              strncpy(p->i->owner->exten,capi_number((char *)INFO_IND_INFOELEMENT(CMSG),3),sizeof(p->i->owner->exten)-1);
-+                              ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(CMSG));
-+                          }
-+                          if (INFO_IND_INFONUMBER(CMSG) == 0x28) {
-+                      //      ast_sendtext(p->i->owner,capi_number(INFO_IND_INFOELEMENT(CMSG),0));
-+                      //      struct ast_frame ft = { AST_FRAME_TEXT, capi_number(INFO_IND_INFOELEMENT(CMSG),0), };
-+                        //            ast_queue_frame(p->i->owner, &ft);
-+                      //      ast_log(LOG_NOTICE,"%s\n",capi_number(INFO_IND_INFOELEMENT(CMSG),0));
-+                          }
-+                          break;
-+                      case CAPI_CONNECT_ACTIVE:
-+//                        ast_log(LOG_NOTICE,"CONNECT_ACTIVE_IND PLCI=%#x\n",(int)CONNECT_ACTIVE_IND_PLCI(CMSG));
-+                          CONNECT_ACTIVE_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber,0);
-+                          CONNECT_ACTIVE_RESP_PLCI(&CMSG2) = PLCI;
-+                          if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                              ast_log(LOG_ERROR,"error sending CONNECT_ACTIVE_RESP (error=%#x)\n",error);
-+                              return -1;
-+                          } else {
-+                              if (option_verbose > 5) {
-+                                  if (capidebug)
-+                                      ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_ACTIVE_RESP (PLCI=%#x)\n",PLCI);
-+                              }
-+                          }
-+                          // normal processing
-+                          if (p->i->earlyB3 != 1) {
-+                              p->i->state = CAPI_STATE_CONNECTED;
-+                          
-+                              // send a CONNECT_B3_REQ
-+                              if (p->i->outgoing == 1) {
-+                                  // outgoing call
-+                                  memset(&CMSG2,0,sizeof(_cmsg));
-+                                  CONNECT_B3_REQ_HEADER(&CMSG2, ast_capi_ApplID, ast_capi_MessageNumber++,0);
-+                                  CONNECT_B3_REQ_PLCI(&CMSG2) = PLCI;
-+                                  if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                                      ast_log(LOG_ERROR,"error sending CONNECT_B3_REQ (error=%#x)\n",error);
-+                                      return -1;
-+                                  } else {
-+                                      if (option_verbose > 1) {
-+                                          if (capidebug)
-+                                              ast_verbose(VERBOSE_PREFIX_3 "sent CONNECT_B3_REQ (PLCI=%#x)\n",PLCI);
-+                                      }
-+                                  }
-+                              } else {
-+                                  // incoming call
-+                                  // RESP already sent ... wait for CONNECT_B3_IND
-+//                                ast_log(LOG_NOTICE,"waiting for CONNECT_B3_IND\n");
-+                              }
-+                          } else {
-+                              // special treatment for early B3 connects
-+                              p->i->state = CAPI_STATE_BCONNECTED;
-+                              if (p->c->_state != AST_STATE_UP) {
-+                                  ast_setstate(p->c,AST_STATE_UP);
-+                              }
-+                              p->i->earlyB3 = 0;      // not early anymore
-+                              fr.frametype = AST_FRAME_CONTROL;
-+                              fr.subclass = AST_CONTROL_ANSWER;
-+                              fr.datalen = 0;
-+                              return pipe_frame(p,(struct ast_frame *)&fr);
-+                              
-+                          }
-+                          break;
-+                      case CAPI_CONNECT_B3:
-+                          // then send a CONNECT_B3_RESP
-+                          memset(&CMSG2,0,sizeof(_cmsg));
-+                          CONNECT_B3_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
-+                          CONNECT_B3_RESP_NCCI(&CMSG2) = CONNECT_B3_IND_NCCI(CMSG);
-+                          p->NCCI = CONNECT_B3_IND_NCCI(CMSG);
-+                          p->i->NCCI = p->NCCI;
-+                          CONNECT_B3_RESP_REJECT(&CMSG2) = 0;
-+
-+                          if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                              ast_log(LOG_ERROR,"error sending CONNECT_B3_RESP (error=%#x)\n",error);
-+                              return -1;
-+                          } else {
-+                              if (option_verbose > 5) {
-+                                  if (capidebug)
-+                                      ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_B3_RESP (NCCI=%#x)\n",p->i->NCCI);
-+                              }
-+                          }
-+              /*          if (p->i->controller > 0) {
-+                              capi_controllers[p->i->controller]->nfreebchannels--;
-+                          } */
-+                          break; 
-+                      case CAPI_CONNECT_B3_ACTIVE:
-+//                        ast_log(LOG_NOTICE,"CONNECT_B3_ACTIVE_IND NCCI=%#x\n",p->i->NCCI);
-+                          // then send a CONNECT_B3__ACTIVERESP
-+
-+                          CONNECT_B3_ACTIVE_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
-+                          CONNECT_B3_ACTIVE_RESP_NCCI(&CMSG2) = p->i->NCCI;
-+
-+                          if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                              ast_log(LOG_ERROR,"error sending CONNECT_B3_ACTIVE_RESP (error=%#x)\n",error);
-+                              return -1;
-+                          } else {
-+                              if (option_verbose > 5) {
-+                                  if (capidebug)
-+                                      ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_B3_ACTIVE_RESP (NCCI=%#x)\n",p->i->NCCI);
-+                              }
-+                          }
-+
-+                          ast_mutex_lock(&contrlock);
-+                          if (p->i->controller > 0) {
-+                              capi_controllers[p->i->controller]->nfreebchannels--;
-+                          }
-+                          ast_mutex_unlock(&contrlock);
-+
-+                          p->i->state = CAPI_STATE_BCONNECTED;
-+                          capi_echo_canceller(p->c,EC_FUNCTION_ENABLE);
-+                          capi_detect_dtmf(p->c,1);
-+
-+                          if (p->i->earlyB3 != 1) {
-+                              ast_setstate(p->c,AST_STATE_UP);
-+                              fr.frametype = AST_FRAME_CONTROL;
-+                              fr.subclass = AST_CONTROL_ANSWER;
-+                              fr.datalen = 0;
-+                              return pipe_frame(p,(struct ast_frame *)&fr);
-+                          }
-+                          return 0;
-+                          break;
-+                  }
-+                  break;
-+
-+              case CAPI_CONF:
-+                  switch (CMSG->Command) {
-+                      case CAPI_FACILITY:
-+                          if (FACILITY_CONF_FACILITYSELECTOR(CMSG) == 0x3) {
-+                              if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[1] == 0x2) && (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[2] == 0x0)) {
-+                                  if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[4] == 0x0) && (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[5] == 0x0)) {
-+                                  } else {
-+                                      p->i->state = CAPI_STATE_BCONNECTED;
-+                                      if (capidebug)
-+                                          ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(CMSG));
-+                                  }
-+                              }
-+                          }
-+                          break;
-+                      case CAPI_DATA_B3:
-+//                        ast_log(LOG_NOTICE,"DATA_B3_CONF (NCCI %#x) for DATAHANDLE %#x\n",DATA_B3_CONF_NCCI(CMSG),DATA_B3_CONF_DATAHANDLE(CMSG));
-+                          break;
-+                      case CAPI_ALERT:
-+//                        ast_log(LOG_NOTICE,"ALERT_CONF (PLCI=%#x)\n",(int)ALERT_CONF_PLCI(CMSG));
-+                          p->i->state = CAPI_STATE_ALERTING;
-+                          if (p->c->_state == AST_STATE_RING) {
-+                              p->c->rings = 1;
-+                          }
-+                          break;
-+                      case CAPI_CONNECT:
-+                          if (option_verbose > 1) {
-+                              if (capidebug)
-+                                  ast_verbose(VERBOSE_PREFIX_2 "received CONNECT_CONF PLCI = %#x INFO = %#x\n",(int)CONNECT_CONF_PLCI(CMSG),CONNECT_CONF_INFO(CMSG));
-+                          }
-+                          if (CONNECT_CONF_INFO(CMSG) == 0) {
-+                              p->i->PLCI = CONNECT_CONF_PLCI(CMSG);
-+                              p->PLCI = p->i->PLCI;
-+                              ast_setstate(p->c,AST_STATE_DIALING);
-+                          } else {
-+      // here, something has to be done -->
-+                              fr.frametype = AST_FRAME_CONTROL;
-+                              fr.subclass = AST_CONTROL_BUSY;
-+                              fr.datalen = 0;
-+                              return pipe_frame(p,(struct ast_frame *)&fr);
-+                          }
-+                          break;
-+                      case CAPI_CONNECT_B3:
-+//                        ast_log(LOG_NOTICE,"received CONNECT_B3_CONF NCCI = %#x INFO = %#x\n",(int)CONNECT_B3_CONF_NCCI(CMSG),CONNECT_B3_CONF_INFO(CMSG));
-+                          if (CONNECT_B3_CONF_INFO(CMSG) == 0) {
-+                              p->i->NCCI = CONNECT_B3_CONF_NCCI(CMSG);
-+                          } else {
-+                              p->i->earlyB3 = -1;
-+                              p->i->doB3 = AST_CAPI_B3_DONT;
-+                          }
-+                          break;
-+                  }
-+                  break;                  
-+          }
-+      }
-+//    ast_log(LOG_NOTICE,"returning\n");
-+      return 0;
-+}
-+
-+static void capi_handle_msg(_cmsg *CMSG) {
-+    struct ast_capi_pvt *i;
-+    char *DNID;
-+    char *CID;
-+    char *msn;
-+    _cmsg CMSG2;
-+    MESSAGE_EXCHANGE_ERROR  error;
-+    int PLCI=0,NCCI;
-+    int NPLAN=0;
-+    int fds[2];
-+    int controller=0;
-+    char buffer[AST_MAX_EXTENSION];
-+    struct capi_pipe *p;
-+    char *magicmsn = "*\0";
-+    char *emptyid = "\0";
-+    char *emptydnid = "s\0";
-+    long flags;
-+#ifdef CAPI_DEFLECT_ON_CIRCUITBUSY
-+    int deflect=0;
-+#endif
-+    
-+    switch (CMSG->Subcommand) {
-+      // indication msgs      
-+      case CAPI_IND:
-+
-+      switch (CMSG->Command) {
-+          case CAPI_CONNECT:  // only connect_ind are global (not channel specific)
-+              if (capidebug)
-+                  ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(CMSG));
-+              DNID = capi_number((char *)CONNECT_IND_CALLEDPARTYNUMBER(CMSG),1);
-+              if ((DNID && *DNID == 0) || !DNID) {
-+                  DNID = emptydnid;
-+              }
-+                NPLAN = (CONNECT_IND_CALLINGPARTYNUMBER(CMSG)[1] & 0x70);
-+              CID = capi_number((char *)CONNECT_IND_CALLINGPARTYNUMBER(CMSG),2);
-+              PLCI = CONNECT_IND_PLCI(CMSG);
-+              controller = PLCI & 0xff;
-+              if (option_verbose > 1) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_2 "CONNECT_IND (PLCI=%#x,DID=%s,CID=%s,CIP=%#x,CONTROLLER=%#x)\n",PLCI,DNID,CID,CONNECT_IND_CIPVALUE(CMSG),controller);
-+              }
-+              if(CONNECT_IND_BCHANNELINFORMATION(CMSG))
-+              if ((CONNECT_IND_BCHANNELINFORMATION(CMSG)[1] == 0x02) && (!capi_controllers[controller]->isdnmode)) {
-+                  // this is a call waiting CONNECT_IND with BChannelinformation[1] == 0x02
-+                  // meaning "no B or D channel for this call", since we can't do anything with call waiting now
-+                  // just reject it with "user busy"
-+                  // however...if we are a p2p BRI then the telco switch will allow us to choose the b channel
-+                  // so it will look like a callwaiting connect_ind to us
-+
-+                    ast_log(LOG_ERROR,"received a call waiting CONNECT_IND\n");
-+#ifndef CAPI_DEFLECT_ON_CIRCUITBUSY
-+                  CONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
-+                    CONNECT_RESP_PLCI(&CMSG2) = CONNECT_IND_PLCI(CMSG);
-+                    CONNECT_RESP_REJECT(&CMSG2) = 3; // user is busy
-+                    if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                       ast_log(LOG_ERROR,"error sending CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
-+                  } else {
-+                       if (option_verbose > 5) {
-+                          if (capidebug)
-+                              ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
-+                     }
-+                  }
-+                    // no need to pipe this
-+                    PLCI = 0;
-+                  break;              
-+#else
-+                  deflect = 1;
-+#endif
-+              }
-+              // well...somebody is calling us. let's set up a channel
-+              ast_mutex_lock(&iflock);
-+              i = iflist;
-+              while(i) {
-+                  //XXX test this!
-+                  // has no owner
-+                  if ((!i->owner) && (i->incomingmsn != NULL)){
-+                      strncpy(buffer,i->incomingmsn,sizeof(buffer)-1);
-+                      msn = strtok(buffer,",");
-+                      while (msn != NULL) {
-+//                    ast_log(LOG_NOTICE,"msn=%s\n",msn);
-+                          if (DNID && ((!strcasecmp(msn,DNID)) ||
-+                               (i->isdnmode && (strlen(msn)<strlen(DNID)) && !strncasecmp(msn, DNID, strlen(msn))) || (!strncasecmp(msn,magicmsn,strlen(msn)))) && 
-+                              (i->controllers & (1 << controller))) {
-+                              if (CID != NULL) {
-+                                  if(NPLAN == CAPI_ETSI_NPLAN_NATIONAL)
-+                                      snprintf(i->cid, (sizeof(i->cid)-1), "%s%s%s", i->prefix, capi_national_prefix, CID);
-+                                  else if(NPLAN == CAPI_ETSI_NPLAN_INTERNAT)
-+                                      snprintf(i->cid, (sizeof(i->cid)-1), "%s%s%s", i->prefix, capi_international_prefix, CID);
-+                                  else
-+                                      snprintf(i->cid, (sizeof(i->cid)-1), "%s%s", i->prefix, CID);
-+                              } else
-+                                  strncpy(i->cid,emptyid,sizeof(i->cid)-1);
-+
-+                              if (DNID != NULL) 
-+                                  strncpy(i->dnid,DNID,sizeof(i->dnid)-1);
-+                              else
-+                                  strncpy(i->dnid,emptydnid,sizeof(i->dnid)-1);
-+                              
-+                              i->controller=controller;
-+                              i->PLCI = PLCI;
-+                              i->MessageNumber = CMSG->Messagenumber;
-+                              if (pipe(fds) == 0) {
-+                                  if (option_verbose > 4) {
-+                                      ast_verbose(VERBOSE_PREFIX_3 "creating pipe for PLCI=%#x msn = %s\n",PLCI,msn);
-+                                  }
-+                                  i->fd = fds[0];
-+                                  flags = fcntl(i->fd,F_GETFL);
-+                                  fcntl(i->fd,F_SETFL,flags | O_SYNC | O_DIRECT);
-+//                                ast_log(LOG_NOTICE,"i->fd = %d\n",i->fd);
-+                                  p = malloc(sizeof(struct capi_pipe));
-+                                  memset(p, 0, sizeof(struct capi_pipe));
-+                                  p->fd = fds[1];
-+                                  flags = fcntl(i->fd,F_GETFL);
-+                                  fcntl(p->fd,F_SETFL,flags | O_SYNC | O_DIRECT);
-+//                                ast_log(LOG_NOTICE,"p->fd = %d\n",p->fd);
-+                                  p->PLCI = PLCI;
-+                                  p->i = i;
-+                                  ast_mutex_init(&(p->lock));
-+                                  i->mypipe = p;
-+                                  if (i->isdnmode) {
-+                                      p->c = capi_new(i,AST_STATE_DOWN);
-+                                      i->state = CAPI_STATE_DID;
-+                                  } else {
-+                                      p->c = capi_new(i,AST_STATE_RING);
-+                                  }
-+                                  p->next = pipelist;
-+                                  pipelist = p;
-+                              // hmmm....
-+                                  ast_mutex_unlock(&iflock);
-+#ifdef CAPI_DEFLECT_ON_CIRCUITBUSY
-+                                  if ((deflect == 1) && (i->deflect2)) {
-+                                      capi_deflect(p->c,i->deflect2);
-+                                  }
-+#endif
-+                                  return;
-+                              } else {
-+                                  ast_log(LOG_ERROR,"creating pipe for PLCI=%#x failed\n",PLCI);
-+                              }
-+                              break;
-+                          } // if strcasecmp
-+                          msn = strtok(NULL,",");
-+                      } // while strtok
-+                  } // if
-+                  i = i->next;
-+              } // while interface list
-+              ast_mutex_unlock(&iflock);              // obviously we are not called...so tell capi to ignore this call
-+              if (capidebug) {
-+                  ast_log(LOG_ERROR,"did not find device for msn = %s\n",DNID);
-+              }
-+              CONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
-+              CONNECT_RESP_PLCI(&CMSG2) = CONNECT_IND_PLCI(CMSG);
-+              CONNECT_RESP_REJECT(&CMSG2) = 1; // ignore
-+              if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
-+                  ast_log(LOG_ERROR,"error sending CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
-+              } else {
-+                  if (option_verbose > 5) {
-+                      if (capidebug)
-+                          ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
-+                  }
-+              }
-+              ast_mutex_lock(&pipelock);
-+              if (pipelist == NULL) {
-+                  capi_last_plci = PLCI;
-+              }
-+              ast_mutex_unlock(&pipelock);
-+              // no need to pipe this
-+              PLCI = 0;
-+//            ast_mutex_unlock(&iflock);
-+//            return;
-+              break;
-+          case CAPI_FACILITY:
-+              PLCI = FACILITY_IND_PLCI(CMSG) & 0xffff;  // this is for you eicon
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"FACILITY_IND PLCI=%#x\n",PLCI);
-+          break;
-+          case CAPI_INFO:
-+              PLCI = INFO_IND_PLCI(CMSG);
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"INFO_IND PLCI=%#x INFO# = %#x\n",PLCI,INFO_IND_INFONUMBER(CMSG));
-+          break;
-+          case CAPI_CONNECT_ACTIVE:
-+              PLCI = CONNECT_ACTIVE_IND_PLCI(CMSG);
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"CONNECT_ACTIVE_IND PLCI=%#x\n",PLCI);
-+          break;
-+          case CAPI_CONNECT_B3:
-+              NCCI = CONNECT_B3_IND_NCCI(CMSG);
-+              PLCI = (NCCI << 16) >> 16;
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"CONNECT_B3_IND NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
-+          break;
-+          case CAPI_CONNECT_B3_ACTIVE:
-+              NCCI = CONNECT_B3_IND_NCCI(CMSG);
-+              PLCI = (NCCI << 16) >> 16;
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"CONNECT_B3_ACTIVE_IND NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
-+          break;
-+          case CAPI_DATA_B3:
-+              NCCI = DATA_B3_IND_NCCI(CMSG);
-+              PLCI = (NCCI << 16) >> 16;
-+//            ast_log(LOG_ERROR,"DATA_B3_IND NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
-+          break;
-+          case CAPI_DISCONNECT_B3:
-+              NCCI = DISCONNECT_B3_IND_NCCI(CMSG);
-+              PLCI = (NCCI << 16) >> 16;
-+              if (option_verbose > 1) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_2 "DISCONNECT_B3_IND NCCI=%#x\n",NCCI);
-+              }
-+          break;
-+          case CAPI_DISCONNECT:
-+              PLCI = DISCONNECT_IND_PLCI(CMSG);
-+              if (option_verbose > 1) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_2 "DISCONNECT_IND PLCI=%#x REASON=%#x\n",PLCI,DISCONNECT_IND_REASON(CMSG));
-+              }
-+          break;
-+          default:
-+              ast_log(LOG_ERROR,"Command.Subcommand = %#x.%#x\n",CMSG->Command,CMSG->Subcommand);
-+      }
-+      break;
-+      // confirmation msgs
-+      case CAPI_CONF:
-+      switch (CMSG->Command) {
-+          case CAPI_FACILITY:
-+              NCCI = FACILITY_CONF_NCCI(CMSG);
-+              PLCI = (NCCI << 16) >> 16;
-+              if (option_verbose > 2) {
-+                      if (FACILITY_CONF_FACILITYSELECTOR(CMSG) == 6) {
-+                              if (FACILITY_CONF_INFO(CMSG)) 
-+                                      ast_verbose (VERBOSE_PREFIX_3 "Error setting up echo canceller (PLCI=%#x, Info=%#04x)\n", PLCI, FACILITY_CONF_INFO(CMSG));
-+                              else
-+                                      ast_verbose (VERBOSE_PREFIX_3 "Echo canceller successfully set up (PLCI=%#x)\n",PLCI);
-+                      }
-+              }
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"FACILITY_CONF NCCI=%#x INFO=%#x\n",(int)FACILITY_CONF_NCCI(CMSG),FACILITY_CONF_INFO(CMSG));
-+          break;
-+          case CAPI_INFO:
-+              PLCI = INFO_CONF_PLCI(CMSG);
-+//            ast_log(LOG_ERROR,"INFO_CONF PLCI=%#x INFO=%#x\n",PLCI,INFO_CONF_INFO(CMSG));
-+          break;
-+          case CAPI_CONNECT:
-+              PLCI = CONNECT_CONF_PLCI(CMSG);
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"CONNECT_CONF PLCI=%#x INFO=%#x MN=%#x\n",PLCI,CONNECT_CONF_INFO(CMSG),CMSG->Messagenumber);
-+          break;
-+          case CAPI_DISCONNECT:
-+              PLCI = DISCONNECT_CONF_PLCI(CMSG);
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"DISCONNECT_CONF PLCI=%#x INFO=%#x MN=%#x\n",PLCI,DISCONNECT_CONF_INFO(CMSG),CMSG->Messagenumber);
-+          break;
-+          case CAPI_DISCONNECT_B3:
-+              NCCI = DISCONNECT_B3_CONF_NCCI(CMSG);
-+              PLCI = (NCCI << 16) >> 16;
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"DISCONNECT_B3_CONF NCCI=%#x INFO=%#x MN=%#x\n",NCCI,DISCONNECT_B3_CONF_INFO(CMSG),CMSG->Messagenumber);
-+          break;
-+          case CAPI_CONNECT_B3:
-+              NCCI = CONNECT_B3_CONF_NCCI(CMSG);
-+              PLCI = (NCCI << 16) >> 16;
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//                ast_log(LOG_ERROR,"CONNECT_B3_CONF PLCI=%#x INFO=%#x MN=%#x\n",PLCI,CONNECT_B3_CONF_INFO(CMSG),CMSG->Messagenumber);
-+          break;
-+          case CAPI_ALERT:
-+              PLCI = ALERT_CONF_PLCI(CMSG);
-+              if (option_verbose > 3) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"ALERT_CONF PLCI=%#x\n",PLCI);
-+          break;          
-+          case CAPI_DATA_B3:
-+              NCCI = DATA_B3_CONF_NCCI(CMSG);
-+              PLCI = (NCCI << 16) >> 16;
-+              if (option_verbose > 5) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
-+              }
-+//            ast_log(LOG_ERROR,"DATA_B3_CONF NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
-+          break;
-+          default:
-+              ast_log(LOG_ERROR,"Command.Subcommand = %#x.%#x\n",CMSG->Command,CMSG->Subcommand);
-+      }
-+      break;
-+    }
-+    if (PLCI > 0) {
-+      pipe_msg(PLCI,CMSG);
-+    }
-+
-+}
-+
-+// module stuff, monitor...
-+
-+static void *do_monitor(void *data) {
-+   unsigned int Info;
-+    _cmsg *monCMSG;
-+    for (;;) {
-+/*
-+      if (ast_mutex_lock(&monlock)) {
-+          ast_log(LOG_ERROR,"Unable to get monitor lock!\n");
-+          return NULL;
-+      }
-+      // do some nifty stuff
-+      ast_mutex_unlock(&monlock);
-+*/
-+      monCMSG = malloc(sizeof(_cmsg));
-+      memset(monCMSG,0,sizeof(_cmsg));
-+      switch(Info = check_wait_get_cmsg(monCMSG)) {
-+          case 0x0000:
-+              if (option_verbose > 8) {
-+                  if (capidebug)
-+                      ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(monCMSG));
-+              }
-+              capi_handle_msg(monCMSG);
-+              break;
-+          case 0x1104:
-+              // CAPI queue is empty
-+              break;
-+          default:
-+              // something is wrong!
-+               break;
-+      } //switch
-+      free(monCMSG);
-+    } // for
-+    // never reached
-+    return NULL;
-+}
-+
-+#ifdef CAPI_GAIN
-+static void capi_gains(struct ast_capi_gains *g,float rxgain,float txgain) {
-+    int i=0;
-+    int x=0;
-+    if (rxgain != 1.0) {
-+      for (i=0;i<256;i++) {
-+          x = (int)(((float)capiXLAW2INT(i)) * rxgain);
-+          if (x > 32767) x = 32767;
-+          if (x < -32767) x = -32767;
-+          g->rxgains[i] = capiINT2XLAW(x);
-+      }
-+    } else {
-+      for (i=0;i<256;i++) {
-+          g->rxgains[i] = i;
-+      }
-+    }
-+    if (txgain != 1.0) {
-+      for (i=0;i<256;i++) {
-+          x = (int)(((float)capiXLAW2INT(i)) * txgain);
-+          if (x > 32767) x = 32767;
-+          if (x < -32767) x = -32767;
-+          g->txgains[i] = capiINT2XLAW(x);
-+      }
-+    } else {
-+      for (i=0;i<256;i++) {
-+          g->txgains[i] = i;
-+      }
-+    }
-+    
-+}
-+#endif
-+#ifdef CAPI_DEFLECT_ON_CIRCUITBUSY
-+int mkif(char *incomingmsn,char *context,char *controllerstr,int devices,int softdtmf,int echocancel,int ecoption,int ectail, char *prefix, int isdnmode, int es,float rxgain,float txgain, char *deflect2, char *accountcode, unsigned int callgroup, unsigned int group) {
-+#else
-+int mkif(char *incomingmsn,char *context,char *controllerstr,int devices,int softdtmf,int echocancel,int ecoption,int ectail, char *prefix, int isdnmode, int es,float rxgain,float txgain, char *accountcode, unsigned int callgroup, unsigned int group) {
-+#endif
-+    struct ast_capi_pvt *tmp;
-+    int i=0;
-+    char buffer[100];
-+    char *contr;
-+    unsigned long contrmap=0;
-+
-+    for (i=0;i<devices;i++) {
-+      tmp = malloc(sizeof(struct ast_capi_pvt));
-+      memset(tmp, 0, sizeof(struct ast_capi_pvt));
-+      if (tmp) {
-+          ast_mutex_init(&(tmp->lock));
-+          strncpy(tmp->context, context, sizeof(tmp->context)-1);
-+          strncpy(tmp->incomingmsn, incomingmsn, sizeof(tmp->incomingmsn)-1);
-+          strncpy(tmp->prefix, prefix, sizeof(tmp->prefix)-1);
-+          strncpy(tmp->accountcode, accountcode, sizeof(tmp->accountcode)-1);
-+          
-+          strncpy(buffer,controllerstr,sizeof(buffer)-1);
-+          contr = strtok(buffer,",");
-+          while (contr != NULL) {
-+              contrmap |= (1 << atoi(contr));
-+              if (capi_controllers[atoi(contr)]) {
-+                  capi_controllers[atoi(contr)]->isdnmode = isdnmode;
-+              //    ast_log(LOG_NOTICE, "contr %d isdnmode %d\n",atoi(contr),isdnmode);
-+              }
-+              contr = strtok(NULL,",");
-+          }
-+          tmp->controllers = contrmap;
-+          capi_used_controllers |= contrmap;
-+          tmp->controller = 0;
-+          tmp->CLIR = 0;
-+          tmp->earlyB3 = -1;
-+          tmp->onholdPLCI = 0;
-+          tmp->doEC = echocancel;
-+          tmp->ecOption = ecoption;
-+          tmp->ecTail = ectail;
-+          tmp->isdnmode = isdnmode;
-+          tmp->doES = es;
-+          tmp->callgroup = callgroup;
-+          tmp->group = group;
-+#ifdef CAPI_ES            
-+#endif
-+#ifdef CAPI_GAIN
-+          tmp->rxgain = rxgain;
-+          tmp->txgain = txgain;
-+          capi_gains(&tmp->g,rxgain,txgain);
-+#endif
-+#ifdef CAPI_DEFLECT_ON_CIRCUITBUSY
-+          strncpy(tmp->deflect2, deflect2, sizeof(tmp->deflect2)-1);
-+#endif
-+#ifndef CAPI_FORCE_SOFTWARE_DTMF
-+          if (softdtmf == 1) {
-+#endif
-+              tmp->doDTMF = 1;
-+#ifndef CAPI_FORCE_SOFTWARE_DTMF
-+          } else {
-+              tmp->doDTMF = 0;
-+          }
-+#endif
-+          tmp->next = iflist; // prepend
-+          iflist = tmp;
-+      //          ast_log(LOG_NOTICE, "ast_capi_pvt(%s,%s,%#x,%d) (%d,%d,%d) (%d)(%f/%f) %d\n",tmp->incomingmsn,tmp->context,(int)tmp->controllers,devices,tmp->doEC,tmp->ecOption,tmp->ecTail,tmp->doES,tmp->rxgain,tmp->txgain,callgroup);
-+          if (option_verbose > 2) {
-+                  ast_verbose(VERBOSE_PREFIX_2 "ast_capi_pvt(%s,%s,%d,%d) (%d,%d,%d)\n",tmp->incomingmsn,tmp->context,tmp->controller,devices,tmp->doEC,tmp->ecOption,tmp->ecTail);
-+          }
-+          
-+      } else {
-+          return -1;
-+      }
-+    }
-+    return 0;
-+}
-+
-+void supported_sservices(struct ast_capi_controller *cp) {
-+    MESSAGE_EXCHANGE_ERROR error;
-+    _cmsg     CMSG,CMSG2;
-+    struct timeval tv;
-+    char fac[20];
-+
-+    FACILITY_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
-+    FACILITY_REQ_CONTROLLER(&CMSG) = cp->controller;
-+    FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 0x0003; // sservices
-+    fac[0] = 3;
-+    fac[1] = 0;
-+    fac[2] = 0;
-+    fac[3] = 0;
-+    FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (unsigned char *)&fac;
-+    if ((error= _capi_put_cmsg(&CMSG)) != 0) {
-+      ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
-+    } else {
-+        if (option_verbose > 5) {
-+          ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_REQ (CONTROLLER=%#x)\n",cp->controller);
-+      }
-+    }
-+
-+    tv.tv_sec = 1;
-+    tv.tv_usec = 0;
-+    for (;;){
-+        error = capi20_waitformessage(ast_capi_ApplID,&tv);
-+        error = capi_get_cmsg(&CMSG2,ast_capi_ApplID); 
-+//        error = check_wait_get_cmsg(&CMSG2);
-+      if (error == 0) {
-+              if (IS_FACILITY_CONF(&CMSG2)) {
-+                  if (option_verbose > 5) {
-+                      ast_verbose(VERBOSE_PREFIX_4 "FACILITY_CONF INFO = %#x\n",FACILITY_CONF_INFO(&CMSG2));
-+                  }
-+                  break;
-+              }
-+      }
-+    } 
-+    // parse supported sservices
-+    if (FACILITY_CONF_FACILITYSELECTOR(&CMSG2) == 0x0003) {
-+      // success
-+      if (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[4] == 0) {
-+          if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 1) == 1) {
-+              cp->holdretrieve = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "HOLD/RETRIEVE\n");
-+          } else {
-+              cp->holdretrieve = 0;   
-+          }
-+          if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 2) >> 1) == 1) {
-+              cp->terminalportability = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "TERMINAL PORTABILITY\n");
-+          } else {
-+              cp->terminalportability = 0;
-+          }
-+          if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 4) >> 2) == 1) {
-+              cp->ECT = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "ECT\n");
-+          } else {
-+              cp->ECT = 0;
-+          }
-+          if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 8) >> 3) == 1) {
-+              cp->threePTY = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "3PTY\n");
-+          } else {
-+              cp->threePTY = 0;
-+          }
-+          if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 16) >> 4) == 1) {
-+              cp->CF = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "CF\n");
-+          } else {
-+              cp->CF = 0;
-+          }
-+          if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 32) >> 5) == 1) {
-+              cp->CD = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "CD\n");
-+          } else {
-+              cp->CD = 0;
-+          }
-+          if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 64) >> 6) == 1) {
-+              cp->MCID = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "MCID\n");
-+          } else {
-+              cp->MCID = 0;
-+          }
-+          if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 128) >> 7) == 1) {
-+              cp->CCBS = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "CCBS\n");
-+          } else {
-+              cp->CCBS = 0;
-+          }
-+          if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[7] & 1) == 1) {
-+              cp->MWI = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "MWI\n");
-+          } else {
-+              cp->MWI = 0;
-+          }
-+          if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[7] & 2) >> 1) == 1) {
-+              cp->CCNR = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "CCNR\n");
-+          } else {
-+              cp->CCNR = 0;
-+          }
-+          if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[7] & 4) >> 2) == 1) {
-+              cp->CONF = 1;
-+              if (option_verbose > 3)
-+                  ast_verbose(VERBOSE_PREFIX_4 "CONF\n");
-+          } else {
-+              cp->CONF = 0;
-+          }
-+      } else {
-+          ast_log(LOG_NOTICE,"supplementary services info  = %#x\n",(short)FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[1]);
-+      }
-+    } else  {
-+      ast_log(LOG_NOTICE,"unexpected FACILITY_SELECTOR = %#x\n",FACILITY_CONF_FACILITYSELECTOR(&CMSG2));
-+    }
-+}
-+
-+static int capi_info(int fd, int argc, char *argv[])
-+{
-+      int i=0;
-+      if (argc != 2)
-+              return RESULT_SHOWUSAGE;
-+      for (i=1;i<=capi_num_controllers;i++) {
-+          ast_mutex_lock(&contrlock);
-+          if (capi_controllers[i] != NULL) {
-+              ast_cli(fd,"Contr%d: %d B channels total, %d B channels free.\n",i,capi_controllers[i]->nbchannels,capi_controllers[i]->nfreebchannels);
-+          }
-+          ast_mutex_unlock(&contrlock);
-+      }
-+      return RESULT_SUCCESS;
-+}
-+
-+static int capi_do_debug(int fd, int argc, char *argv[])
-+{
-+      if (argc != 2)
-+              return RESULT_SHOWUSAGE;
-+      capidebug = 1;
-+      ast_cli(fd, "CAPI Debugging Enabled\n");
-+      return RESULT_SUCCESS;
-+}
-+
-+static int capi_no_debug(int fd, int argc, char *argv[])
-+{
-+      if (argc != 3)
-+              return RESULT_SHOWUSAGE;
-+      capidebug = 0;
-+      ast_cli(fd, "CAPI Debugging Disabled\n");
-+      return RESULT_SUCCESS;
-+}
-+
-+static char info_usage[] = 
-+"Usage: capi info\n"
-+"       Show info about B channels.\n";
-+
-+static char debug_usage[] = 
-+"Usage: capi debug\n"
-+"       Enables dumping of CAPI packets for debugging purposes\n";
-+
-+static char no_debug_usage[] = 
-+"Usage: capi no debug\n"
-+"       Disables dumping of CAPI packets for debugging purposes\n";
-+
-+static struct ast_cli_entry  cli_info =
-+      { { "capi", "info", NULL }, capi_info, "Show CAPI info", info_usage };
-+static struct ast_cli_entry  cli_debug =
-+      { { "capi", "debug", NULL }, capi_do_debug, "Enable CAPI debugging", debug_usage };
-+static struct ast_cli_entry  cli_no_debug =
-+      { { "capi", "no", "debug", NULL }, capi_no_debug, "Disable CAPI debugging", no_debug_usage };
-+
-+static const struct ast_channel_tech capi_tech = {
-+      .type = type,
-+      .description = tdesc,
-+#ifdef CAPI_ULAW
-+      .capabilities = AST_FORMAT_ULAW,
-+#else
-+      .capabilities = AST_FORMAT_ALAW,
-+#endif
-+      .requester = capi_request,
-+      .send_digit = capi_send_digit,
-+      .send_text = NULL,
-+      .call = capi_call,
-+      .hangup = capi_hangup,
-+      .answer = capi_answer,
-+      .read = capi_read,
-+      .write = capi_write,
-+      .bridge = NULL,
-+      .exception = NULL,
-+      .indicate = capi_indicate,
-+      .fixup = capi_fixup,
-+      .setoption = NULL,
-+};
-+
-+int load_module(void)
-+{
-+      struct ast_config *cfg;
-+      struct ast_variable *v;
-+      char *config = "capi.conf";
-+      char incomingmsn[AST_MAX_EXTENSION]="";
-+      char context[AST_MAX_EXTENSION]="";
-+      char prefix[AST_MAX_EXTENSION]="";
-+      char accountcode[20]="";
-+      char *empty = "\0";
-+      char deflect2[AST_MAX_EXTENSION]="";
-+      char controllerstr[AST_MAX_EXTENSION]="";
-+      int res = 0;
-+      int controller=0;
-+      int softdtmf=0;
-+      int echocancel=1;
-+      int ecoption=EC_OPTION_DISABLE_G165;
-+      int ectail=EC_DEFAULT_TAIL;
-+      int es=0;
-+      float rxgain = 1.0;
-+      float txgain = 1.0;
-+      int isdnmode = 0;
-+      unsigned int callgroup=0;
-+      unsigned int group=0;
-+      struct ast_capi_controller *cp;
-+
-+      cfg = ast_config_load(config);
-+
-+      /* We *must* have a config file otherwise stop immediately, well no... */
-+      if (!cfg) {
-+              ast_log(LOG_ERROR, "Unable to load config %s, CAPI disabled\n", config);
-+              return 0;
-+      }
-+      if (ast_mutex_lock(&iflock)) {
-+              ast_log(LOG_ERROR, "Unable to lock interface list???\n");
-+              return -1;
-+      }
-+
-+      strncpy(capi_national_prefix, AST_CAPI_NATIONAL_PREF, sizeof(capi_national_prefix)-1);
-+      strncpy(capi_international_prefix, AST_CAPI_NATIONAL_PREF, sizeof(capi_national_prefix)-1);
-+      v = ast_variable_browse(cfg, "general");
-+      while(v) {
-+              if (!strcasecmp(v->name, "nationalprefix")) {
-+                  strncpy(capi_national_prefix, v->value, sizeof(capi_national_prefix)-1);
-+              } else if (!strcasecmp(v->name, "internationalprefix")) {
-+                      strncpy(capi_international_prefix, v->value, sizeof(capi_international_prefix)-1);
-+              } else if (!strcasecmp(v->name, "rxgain")) {
-+                      if (sscanf(v->value,"%f",&rxgain) != 1) {
-+                          ast_log(LOG_ERROR,"invalid rxgain\n");
-+                      }
-+              } else if (!strcasecmp(v->name, "txgain")) {
-+                      if (sscanf(v->value,"%f",&txgain) != 1) {
-+                          ast_log(LOG_ERROR,"invalid txgain\n");
-+                      }
-+              }
-+              v = v->next;
-+      }
-+
-+
-+
-+      
-+      if (capi20_isinstalled() != 0) {
-+          ast_log(LOG_WARNING,"CAPI not installed, CAPI disabled!\n");
-+          return 0;
-+      }
-+
-+      if (capi20_register(AST_CAPI_BCHANS,AST_CAPI_MAX_B3_BLOCKS,AST_CAPI_MAX_B3_BLOCK_SIZE,&ast_capi_ApplID) != 0) {
-+          ast_log(LOG_NOTICE,"unable to register application at CAPI!\n");
-+          return -1;
-+      }
-+
-+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
-+      if (capi20_get_profile(0,&profile) != 0) {
-+#else
-+      if (capi20_get_profile(0,(unsigned char *)&profile) != 0) {
-+#endif
-+          ast_log(LOG_NOTICE,"unable to get CAPI profile!\n");
-+          return -1;
-+      } else {
-+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
-+          capi_num_controllers = profile.wCtlr;
-+#else
-+          capi_num_controllers = profile.ncontrollers;
-+#endif
-+          if (option_verbose > 3)
-+          ast_verbose(VERBOSE_PREFIX_3 "This box has %d capi controller(s).\n",capi_num_controllers);
-+          for (controller=1;controller<=capi_num_controllers;controller++) {
-+
-+              memset(&profile,0,sizeof(profile));
-+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
-+              capi20_get_profile(controller,&profile);
-+#else
-+              capi20_get_profile(controller,(unsigned char *)&profile);
-+#endif
-+              cp = malloc(sizeof(struct ast_capi_controller));
-+              cp->controller = controller;
-+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
-+              cp->nbchannels = profile.wNumBChannels;
-+              cp->nfreebchannels = profile.wNumBChannels;
-+              if (profile.dwGlobalOptions & CAPI_PROFILE_DTMF_SUPPORT) {
-+#else
-+              cp->nbchannels = profile.nbchannels;
-+              cp->nfreebchannels = profile.nbchannels;
-+              if ((profile.globaloptions & 8) >> 3 == 1) {
-+#endif
-+                  if (option_verbose > 3)
-+                      ast_verbose(VERBOSE_PREFIX_3 "CAPI/contr%d supports DTMF\n",controller);
-+                  cp->dtmf = 1;
-+              } else {
-+                  cp->dtmf = 0;           
-+              }
-+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
-+              if (profile.dwGlobalOptions & CAPI_PROFILE_ECHO_CANCELLATION) {
-+#else
-+              if (profile.globaloptions2 & 1) {
-+#endif
-+                  if (option_verbose > 3)
-+                      ast_verbose(VERBOSE_PREFIX_3 "CAPI/contr%d supports echo cancellation\n",controller);
-+                  cp->echocancel = 1;
-+              } else {
-+                  cp->echocancel = 0;
-+              }
-+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
-+              if (profile.dwGlobalOptions & CAPI_PROFILE_SUPPLEMENTARY_SERVICES)  {
-+#else
-+              if ((profile.globaloptions & 16) >> 4 == 1) {
-+#endif
-+                  cp->sservices = 1;
-+              } else {
-+                  cp->sservices = 0;      
-+              }
-+              capi_controllers[controller] = cp;
-+              if (cp->sservices == 1) {
-+                  if (option_verbose > 3)
-+                      ast_verbose(VERBOSE_PREFIX_3 "CAPI/contr%d supports supplementary services\n",controller);
-+                  supported_sservices(cp);
-+              }
-+          }
-+      }
-+
-+      v = ast_variable_browse(cfg, "interfaces");
-+      while(v) {
-+              /* Create the interface list */
-+              if (!strcasecmp(v->name, "devices")) {
-+#ifdef CAPI_DEFLECT_ON_CIRCUITBUSY
-+                      if (mkif(incomingmsn,context,controllerstr,atoi(v->value),softdtmf,echocancel,ecoption,ectail, prefix, isdnmode, es,rxgain,txgain,deflect2,accountcode,callgroup, group)) {
-+#else
-+                      if (mkif(incomingmsn,context,controllerstr,atoi(v->value),softdtmf,echocancel,ecoption,ectail, prefix, isdnmode, es,rxgain,txgain,accountcode,callgroup, group)) {
-+#endif
-+                          ast_log(LOG_ERROR,"Error creating interface list\n");
-+                          return -1;
-+                      }
-+                      es=0; 
-+                      strncpy(deflect2, empty, sizeof(deflect2)-1);
-+              } else if (!strcasecmp(v->name, "context")) {
-+                      strncpy(context, v->value, sizeof(context)-1);
-+              } else if (!strcasecmp(v->name, "incomingmsn")) {
-+                      strncpy(incomingmsn, v->value, sizeof(incomingmsn)-1);
-+              } else if (!strcasecmp(v->name, "controller")) {
-+                      strncpy(controllerstr, v->value, sizeof(controllerstr)-1);
-+              } else if (!strcasecmp(v->name, "softdtmf")) {
-+                      softdtmf = atoi(v->value);
-+              } else if (!strcasecmp(v->name, "echosquelch")) {
-+                      es = atoi(v->value);
-+              } else if (!strcasecmp(v->name, "callgroup")) {
-+                      callgroup = ast_get_group(v->value);
-+              } else if (!strcasecmp(v->name, "group")) {
-+                      group = ast_get_group(v->value);
-+              } else if (!strcasecmp(v->name, "deflect")) {
-+                      strncpy(deflect2, v->value, sizeof(deflect2)-1);
-+              } else if (!strcasecmp(v->name, "rxgain")) {
-+                      if (sscanf(v->value,"%f",&rxgain) != 1) {
-+                          ast_log(LOG_ERROR,"invalid rxgain\n");
-+                      }
-+              } else if (!strcasecmp(v->name, "txgain")) {
-+                      if (sscanf(v->value,"%f",&txgain) != 1) {
-+                          ast_log(LOG_ERROR,"invalid txgain\n");
-+                      }
-+              } else if (!strcasecmp(v->name, "echocancel")) {
-+                      if (!strcasecmp(v->value, "yes") || !strcasecmp(v->value, "1") || !strcasecmp(v->value, "on")) {
-+                              echocancel=1;
-+                              ecoption=EC_OPTION_DISABLE_G165;
-+                      }       
-+                      else if (!strcasecmp(v->value, "no") || !strcasecmp(v->value, "0") || !strcasecmp(v->value, "off")) {
-+                              echocancel=0;
-+                              ecoption=0;
-+                      }       
-+                      else if (!strcasecmp(v->value, "g165") || !strcasecmp(v->value, "g.165")) {
-+                              echocancel=1;
-+                              ecoption=EC_OPTION_DISABLE_G165;
-+                      }       
-+                      else if (!strcasecmp(v->value, "g164") || !strcasecmp(v->value, "g.164")) {
-+                              echocancel=1;
-+                              ecoption=EC_OPTION_DISABLE_G164_OR_G165;
-+                      }       
-+                      else if (!strcasecmp(v->value, "force")) {
-+                              echocancel=1;
-+                              ecoption=EC_OPTION_DISABLE_NEVER;
-+                      }
-+                      else {
-+                              ast_log(LOG_ERROR,"Unknown echocancel parameter \"%s\" -- ignoring\n",v->value);
-+                      }
-+              } else if (!strcasecmp(v->name, "echotail")) {
-+                      ectail = atoi(v->value);
-+                      if (ectail > 255)
-+                              ectail = 255;
-+              } else if (!strcasecmp(v->name, "prefix")) {
-+                      strncpy(prefix, v->value, sizeof(prefix)-1);
-+              } else if (!strcasecmp(v->name, "accountcode")) {
-+                      strncpy(accountcode, v->value, sizeof(accountcode)-1);
-+              } else if (!strcasecmp(v->name, "isdnmode")) {
-+                      if (!strcasecmp(v->value, "ptp") || !strcasecmp(v->value, "1"))
-+                          isdnmode = 1;
-+                      else if (!strcasecmp(v->value, "ptm") || !strcasecmp(v->value, "0") || !strcasecmp(v->value, "ptmp"))
-+                          isdnmode = 0;
-+                      else
-+                          ast_log(LOG_ERROR,"Unknown isdnmode parameter \"%s\" -- ignoring\n",v->value);
-+
-+              }
-+
-+              v = v->next;
-+      }
-+      ast_config_destroy(cfg);
-+
-+          for (controller=1;controller<=capi_num_controllers;controller++) {
-+              if (capi_used_controllers & (1 << controller)) {
-+                  if (ListenOnController(ALL_SERVICES,controller) != 0) {
-+                      ast_log(LOG_ERROR,"Unable to listen on contr%d\n",controller);
-+                  } else {
-+                      if (option_verbose > 2) 
-+                          ast_verbose(VERBOSE_PREFIX_3 "listening on contr%d CIPmask = %#x\n",controller,ALL_SERVICES);
-+                  }
-+              } else {
-+                  ast_log(LOG_WARNING,"Unused contr%d\n",controller);
-+              }
-+          }
-+
-+
-+      ast_mutex_unlock(&iflock);
-+
-+      if (ast_channel_register(&capi_tech)) {
-+              ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
-+              unload_module();
-+              return -1;
-+      }
-+
-+      ast_cli_register(&cli_info);
-+      ast_cli_register(&cli_debug);
-+      ast_cli_register(&cli_no_debug);
-+
-+      if (ast_mutex_lock(&monlock)) {
-+          ast_log(LOG_WARNING,"Unable to get monitor lock!\n");
-+          return -1;
-+      }
-+        if (monitor_thread == pthread_self()) {
-+          ast_mutex_unlock(&monlock);
-+          ast_log(LOG_WARNING,"Unable to kill myself!\n");
-+          return -1;
-+      }
-+    
-+      if (ast_pthread_create(&monitor_thread,NULL,do_monitor,NULL) < 0) {
-+          ast_mutex_unlock(&monlock);
-+          ast_log(LOG_ERROR,"Unable to start monitor thread!\n");
-+          return -1;
-+      }
-+
-+      return res;
-+}
-+
-+
-+int unload_module()
-+{
-+      if (capi20_release(ast_capi_ApplID) != 0)
-+              ast_log(LOG_WARNING,"Unable to unregister from CAPI!\n");
-+      ast_channel_unregister(&capi_tech);
-+      return 0;
-+}
-+
-+int usecount()
-+{
-+      int res;
-+      ast_mutex_lock(&usecnt_lock);
-+      res = usecnt;
-+      ast_mutex_unlock(&usecnt_lock);
-+      return res;
-+}
-+
-+char *description()
-+{
-+      return desc;
-+}
-+
-+
-+char *key()
-+{
-+      return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/channels/chan_features.c asterisk-1.2.10/channels/chan_features.c
---- asterisk-1.2.10.orig/channels/chan_features.c      2006-07-03 06:19:09.000000000 +0200
-+++ asterisk-1.2.10/channels/chan_features.c   2006-07-31 14:13:08.000000000 +0200
-@@ -427,7 +427,7 @@
-       }
-       ast_mutex_unlock(&featurelock);
-       if (!tmp) {
--              chan = ast_request(tech, format, dest, &status);
-+              chan = ast_request(tech, format, dest, &status, NULL);
-               if (!chan) {
-                       ast_log(LOG_NOTICE, "Unable to allocate subchannel '%s/%s'\n", tech, dest);
-                       return NULL;
-diff -urN asterisk-1.2.10.orig/channels/chan_iax2.c asterisk-1.2.10/channels/chan_iax2.c
---- asterisk-1.2.10.orig/channels/chan_iax2.c  2006-07-12 17:23:59.000000000 +0200
-+++ asterisk-1.2.10/channels/chan_iax2.c       2006-07-31 14:13:08.000000000 +0200
-@@ -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.
-@@ -3089,7 +3092,7 @@
-       memset(&ied, 0, sizeof(ied));
-       ast_mutex_lock(&iaxsl[callno]);
-       if (callno && iaxs[callno]) {
--              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);
-@@ -3141,7 +3144,8 @@
- static struct ast_frame *iax2_read(struct ast_channel *c) 
- {
-       static struct ast_frame f = { AST_FRAME_NULL, };
--      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 &f;
- }
-diff -urN asterisk-1.2.10.orig/channels/chan_sip.c asterisk-1.2.10/channels/chan_sip.c
---- asterisk-1.2.10.orig/channels/chan_sip.c   2006-07-13 18:44:23.000000000 +0200
-+++ asterisk-1.2.10/channels/chan_sip.c        2006-07-31 14:53:09.000000000 +0200
-@@ -603,6 +603,7 @@
-       unsigned int flags;                     /*!< SIP_ flags */      
-       int timer_t1;                           /*!< SIP timer T1, ms rtt */
-       unsigned int sipoptions;                /*!< Supported SIP sipoptions on the other end */
-+      int dialog_established;                 /*!< SIP dialog established */
-       int capability;                         /*!< Special capability (codec) */
-       int jointcapability;                    /*!< Supported capability at both ends (codecs ) */
-       int peercapability;                     /*!< Supported peer capability */
-@@ -626,6 +627,7 @@
-       char refer_to[AST_MAX_EXTENSION];       /*!< Place to store REFER-TO extension */
-       char referred_by[AST_MAX_EXTENSION];    /*!< Place to store REFERRED-BY extension */
-       char refer_contact[SIP_LEN_CONTACT];    /*!< Place to store Contact info from a REFER extension */
-+      char refer_replaces[AST_MAX_EXTENSION]; /*!< Place to store Replaces header of REFER-TO header */
-       struct sip_pvt *refer_call;             /*!< Call we are referring */
-       struct sip_route *route;                /*!< Head of linked list of routing steps (fm Record-Route) */
-       int route_persistant;                   /*!< Is this the "real" route? */
-@@ -645,6 +647,7 @@
-       char peername[256];                     /*!< [peer] name, not set if [user] */
-       char authname[256];                     /*!< Who we use for authentication */
-       char uri[256];                          /*!< Original requested URI */
-+      char origuri[SIP_LEN_CONTACT];                  /*!< REAL! Original requested URI */
-       char okcontacturi[SIP_LEN_CONTACT];     /*!< URI from the 200 OK on INVITE */
-       char peersecret[256];                   /*!< Password */
-       char peermd5secret[256];
-@@ -768,6 +771,9 @@
-       int callingpres;                /*!< Calling id presentation */
-       int inUse;                      /*!< Number of calls in use */
-       int call_limit;                 /*!< Limit of concurrent calls */
-+      int max_regs;                   /*!< Limit of concurrent registrations */
-+      int subpeer;                    /*!< Peer entry used for multiple registrations */
-+      char reg_callid[80];            /*!< Call-ID used for registration */
-       char vmexten[AST_MAX_EXTENSION]; /*!< Dialplan extension for MWI notify message*/
-       char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox setting for MWI checks */
-       char language[MAX_LANGUAGE];    /*!<  Default language for prompts */
-@@ -928,7 +934,7 @@
- static int determine_firstline_parts(struct sip_request *req);
- static void sip_dump_history(struct sip_pvt *dialog); /* Dump history to LOG_DEBUG at end of dialog, before destroying data */
- static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype);
--static int transmit_state_notify(struct sip_pvt *p, int state, int full, int substate);
-+static int transmit_state_notify(struct sip_pvt *p, int state, int full, int substate, char *cid_num, char *cid_name);
- static char *gettag(struct sip_request *req, char *header, char *tagbuf, int tagbufsize);
- /*! \brief Definition of this channel for PBX channel registration */
-@@ -1311,7 +1317,7 @@
-       /* If this is a subscription, tell the phone that we got a timeout */
-       if (p->subscribed) {
-               p->subscribed = TIMEOUT;
--              transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, 1);      /* Send first notification */
-+              transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, 1, NULL, NULL);  /* Send first notification */
-               p->subscribed = NONE;
-               append_history(p, "Subscribestatus", "timeout");
-               return 10000;   /* Reschedule this destruction so that we know that it's gone */
-@@ -3144,16 +3150,30 @@
- /*! \brief  find_call: Connect incoming SIP message to current dialog or create new dialog structure */
- /*               Called by handle_request, sipsock_read */
--static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
-+static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method, const int replaces_callid)
- {
-       struct sip_pvt *p;
-       char *callid;
-       char *tag = "";
-+      char *replaces;
-       char totag[128];
-       char fromtag[128];
-+      char *c;
-       callid = get_header(req, "Call-ID");
-+      if (replaces_callid) {
-+          replaces = get_header(req, "Replaces");
-+          c = strchr(replaces, ';');
-+          if (c)
-+              *c = '\0';
-+          if (!ast_strlen_zero(replaces)) {
-+              callid = replaces;
-+          } else {
-+              return NULL;
-+          }
-+      }
-+
-       if (pedanticsipchecking) {
-               /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
-                  we need more to identify a branch - so we have to check branch, from
-@@ -4135,6 +4155,7 @@
-       if (sipmethod == SIP_CANCEL) {
-               c = p->initreq.rlPart2; /* Use original URI */
-       } else if (sipmethod == SIP_ACK) {
-+// XXX+       } else if (!strcasecmp(msg, "ACK") && !p->dialog_established) {
-               /* Use URI from Contact: in 200 OK (if INVITE) 
-               (we only have the contacturi on INVITEs) */
-               if (!ast_strlen_zero(p->okcontacturi))
-@@ -4901,13 +4922,15 @@
-               ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
-       ast_copy_string(p->uri, invite_buf, sizeof(p->uri));
-+      ast_copy_string(p->origuri, invite, sizeof(p->origuri));
-       if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
-               /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
-               snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
-       } else if (p->options && p->options->vxml_url) {
-               /* If there is a VXML URL append it to the SIP URL */
--              snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
-+//            snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
-+              snprintf(to, sizeof(to), "<%s;%s>", p->uri, p->options->vxml_url);
-       } else {
-               snprintf(to, sizeof(to), "<%s>", p->uri);
-       }
-@@ -4964,6 +4987,11 @@
-               if (!ast_strlen_zero(p->referred_by))
-                       add_header(&req, "Referred-By", p->referred_by);
-       }
-+      if (sipmethod == SIP_INVITE) {
-+          if (!ast_strlen_zero(p->refer_replaces)) {
-+              add_header(&req, "Replaces", p->refer_replaces);
-+          }
-+      }
- #ifdef OSP_SUPPORT
-       if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) {
-               ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken);
-@@ -5038,8 +5066,7 @@
- }
- /*! \brief  transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----*/
--static int transmit_state_notify(struct sip_pvt *p, int state, int full, int substate)
--{
-+static int transmit_state_notify(struct sip_pvt *p, int state, int full, int substate, char *cid_num, char *cid_name) {
-       char tmp[4000], from[256], to[256];
-       char *t = tmp, *c, *a, *mfrom, *mto;
-       size_t maxbytes = sizeof(tmp);
-@@ -5183,10 +5210,19 @@
-       case DIALOG_INFO_XML: /* SNOM subscribes in this format */
-               ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
-               ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
--              if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
--                      ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
--              else
-+              if ((state & AST_EXTENSION_RINGING) && global_notifyringing) {
-+                  ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
-+                  if (cid_num) {
-+                      ast_build_string(&t, &maxbytes, "<local><identity display=\"%s\">%s</identity><target uri=\"%s\"/></local>\n", p->exten, p->exten, mfrom);
-+                      if (cid_name && !ast_strlen_zero(cid_name)) {
-+                           ast_build_string(&t, &maxbytes, "<remote><identity display=\"%s\">sip:%s@%s</identity><target uri=\"sip:%s%s@%s\"/></remote>\n", cid_name, cid_num, p->fromdomain, ast_pickup_ext(), p->exten, p->fromdomain);
-+                      } else {
-+                           ast_build_string(&t, &maxbytes, "<remote><identity display=\"%s\">sip:%s@%s</identity><target uri=\"sip:%s%s@%s\"/></remote>\n", cid_num, cid_num, p->fromdomain, ast_pickup_ext(), p->exten, p->fromdomain);
-+                      }
-+                  }
-+              } else {
-                       ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
-+              }
-               ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
-               ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
-               break;
-@@ -6013,8 +6049,10 @@
-               p->expire = -1;
-       pvt->expiry = expiry;
-       snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username, p->fullcontact);
--      if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 
-+      if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) {
-+      //      ast_log(LOG_NOTICE, "updating SIP/Registry for peer %s with data %s\n", p->name, data);
-               ast_db_put("SIP/Registry", p->name, data);
-+      }
-       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name);
-       if (inaddrcmp(&p->addr, &oldsin)) {
-               sip_poke_peer(p);
-@@ -6405,7 +6443,7 @@
- /*! \brief  cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---*/
- /*    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;
-@@ -6424,7 +6462,7 @@
-               p->laststate = state;
-               break;
-       }
--      transmit_state_notify(p, state, 1, 1);
-+      transmit_state_notify(p, state, 1, 1, cid_num, cid_name);
-       if (option_debug > 1)
-               ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
-@@ -6450,7 +6488,13 @@
-       char *name, *c;
-       char *t;
-       char *domain;
--
-+      char *callid;
-+      struct sip_peer *clone;
-+      char clone_name[256];
-+      int found = 0;
-+      struct sip_peer *recycle_peer = NULL;
-+      char peer_name[256];
-+      
-       /* Terminate URI */
-       t = uri;
-       while(*t && (*t > 32) && (*t != ';'))
-@@ -6499,9 +6543,68 @@
-               if (!ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) {
-                       ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
-               } else {
-+                      callid = get_header(req, "Call-ID");
-+                      ast_copy_string(peer_name, peer->name, sizeof(peer_name));
-+                      if (peer->max_regs > 1) {
-+                          int i = 0;
-+                          /* check if peer matches callid */
-+                          if ((peer->expire > -1) && (!strncmp(peer->reg_callid, callid, strlen(callid)))) {
-+                      //      ast_log(LOG_NOTICE, "peer->reg_callid %s, req->callid %s found in peer\n", peer->reg_callid, callid);
-+                              found++;
-+                          } else {
-+                              /* otherwise check subpeers for callid */
-+                              for (i=0; i<peer->max_regs - 1; i++) {
-+                                  snprintf(clone_name, sizeof(clone_name), "%s@%d", peer->name, i);
-+                              //    ast_log(LOG_NOTICE, "checking subpeer %s\n", clone_name);
-+                                  clone = find_peer(clone_name, NULL, 1);
-+                                  if (clone && (clone->expire > -1)) {
-+                                      if (!strncmp(clone->reg_callid, callid, strlen(callid))) {
-+                                      //    ast_log(LOG_NOTICE, "clone->reg_callid %s, req->callid %s found in subpeer\n", clone->reg_callid, callid);
-+                                          found++;
-+                                          peer = clone;
-+                                          break;
-+                                      }
-+                                  }
-+                              }
-+                          }
-+                          if (!found) {
-+                      //      ast_log(LOG_NOTICE, "did not find callid in peer or subpeer\n");
-+                              /* choose the next best peer or subpeer (that means: find the peer with the smalles expiry time */
-+                              if (peer->expire == -1) {
-+                                  recycle_peer = peer;
-+                      //          ast_log(LOG_NOTICE, "peer %s expiry %d\n", peer->name, peer->expire);
-+                              } else {
-+                                  for (i=0; i<peer->max_regs - 1; i++) {
-+                                      snprintf(clone_name, sizeof(clone_name), "%s@%d", peer->name, i);
-+                                      clone = find_peer(clone_name, NULL, 1);
-+                                      if (clone) {
-+                                          if (clone->expire == -1) {
-+                                              recycle_peer = clone;
-+                                              break;
-+                                          }
-+                      //              ast_log(LOG_NOTICE, "clone %s expiry %d\n", clone->name, clone->expire);
-+                                      }
-+                                  }   
-+                              }
-+                              if (recycle_peer) {
-+                                  peer = recycle_peer;
-+                                  ast_copy_string(peer_name, peer->name, sizeof(peer_name));
-+                              //    ast_log(LOG_NOTICE, "recycling peer %s\n", peer->name);
-+                                  if (peer->subpeer) {
-+                                      i = strchr(peer_name, '@') - peer_name;
-+                                      if (i < sizeof(peer_name))
-+                                          peer_name[i] = '\0';
-+                              //      ast_log(LOG_NOTICE, "i = %d\n", i);
-+                                  }
-+                              } else {
-+                                  /* deny registration */
-+                                  peer_name[0] = '\0';
-+                              }
-+                          }
-+                      }
-                       ast_copy_flags(p, peer, SIP_NAT);
-                       transmit_response(p, "100 Trying", req);
--                      if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) {
-+                      if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer_name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) {
-                               sip_cancel_destroy(p);
-                               switch (parse_register_contact(p, peer, req)) {
-                               case PARSE_REGISTER_FAILED:
-@@ -6521,6 +6624,7 @@
-                                       transmit_response_with_date(p, "200 OK", req);
-                                       peer->lastmsgssent = -1;
-                                       res = 0;
-+                                      ast_copy_string(peer->reg_callid, callid, sizeof(peer->reg_callid));
-                                       break;
-                               }
-                       } 
-@@ -6866,6 +6970,11 @@
-                       /* XXX The refer_to could contain a call on an entirely different machine, requiring an 
-                         INVITE with a replaces header -anthm XXX */
-                       /* The only way to find out is to use the dialplan - oej */
-+                      ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to));
-+                      ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by));
-+                      ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact));
-+                      ast_copy_string(sip_pvt->refer_replaces, replace_callid, sizeof(sip_pvt->referred_by));
-+                      return 2;
-               }
-       } else if (ast_exists_extension(NULL, transfercontext, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) {
-               /* This is an unsupervised transfer (blind transfer) */
-@@ -7586,6 +7695,8 @@
-       int peers_offline = 0;
-       char *id;
-       char idtext[256] = "";
-+      char *tmp;
-+      int i = 0;
-       if (s) {        /* Manager - get ActionID */
-               id = astman_get_header(m,"ActionID");
-@@ -7628,6 +7739,7 @@
-               else
-                       ast_copy_string(name, iterator->name, sizeof(name));
-+      if ((iterator->expire != -1) || (iterator->subpeer != 1)) {
-               pstatus = peer_status(iterator, status, sizeof(status));
-               if (pstatus)    
-                       peers_online++;
-@@ -7644,14 +7756,24 @@
-                       }
-               }                       
-               
--              snprintf(srch, sizeof(srch), FORMAT, name,
-+      }       
-+              /* multiple registration, peer used ? */
-+              if ((iterator->expire != -1) || (iterator->subpeer != 1)) {
-+                  snprintf(srch, sizeof(srch), FORMAT, name,
-                       iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
-                       ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : "   ",       /* Dynamic or not? */
-                       (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : "   ",     /* NAT=yes? */
-                       iterator->ha ? " A " : "   ",   /* permit/deny */
-                       ntohs(iterator->addr.sin_port), status);
-+              }
-               if (!s)  {/* Normal CLI list */
-+                  if ((iterator->expire != -1) || (iterator->subpeer != 1)) {
-+                      if (iterator->subpeer == 1) {
-+                          tmp = strchr(name, '@');
-+                          i = tmp - name;
-+                          name[i] = '\0';
-+                      }
-                       ast_cli(fd, FORMAT, name, 
-                       iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
-                       ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
-@@ -7659,6 +7781,7 @@
-                       iterator->ha ? " A " : "   ",       /* permit/deny */
-                       
-                       ntohs(iterator->addr.sin_port), status);
-+                  }
-               } else {        /* Manager format */
-                       /* The names here need to be the same as other channels */
-                       ast_cli(fd, 
-@@ -7684,7 +7807,9 @@
-               ASTOBJ_UNLOCK(iterator);
--              total_peers++;
-+              if ((iterator->expire != -1) || (iterator->subpeer != 1)) {
-+                  total_peers++;
-+              }
-       } while(0) );
-       if (!s) {
-@@ -8719,6 +8844,7 @@
-       char buf[1024];
-       unsigned int event;
-       char *c;
-+      struct ast_call_feature *feature;
-       
-       /* Need to check the media/type */
-       if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") ||
-@@ -8782,6 +8908,19 @@
-                       ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
-               transmit_response(p, "200 OK", req);
-               return;
-+      } else if ((c = get_header(req, "Record"))) {
-+              feature = ast_find_builtin_feature("automon");
-+              if (feature && (!ast_strlen_zero(feature->exten))) {
-+                  int i = 0;
-+//                ast_log(LOG_NOTICE, "feature exten %s\n", feature->exten);
-+                  for (i=0; i<strlen(feature->exten); i++) {
-+                      struct ast_frame f = { AST_FRAME_DTMF, feature->exten[i] };
-+                      ast_queue_frame(p->owner, &f); 
-+                  }
-+              } else {
-+                  ast_log(LOG_NOTICE, "Feature \"One Touch Monitor\" not configured in features.conf.\n");
-+              }
-+              return;
-       } else if ((c = get_header(req, "X-ClientCode"))) {
-               /* Client code (from SNOM phone) */
-               if (ast_test_flag(p, SIP_USECLIENTCODE)) {
-@@ -8881,12 +9020,63 @@
-       return RESULT_SUCCESS;
- }
-+
-+/*! \brief  sip_notify: Send SIP notify to peer */
-+static int sip_send_notify(int fd, char *notify_type, char *peer)
-+{
-+      struct ast_variable *varlist;
-+      struct sip_pvt *p;
-+      struct sip_request req;
-+      struct ast_variable *var;
-+
-+      varlist = ast_variable_browse(notify_types, notify_type);
-+
-+      if (!varlist) {
-+              if (fd > 0)
-+                  ast_cli(fd, "Unable to find notify type '%s'\n", notify_type);
-+              return RESULT_FAILURE;
-+      }
-+
-+      p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
-+      if (!p) {
-+              ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n");
-+              return RESULT_FAILURE;
-+      }
-+
-+      if (create_addr(p, peer)) {
-+              /* Maybe they're not registered, etc. */
-+              sip_destroy(p);
-+              if (fd > 0)
-+                  ast_cli(fd, "Could not create address for '%s'\n", peer);
-+              return RESULT_FAILURE;
-+      }
-+
-+      initreqprep(&req, p, SIP_NOTIFY);
-+
-+      for (var = varlist; var; var = var->next)
-+              add_header(&req, var->name, var->value);
-+
-+      add_blank_header(&req);
-+      /* Recalculate our side, and recalculate Call ID */
-+      if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-+              memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
-+      build_via(p, p->via, sizeof(p->via));
-+      build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
-+      if (fd > 0)
-+          ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", notify_type, peer);
-+      transmit_sip_request(p, &req);
-+      sip_scheddestroy(p, 15000);
-+
-+      return RESULT_SUCCESS;
-+}
-+
- /*! \brief  sip_notify: Send SIP notify to peer */
- static int sip_notify(int fd, int argc, char *argv[])
- {
-       struct ast_variable *varlist;
-       int i;
--
-+      int res = RESULT_SUCCESS;
-+      
-       if (argc < 4)
-               return RESULT_SHOWUSAGE;
-@@ -8903,41 +9093,13 @@
-       }
-       for (i = 3; i < argc; i++) {
--              struct sip_pvt *p;
--              struct sip_request req;
--              struct ast_variable *var;
--
--              p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY);
--              if (!p) {
--                      ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n");
--                      return RESULT_FAILURE;
--              }
--
--              if (create_addr(p, argv[i])) {
--                      /* Maybe they're not registered, etc. */
--                      sip_destroy(p);
--                      ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
--                      continue;
--              }
--
--              initreqprep(&req, p, SIP_NOTIFY);
-+              if (sip_send_notify(fd, argv[2], argv[i]) == RESULT_FAILURE) 
-+                  res = RESULT_FAILURE;
-+      }
-+      return res;
-+}
--              for (var = varlist; var; var = var->next)
--                      add_header(&req, var->name, var->value);
--              add_blank_header(&req);
--              /* Recalculate our side, and recalculate Call ID */
--              if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
--                      memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
--              build_via(p, p->via, sizeof(p->via));
--              build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
--              ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
--              transmit_sip_request(p, &req);
--              sip_scheddestroy(p, 15000);
--      }
--
--      return RESULT_SUCCESS;
--}
- /*! \brief  sip_do_history: Enable SIP History logging (CLI) ---*/
- static int sip_do_history(int fd, int argc, char *argv[])
- {
-@@ -9598,7 +9760,7 @@
-               if (!ignore && p->owner) {
-                       ast_queue_control(p->owner, AST_CONTROL_RINGING);
-                       if (p->owner->_state != AST_STATE_UP)
--                              ast_setstate(p->owner, AST_STATE_RINGING);
-+                              ast_setstate_and_cid(p->owner, AST_STATE_RINGING, p->owner->cid.cid_num, p->owner->cid.cid_name);
-               }
-               if (find_sdp(req)) {
-                       process_sdp(p, req);
-@@ -10423,9 +10585,18 @@
-               /* This is a call to ourself.  Send ourselves an error code and stop
-                  processing immediately, as SIP really has no good mechanism for
-                  being able to call yourself */
--              transmit_response(p, "482 Loop Detected", req);
--              /* We do NOT destroy p here, so that our response will be accepted */
--              return 0;
-+/*            char tmp[256] = "", *uri;
-+              if (req->rlPart2)
-+                  ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
-+              uri = get_in_brackets(tmp);
-+              if (strcmp(p->uri, uri)) {
-+                  ast_log(LOG_NOTICE, "SPIRAL DETECTED p->uri: %s uri: %s\n", p->uri, uri);
-+              } else {
-+                  ast_log(LOG_NOTICE, "LOOP DETECTED p->uri: %s uri: %s\n", p->uri, uri);*/
-+                  transmit_response(p, "482 Loop Detected", req);
-+                  /* We do NOT destroy p here, so that our response will be accepted */
-+                  return 0;
-+/*            }*/
-       }
-       if (!ignore) {
-               /* Use this as the basis */
-@@ -10657,6 +10828,7 @@
-       struct ast_channel *c=NULL;
-       int res;
-       struct ast_channel *transfer_to;
-+      struct sip_pvt *rp; /* replace call */
-       if (option_debug > 2)
-               ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid);
-@@ -10665,9 +10837,73 @@
-       res = get_refer_info(p, req);
-       if (res < 0)
-               transmit_response(p, "603 Declined", req);
--      else if (res > 0)
-+      else if (res == 1)
-               transmit_response(p, "484 Address Incomplete", req);
--      else {
-+      else if (res == 2) {
-+              transmit_response(p, "202 Accepted", req);
-+              rp = sip_alloc(NULL, NULL, 0, SIP_INVITE);
-+              if (!rp) {
-+                  return -1;
-+              }
-+              rp->capability = global_capability;
-+
-+              build_route(rp, req, 0);
-+              if (option_verbose > 3)
-+                  ast_log(LOG_NOTICE, "got REFER for callid %s TO %s CONTACT %s replacing callid %s (tohost %s, p->route %s, rp->route %s)\n", p->callid, p->refer_to, p->refer_contact, p->refer_replaces, p->tohost, p->route->hop, rp->route->hop);
-+                  if (create_addr(rp, p->tohost)) {
-+                      sip_destroy(rp);
-+                      return -1;
-+                  }
-+
-+              if (ast_sip_ouraddrfor(&rp->sa.sin_addr,&rp->ourip)) {
-+                  memcpy(&rp->ourip, &__ourip, sizeof(rp->ourip));
-+              }
-+              build_via(rp, rp->via, sizeof(rp->via));
-+              build_callid(rp->callid, sizeof(rp->callid) - 1, rp->ourip, rp->fromdomain);
-+      
-+          ast_log(LOG_NOTICE, "1\n");
-+              rp->prefcodec = p->prefcodec;
-+              rp->jointcapability = rp->capability;
-+              rp->rtp = p->rtp;
-+              p->rtp = NULL;
-+              if (!ast_strlen_zero(p->refer_to)) {
-+                  ast_copy_string(rp->username, p->refer_to, sizeof(rp->username));
-+                  rp->fullcontact[0] = '\0';
-+              }
-+              if (!ast_strlen_zero(p->refer_replaces)) {
-+                  ast_copy_string(rp->refer_replaces, p->refer_replaces, sizeof(rp->refer_replaces));
-+              }
-+          ast_log(LOG_NOTICE, "2\n");
-+                      ast_set_flag(rp, SIP_OUTGOING);
-+                      
-+          ast_log(LOG_NOTICE, "3\n");
-+
-+                      if (p->owner) {
-+                          c = p->owner;
-+//                        ast_copy_string(rp->cid_num, c->cid.cid_num, sizeof(rp->cid_num));
-+//                        ast_copy_string(rp->cid_name, c->cid.cid_name, sizeof(rp->cid_name));
-+          ast_log(LOG_NOTICE, "4\n");
-+                          c->tech_pvt = rp;
-+                          rp->owner = c;
-+          ast_log(LOG_NOTICE, "5\n");
-+                          ast_mutex_unlock(&c->lock);
-+                      }
-+                      p->owner = NULL;
-+          ast_log(LOG_NOTICE, "6\n");
-+
-+                      transmit_invite(rp, SIP_INVITE, 1, 2);
-+                      if (rp->maxtime) {
-+                          /* Initialize auto-congest time */
-+                          rp->initid = ast_sched_add(sched, rp->maxtime * 4, auto_congest, rp);
-+                      }
-+
-+                      transmit_notify_with_sipfrag(p, seqno);
-+
-+                      /* Always increment on a BYE */
-+                      transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
-+                      ast_set_flag(p, SIP_ALREADYGONE);
-+                      return 0;
-+      } else { /* res == 0 */
-               int nobye = 0;
-               if (!ignore) {
-                       if (p->refer_call) {
-@@ -10995,7 +11231,7 @@
-                       struct sip_pvt *p_old;
-                       transmit_response(p, "200 OK", req);
--                      transmit_state_notify(p, firststate, 1, 1);     /* Send first notification */
-+                      transmit_state_notify(p, firststate, 1, 1, NULL, NULL); /* Send first notification */
-                       append_history(p, "Subscribestatus", ast_extension_state2str(firststate));
-                       /* remove any old subscription from this peer for the same exten/context,
-@@ -11189,6 +11425,8 @@
-               res = handle_request_options(p, req, debug);
-               break;
-       case SIP_INVITE:
-+              /* XXX quick fix for xfers */
-+              ast_copy_string(p->tohost, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), sizeof(p->tohost));
-               res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e);
-               break;
-       case SIP_REFER:
-@@ -11309,7 +11547,7 @@
-       /* Process request, with netlock held */
- retrylock:
-       ast_mutex_lock(&netlock);
--      p = find_call(&req, &sin, req.method);
-+      p = find_call(&req, &sin, req.method, 0);
-       if (p) {
-               /* Go ahead and lock the owner if it has one -- we may need it */
-               if (p->owner && ast_mutex_trylock(&p->owner->lock)) {
-@@ -11636,6 +11874,52 @@
-       return 0;
- }
-+static char mandescr_sip_notify[] = 
-+"Description: Send a NOTIFY message to one or more SIP peers.\n"
-+"Variables: \n"
-+"  Peer: <name>           The peer name you want to send a NOTIFY to.\n"
-+"  Type: <name>           The notify type (see sip_notify.conf).\n"
-+"  ActionID: <id>       Optional action ID for this AMI transaction.\n";
-+
-+/*! \brief  manager_sip_notify: Send a notify (see sip_notify.conf) to a peer ---*/
-+static int manager_sip_notify(struct mansession *s, struct message *m)
-+{
-+      char *id = astman_get_header(m,"ActionID");
-+      char *peer;
-+      char *notify_type;
-+      int res = 0;
-+
-+      peer = astman_get_header(m,"Peer");
-+      if (ast_strlen_zero(peer)) {
-+              astman_send_error(s, m, "Peer: <name> missing.\n");
-+              return 0;
-+      }
-+      notify_type = astman_get_header(m,"Type");
-+      if (ast_strlen_zero(notify_type)) {
-+              astman_send_error(s, m, "Type: <name> missing.\n");
-+              return 0;
-+      }
-+
-+      res = sip_send_notify(-1, notify_type, peer);
-+      if (res != RESULT_SUCCESS) {
-+          ast_cli(s->fd, "Response: SIPNotify Failure\r\n"
-+                      "Peer: %s\r\n"
-+                      "Type: %s\r\n"
-+                      "ActionID: %s\r\n"
-+                      "\r\n",
-+                      peer, notify_type, id);
-+      } else {
-+          ast_cli(s->fd, "Response: SIPNotify Success\r\n"
-+                      "Peer: %s\r\n"
-+                      "Type: %s\r\n"
-+                      "ActionID: %s\r\n"
-+                      "\r\n",
-+                      peer, notify_type, id);
-+      }
-+      return res;
-+}
-+
-+
- /*! \brief  sip_devicestate: Part of PBX channel interface ---*/
- /* Return values:---
-@@ -12173,6 +12457,7 @@
-       peer->expire = -1;
-       peer->pokeexpire = -1;
-+      peer->max_regs = 1;
-       ast_copy_string(peer->name, name, sizeof(peer->name));
-       ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
-       strcpy(peer->context, default_context);
-@@ -12218,7 +12503,9 @@
-       if (peer) {
-               /* Already in the list, remove it and it will be added back (or FREE'd)  */
--              found++;
-+              if (peer->max_regs == 1) {
-+                  found++;
-+              }
-       } else {
-               peer = malloc(sizeof(*peer));
-               if (peer) {
-@@ -12230,6 +12517,7 @@
-                       ASTOBJ_INIT(peer);
-                       peer->expire = -1;
-                       peer->pokeexpire = -1;
-+                      peer->max_regs = 1;
-               } else {
-                       ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n");
-               }
-@@ -12375,6 +12663,10 @@
-                       peer->call_limit = atoi(v->value);
-                       if (peer->call_limit < 0)
-                               peer->call_limit = 0;
-+              } else if (!strcasecmp(v->name, "registrations")) {
-+                      peer->max_regs = atoi(v->value);
-+                      if (peer->max_regs < 0)
-+                              peer->max_regs = 0;
-               } else if (!strcasecmp(v->name, "amaflags")) {
-                       format = ast_cdr_amaflags2int(v->value);
-                       if (format < 0) {
-@@ -12770,8 +13062,24 @@
-                               if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
-                                       peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
-                                       if (peer) {
--                                              ASTOBJ_CONTAINER_LINK(&peerl,peer);
--                                              ASTOBJ_UNREF(peer, sip_destroy_peer);
-+                                          if (peer->max_regs > 1) {
-+                                              int i = 0;
-+                                              int clones = peer->max_regs - 1;
-+                                              struct sip_peer *clone = NULL;
-+                                              char clone_name[sizeof(clone->name)];
-+                                              /* clone clone clone */
-+                                              for (i=0;i<clones;i++) {
-+                                                  snprintf(clone_name, sizeof(clone_name), "%s@%d", cat, i);
-+                                                  clone = build_peer(clone_name, ast_variable_browse(cfg, cat), 0);
-+                                                  if (clone) {
-+                                                      clone->subpeer = 1;
-+                                                      ASTOBJ_CONTAINER_LINK(&peerl,clone);
-+                                                      ASTOBJ_UNREF(clone, sip_destroy_peer);
-+                                                  }
-+                                              }
-+                                          }
-+                                          ASTOBJ_CONTAINER_LINK(&peerl,peer);
-+                                          ASTOBJ_UNREF(peer, sip_destroy_peer);
-                                       }
-                               } else if (strcasecmp(utype, "user")) {
-                                       ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
-@@ -13361,6 +13669,8 @@
-                       "List SIP peers (text format)", mandescr_show_peers);
-       ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
-                       "Show SIP peer (text format)", mandescr_show_peer);
-+      ast_manager_register2("SIPNotify", EVENT_FLAG_SYSTEM, manager_sip_notify,
-+                      "Send NOTIFY to peer", mandescr_sip_notify);
-       sip_poke_all_peers();   
-       sip_send_all_registers();
-@@ -13391,6 +13701,7 @@
-       ast_rtp_proto_unregister(&sip_rtp);
-+      ast_manager_unregister("SIPNotify");
-       ast_manager_unregister("SIPpeers");
-       ast_manager_unregister("SIPshowpeer");
-diff -urN asterisk-1.2.10.orig/channels/chan_zap.c asterisk-1.2.10/channels/chan_zap.c
---- asterisk-1.2.10.orig/channels/chan_zap.c   2006-07-12 15:54:10.000000000 +0200
-+++ asterisk-1.2.10/channels/chan_zap.c        2006-08-09 16:15:04.000000000 +0200
-@@ -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.
-@@ -65,6 +69,9 @@
- #ifdef ZAPATA_R2
- #include <libmfcr2.h>
- #endif
-+#ifdef ZAPATA_GSM
-+#include <libgsmat.h>
-+#endif
- #include "asterisk.h"
-@@ -96,6 +103,7 @@
- #include "asterisk/term.h"
- #include "asterisk/utils.h"
- #include "asterisk/transcap.h"
-+#include "asterisk/devicestate.h"
- #ifndef ZT_SIG_EM_E1
- #error "Your zaptel is too old.  please cvs update"
-@@ -173,6 +181,7 @@
- #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_R2                ZT_SIG_CAS
- #define       SIG_SF          ZT_SIG_SF
- #define SIG_SFWINK    (0x0100000 | ZT_SIG_SF)
-@@ -183,7 +192,7 @@
- #define SIG_GR303FXOKS        (0x0100000 | ZT_SIG_FXOKS)
- #define SIG_GR303FXSKS        (0x0100000 | ZT_SIG_FXSKS)
--#define NUM_SPANS             32
-+#define NUM_SPANS             128     /*!<"32 spans", muahahaha, us alaws like to have some more... */
- #define NUM_DCHANS            4       /*!< No more than 4 d-channels */
- #define MAX_CHANNELS  672             /*!< No more than a DS3 per trunk group */
-@@ -201,6 +210,11 @@
- static char defaultcic[64] = "";
- static char defaultozz[64] = "";
-+static char nocid[256] = "No CID available";
-+static char withheldcid[256] = "CID withheld";
-+static char gsm_modem_pin[20];
-+static char gsm_modem_exten[AST_MAX_EXTENSION];
-+
- static char language[MAX_LANGUAGE] = "";
- static char musicclass[MAX_MUSICCLASS] = "";
- static char progzone[10]= "";
-@@ -287,6 +301,7 @@
- static int cur_priexclusive = 0;
- static int priindication_oob = 0;
-+static int pritransfer = 0;
- #ifdef ZAPATA_PRI
- static int minunused = 2;
-@@ -294,6 +309,7 @@
- static char idleext[AST_MAX_EXTENSION];
- static char idledial[AST_MAX_EXTENSION];
- static int overlapdial = 0;
-+static int usercid = 0;
- static int facilityenable = 0;
- static char internationalprefix[10] = "";
- static char nationalprefix[10] = "";
-@@ -305,8 +321,6 @@
- #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) */
-@@ -327,10 +341,6 @@
- static int ifcount = 0;
--#ifdef ZAPATA_PRI
--AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
--#endif
--
- /*! \brief Whether we answer on a Polarity Switch event */
- static int answeronpolarityswitch = 0;
-@@ -389,6 +399,18 @@
- struct zt_pvt;
-+#ifdef ZAPATA_GSM
-+struct zt_gsm {
-+      pthread_t master;
-+      ast_mutex_t lock;               /* Mutex */
-+      int fd;
-+      int span;
-+      struct gsm_modul *modul;
-+      char pin[256];
-+      char exten[AST_MAX_EXTENSION];          /* Where to idle extra calls */
-+      struct zt_pvt *pvt;
-+};
-+#endif
- #ifdef ZAPATA_R2
- static int r2prot = -1;
-@@ -403,6 +425,28 @@
- #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_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 */
-@@ -416,6 +460,8 @@
-       int nsf;                                                        /*!< Network-Specific Facilities */
-       int dialplan;                                                   /*!< Dialing plan */
-       int localdialplan;                                              /*!< Local dialing plan */
-+      char nocid[256];
-+      char withheldcid[256];
-       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) */
-@@ -435,6 +481,7 @@
-       int fds[NUM_DCHANS];                                            /*!< FD's for d-channels */
-       int offset;
-       int span;
-+      int usercid;                                                    /* trust user provided callerid (callerani) ?? */
-       int resetting;
-       int resetpos;
-       time_t lastreset;                                               /*!< time when unused channels were last reset */
-@@ -442,6 +489,9 @@
-       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 */
-+      struct zt_holded_call *holded_calls; /* Calls on hold */
-+      int debugfd;
- };
-@@ -561,6 +611,8 @@
-       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;
-@@ -573,7 +625,8 @@
-       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 */
-@@ -612,6 +665,7 @@
- #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];
-@@ -672,10 +726,15 @@
-       int polarityonanswerdelay;
-       struct timeval polaritydelaytv;
-       int sendcalleridafter;
-+#ifdef ZAPATA_GSM
-+      struct zt_gsm gsm;
-+#endif
- #ifdef ZAPATA_PRI
-       struct zt_pri *pri;
-       struct zt_pvt *bearer;
-       struct zt_pvt *realcall;
-+      int tei;                                        /* channel in use by this tei */
-+      q931_call *holdedcall;
-       q931_call *call;
-       int prioffset;
-       int logicalspan;
-@@ -701,11 +760,14 @@
- static int zt_indicate(struct ast_channel *chan, int condition);
- 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_devicestate(void *data);
-+static void disable_dtmf_detect(struct zt_pvt *p);
-+static void enable_dtmf_detect(struct zt_pvt *p);
- static const struct ast_channel_tech zap_tech = {
-       .type = type,
-       .description = tdesc,
--      .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW,
-+      .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
-       .requester = zt_request,
-       .send_digit = zt_digit,
-       .send_text = zt_sendtext,
-@@ -719,6 +781,7 @@
-       .indicate = zt_indicate,
-       .fixup = zt_fixup,
-       .setoption = zt_setoption,
-+      .devicestate = zt_devicestate
- };
- #ifdef ZAPATA_PRI
-@@ -730,6 +793,13 @@
- struct zt_pvt *round_robin[32];
- #ifdef ZAPATA_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;
-@@ -779,6 +849,112 @@
- #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
- #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
-+static int zt_devicestate(void *data)
-+{
-+      int groupmatch = 0;
-+      int channelmatch = 0;
-+      struct zt_pvt *p;
-+      char *dest=NULL;
-+      int x,d;
-+      char *s;
-+      char opt=0;
-+      int res, y=0;
-+      struct zt_pvt *exit, *start, *end;
-+      ast_mutex_t *lock;
-+
-+//    ast_log(LOG_NOTICE, "data = %s\n", (char *)data);
-+      return AST_DEVICE_UNKNOWN;
-+      
-+      /* Assume we're locking the iflock */
-+      lock = &iflock;
-+      start = iflist;
-+      end = ifend;
-+
-+      if (data) {
-+              dest = ast_strdupa((char *)data);
-+      } else {
-+              ast_log(LOG_WARNING, "Channel requested with no data\n");
-+              return AST_DEVICE_INVALID;
-+      }
-+      if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
-+              /* Retrieve the group number */
-+              char *stringp=NULL;
-+              stringp=dest + 1;
-+              s = strsep(&stringp, "/");
-+              if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
-+                      ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
-+                      return AST_DEVICE_INVALID;
-+              }
-+              groupmatch = 1 << x;
-+      } else {
-+              char *stringp=NULL;
-+              stringp=dest;
-+              s = strsep(&stringp, "/");
-+              p = iflist;
-+              if (!strcasecmp(s, "pseudo")) {
-+                      /* Special case for pseudo */
-+                      x = CHAN_PSEUDO;
-+                      channelmatch = x;
-+                      /* bail out */
-+                      return AST_DEVICE_INVALID;
-+              } 
-+
-+              else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
-+                      ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
-+                      return AST_DEVICE_INVALID;
-+              } else {
-+                      channelmatch = x;
-+                      ast_log(LOG_NOTICE, "channelmatch = %d\n", channelmatch);
-+              }
-+      }
-+      /* Search for an unowned channel */
-+      if (ast_mutex_lock(lock)) {
-+              ast_log(LOG_ERROR, "Unable to lock interface list???\n");
-+              return AST_DEVICE_INVALID;
-+      }
-+      p = iflist;
-+      exit = iflist;
-+      res = AST_DEVICE_INVALID; /* start pessimistic */
-+      while(p) {
-+              if (p) {
-+                  ast_mutex_lock(&p->lock);
-+                  if ((groupmatch && ((p->group & groupmatch) != 0)) || (channelmatch && (p->channel == channelmatch))) {
-+#ifdef ZAPATA_PRI
-+                      if (p->pri) {
-+                          for(d=0;d<NUM_DCHANS;d++) {
-+                              if (p->pri->dchanavail[d] & DCHAN_UP) {
-+                                  res = AST_DEVICE_UNKNOWN;
-+                              }
-+                          }
-+                      }
-+#endif
-+                      if ((!ast_strlen_zero(p->cid_num) && (strncasecmp(p->cid_num, dest, strlen(p->cid_num)))) || (!ast_strlen_zero(p->dnid) && (strncasecmp(p->dnid, dest, strlen(p->dnid))))) {
-+                          res = AST_DEVICE_UNKNOWN;
-+                          if (p->owner) {
-+                                  if ((p->owner->_state == AST_STATE_RINGING) && (p->outgoing)) {
-+                                      res = AST_DEVICE_RINGING;
-+                                  }
-+                                  if (((p->owner->_state == AST_STATE_RINGING) && (!p->outgoing)) || (p->owner->_state == AST_STATE_UP) || (p->owner->_state == AST_STATE_DIALING) || (p->owner->_state == AST_STATE_RESERVED) || (p->owner->_state == AST_STATE_RING)){
-+                                      res = AST_DEVICE_INUSE;
-+                                  }
-+                          }
-+                          if ((res == AST_DEVICE_INUSE) || (res == AST_DEVICE_RINGING)) {
-+                              /* stop searching now, one non-idle channel is sufficient */
-+                              ast_mutex_unlock(&p->lock);
-+                              break;
-+                          }
-+                      }
-+                  }
-+                  ast_mutex_unlock(&p->lock);
-+              }       
-+              p = p->next;
-+      }
-+      ast_mutex_unlock(lock);
-+
-+      return res;
-+
-+}
-+
- static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok)
- {
-       int res;
-@@ -1181,6 +1357,8 @@
-               return "GR-303 Signalling with FXOKS";
-       case SIG_GR303FXSKS:
-               return "GR-303 Signalling with FXSKS";
-+      case SIG_GSM:
-+              return "GSM Signalling";
-       case 0:
-               return "Pseudo Signalling";
-       default:
-@@ -1381,12 +1559,16 @@
-       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) {
-@@ -1412,7 +1594,7 @@
- {
-       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) 
-@@ -1592,7 +1774,7 @@
- {
-       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)
-@@ -1774,7 +1956,12 @@
-               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);
-+      }
-+
-       switch(p->sig) {
-       case SIG_FXOLS:
-@@ -1998,6 +2185,26 @@
-       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;
-+      case SIG_GSM:
-+#ifdef ZAPATA_GSM
-+              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");
-@@ -2016,6 +2223,12 @@
-               int ldp_strip;
-               int exclusive;
-+              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++;
-@@ -2033,6 +2246,7 @@
-                       ast_mutex_unlock(&p->lock);
-                       return -1;
-               }
-+              strncpy(p->dnid, (c + p->stripmsd), sizeof(p->dnid)-1);
-               if (p->sig != SIG_FXSKS) {
-                       p->dop.op = ZT_DIAL_OP_REPLACE;
-                       s = strchr(c + p->stripmsd, 'w');
-@@ -2056,6 +2270,8 @@
-                       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);
-@@ -2085,7 +2301,7 @@
-               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);
-@@ -2286,8 +2502,10 @@
-       }
-       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",
-@@ -2343,8 +2561,7 @@
-       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;
-@@ -2441,6 +2658,7 @@
-       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;
-@@ -2477,19 +2695,61 @@
-                       if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
-                               if (!pri_grab(p, p->pri)) {
-                                       if (p->alreadyhungup) {
-+/*                                            char *aoc = pbx_builtin_getvar_helper(ast,"AOCEUNITS");
-+                                              int iaoc = aoc ? atoi(aoc) : -1;
-+                                              char *aocpm = pbx_builtin_getvar_helper(ast,"AOCEUNITSPERMIN");
-+                                              int iaocpm = aocpm ? atoi(aocpm) : -1;
-+
-+                                              if (iaocpm > -1) {
-+                                                  if (ast->cdr) {
-+                                                  long bill_sec = ast->cdr->billsec;
-+                                                  long bill_min = 0;
-+                                                  if (bill_sec > 0) {
-+                                                      bill_min = bill_sec / 60;
-+                                                      if (bill_min < 1) bill_min = 1;
-+                                                  }
-+                                                  iaoc = bill_min * iaocpm;
-+                                                  } else {
-+                                                      ast_log(LOG_NOTICE, "no cdr \n");
-+                                                  }
-+                                              } else {
-+                                                      ast_log(LOG_NOTICE, "iaocpm %d \n", iaocpm);
-+                                              }
-+*/
-                                               ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
- #ifdef SUPPORT_USERUSER
-                                               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;
-                                       } else {
-                                               char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
-                                               int icause = ast->hangupcause ? ast->hangupcause : -1;
-+/*                                            char *aoc = pbx_builtin_getvar_helper(ast,"AOCEUNITS");
-+                                              int iaoc = aoc ? atoi(aoc) : -1;
-+                                              char *aocpm = pbx_builtin_getvar_helper(ast,"AOCEUNITSPERMIN");
-+                                              int iaocpm = aocpm ? atoi(aocpm) : -1;
-+
-+                                              if (iaocpm > -1) {
-+                                                  if (ast->cdr) {
-+                                                  long bill_sec = ast->cdr->billsec;
-+                                                  long bill_min = 0;
-+                                                  if (bill_sec > 0) {
-+                                                      bill_min = bill_sec / 60;
-+                                                      if (bill_min < 1) bill_min = 1;
-+                                                  }
-+                                                  iaoc = bill_min * iaocpm;
-+                                                  } else {
-+                                                      ast_log(LOG_NOTICE, "no cdr \n");
-+                                                  }
-+                                              } else {
-+                                                      ast_log(LOG_NOTICE, "iaocpm %d \n", iaocpm);
-+                                              }
-+*/
-                                               ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
- #ifdef SUPPORT_USERUSER
-@@ -2503,7 +2763,28 @@
-                                                       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 release 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)) {
-+                                                      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");
-@@ -2531,7 +2812,13 @@
-               }
- #endif
--              if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_R2))
-+#ifdef ZAPATA_GSM
-+              if (p->gsm.modul) {
-+                  if (!p->alreadyhungup)
-+                      gsm_hangup(p->gsm.modul);
-+              }
-+#endif
-+              if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_R2) && (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);
-@@ -2700,10 +2987,14 @@
-                       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
- #ifdef ZAPATA_R2
-@@ -2713,6 +3004,13 @@
-                       ast_log(LOG_WARNING, "R2 Answer call failed :( on %s\n", ast->name);
-               break;
- #endif                        
-+#ifdef ZAPATA_GSM
-+      case SIG_GSM:
-+              if (p->gsm.modul) {
-+                  gsm_answer(p->gsm.modul);
-+              }
-+              break;
-+#endif
-       case 0:
-               ast_mutex_unlock(&p->lock);
-               return 0;
-@@ -3273,6 +3571,15 @@
- {
-       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) {
-@@ -3633,7 +3940,7 @@
-                       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);
-@@ -4596,7 +4903,7 @@
-               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) {
-@@ -4608,8 +4915,9 @@
-                               }
-                       } else if (f->frametype == AST_FRAME_DTMF) {
- #ifdef ZAPATA_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;
-                               }
-@@ -4657,8 +4965,10 @@
-                                               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
--                                              ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
-+                                      } else {
-+                                          if (option_verbose > 2)
-+                                              ast_verbose(VERBOSE_PREFIX_3 "Fax detected, but no fax extension\n");
-+                                      }
-                               } else
-                                       ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
-                       } else
-@@ -4744,7 +5054,9 @@
- #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;
-       }
-@@ -4815,7 +5127,7 @@
-               switch(condition) {
-               case AST_CONTROL_BUSY:
- #ifdef ZAPATA_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;
-@@ -4897,7 +5209,7 @@
-               case AST_CONTROL_CONGESTION:
-                       chan->hangupcause = AST_CAUSE_CONGESTION;
- #ifdef ZAPATA_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;
-@@ -5082,8 +5394,12 @@
-               if (state == AST_STATE_RING)
-                       tmp->rings = 1;
-               tmp->tech_pvt = i;
--              if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
--                      /* Only FXO signalled stuff can be picked up */
-+#ifdef ZAPATA_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)) {
-+#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;
-               }
-@@ -5213,6 +5529,7 @@
-       int len = 0;
-       int res;
-       int index;
-+      int network;
-       if (option_verbose > 2) 
-               ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
-       index = zt_get_index(chan, p, 1);
-@@ -5231,10 +5548,17 @@
-               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
-@@ -6327,18 +6651,44 @@
-               break;
-       case ZT_EVENT_NOALARM:
-               i->inalarm = 0;
-+#ifdef ZAPATA_PRI
-+              if (i->pri) {
-+                  if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE_PTMP)) {
-+                      /* dont annoy BRI TE mode users with layer2layer alarms */
-+                  } else {
-+                      ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
-+                      manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
-+                            "Channel: %d\r\n", i->channel);
-+                  }
-+              }
-+#else
-               ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
-               manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
-                             "Channel: %d\r\n", i->channel);
-+#endif
-               break;
-       case ZT_EVENT_ALARM:
-               i->inalarm = 1;
-               res = get_alarms(i);
-+#ifdef ZAPATA_PRI
-+              if (i->pri) {
-+                  if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE_PTMP)) {
-+                      /* dont annoy BRI TE mode users with layer2layer alarms */
-+                  } else {
-+                      ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
-+                      manager_event(EVENT_FLAG_SYSTEM, "Alarm",
-+                            "Alarm: %s\r\n"
-+                            "Channel: %d\r\n",
-+                            alarm2str(res), i->channel);
-+                  }
-+              }
-+#else
-               ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
-               manager_event(EVENT_FLAG_SYSTEM, "Alarm",
-                             "Alarm: %s\r\n"
-                             "Channel: %d\r\n",
-                             alarm2str(res), i->channel);
-+#endif
-               /* fall thru intentionally */
-       case ZT_EVENT_ONHOOK:
-               if (i->radio) break;
-@@ -6378,8 +6728,10 @@
-                       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);
-@@ -6702,6 +7054,8 @@
-               } 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;
-                       }
-@@ -6789,6 +7143,10 @@
- #endif
-+#ifdef ZAPATA_GSM
-+static void *gsm_dchannel(void *vgsm);
-+#endif
-+
- static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_pri *pri, int reloading)
- {
-       /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
-@@ -6947,6 +7305,11 @@
-                                                       destroy_zt_pvt(&tmp);
-                                                       return NULL;
-                                               }
-+                                              if ((pris[span].localdialplan) && (pris[span].localdialplan != 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 (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, idledial)) {
-                                                       ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, idledial);
-                                                       destroy_zt_pvt(&tmp);
-@@ -6974,6 +7337,17 @@
-                                                       return NULL;
-                                               }
-                                               pris[span].nodetype = pritype;
-+// XXX
-+                                              if (pritype == BRI_NETWORK_PTMP) {
-+                                                  pris[span].dchanavail[0] =  DCHAN_AVAILABLE;
-+                                                  pri_find_dchan(&pris[span]);
-+                                              }
-+// XXX tuev
-+
-+//                                            if ((pritype == BRI_CPE) || (pritype == BRI_CPE_PTMP)) {
-+//                                                pris[span].dchanavail[0] =  DCHAN_AVAILABLE;
-+//                                                pri_find_dchan(&pris[span]);
-+//                                            }
-                                               pris[span].switchtype = myswitchtype;
-                                               pris[span].nsf = nsf;
-                                               pris[span].dialplan = dialplan;
-@@ -6982,9 +7356,14 @@
-                                               pris[span].minunused = minunused;
-                                               pris[span].minidle = minidle;
-                                               pris[span].overlapdial = overlapdial;
-+                                              pris[span].usercid = usercid;
-+                                              pris[span].suspended_calls = NULL;
-+                                              pris[span].holded_calls = NULL;
-                                               pris[span].facilityenable = facilityenable;
-                                               ast_copy_string(pris[span].idledial, idledial, sizeof(pris[span].idledial));
-                                               ast_copy_string(pris[span].idleext, idleext, sizeof(pris[span].idleext));
-+                                              ast_copy_string(pris[span].nocid, nocid, sizeof(pris[span].nocid) - 1);
-+                                              ast_copy_string(pris[span].withheldcid, withheldcid, sizeof(pris[span].withheldcid) - 1);
-                                               ast_copy_string(pris[span].internationalprefix, internationalprefix, sizeof(pris[span].internationalprefix));
-                                               ast_copy_string(pris[span].nationalprefix, nationalprefix, sizeof(pris[span].nationalprefix));
-                                               ast_copy_string(pris[span].localprefix, localprefix, sizeof(pris[span].localprefix));
-@@ -7005,6 +7384,36 @@
-                               tmp->prioffset = 0;
-                       }
- #endif
-+#ifdef ZAPATA_GSM
-+              if (signalling == 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);
-+                  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
- #ifdef ZAPATA_R2
-                       if (signalling == SIG_R2) {
-                               if (r2prot < 0) {
-@@ -7138,6 +7547,7 @@
-               tmp->restrictcid = restrictcid;
-               tmp->use_callingpres = use_callingpres;
-               tmp->priindication_oob = priindication_oob;
-+              tmp->pritransfer = pritransfer;
-               tmp->priexclusive = cur_priexclusive;
-               if (tmp->usedistinctiveringdetection) {
-                       if (!tmp->use_callerid) {
-@@ -7411,7 +7821,7 @@
-                       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;
-@@ -7458,7 +7868,7 @@
-       end = ifend;
-       /* We do signed linear */
-       oldformat = format;
--      format &= (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
-+      format &= (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW);
-       if (!format) {
-               ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
-               return NULL;
-@@ -7618,6 +8028,11 @@
-                                       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);
-                               }
-@@ -7651,12 +8066,174 @@
-                               *cause = AST_CAUSE_BUSY;
-               } else if (groupmatched) {
-                       *cause = AST_CAUSE_CONGESTION;
-+              } else {
-+                      *cause = AST_CAUSE_CONGESTION;
-               }
-       }
-               
-       return tmp;
- }
-+#ifdef ZAPATA_GSM
-+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);
-+              break;
-+      case GSM_EVENT_DCHAN_DOWN:
-+              if (option_verbose > 2)
-+                  ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d unregistered from network!\n", gsm->span);
-+              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, withheldcid, 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->_softhangup |= AST_SOFTHANGUP_DEV;
-+              }
-+              ast_mutex_unlock(&gsm->pvt->lock);
-+              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 received on span %d. PDU: %s\n", gsm->span, 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);
-+                          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 ZAPATA_PRI
- static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
-@@ -7671,6 +8248,57 @@
-       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)
- {
-@@ -7703,7 +8331,9 @@
- static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
- {
-       int x;
-+      int res = 0;
-       struct zt_pvt *crv;
-+      char tmpname[256];
-       if (!c) {
-               if (principle < 0)
-                       return -1;
-@@ -7717,6 +8347,7 @@
-       /* First, check for other bearers */
-       for (x=0;x<pri->numchans;x++) {
-               if (!pri->pvts[x]) continue;
-+// ast_log(LOG_NOTICE, "principle %d channel %d call %d channel[x]->call %d\n",principle, x, c, pri->pvts[x]->call);
-               if (pri->pvts[x]->call == c) {
-                       /* Found our call */
-                       if (principle != x) {
-@@ -7730,19 +8361,56 @@
-                               }
-                               /* Fix it all up now */
-                               pri->pvts[principle]->owner = pri->pvts[x]->owner;
-+                              pri->pvts[principle]->outgoing = pri->pvts[x]->outgoing;
-                               if (pri->pvts[principle]->owner) {
-                                       snprintf(pri->pvts[principle]->owner->name, sizeof(pri->pvts[principle]->owner->name), 
-                                               "Zap/%d:%d-%d", pri->trunkgroup, pri->pvts[principle]->channel, 1);
-                                       pri->pvts[principle]->owner->tech_pvt = pri->pvts[principle];
-                                       pri->pvts[principle]->owner->fds[0] = pri->pvts[principle]->subs[SUB_REAL].zfd;
-                                       pri->pvts[principle]->subs[SUB_REAL].owner = pri->pvts[x]->subs[SUB_REAL].owner;
--                              } else
-+                              } else {
-                                       ast_log(LOG_WARNING, "Whoa, there's no  owner, and we're having to fix up channel %d to channel %d\n", pri->pvts[x]->channel, pri->pvts[principle]->channel);
-+                              }
-                               pri->pvts[principle]->call = pri->pvts[x]->call;
-+                              pri->pvts[principle]->dsp = pri->pvts[x]->dsp;
-+                              pri->pvts[principle]->alreadyhungup = pri->pvts[x]->alreadyhungup;
-+                              pri->pvts[principle]->digital = pri->pvts[x]->digital;
-+                              pri->pvts[principle]->faxhandled = pri->pvts[x]->faxhandled;
-+  
-+                              if ((pri->nodetype == BRI_CPE_PTMP) || (pri->nodetype == BRI_CPE)) { 
-+                                  /* this might also apply for other pri types! */
-+                                  pri->pvts[principle]->law = pri->pvts[x]->law;
-+                                  if (ioctl(pri->pvts[principle]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &pri->pvts[principle]->law) == -1)
-+                                      ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[principle]->channel, pri->pvts[principle]->law);
-+                                  res = zt_setlaw(pri->pvts[principle]->subs[SUB_REAL].zfd, pri->pvts[principle]->law);
-+                                  if (res < 0) 
-+                                      ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[principle]->channel);
-+                                  if (!pri->pvts[principle]->digital) {
-+                                      res = set_actual_gain(pri->pvts[principle]->subs[SUB_REAL].zfd, 0, pri->pvts[principle]->rxgain, pri->pvts[principle]->txgain, pri->pvts[principle]->law);
-+                                  } else {
-+                                      res = set_actual_gain(pri->pvts[principle]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[principle]->law);
-+                                  }
-+                                  if (res < 0) 
-+                                      ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[principle]->channel);
-+                                  zt_confmute(pri->pvts[x], 0);
-+                                  update_conf(pri->pvts[x]);
-+                                  reset_conf(pri->pvts[x]);
-+                                  restore_gains(pri->pvts[x]);
-+                                  zt_disable_ec(pri->pvts[x]);
-+                                  zt_setlinear(pri->pvts[x]->subs[SUB_REAL].zfd, 0);
-+                              }
-+  
-+                              if (pri->pvts[principle]->owner) {
-+                                  snprintf(tmpname, sizeof(tmpname), "Zap/%d-1", pri->pvts[principle]->channel);
-+                                  ast_change_name(pri->pvts[principle]->owner, tmpname);
-+                              }
-+
-+
-                               /* Free up the old channel, now not in use */
-                               pri->pvts[x]->subs[SUB_REAL].owner = NULL;
-                               pri->pvts[x]->owner = NULL;
-                               pri->pvts[x]->call = NULL;
-+                              pri->pvts[x]->dsp = NULL;
-                       }
-                       return principle;
-               }
-@@ -7771,7 +8439,9 @@
-               }
-               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;
- }
-@@ -7830,86 +8500,33 @@
- #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_verbose("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;
-+      ast_log(LOG_WARNING, "%d %s", span, s);
-+}
--      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_WARNING, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
--                      else
--                              ast_verbose("%s", s);
--              } else
--                      ast_verbose("PRI debug error: could not find pri associated it with debug message output\n");
--      } else
--              ast_log(LOG_WARNING, "%s", s);
--
--      ast_mutex_lock(&pridebugfdlock);
--
--      if (pridebugfd >= 0)
--              write(pridebugfd, s, strlen(s));
-+#ifdef ZAPATA_GSM
-+static void zt_gsm_message(char *s, int channel)
-+{
-+      ast_verbose("GSM %d: %s", channel, s);
-+}
--      ast_mutex_unlock(&pridebugfdlock);
-+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)) {
-+          return 0;
-+      }
-       do {
-               pri->resetpos++;
-       } while((pri->resetpos < pri->numchans) &&
-@@ -7992,6 +8609,32 @@
-       }
- }
-+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)
- {
-       struct zt_pri *pri = vpri;
-@@ -8172,15 +8815,44 @@
-                                       /* 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)
-@@ -8192,8 +8864,7 @@
-                                       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);
-@@ -8201,32 +8872,102 @@
-                               pri->dchanavail[which] |= DCHAN_UP;
-                       switch(e->e) {
-                       case PRI_EVENT_DCHAN_UP:
--                              if (option_verbose > 1) 
--                                      ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
--                              pri->dchanavail[which] |= DCHAN_UP;
--                              if (!pri->pri) pri_find_dchan(pri);
--
--                              /* Note presense of D-channel */
--                              time(&pri->lastreset);
--
--                              /* Restart in 5 seconds */
--                              if (pri->resetinterval > -1) {
--                                      pri->lastreset -= pri->resetinterval;
--                                      pri->lastreset += 5;
--                              }
--                              pri->resetting = 0;
--                              /* Take the channels from inalarm condition */
--                              for (i=0; i<pri->numchans; i++)
--                                      if (pri->pvts[i]) {
--                                              pri->pvts[i]->inalarm = 0;
--                                      }
-+                              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);
-+                                  pri->dchanavail[which] |= (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP);
-+                                  pri_find_dchan(pri);
-+  
-+                                  /* Note presense of D-channel */
-+                                  time(&pri->lastreset);
-+  
-+                                  pri->resetting = 0;
-+                                  /* Take the channels from inalarm condition */
-+                                  for (i=0; i<pri->numchans; i++)
-+                                      if (pri->pvts[i]) {
-+                                              pri->pvts[i]->inalarm = 0;
-+                                      }
-+                              } 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);
-+                                  }
-+                                  pri->dchanavail[which] |= (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP);
-+                                  pri_find_dchan(pri);
-+  
-+                                  /* Note presense of D-channel */
-+                                  time(&pri->lastreset);
-+  
-+                                  /* Restart in 5 seconds */
-+                                  pri->lastreset -= pri->resetinterval;
-+                                  pri->lastreset += 5;
-+                                  pri->resetting = 0;
-+                                  /* Take the channels from inalarm condition */
-+                                  for (i=0; i<pri->numchans; i++) {
-+                                      struct zt_pvt *p = pri->pvts[i];
-+                                      if (p) {
-+                                          p->inalarm = 0;
-+                                          /* hang up calls that are not bridged yet, dont touch bridged calls */
-+                                          if (p->call) {
-+                                              if (p->pri && p->pri->pri) {
-+                                                  if (p->owner) {
-+                                                      if (p->owner->_state != AST_STATE_UP) {
-+                                                          p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-+                                                          pri_destroycall(p->pri->pri, p->call);
-+                                                          p->call = NULL;
-+                                                      }
-+                                                  } else {
-+                                                      pri_destroycall(p->pri->pri, p->call);
-+                                                      p->call = NULL;
-+                                                  }
-+                                              }
-+                                          }
-+                                      }
-+                                  }
-+                              }
-                               break;
-                       case PRI_EVENT_DCHAN_DOWN:
--                              if (option_verbose > 1) 
--                                      ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
--                              pri->dchanavail[which] &= ~DCHAN_UP;
--                              pri_find_dchan(pri);
--                              if (!pri_is_up(pri)) {
-+                              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;
-+                                  /* Hangup active channels */
-+                                  for (i=0; i<pri->numchans; i++) {
-+                                      struct zt_pvt *p = pri->pvts[i];
-+                                      if (p) {
-+                      //              ast_log(LOG_NOTICE, "chan %d tei %d\n",i,p->tei);
-+                                          if (p->tei == e->gen.tei) {
-+                                              if (p->call) {
-+                                                      if (p->pri && p->pri->pri) {
-+                                                      //      pri_hangup(p->pri->pri, p->call, -1);
-+                                                              pri_destroycall(p->pri->pri, p->call);
-+                                                              p->tei = -1;
-+                                                              p->call = NULL;
-+                                                      } 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;
-+                                              p->tei = -1;
-+                                          }
-+                                      }
-+                                  } 
-+                              } else {
-+                                  if (pri->nodetype == BRI_CPE_PTMP) {
-+                                      if (option_verbose > 3) 
-+                                          ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
-+                                  } else {
-+                                      if (option_verbose > 1) 
-+                                          ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
-+                                  }
-+                                  pri->dchanavail[which] &= ~DCHAN_UP;
-+                                  pri_find_dchan(pri);
-+                                  if (!pri_is_up(pri)) {
-                                       pri->resetting = 0;
-                                       /* Hangup active channels and put them in alarm mode */
-                                       for (i=0; i<pri->numchans; i++) {
-@@ -8234,19 +8975,29 @@
-                                               if (p) {
-                                                       if (p->call) {
-                                                               if (p->pri && p->pri->pri) {
--                                                                      pri_hangup(p->pri->pri, p->call, -1);
--                                                                      pri_destroycall(p->pri->pri, p->call);
--                                                                      p->call = NULL;
-+                                                                  if (p->owner) {
-+                                                                      if (p->owner->_state != AST_STATE_UP) {
-+                                                              //          pri_hangup(p->pri->pri, p->call, -1);
-+                                                                          pri_destroycall(p->pri->pri, p->call);
-+                                                                          p->call = NULL;
-+                                                                          p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-+                                                                          p->inalarm = 1;
-+                                                                      }
-+                                                                  } else {
-+                                                                          pri_destroycall(p->pri->pri, p->call);
-+                                                                          p->call = NULL;
-+                                                                          p->inalarm = 1;
-+                                                                  }
-                                                               } else
-                                                                       ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
-                                                       }
-                                                       if (p->realcall) {
--                                                              pri_hangup_all(p->realcall, pri);
--                                                      } else if (p->owner)
--                                                              p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
--                                                      p->inalarm = 1;
-+                                                          pri_hangup_all(p->realcall, pri);
-+                                                          p->inalarm = 1;
-+                                                      } 
-                                               }
-                                       }
-+                                  }
-                               }
-                               break;
-                       case PRI_EVENT_RESTART:
-@@ -8281,8 +9032,8 @@
-                                                               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);
-@@ -8316,7 +9067,6 @@
-                                       }
-                               }
-                               break;
--                              
-                       case PRI_EVENT_INFO_RECEIVED:
-                               chanpos = pri_find_principle(pri, e->ring.channel);
-                               if (chanpos < 0) {
-@@ -8325,9 +9075,11 @@
-                               } 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;
-@@ -8339,6 +9091,14 @@
-                                                                       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);
-                                       }
-@@ -8346,39 +9106,58 @@
-                               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 == -1) {
-+                                          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", 
--                                                              PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
--                                                      break;
--                                              } else {
--                                                      ast_log(LOG_WARNING, "Ring requested on channel %d/%d already in use on span %d.  Hanging up owner.\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);
--                                                      if (pri->pvts[chanpos]->realcall) 
--                                                              pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
--                                                      else
--                                                              pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
--                                                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
--                                                      chanpos = -1;
-+                                              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 {
-+                                                      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));
-@@ -8392,13 +9171,14 @@
-                                                               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) {
-@@ -8423,29 +9203,78 @@
-                                       }
-                                       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:
-+                                              strncpy(pri->pvts[chanpos]->cid_name, pri->withheldcid, sizeof(pri->pvts[chanpos]->cid_name));
-+                                              break;
-+                                          case PRES_NUMBER_NOT_AVAILABLE:
-+                                              strncpy(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
--                                              pri->pvts[chanpos]->exten[0] = '\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 {
-+                                                  pri->pvts[chanpos]->exten[0] = '\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)) {
-@@ -8464,22 +9293,38 @@
-                                               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_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
--                                              else  {
-+                                              //      pri->pvts[chanpos]->ignoredtmf = 0;
-+                                                  } 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);
-+                                                      }
-                                               }
--                                              /* Get the use_callingpres state */
--                                              pri->pvts[chanpos]->callingpres = e->ring.callingpres;
--                                      
--                                              /* Start PBX */
-+
-+                                              /* overlapdial = yes  and the extension can be valid */
-+
-                                               if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
-                                                       /* Release the PRI lock while we create the channel */
-                                                       ast_mutex_unlock(&pri->lock);
-@@ -8487,14 +9332,31 @@
-                                                               /* 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]);
-                                                       }
-                                                       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);
-@@ -8514,8 +9376,8 @@
-                                                       ast_mutex_lock(&pri->lock);
-                                                       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, !ast_strlen_zero(pri->pvts[chanpos]->exten) ? 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, !ast_strlen_zero(pri->pvts[chanpos]->exten) ? 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", 
-@@ -8523,14 +9385,18 @@
-                                                               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;
-                                                               }
-                                                       }
-                                               } 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));
-+                                                      }
-                                                       ast_mutex_lock(&pri->lock);
-                                                       if (c) {
-                                                               char calledtonstr[10];
-@@ -8551,23 +9417,40 @@
-                                                               snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
-                                                               pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
-                                                               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_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';
-                                       }
-@@ -8575,7 +9458,7 @@
-                                               ast_mutex_unlock(&crv->lock);
-                                       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-                               } 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:
-                               chanpos = pri_find_principle(pri, e->ringing.channel);
-@@ -8593,7 +9476,7 @@
-                                       } 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
-@@ -8622,9 +9505,16 @@
-                               }
-                               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
-@@ -8671,6 +9561,12 @@
-                       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, };
-                                               
-@@ -8721,6 +9617,295 @@
-                                       }
-                               }
-                               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;
-+                              }
-+                              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;
-+                              }
-+                              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);
-+                              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) {
-@@ -8736,6 +9921,7 @@
-                                               chanpos = -1;
-                                       } 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.
-@@ -8765,11 +9951,16 @@
-                                                               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
-@@ -8818,23 +10009,32 @@
-                                                               }
-                                                       }
-                                                       if (option_verbose > 2) 
--                                                              ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup\n", 
--                                                                      pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
-+                                                              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;
-+                                                          pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
-+                                                          pri->pvts[chanpos]->resetting = 1;
-+                                                      }
-                                               }
--                                              if (e->hangup.aoc_units > -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 (!ast_strlen_zero(e->hangup.useruserinfo)) {
-@@ -8844,8 +10044,20 @@
-                                               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);
-+                                              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;
-@@ -8855,17 +10067,25 @@
-                       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);
-+                                      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);
-+                                      }
-                                       chanpos = -1;
-                               }
--                              if (chanpos > -1) {
-+                              /* dont hang up if we want to hear inband call progress */
-+                              if ((chanpos > -1) && ((pri->pvts[chanpos]->priindication_oob != 2) || (!e->hangup.inband_progress) || (!pri->pvts[chanpos]->outgoing))){
-                                       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;
-                                                       switch(e->hangup.cause) {
-                                                       case PRI_CAUSE_USER_BUSY:
-@@ -8884,20 +10104,87 @@
-                                                       }
-                                                       if (option_verbose > 2) 
-                                                               ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup request\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
--                                                      if (e->hangup.aoc_units > -1)
--                                                              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) {
-+                                                          // 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);
-+                                                      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)
--                                                              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;
-+                                                      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;
-+                                                      }
-+
-                                               }
- #ifdef SUPPORT_USERUSER
-@@ -8908,9 +10195,37 @@
-                                               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 {
-+                                                  // 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);
-+                                                  }
-+                                              }
-                                       }
-                               } 
-+                              if ((chanpos > -1) && (pri->pvts[chanpos]->owner) && (pri->pvts[chanpos]->priindication_oob == 2) && (e->hangup.inband_progress) && (pri->pvts[chanpos]->outgoing)) {
-+                                  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);
-+                              }
-                               break;
-                       case PRI_EVENT_HANGUP_ACK:
-                               chanpos = pri_find_principle(pri, e->hangup.channel);
-@@ -8924,6 +10239,7 @@
-                                       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) 
-@@ -8937,7 +10253,9 @@
- #endif
-                                               ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+                                          }
-                                       }
-+                                  }
-                               }
-                               break;
-                       case PRI_EVENT_CONFIG_ERR:
-@@ -9029,10 +10347,22 @@
-                                       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);
-+                                              } 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;
-@@ -9040,6 +10370,77 @@
-                                       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-                               }
-                               break;
-+                      case PRI_EVENT_FACILITY:
-+                                  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 (pri->pvts[chanpos]->owner) {
-+                                              snprintf(pri->pvts[chanpos]->owner->call_forward, sizeof(pri->pvts[chanpos]->owner->call_forward), "Local/%s@%s", e->facility.forwardnum, pri->pvts[chanpos]->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);
-                       }
-@@ -9101,7 +10502,7 @@
-                       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;
-@@ -9170,39 +10571,77 @@
- 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);
-               if (myfd < 0) {
--                      ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
--                      return RESULT_SUCCESS;
-+                  ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
-+                  return RESULT_SUCCESS;
-               }
--
--              ast_mutex_lock(&pridebugfdlock);
--
--              if (pridebugfd >= 0)
--                      close(pridebugfd);
--
--              pridebugfd = myfd;
--              ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
--              
--              ast_mutex_unlock(&pridebugfdlock);
--
--              ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
-+              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 = 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 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;
-@@ -9234,6 +10673,7 @@
-+
- static int handle_pri_no_debug(int fd, int argc, char *argv[])
- {
-       int span;
-@@ -9340,36 +10780,6 @@
-       return RESULT_SUCCESS;
- }
--static int handle_pri_show_debug(int fd, int argc, char *argv[])
--{
--      int x;
--      int span;
--      int count=0;
--      int debug=0;
--
--      for(span=0;span<NUM_SPANS;span++) {
--              if (pris[span].pri) {
--                      for(x=0;x<NUM_DCHANS;x++) {
--                              debug=0;
--                              if (pris[span].dchans[x]) {
--                                      debug = pri_get_debug(pris[span].dchans[x]);
--                                      ast_cli(fd, "Span %d: Debug: %s\tIntense: %s\n", span+1, (debug&PRI_DEBUG_Q931_STATE)? "Yes" : "No" ,(debug&PRI_DEBUG_Q921_RAW)? "Yes" : "No" );
--                                      count++;
--                              }
--                      }
--              }
--
--      }
--      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");
--      return RESULT_SUCCESS;
--}
--
- static char pri_debug_help[] = 
-       "Usage: pri debug span <span>\n"
-       "       Enables debugging on a given PRI span\n";
-@@ -9386,6 +10796,18 @@
-       "Usage: pri show span <span>\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", pri_debug_help, complete_span_4 },
-@@ -9393,19 +10815,282 @@
-         "Disables PRI debugging on a span", pri_no_debug_help, complete_span_5 },
-       { { "pri", "intense", "debug", "span", NULL }, handle_pri_really_debug,
-         "Enables REALLY INTENSE PRI debugging", pri_really_debug_help, complete_span_5 },
-+      { { "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", "show", "span", NULL }, handle_pri_show_span,
-         "Displays PRI Information", pri_show_span_help, complete_span_4 },
--      { { "pri", "show", "debug", NULL }, handle_pri_show_debug,
--        "Displays current PRI debug settings" },
-       { { "pri", "set", "debug", "file", NULL }, handle_pri_set_debug_file,
-         "Sends PRI debug output to the specified file" },
--      { { "pri", "unset", "debug", "file", NULL }, handle_pri_set_debug_file,
-+      { { "pri", "unset", "debug", "file", "span", NULL }, handle_pri_set_debug_file,
-         "Ends PRI debug output to file" },
- };
-+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(!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 /* ZAPATA_PRI */
-+#ifdef ZAPATA_GSM
-+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 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[] = {
-+      { { "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> <length> <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;
-+      int len;
-+      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;
-+      }
-+      len = atoi(argv[4]);
-+      if (len < 1) {
-+              ast_cli(fd, "Invalid length %s.  Should be a number.\n", argv[4]);
-+              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[5], len);
-+                  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 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 /* ZAPATA_GSM */
-+
-+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->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";
-+
-+
-+
- #ifdef ZAPATA_R2
- static int handle_r2_no_debug(int fd, int argc, char *argv[])
- {
-@@ -10017,6 +11702,14 @@
-                       pthread_cancel(pris[i].master);
-       }
-       ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0]));
-+      ast_unregister_application(zapCD_app);
-+      ast_unregister_application(zapInband_app);
-+#endif
-+#ifdef ZAPATA_GSM
-+      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
- #ifdef ZAPATA_R2
-       ast_cli_unregister_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
-@@ -10028,6 +11721,7 @@
-       ast_manager_unregister( "ZapDNDoff" );
-       ast_manager_unregister( "ZapDNDon" );
-       ast_manager_unregister("ZapShowChannels");
-+      ast_unregister_application(zapEC_app);
-       ast_channel_unregister(&zap_tech);
-       if (!ast_mutex_lock(&iflock)) {
-               /* Hangup all interfaces if they have an owner */
-@@ -10386,8 +12080,8 @@
-                       }
-               } else if (!strcasecmp(v->name, "echotraining")) {
-                       if (sscanf(v->value, "%d", &y) == 1) {
--                              if ((y < 10) || (y > 4000)) {
--                                      ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 2000 ms at line %d\n", v->lineno);                                   
-+                              if ((y < 10) || (y > 1000)) {
-+                                      ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 1000 ms at line %d\n", v->lineno);                                   
-                               } else {
-                                       echotraining = y;
-                               }
-@@ -10573,12 +12267,33 @@
-                                       cur_signalling = SIG_GR303FXSKS;
-                                       cur_radio = 0;
-                                       pritype = PRI_CPE;
-+                      } else if (!strcasecmp(v->value, "bri_net_ptmp")) {
-+                              cur_radio = 0;
-+                              cur_signalling = SIG_PRI;
-+                              pritype = BRI_NETWORK_PTMP;
-+                      } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) {
-+                              cur_signalling = SIG_PRI;
-+                              cur_radio = 0;
-+                              pritype = BRI_CPE_PTMP;
-+                      } else if (!strcasecmp(v->value, "bri_net")) {
-+                              cur_radio = 0;
-+                              cur_signalling = SIG_PRI;
-+                              pritype = BRI_NETWORK;
-+                      } else if (!strcasecmp(v->value, "bri_cpe")) {
-+                              cur_signalling = SIG_PRI;
-+                              cur_radio = 0;
-+                              pritype = BRI_CPE;
- #endif
- #ifdef ZAPATA_R2
-                               } else if (!strcasecmp(v->value, "r2")) {
-                                       cur_signalling = SIG_R2;
-                                       cur_radio = 0;
- #endif                        
-+#ifdef ZAPATA_GSM
-+                              } else if (!strcasecmp(v->value, "gsm")) {
-+                                      cur_signalling = SIG_GSM;
-+                                      cur_radio = 0;
-+#endif                                
-                               } else {
-                                       ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
-                               }
-@@ -10661,8 +12376,20 @@
-                                       priindication_oob = 1;
-                               else if (!strcasecmp(v->value, "inband"))
-                                       priindication_oob = 0;
-+                              else if (!strcasecmp(v->value, "passthrough"))
-+                                      priindication_oob = 2;
-+                              else
-+                                      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"))
-+                                      pritransfer = 0;
-+                              else if (!strcasecmp(v->value, "ect"))
-+                                      pritransfer = 1;
-+                              else if (!strcasecmp(v->value, "hangup"))
-+                                      pritransfer = 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 transfer value, should be 'no' , 'ect' or 'hangup' at line %d\n",
-                                               v->value, v->lineno);
-                       } else if (!strcasecmp(v->name, "priexclusive")) {
-                               cur_priexclusive = ast_true(v->value);
-@@ -10676,6 +12403,14 @@
-                               ast_copy_string(privateprefix, v->value, sizeof(privateprefix));
-                       } else if (!strcasecmp(v->name, "unknownprefix")) {
-                               ast_copy_string(unknownprefix, v->value, sizeof(unknownprefix));
-+                      } else if (!strcasecmp(v->name, "nocid")) {
-+                              ast_copy_string(nocid, v->value, sizeof(nocid) - 1);
-+                      } else if (!strcasecmp(v->name, "withheldcid")) {
-+                              ast_copy_string(withheldcid, v->value, sizeof(withheldcid) - 1);
-+                      } 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"))
-                                       resetinterval = -1;
-@@ -10692,6 +12427,8 @@
-                               ast_copy_string(idleext, v->value, sizeof(idleext));
-                       } else if (!strcasecmp(v->name, "idledial")) {
-                               ast_copy_string(idledial, v->value, sizeof(idledial));
-+                      } else if (!strcasecmp(v->name, "pritrustusercid")) {
-+                              usercid = ast_true(v->value);
-                       } else if (!strcasecmp(v->name, "overlapdial")) {
-                               overlapdial = ast_true(v->value);
-                       } else if (!strcasecmp(v->name, "pritimer")) {
-@@ -10877,6 +12614,7 @@
- #ifdef ZAPATA_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);
-@@ -10909,6 +12647,10 @@
-       pri_set_error(zt_pri_error);
-       pri_set_message(zt_pri_message);
- #endif
-+#ifdef ZAPATA_GSM
-+      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) {
-@@ -10926,6 +12668,12 @@
-       ast_cli_register_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
- #endif        
-       ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(zap_cli[0]));
-+#ifdef ZAPATA_GSM
-+      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" );
-@@ -10934,11 +12682,47 @@
-       ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
-       ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
-       ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
--
-+      ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc);
-+#ifdef ZAPATA_PRI
-+        ast_register_application(zapCD_app, app_zapCD, zapCD_synopsis, zapCD_tdesc);
-+        ast_register_application(zapInband_app, app_zapInband, zapInband_synopsis, zapInband_tdesc);
-+#endif
-       return res;
- }
-+#ifdef ZAPATA_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;
-+}
-+
-+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) {
-+      return zt_pri_sendtext(c, text);
-+    } else {
-+      return zt_tdd_sendtext(c, text);
-+    }
-+}
-+
-+static int zt_tdd_sendtext(struct ast_channel *c, const char *text)
-+#else
- static int zt_sendtext(struct ast_channel *c, const char *text)
-+#endif
- {
- #define       END_SILENCE_LEN 400
- #define       HEADER_MS 50
-@@ -10957,6 +12741,7 @@
-       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");
-diff -urN asterisk-1.2.10.orig/codecs/codec_ilbc.c asterisk-1.2.10/codecs/codec_ilbc.c
---- asterisk-1.2.10.orig/codecs/codec_ilbc.c   2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/codecs/codec_ilbc.c        2006-07-31 14:13:08.000000000 +0200
-@@ -49,7 +49,7 @@
- #include "slin_ilbc_ex.h"
- #include "ilbc_slin_ex.h"
--#define USE_ILBC_ENHANCER     0
-+#define USE_ILBC_ENHANCER     1
- #define ILBC_MS                       30
- /* #define ILBC_MS                    20 */
-diff -urN asterisk-1.2.10.orig/configs/capi.conf.sample asterisk-1.2.10/configs/capi.conf.sample
---- asterisk-1.2.10.orig/configs/capi.conf.sample      1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/configs/capi.conf.sample   2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,44 @@
-+;
-+; CAPI config
-+;
-+;
-+[general]
-+nationalprefix=0
-+internationalprefix=00
-+rxgain=0.8
-+txgain=0.8
-+
-+[interfaces]
-+
-+; mode: ptmp (point-to-multipoint) or ptp (point-to-point)
-+isdnmode=ptmp
-+; allow incoming calls to this list of MSNs, * == any
-+incomingmsn=*
-+; capi controller number
-+controller=1
-+; dialout group
-+group=1
-+; enable/disable software dtmf detection, recommended for AVM cards
-+softdtmf=1
-+; accountcode to use in CDRs
-+accountcode=
-+; context for incoming calls
-+context=capi-in
-+; _VERY_PRIMITIVE_ echo suppression
-+;echosquelch=1
-+; EICON DIVA SERVER echo cancelation
-+;echocancel=yes
-+;echotail=64
-+; call group
-+;callgroup=1
-+; deflect incoming calls to 12345678 if all B channels are busy
-+;deflect=12345678
-+; number of concurrent calls on this controller (2 makes sense for single BRI)
-+devices => 2
-+
-+
-+;PointToPoint (55512-0)
-+;isdnmode=ptp
-+;msn=55512
-+;controller=2
-+;devices => 30
-diff -urN asterisk-1.2.10.orig/configs/modules.conf.sample asterisk-1.2.10/configs/modules.conf.sample
---- asterisk-1.2.10.orig/configs/modules.conf.sample   2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/configs/modules.conf.sample        2006-07-31 14:13:08.000000000 +0200
-@@ -51,3 +51,4 @@
- ; exported to modules loaded after them.
- ;
- [global]
-+chan_capi.so=yes
-diff -urN asterisk-1.2.10.orig/configs/watchdog.conf.sample asterisk-1.2.10/configs/watchdog.conf.sample
---- asterisk-1.2.10.orig/configs/watchdog.conf.sample  1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/configs/watchdog.conf.sample       2006-07-31 14:13:08.000000000 +0200
-@@ -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
-+
-diff -urN asterisk-1.2.10.orig/configs/zapata.conf.sample asterisk-1.2.10/configs/zapata.conf.sample
---- asterisk-1.2.10.orig/configs/zapata.conf.sample    2006-04-28 18:40:32.000000000 +0200
-+++ asterisk-1.2.10/configs/zapata.conf.sample 2006-07-31 14:13:08.000000000 +0200
-@@ -121,9 +121,20 @@
- ; 
- ; 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
-diff -urN asterisk-1.2.10.orig/db.c asterisk-1.2.10/db.c
---- asterisk-1.2.10.orig/db.c  2006-01-09 19:09:53.000000000 +0100
-+++ asterisk-1.2.10/db.c       2006-07-31 14:13:08.000000000 +0200
-@@ -516,11 +516,18 @@
- struct ast_cli_entry cli_database_deltree =
- { { "database", "deltree", NULL }, database_deltree, "Removes database keytree/values", database_deltree_usage };
-+static char mandescr_dbput[] = 
-+"Description: Put a value into astdb\n"
-+"Variables: \n"
-+"     Family: ...\n"
-+"     Key: ...\n"
-+"     Value: ...\n";
-+
- static int manager_dbput(struct mansession *s, struct message *m)
- {
-       char *family = astman_get_header(m, "Family");
-       char *key = astman_get_header(m, "Key");
--      char *val = astman_get_header(m, "Val");
-+      char *val = astman_get_header(m, "Value");
-       int res;
-       if (!strlen(family)) {
-@@ -545,6 +552,12 @@
-       return 0;
- }
-+static char mandescr_dbget[] = 
-+"Description: Get a value from astdb\n"
-+"Variables: \n"
-+"     Family: ...\n"
-+"     Key: ...\n";
-+
- static int manager_dbget(struct mansession *s, struct message *m)
- {
-       char *id = astman_get_header(m,"ActionID");
-@@ -574,7 +587,7 @@
-               ast_cli(s->fd, "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,6 +595,39 @@
-       return 0;
- }
-+static char mandescr_dbdel[] = 
-+"Description: remove value from astdb\n"
-+"Variables: \n"
-+"     Family: ...\n"
-+"     Key: ...\n";
-+
-+static int manager_dbdel(struct mansession *s, struct message *m)
-+{
-+        char *family = astman_get_header(m, "Family");
-+        char *key = astman_get_header(m, "Key");
-+      char *id = astman_get_header(m,"ActionID");
-+
-+      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)) {
-+          ast_cli(s->fd, "Response: Failed\r\n");
-+      } else {
-+          ast_cli(s->fd, "Response: Success\r\n");
-+      }
-+      if (id && !ast_strlen_zero(id))
-+              ast_cli(s->fd, "ActionID: %s\r\n",id);
-+      ast_cli(s->fd, "\r\n");
-+
-+      return 0;
-+}
-+
- int astdb_init(void)
- {
-       dbinit();
-@@ -591,7 +637,8 @@
-       ast_cli_register(&cli_database_put);
-       ast_cli_register(&cli_database_del);
-       ast_cli_register(&cli_database_deltree);
--      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, mandescr_dbget);
-+      ast_manager_register("DBput", EVENT_FLAG_SYSTEM, manager_dbput, mandescr_dbput);
-+      ast_manager_register("DBdel", EVENT_FLAG_SYSTEM, manager_dbdel, mandescr_dbdel);
-       return 0;
- }
-diff -urN asterisk-1.2.10.orig/devicestate.c asterisk-1.2.10/devicestate.c
---- asterisk-1.2.10.orig/devicestate.c 2006-02-10 21:38:59.000000000 +0100
-+++ asterisk-1.2.10/devicestate.c      2006-07-31 14:13:08.000000000 +0200
-@@ -62,6 +62,8 @@
- struct state_change {
-       AST_LIST_ENTRY(state_change) list;
-+      char cid_num[AST_MAX_EXTENSION];
-+      char cid_name[AST_MAX_EXTENSION];
-       char device[1];
- };
-@@ -177,7 +179,7 @@
- }
- /*--- do_state_change: Notify callback watchers of change, and notify PBX core for hint updates */
--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;
-@@ -188,13 +190,13 @@
-       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)
-+static int __ast_device_state_changed_literal(char *buf, char *cid_num, char *cid_name)
- {
-       char *device, *tmp;
-       struct state_change *change = NULL;
-@@ -209,10 +211,16 @@
-       if (!change) {
-               /* 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)
-@@ -224,11 +232,17 @@
-       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);
-+      if (cid_num)
-+          buf2 = ast_strdupa(cid_num);
-+      if (cid_name)
-+          buf3 = ast_strdupa(cid_name);
-+      return __ast_device_state_changed_literal(buf, buf2, buf3);
- }
- /*--- ast_device_state_changed: Accept change notification, add it to change queue */
-@@ -240,7 +254,7 @@
-       va_start(ap, fmt);
-       vsnprintf(buf, sizeof(buf), fmt, ap);
-       va_end(ap);
--      return __ast_device_state_changed_literal(buf);
-+      return __ast_device_state_changed_literal(buf, NULL, NULL);
- }
- /*--- do_devstate_changes: Go through the dev state change queue and update changes in the dev state thread */
-@@ -255,7 +269,7 @@
-               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 {
-diff -urN asterisk-1.2.10.orig/doc/README.asterisk.conf asterisk-1.2.10/doc/README.asterisk.conf
---- asterisk-1.2.10.orig/doc/README.asterisk.conf      2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/doc/README.asterisk.conf   2006-07-31 14:13:08.000000000 +0200
-@@ -62,6 +62,7 @@
- maxcalls = 255                                        ; The maximum number of concurrent calls you want to allow 
- execincludes = yes | no                       ; Allow #exec entries in configuration files
- dontwarn = yes | no                           ; Don't over-inform the Asterisk sysadm, he's a guru
-+uniquename = asterisk                         ; host name part to be included in the uniqueid
- [files]
- ; Changing the following lines may compromise your security
-diff -urN asterisk-1.2.10.orig/editline/cygdef.h asterisk-1.2.10/editline/cygdef.h
---- asterisk-1.2.10.orig/editline/cygdef.h     1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/editline/cygdef.h  2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,11 @@
-+/* cygdef.h. Generated automatically by configure. */ 
-+#ifndef _CYGDEF_H_
-+#define _CYGDEF_H_ 1
-+#include <sys/ioctl.h>
-+#define __linux__ 1
-+ 
-+
-+typedef void (*sig_t)(int);
-+ 
-+
-+#endif /* _CYGDEF_H_ */
-diff -urN asterisk-1.2.10.orig/include/asterisk/agi.h asterisk-1.2.10/include/asterisk/agi.h
---- asterisk-1.2.10.orig/include/asterisk/agi.h        2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/include/asterisk/agi.h     2006-07-31 14:13:08.000000000 +0200
-@@ -29,7 +29,8 @@
- typedef struct agi_state {
-       int fd;         /* FD for general output */
--      int audio;      /* FD for audio output */
-+      int audio_out;  /* FD for audio output */
-+      int audio_in;   /* FD for audio output */
-       int ctrl;       /* FD for input control */
- } AGI;
-diff -urN asterisk-1.2.10.orig/include/asterisk/chan_capi.h asterisk-1.2.10/include/asterisk/chan_capi.h
---- asterisk-1.2.10.orig/include/asterisk/chan_capi.h  1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/include/asterisk/chan_capi.h       2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,276 @@
-+/*
-+ * (CAPI*)
-+ *
-+ * An implementation of Common ISDN API 2.0 for Asterisk
-+ *
-+ * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
-+ *
-+ * This program is free software and may be modified and 
-+ * distributed under the terms of the GNU Public License.
-+ */
-+ 
-+#ifndef _ASTERISK_CAPI_H
-+#define _ASTERISK_CAPI_H
-+
-+#define AST_CAPI_MAX_CONTROLLERS 16
-+#define AST_CAPI_MAX_DEVICES 30
-+#define AST_CAPI_MAX_BUF 160
-+
-+#define AST_CAPI_MAX_B3_BLOCKS 7
-+
-+/* was : 130 bytes Alaw = 16.25 ms audio not suitable for VoIP */
-+/* now : 160 bytes Alaw = 20 ms audio */
-+/* you can tune this to your need. higher value == more latency */
-+#define AST_CAPI_MAX_B3_BLOCK_SIZE 160
-+
-+#define AST_CAPI_BCHANS 120
-+#define ALL_SERVICES 0x1FFF03FF
-+
-+/* duration in ms for sending and detecting dtmfs */
-+#define AST_CAPI_DTMF_DURATION        0x40
-+
-+#define AST_CAPI_NATIONAL_PREF                "0"
-+#define AST_CAPI_INTERNAT_PREF                "00"
-+
-+#ifdef CAPI_ES
-+#define ECHO_TX_COUNT 5                       // 5 x 20ms = 100ms
-+#define ECHO_EFFECTIVE_TX_COUNT 3     // 2 x 20ms = 40ms == 40-100ms  ... ignore first 40ms
-+#define ECHO_TXRX_RATIO 2.3           // if( rx < (txavg/ECHO_TXRX_RATIO) ) rx=0;
-+#endif
-+
-+/*
-+ * state combination for a normal incoming call:
-+ * DIS -> ALERT -> CON -> BCON -> CON -> DIS
-+ *
-+ * outgoing call:
-+ * DIS -> CONP -> BCONNECTED -> CON -> DIS
-+ */
-+
-+#define CAPI_STATE_ALERTING 1
-+#define CAPI_STATE_CONNECTED 2
-+#define CAPI_STATE_BCONNECTED 3
-+
-+#define CAPI_STATE_DISCONNECTING 4
-+#define CAPI_STATE_DISCONNECTED 5
-+#define CAPI_STATE_REMOTE_HANGUP 6
-+
-+#define CAPI_STATE_CONNECTPENDING 7
-+#define CAPI_STATE_ONHOLD 8
-+#define CAPI_STATE_NETWORKHANGUP 9
-+#define CAPI_STATE_ANSWERING 10
-+#define CAPI_STATE_PUTTINGONHOLD 11
-+#define CAPI_STATE_RETRIEVING 12
-+
-+#define CAPI_STATE_DID 13
-+
-+#define AST_CAPI_B3_DONT 0
-+#define AST_CAPI_B3_ALWAYS 1
-+#define AST_CAPI_B3_ON_SUCCESS 2
-+
-+#ifdef CAPI_GAIN
-+struct ast_capi_gains {
-+      unsigned char   txgains[256];
-+      unsigned char   rxgains[256];
-+};
-+#endif
-+
-+#define PRES_ALLOWED_USER_NUMBER_NOT_SCREENED   0x00
-+#define PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN  0x01
-+#define PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN  0x02
-+#define PRES_ALLOWED_NETWORK_NUMBER                             0x03
-+#define PRES_PROHIB_USER_NUMBER_NOT_SCREENED    0x20
-+#define PRES_PROHIB_USER_NUMBER_PASSED_SCREEN   0x21
-+#define PRES_PROHIB_USER_NUMBER_FAILED_SCREEN   0x22
-+#define PRES_PROHIB_NETWORK_NUMBER                              0x23
-+#define PRES_NUMBER_NOT_AVAILABLE                               0x43
-+
-+
-+//! Private data for a capi device
-+struct ast_capi_pvt {
-+      ast_mutex_t lock;
-+      int fd;
-+
-+      /*! Channel we belong to, possibly NULL */
-+      struct ast_channel *owner;              
-+      /*! Frame */
-+      struct ast_frame fr;                    
-+      
-+      char offset[AST_FRIENDLY_OFFSET];
-+      
-+      // capi message number
-+      _cword MessageNumber;   
-+      int NCCI;
-+      int PLCI;
-+      /* on which controller we do live */
-+      int controller;
-+      
-+      /* we could live on those */
-+      unsigned long controllers;
-+
-+      int datahandle;
-+
-+      short buf[AST_CAPI_MAX_BUF];
-+      int buflen;
-+      /*! Immediate, or wait for an answer */
-+      int mode;                                               
-+      /*! State of modem in miniature */
-+      int state;                                      
-+      /*! Digits to strip on outgoing numbers */
-+      int stripmsd;                                   
-+      /*! ringer timeout */
-+      int ringt;                              
-+      /*! actual time of last ring */
-+      time_t lastring;                        
-+      /*! dtmf receive state/data */
-+      char dtmfrx;                            
-+      
-+      char context[AST_MAX_EXTENSION];
-+      /*! Multiple Subscriber Number we listen to (, seperated list) */
-+      char incomingmsn[AST_MAX_EXTENSION];    
-+      /*! Prefix to Build CID */
-+      char prefix[AST_MAX_EXTENSION]; 
-+      /*! Caller ID if available */
-+      char cid[AST_MAX_EXTENSION];    
-+      /*! Dialed Number if available */
-+      char dnid[AST_MAX_EXTENSION];   
-+
-+      char accountcode[20];   
-+
-+      unsigned int callgroup;
-+      unsigned int group;
-+      
-+      /*! default language */
-+      char language[MAX_LANGUAGE];    
-+      /*! Static response buffer */
-+      char response[256];                             
-+
-+      int calledPartyIsISDN;
-+      // this is an outgoing channel
-+      int outgoing;
-+      // use CLIR
-+      int CLIR;
-+      // are we doing early B3 connect on this interface?
-+      int earlyB3;
-+      // should we do early B3 on this interface?
-+      int doB3;
-+      // store plci here for the call that is onhold
-+      int onholdPLCI;
-+      // do software dtmf detection
-+      int doDTMF;
-+      // CAPI echo cancellation
-+      int doEC;
-+      int ecOption;
-+      int ecTail;
-+      // isdnmode ptp or ptm 
-+      int isdnmode;
-+#ifdef CAPI_DEFLECT_ON_CIRCUITBUSY
-+      // deflect on circuitbusy
-+      char deflect2[AST_MAX_EXTENSION];
-+#endif
-+      
-+    // not all codecs supply frames in nice 320 byte chunks
-+    struct ast_smoother *smoother;
-+    // ok, we stop to be nice and give them the lowest possible latency 130 samples * 2 = 260 bytes */
-+#ifdef CAPI_SYNC
-+      int B3in;
-+      ast_mutex_t lockB3in;
-+#endif
-+
-+      // do ECHO SURPRESSION
-+      int doES;
-+#ifdef CAPI_ES
-+      short txavg[ECHO_TX_COUNT];
-+      float rxmin;
-+      float txmin;
-+#endif    
-+#ifdef CAPI_GAIN
-+      struct ast_capi_gains g;
-+#endif    
-+      float txgain;
-+      float rxgain;
-+      struct ast_dsp *vad;
-+      
-+      
-+      struct capi_pipe *mypipe;
-+      /*! Next channel in list */
-+      struct ast_capi_pvt *next;                      
-+};
-+
-+
-+struct ast_capi_profile {
-+    unsigned short ncontrollers;
-+    unsigned short nbchannels;
-+    unsigned char globaloptions;
-+    unsigned char globaloptions2;
-+    unsigned char globaloptions3;
-+    unsigned char globaloptions4;
-+    unsigned int b1protocols;
-+    unsigned int b2protocols;
-+    unsigned int b3protocols;
-+    unsigned int reserved3[6];
-+    unsigned int manufacturer[5];
-+};
-+
-+struct capi_pipe {
-+    // lock
-+    ast_mutex_t lock;
-+
-+    // fd for writing to the channel
-+    int fd;
-+
-+    // PLCI and NCCI of the B3 CON
-+    int PLCI;
-+    int NCCI;
-+    // pointer to the interface
-+    struct ast_capi_pvt *i;
-+    // pointer to the channel
-+    struct ast_channel *c;
-+    // next pipe
-+    struct capi_pipe *next;
-+};
-+
-+struct ast_capi_controller {
-+    // which controller is this?
-+    int controller;
-+    // how many bchans?
-+    int nbchannels;
-+    // free bchans
-+    int nfreebchannels;
-+    // DID
-+    int isdnmode;
-+    // features:
-+    int dtmf;
-+    int echocancel;
-+    int sservices;    // supplementray services
-+    // supported sservices:
-+    int holdretrieve;
-+    int terminalportability;
-+    int ECT;
-+    int threePTY;
-+    int CF;
-+    int CD;
-+    int MCID;
-+    int CCBS;
-+    int MWI;
-+    int CCNR;
-+    int CONF;
-+};
-+
-+
-+// ETSI 300 102-1 information element identifiers
-+#define CAPI_ETSI_IE_CAUSE 0x08;
-+#define CAPI_ETSI_IE_PROGRESS_INDICATOR 0x1e;
-+#define CAPI_ETSI_IE_CALLED_PARTY_NUMBER 0x70;
-+
-+// ETIS 300 102-1 message types
-+#define CAPI_ETSI_ALERTING 0x01;
-+#define CAPI_ETSI_SETUP_ACKKNOWLEDGE 0x0d;
-+#define CAPI_ETSI_DISCONNECT 0x45;
-+
-+// ETSI 300 102-1 Numbering Plans
-+#define CAPI_ETSI_NPLAN_NATIONAL      0x20
-+#define CAPI_ETSI_NPLAN_INTERNAT      0x10
-+
-+#endif
-diff -urN asterisk-1.2.10.orig/include/asterisk/chan_capi_app.h asterisk-1.2.10/include/asterisk/chan_capi_app.h
---- asterisk-1.2.10.orig/include/asterisk/chan_capi_app.h      1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/include/asterisk/chan_capi_app.h   2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,30 @@
-+/*
-+ * (CAPI*)
-+ *
-+ * An implementation of Common ISDN API 2.0 for Asterisk
-+ *
-+ * include file for helper applications
-+ *
-+ * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
-+ *
-+ * This program is free software and may be modified and 
-+ * distributed under the terms of the GNU Public License.
-+ */
-+
-+#ifndef _ASTERISK_CAPI_IF_H
-+#define _ASTERISK_CAPI_IF_H
-+ 
-+// exported symbols from chan_capi
-+
-+// important things we need
-+extern unsigned ast_capi_ApplID;
-+extern unsigned ast_capi_MessageNumber;
-+extern int capidebug;
-+
-+extern int capi_call(struct ast_channel *c, char *idest, int timeout);
-+extern int capi_detect_dtmf(struct ast_channel *c, int flag);
-+extern MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG);
-+
-+#endif
-diff -urN asterisk-1.2.10.orig/include/asterisk/channel.h asterisk-1.2.10/include/asterisk/channel.h
---- asterisk-1.2.10.orig/include/asterisk/channel.h    2006-06-01 22:27:50.000000000 +0200
-+++ asterisk-1.2.10/include/asterisk/channel.h 2006-07-31 14:13:08.000000000 +0200
-@@ -86,6 +86,9 @@
- #ifndef _ASTERISK_CHANNEL_H
- #define _ASTERISK_CHANNEL_H
-+/* Max length of the uniqueid */
-+#define AST_MAX_UNIQUEID 64
-+
- #include <unistd.h>
- #include <setjmp.h>
- #ifdef POLLCOMPAT 
-@@ -381,7 +384,7 @@
-       unsigned int fout;
-       /* Unique Channel Identifier */
--      char uniqueid[32];
-+      char uniqueid[AST_MAX_UNIQUEID];
-       /* Why is the channel hanged up */
-       int hangupcause;
-@@ -398,6 +401,12 @@
-       /*! ISDN Transfer Capbility - AST_FLAG_DIGITAL is not enough */
-       unsigned short transfercapability;
-+      /*! ISDN Low Layer Compatibility */
-+      char lowlayercompat[16];
-+
-+      /*! ISDN High Layer Compatibility */
-+      char highlayercompat[4];
-+
-       struct ast_frame *readq;
-       int alertpipe[2];
-       /*! Write translation path */
-@@ -534,6 +543,11 @@
- #define AST_STATE_MUTE                (1 << 16)       
- /*! @} */
-+extern ast_mutex_t uniquelock;                        
-+
-+/*! \brief Change the state of a channel and the callerid of the calling channel*/
-+int ast_setstate_and_cid(struct ast_channel *chan, int state, char *cid_num, char *cid_name);
-+
- /*! \brief Change the state of a channel */
- int ast_setstate(struct ast_channel *chan, int state);
-@@ -570,7 +584,7 @@
-  * by the low level module
-  * \return Returns an ast_channel on success, NULL on failure.
-  */
--struct ast_channel *ast_request(const char *type, int format, void *data, int *status);
-+struct ast_channel *ast_request(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 
-@@ -585,9 +599,9 @@
-  * \return Returns an ast_channel on success or no answer, NULL on failure.  Check the value of chan->_state
-  * to know if the call was answered or not.
-  */
--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(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(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 Register a channel technology (a new channel driver)
-  * Called by a channel module to register the kind of channels it supports.
-@@ -840,6 +854,10 @@
- /*--- ast_get_channel_by_exten_locked: 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);
-+/*! Get channel by uniqueid (locks channel) */
-+struct ast_channel *ast_get_channel_by_uniqueid_locked(const char *uniqueid);
-+ 
-+
- /*! Waits for a digit */
- /*! 
-  * \param c channel to wait for a digit on
-@@ -910,6 +928,9 @@
-    p->owner pointer) that is affected by the change.  The physical layer of the original
-    channel is hung up.  */
- int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone);
-+int ast_channel_masquerade_locked(struct ast_channel *original, struct ast_channel *clone);
-+ 
-+char *ast_alloc_uniqueid(void);
- /*! Gives the string form of a given cause code */
- /*! 
-diff -urN asterisk-1.2.10.orig/include/asterisk/devicestate.h asterisk-1.2.10/include/asterisk/devicestate.h
---- asterisk-1.2.10.orig/include/asterisk/devicestate.h        2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/include/asterisk/devicestate.h     2006-07-31 14:13:08.000000000 +0200
-@@ -42,7 +42,7 @@
- /*! Device is ringing */
- #define AST_DEVICE_RINGING    6
--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 Convert device state to text string for output 
-  * \param devstate Current device state 
-@@ -84,7 +84,7 @@
-  * 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
-diff -urN asterisk-1.2.10.orig/include/asterisk/features.h asterisk-1.2.10/include/asterisk/features.h
---- asterisk-1.2.10.orig/include/asterisk/features.h   2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/include/asterisk/features.h        2006-07-31 14:13:08.000000000 +0200
-@@ -45,6 +45,8 @@
- };
-+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
-@@ -68,11 +70,19 @@
- */
- extern 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 */
- extern char *ast_parking_ext(void);
-+extern char *ast_parking_con(void);
-+
- /*! \brief Determine system call pickup extension */
- extern char *ast_pickup_ext(void);
-@@ -92,4 +102,12 @@
-     \param feature the ast_call_feature object which was registered before*/
- extern void ast_unregister_feature(struct ast_call_feature *feature);
-+/*! \brief find a  feature by name
-+    \param name of the feature to be returned */
-+extern struct ast_call_feature *ast_find_feature(char *name);
-+
-+/*! \brief find a builtin feature by name
-+    \param name of the feature to be returned */
-+extern struct ast_call_feature *ast_find_builtin_feature(char *name);
-+
- #endif /* _AST_FEATURES_H */
-diff -urN asterisk-1.2.10.orig/include/asterisk/manager.h asterisk-1.2.10/include/asterisk/manager.h
---- asterisk-1.2.10.orig/include/asterisk/manager.h    2006-02-11 19:15:00.000000000 +0100
-+++ asterisk-1.2.10/include/asterisk/manager.h 2006-07-31 14:13:08.000000000 +0200
-@@ -54,6 +54,7 @@
- #define EVENT_FLAG_COMMAND            (1 << 4) /* Ability to read/set commands */
- #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_EXTENSIONSTATUS    (1 << 7) /* ExtensionStatus events */
- /* Export manager structures */
- #define AST_MAX_MANHEADERS 80
-diff -urN asterisk-1.2.10.orig/include/asterisk/monitor.h asterisk-1.2.10/include/asterisk/monitor.h
---- asterisk-1.2.10.orig/include/asterisk/monitor.h    2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/include/asterisk/monitor.h 2006-07-31 14:13:08.000000000 +0200
-@@ -35,6 +35,8 @@
-       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;
-       int (*stop)(struct ast_channel *chan, int need_lock);
-@@ -42,7 +44,7 @@
- /* 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);
-diff -urN asterisk-1.2.10.orig/include/asterisk/pbx.h asterisk-1.2.10/include/asterisk/pbx.h
---- asterisk-1.2.10.orig/include/asterisk/pbx.h        2006-03-29 21:11:18.000000000 +0200
-+++ asterisk-1.2.10/include/asterisk/pbx.h     2006-07-31 14:13:08.000000000 +0200
-@@ -57,7 +57,7 @@
-       AST_EXTENSION_BUSY = 1 << 1,
-       /*! All devices UNAVAILABLE/UNREGISTERED */
-       AST_EXTENSION_UNAVAILABLE = 1 << 2,
--      /*! All devices RINGING */
-+      /*! One or more devices RINGING */
-       AST_EXTENSION_RINGING = 1 << 3,
- };
-@@ -80,7 +80,7 @@
- struct ast_ignorepat;
- struct ast_sw;
--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);
- /*! Data structure associated with a custom function */
- struct ast_custom_function {
-@@ -156,6 +156,8 @@
-  */
- extern struct ast_app *pbx_findapp(const char *app);
-+void *ast_pbx_run_app(void *data);
-+
- /*! executes an application */
- /*!
-  * \param c channel to execute on
-@@ -563,11 +565,11 @@
- /* Synchronously or asynchronously make an outbound call and send it to a
-    particular extension */
--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);
-+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, 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);
-+int ast_pbx_outgoing_app(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);
- /* Evaluate a condition for non-falseness and return a boolean */
- int pbx_checkcondition(char *condition);
-@@ -659,7 +661,7 @@
-  */
- void ast_func_write(struct ast_channel *chan, const char *in, 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)
- }
-diff -urN asterisk-1.2.10.orig/include/asterisk/xlaw.h asterisk-1.2.10/include/asterisk/xlaw.h
---- asterisk-1.2.10.orig/include/asterisk/xlaw.h       1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/include/asterisk/xlaw.h    2006-07-31 14:13:08.000000000 +0200
-@@ -0,0 +1,1665 @@
-+#ifndef _ASTERISK_XLAW_H
-+#define _ASTERISK_XLAW_H
-+
-+#ifdef CAPI_ULAW
-+#define capiXLAW2INT(x) capiULAW2INT[x]
-+#define capiINT2XLAW(x) capiINT2ULAW[((unsigned short)x) >> 2]
-+#else
-+#define capiXLAW2INT(x) capiALAW2INT[x]
-+#define capiINT2XLAW(x) capiINT2ALAW[(x>>4)+4096]
-+#endif
-+
-+static unsigned char reversebits[256] =
-+{
-+0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-+0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-+0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-+0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-+0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-+0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-+0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-+0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-+0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-+0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-+0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-+0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-+0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-+0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-+0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-+0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-+0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-+0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-+0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-+0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-+0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-+0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-+0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-+0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-+0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-+0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-+0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-+0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-+0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-+0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-+0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-+0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
-+};
-+
-+#ifdef CAPI_ULAW
-+static short capiULAW2INT[] =
-+{
-+0x8284, 0x7d7c, 0xf8a4, 0x075c, 0xe104, 0x1efc, 0xfe8c, 0x0174,
-+0xc184, 0x3e7c, 0xfc94, 0x036c, 0xf0c4, 0x0f3c, 0xff88, 0x0078,
-+0xa284, 0x5d7c, 0xfaa4, 0x055c, 0xe904, 0x16fc, 0xff0c, 0x00f4,
-+0xd184, 0x2e7c, 0xfd94, 0x026c, 0xf4c4, 0x0b3c, 0xffc8, 0x0038,
-+0x9284, 0x6d7c, 0xf9a4, 0x065c, 0xe504, 0x1afc, 0xfecc, 0x0134,
-+0xc984, 0x367c, 0xfd14, 0x02ec, 0xf2c4, 0x0d3c, 0xffa8, 0x0058,
-+0xb284, 0x4d7c, 0xfba4, 0x045c, 0xed04, 0x12fc, 0xff4c, 0x00b4,
-+0xd984, 0x267c, 0xfe14, 0x01ec, 0xf6c4, 0x093c, 0xffe8, 0x0018,
-+0x8a84, 0x757c, 0xf924, 0x06dc, 0xe304, 0x1cfc, 0xfeac, 0x0154,
-+0xc584, 0x3a7c, 0xfcd4, 0x032c, 0xf1c4, 0x0e3c, 0xff98, 0x0068,
-+0xaa84, 0x557c, 0xfb24, 0x04dc, 0xeb04, 0x14fc, 0xff2c, 0x00d4,
-+0xd584, 0x2a7c, 0xfdd4, 0x022c, 0xf5c4, 0x0a3c, 0xffd8, 0x0028,
-+0x9a84, 0x657c, 0xfa24, 0x05dc, 0xe704, 0x18fc, 0xfeec, 0x0114,
-+0xcd84, 0x327c, 0xfd54, 0x02ac, 0xf3c4, 0x0c3c, 0xffb8, 0x0048,
-+0xba84, 0x457c, 0xfc24, 0x03dc, 0xef04, 0x10fc, 0xff6c, 0x0094,
-+0xdd84, 0x227c, 0xfe54, 0x01ac, 0xf7c4, 0x083c, 0xfff8, 0x0008,
-+0x8684, 0x797c, 0xf8e4, 0x071c, 0xe204, 0x1dfc, 0xfe9c, 0x0164,
-+0xc384, 0x3c7c, 0xfcb4, 0x034c, 0xf144, 0x0ebc, 0xff90, 0x0070,
-+0xa684, 0x597c, 0xfae4, 0x051c, 0xea04, 0x15fc, 0xff1c, 0x00e4,
-+0xd384, 0x2c7c, 0xfdb4, 0x024c, 0xf544, 0x0abc, 0xffd0, 0x0030,
-+0x9684, 0x697c, 0xf9e4, 0x061c, 0xe604, 0x19fc, 0xfedc, 0x0124,
-+0xcb84, 0x347c, 0xfd34, 0x02cc, 0xf344, 0x0cbc, 0xffb0, 0x0050,
-+0xb684, 0x497c, 0xfbe4, 0x041c, 0xee04, 0x11fc, 0xff5c, 0x00a4,
-+0xdb84, 0x247c, 0xfe34, 0x01cc, 0xf744, 0x08bc, 0xfff0, 0x0010,
-+0x8e84, 0x717c, 0xf964, 0x069c, 0xe404, 0x1bfc, 0xfebc, 0x0144,
-+0xc784, 0x387c, 0xfcf4, 0x030c, 0xf244, 0x0dbc, 0xffa0, 0x0060,
-+0xae84, 0x517c, 0xfb64, 0x049c, 0xec04, 0x13fc, 0xff3c, 0x00c4,
-+0xd784, 0x287c, 0xfdf4, 0x020c, 0xf644, 0x09bc, 0xffe0, 0x0020,
-+0x9e84, 0x617c, 0xfa64, 0x059c, 0xe804, 0x17fc, 0xfefc, 0x0104,
-+0xcf84, 0x307c, 0xfd74, 0x028c, 0xf444, 0x0bbc, 0xffc0, 0x0040,
-+0xbe84, 0x417c, 0xfc64, 0x039c, 0xf004, 0x0ffc, 0xff7c, 0x0084,
-+0xdf84, 0x207c, 0xfe74, 0x018c, 0xf844, 0x07bc, 0x0000, 0x0000
-+};
-+
-+const unsigned char capiINT2ULAW[16384] = {
-+255,127,127,191,191,63,63,223,223,95,95,159,159,31,31,239,
-+239,111,111,175,175,47,47,207,207,79,79,143,143,15,15,247,
-+247,247,247,119,119,119,119,183,183,183,183,55,55,55,55,215,
-+215,215,215,87,87,87,87,151,151,151,151,23,23,23,23,231,
-+231,231,231,103,103,103,103,167,167,167,167,39,39,39,39,199,
-+199,199,199,71,71,71,71,135,135,135,135,7,7,7,7,251,
-+251,251,251,251,251,251,251,123,123,123,123,123,123,123,123,187,
-+187,187,187,187,187,187,187,59,59,59,59,59,59,59,59,219,
-+219,219,219,219,219,219,219,91,91,91,91,91,91,91,91,155,
-+155,155,155,155,155,155,155,27,27,27,27,27,27,27,27,235,
-+235,235,235,235,235,235,235,107,107,107,107,107,107,107,107,171,
-+171,171,171,171,171,171,171,43,43,43,43,43,43,43,43,203,
-+203,203,203,203,203,203,203,75,75,75,75,75,75,75,75,139,
-+139,139,139,139,139,139,139,11,11,11,11,11,11,11,11,243,
-+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,115,
-+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,179,
-+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,51,
-+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,211,
-+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,83,
-+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,147,
-+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,19,
-+19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,227,
-+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,99,
-+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,163,
-+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,35,
-+35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,195,
-+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,67,
-+67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,131,
-+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,3,
-+3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,253,
-+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,125,
-+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
-+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,189,
-+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
-+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,61,
-+61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
-+61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,221,
-+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
-+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,93,
-+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
-+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,157,
-+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
-+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,29,
-+29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
-+29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,237,
-+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
-+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,109,
-+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,173,
-+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
-+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,45,
-+45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
-+45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,205,
-+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
-+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,77,
-+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
-+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,141,
-+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
-+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,13,
-+13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
-+13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,245,
-+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,117,
-+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
-+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
-+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
-+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,181,
-+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
-+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
-+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
-+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,53,
-+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
-+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
-+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
-+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,213,
-+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
-+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
-+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
-+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,85,
-+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,149,
-+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
-+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
-+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
-+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,21,
-+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
-+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
-+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
-+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,229,
-+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
-+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
-+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
-+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,101,
-+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,165,
-+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
-+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
-+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
-+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,37,
-+37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
-+37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
-+37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
-+37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,197,
-+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
-+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
-+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
-+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,69,
-+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
-+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
-+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
-+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,133,
-+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
-+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
-+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
-+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,5,
-+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,249,
-+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
-+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
-+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
-+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
-+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
-+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
-+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
-+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,121,
-+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
-+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
-+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
-+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
-+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
-+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
-+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
-+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,185,
-+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
-+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
-+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
-+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
-+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
-+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
-+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
-+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,57,
-+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
-+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
-+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
-+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
-+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
-+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
-+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
-+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,217,
-+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
-+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
-+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
-+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
-+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
-+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
-+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
-+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,89,
-+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
-+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
-+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
-+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
-+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
-+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
-+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
-+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,153,
-+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
-+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
-+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
-+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
-+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
-+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
-+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
-+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,25,
-+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
-+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
-+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
-+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
-+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
-+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
-+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
-+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,233,
-+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
-+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
-+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
-+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
-+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
-+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
-+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
-+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,105,
-+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
-+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
-+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
-+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
-+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
-+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
-+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
-+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,169,
-+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
-+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
-+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
-+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
-+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
-+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
-+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
-+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,41,
-+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
-+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
-+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
-+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
-+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
-+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
-+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
-+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,201,
-+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
-+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
-+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
-+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
-+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
-+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
-+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
-+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,73,
-+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
-+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
-+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
-+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
-+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
-+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
-+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
-+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,137,
-+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
-+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
-+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
-+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
-+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
-+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
-+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
-+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,9,
-+9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-+9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-+9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-+9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-+9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-+9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-+9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-+9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+128,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+64,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+192,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+32,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+160,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+96,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+224,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+16,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+144,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+80,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+208,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+48,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+176,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+112,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+240,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+8,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
-+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
-+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
-+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
-+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
-+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
-+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
-+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
-+136,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
-+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
-+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
-+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
-+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
-+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
-+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
-+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
-+72,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-+200,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
-+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
-+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
-+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
-+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
-+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
-+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
-+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
-+40,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
-+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
-+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
-+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
-+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
-+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
-+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
-+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
-+168,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-+104,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
-+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
-+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
-+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
-+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
-+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
-+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
-+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
-+232,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
-+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
-+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
-+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
-+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
-+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
-+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
-+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
-+24,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-+152,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
-+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
-+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
-+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
-+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
-+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
-+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
-+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
-+88,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
-+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
-+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
-+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
-+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
-+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
-+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
-+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
-+216,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
-+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
-+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
-+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
-+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
-+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
-+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
-+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
-+56,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
-+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
-+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
-+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
-+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
-+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
-+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
-+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
-+184,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-+120,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-+248,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-+4,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-+132,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
-+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
-+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
-+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
-+68,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-+196,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
-+36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
-+36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
-+36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
-+36,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-+164,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-+100,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
-+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
-+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
-+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
-+228,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
-+20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
-+20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
-+20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
-+20,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
-+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
-+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
-+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
-+148,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+84,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-+212,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
-+52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
-+52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
-+52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
-+52,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
-+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
-+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
-+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
-+180,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
-+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
-+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
-+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
-+116,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-+244,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
-+12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
-+12,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
-+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
-+140,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
-+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
-+76,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
-+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
-+204,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
-+44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
-+44,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
-+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
-+172,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
-+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
-+108,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
-+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
-+236,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
-+28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
-+28,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
-+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
-+156,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
-+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
-+92,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
-+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
-+220,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
-+60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
-+60,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
-+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
-+188,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
-+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
-+124,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
-+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
-+252,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-+2,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
-+130,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
-+66,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
-+194,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,
-+34,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
-+162,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
-+98,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
-+226,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
-+18,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
-+146,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
-+82,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
-+210,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
-+50,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
-+178,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
-+114,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
-+242,10,10,10,10,10,10,10,10,138,138,138,138,138,138,138,
-+138,74,74,74,74,74,74,74,74,202,202,202,202,202,202,202,
-+202,42,42,42,42,42,42,42,42,170,170,170,170,170,170,170,
-+170,106,106,106,106,106,106,106,106,234,234,234,234,234,234,234,
-+234,26,26,26,26,26,26,26,26,154,154,154,154,154,154,154,
-+154,90,90,90,90,90,90,90,90,218,218,218,218,218,218,218,
-+218,58,58,58,58,58,58,58,58,186,186,186,186,186,186,186,
-+186,122,122,122,122,122,122,122,122,250,250,250,250,250,250,250,
-+250,6,6,6,6,134,134,134,134,70,70,70,70,198,198,198,
-+198,38,38,38,38,166,166,166,166,102,102,102,102,230,230,230,
-+230,22,22,22,22,150,150,150,150,86,86,86,86,214,214,214,
-+214,54,54,54,54,182,182,182,182,118,118,118,118,246,246,246,
-+246,14,14,142,142,78,78,206,206,46,46,174,174,110,110,238,
-+238,30,30,158,158,94,94,222,222,62,62,190,190,126,126,254,
-+};
-+#else
-+static short capiALAW2INT[] =
-+{
-+      0x13fc, 0xec04, 0x0144, 0xfebc, 0x517c, 0xae84, 0x051c, 0xfae4,
-+      0x0a3c, 0xf5c4, 0x0048, 0xffb8, 0x287c, 0xd784, 0x028c, 0xfd74,
-+      0x1bfc, 0xe404, 0x01cc, 0xfe34, 0x717c, 0x8e84, 0x071c, 0xf8e4,
-+      0x0e3c, 0xf1c4, 0x00c4, 0xff3c, 0x387c, 0xc784, 0x039c, 0xfc64,
-+      0x0ffc, 0xf004, 0x0104, 0xfefc, 0x417c, 0xbe84, 0x041c, 0xfbe4,
-+      0x083c, 0xf7c4, 0x0008, 0xfff8, 0x207c, 0xdf84, 0x020c, 0xfdf4,
-+      0x17fc, 0xe804, 0x018c, 0xfe74, 0x617c, 0x9e84, 0x061c, 0xf9e4,
-+      0x0c3c, 0xf3c4, 0x0084, 0xff7c, 0x307c, 0xcf84, 0x030c, 0xfcf4,
-+      0x15fc, 0xea04, 0x0164, 0xfe9c, 0x597c, 0xa684, 0x059c, 0xfa64,
-+      0x0b3c, 0xf4c4, 0x0068, 0xff98, 0x2c7c, 0xd384, 0x02cc, 0xfd34,
-+      0x1dfc, 0xe204, 0x01ec, 0xfe14, 0x797c, 0x8684, 0x07bc, 0xf844,
-+      0x0f3c, 0xf0c4, 0x00e4, 0xff1c, 0x3c7c, 0xc384, 0x03dc, 0xfc24,
-+      0x11fc, 0xee04, 0x0124, 0xfedc, 0x497c, 0xb684, 0x049c, 0xfb64,
-+      0x093c, 0xf6c4, 0x0028, 0xffd8, 0x247c, 0xdb84, 0x024c, 0xfdb4,
-+      0x19fc, 0xe604, 0x01ac, 0xfe54, 0x697c, 0x9684, 0x069c, 0xf964,
-+      0x0d3c, 0xf2c4, 0x00a4, 0xff5c, 0x347c, 0xcb84, 0x034c, 0xfcb4,
-+      0x12fc, 0xed04, 0x0134, 0xfecc, 0x4d7c, 0xb284, 0x04dc, 0xfb24,
-+      0x09bc, 0xf644, 0x0038, 0xffc8, 0x267c, 0xd984, 0x026c, 0xfd94,
-+      0x1afc, 0xe504, 0x01ac, 0xfe54, 0x6d7c, 0x9284, 0x06dc, 0xf924,
-+      0x0dbc, 0xf244, 0x00b4, 0xff4c, 0x367c, 0xc984, 0x036c, 0xfc94,
-+      0x0f3c, 0xf0c4, 0x00f4, 0xff0c, 0x3e7c, 0xc184, 0x03dc, 0xfc24,
-+      0x07bc, 0xf844, 0x0008, 0xfff8, 0x1efc, 0xe104, 0x01ec, 0xfe14,
-+      0x16fc, 0xe904, 0x0174, 0xfe8c, 0x5d7c, 0xa284, 0x05dc, 0xfa24,
-+      0x0bbc, 0xf444, 0x0078, 0xff88, 0x2e7c, 0xd184, 0x02ec, 0xfd14,
-+      0x14fc, 0xeb04, 0x0154, 0xfeac, 0x557c, 0xaa84, 0x055c, 0xfaa4,
-+      0x0abc, 0xf544, 0x0058, 0xffa8, 0x2a7c, 0xd584, 0x02ac, 0xfd54,
-+      0x1cfc, 0xe304, 0x01cc, 0xfe34, 0x757c, 0x8a84, 0x075c, 0xf8a4,
-+      0x0ebc, 0xf144, 0x00d4, 0xff2c, 0x3a7c, 0xc584, 0x039c, 0xfc64,
-+      0x10fc, 0xef04, 0x0114, 0xfeec, 0x457c, 0xba84, 0x045c, 0xfba4,
-+      0x08bc, 0xf744, 0x0018, 0xffe8, 0x227c, 0xdd84, 0x022c, 0xfdd4,
-+      0x18fc, 0xe704, 0x018c, 0xfe74, 0x657c, 0x9a84, 0x065c, 0xf9a4,
-+      0x0cbc, 0xf344, 0x0094, 0xff6c, 0x327c, 0xcd84, 0x032c, 0xfcd4
-+};
-+
-+const unsigned char capiINT2ALAW[8192] = {
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-+  212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-+  212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-+  212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-+  212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-+  20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
-+  20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
-+  20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
-+  20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
-+  148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
-+  148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
-+  148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
-+  148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
-+  116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
-+  116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
-+  116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
-+  116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
-+  244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-+  244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-+  244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-+  244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-+  52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
-+  52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
-+  52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
-+  52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
-+  180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
-+  180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
-+  180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
-+  180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
-+  68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
-+  68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
-+  68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
-+  68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
-+  196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-+  196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-+  196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-+  196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-+  4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-+  4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-+  4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-+  4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-+  132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-+  132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-+  132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-+  132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-+  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-+  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-+  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-+  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-+  228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
-+  228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
-+  228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
-+  228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
-+  36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
-+  36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
-+  36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
-+  36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
-+  164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-+  164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-+  164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-+  164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-+  92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
-+  92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
-+  220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
-+  220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
-+  28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
-+  28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
-+  156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
-+  156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
-+  124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
-+  124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
-+  252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
-+  252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
-+  60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
-+  60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
-+  188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
-+  188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
-+  76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
-+  76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
-+  204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
-+  204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
-+  12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
-+  12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
-+  140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
-+  140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
-+  108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
-+  108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
-+  236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
-+  236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
-+  44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
-+  44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
-+  172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
-+  172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
-+  80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
-+  208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
-+  16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
-+  144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
-+  112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-+  240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
-+  48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
-+  176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
-+  64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
-+  192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
-+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-+  96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
-+  224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-+  32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-+  160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
-+  88,88,88,88,88,88,88,88,216,216,216,216,216,216,216,216,
-+  24,24,24,24,24,24,24,24,152,152,152,152,152,152,152,152,
-+  120,120,120,120,120,120,120,120,248,248,248,248,248,248,248,248,
-+  56,56,56,56,56,56,56,56,184,184,184,184,184,184,184,184,
-+  72,72,72,72,72,72,72,72,200,200,200,200,200,200,200,200,
-+  8,8,8,8,8,8,8,8,136,136,136,136,136,136,136,136,
-+  104,104,104,104,104,104,104,104,232,232,232,232,232,232,232,232,
-+  40,40,40,40,40,40,40,40,168,168,168,168,168,168,168,168,
-+  86,86,86,86,214,214,214,214,22,22,22,22,150,150,150,150,
-+  118,118,118,118,246,246,246,246,54,54,54,54,182,182,182,182,
-+  70,70,70,70,198,198,198,198,6,6,6,6,134,134,134,134,
-+  102,102,102,102,230,230,230,230,38,38,38,38,166,166,166,166,
-+  94,94,222,222,30,30,158,158,126,126,254,254,62,62,190,190,
-+  78,78,206,206,14,14,142,142,110,110,238,238,46,46,174,174,
-+  82,210,18,146,114,242,50,178,66,194,2,130,98,226,34,162,
-+  90,218,26,154,122,250,58,186,74,202,10,138,106,234,42,170,
-+  171,43,235,107,139,11,203,75,187,59,251,123,155,27,219,91,
-+  163,35,227,99,131,3,195,67,179,51,243,115,147,19,211,83,
-+  175,175,47,47,239,239,111,111,143,143,15,15,207,207,79,79,
-+  191,191,63,63,255,255,127,127,159,159,31,31,223,223,95,95,
-+  167,167,167,167,39,39,39,39,231,231,231,231,103,103,103,103,
-+  135,135,135,135,7,7,7,7,199,199,199,199,71,71,71,71,
-+  183,183,183,183,55,55,55,55,247,247,247,247,119,119,119,119,
-+  151,151,151,151,23,23,23,23,215,215,215,215,87,87,87,87,
-+  169,169,169,169,169,169,169,169,41,41,41,41,41,41,41,41,
-+  233,233,233,233,233,233,233,233,105,105,105,105,105,105,105,105,
-+  137,137,137,137,137,137,137,137,9,9,9,9,9,9,9,9,
-+  201,201,201,201,201,201,201,201,73,73,73,73,73,73,73,73,
-+  185,185,185,185,185,185,185,185,57,57,57,57,57,57,57,57,
-+  249,249,249,249,249,249,249,249,121,121,121,121,121,121,121,121,
-+  153,153,153,153,153,153,153,153,25,25,25,25,25,25,25,25,
-+  217,217,217,217,217,217,217,217,89,89,89,89,89,89,89,89,
-+  161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
-+  33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
-+  225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-+  97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-+  129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
-+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-+  193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-+  65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
-+  177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-+  49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
-+  241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
-+  113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-+  145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
-+  17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
-+  209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
-+  81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
-+  173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
-+  173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
-+  45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
-+  45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
-+  237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
-+  237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
-+  109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-+  109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-+  141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
-+  141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
-+  13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
-+  13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
-+  205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
-+  205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
-+  77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
-+  77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
-+  189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
-+  189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
-+  61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
-+  61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
-+  253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-+  253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-+  125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
-+  125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
-+  157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
-+  157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
-+  29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
-+  29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
-+  221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
-+  221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
-+  93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
-+  93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
-+  165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
-+  165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
-+  165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
-+  165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
-+  37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
-+  37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
-+  37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
-+  37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
-+  229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
-+  229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
-+  229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
-+  229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
-+  101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-+  101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-+  101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-+  101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-+  133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
-+  133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
-+  133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
-+  133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
-+  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-+  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-+  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-+  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-+  197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
-+  197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
-+  197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
-+  197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
-+  69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
-+  69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
-+  69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
-+  69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
-+  181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
-+  181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
-+  181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
-+  181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
-+  53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
-+  53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
-+  53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
-+  53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
-+  245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-+  245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-+  245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-+  245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-+  117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
-+  117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
-+  117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
-+  117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
-+  149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
-+  149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
-+  149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
-+  149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
-+  21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
-+  21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
-+  21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
-+  21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
-+  213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
-+  213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
-+  213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
-+  213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
-+  85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85
-+};
-+
-+#endif // CAPI_ULAW
-+#endif
-+
-diff -urN asterisk-1.2.10.orig/include/asterisk.h asterisk-1.2.10/include/asterisk.h
---- asterisk-1.2.10.orig/include/asterisk.h    2005-11-30 04:37:37.000000000 +0100
-+++ asterisk-1.2.10/include/asterisk.h 2006-07-31 14:13:08.000000000 +0200
-@@ -36,6 +36,7 @@
- extern char ast_config_AST_PID[AST_CONFIG_MAX_PATH];
- extern char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH];
- extern char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH];
-+extern char ast_config_AST_SYMBOLIC_NAME[20];
- extern char ast_config_AST_CTL_PERMISSIONS[AST_CONFIG_MAX_PATH];
- extern char ast_config_AST_CTL_OWNER[AST_CONFIG_MAX_PATH];
- extern char ast_config_AST_CTL_GROUP[AST_CONFIG_MAX_PATH];
-diff -urN asterisk-1.2.10.orig/manager.c asterisk-1.2.10/manager.c
---- asterisk-1.2.10.orig/manager.c     2006-02-11 19:15:00.000000000 +0100
-+++ asterisk-1.2.10/manager.c  2006-07-31 14:13:08.000000000 +0200
-@@ -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.
-@@ -62,6 +65,7 @@
- #include "asterisk/md5.h"
- #include "asterisk/acl.h"
- #include "asterisk/utils.h"
-+#include "asterisk/astdb.h"
- struct fast_originate_helper {
-       char tech[AST_MAX_MANHEADER_LEN];
-@@ -76,6 +80,8 @@
-       char idtext[AST_MAX_MANHEADER_LEN];
-       char account[AST_MAX_ACCOUNT_CODE];
-       int priority;
-+      int callingpres;
-+      char uniqueid[64];
-       struct ast_variable *vars;
- };
-@@ -99,6 +105,7 @@
-       { EVENT_FLAG_COMMAND, "command" },
-       { EVENT_FLAG_AGENT, "agent" },
-       { EVENT_FLAG_USER, "user" },
-+      { EVENT_FLAG_EXTENSIONSTATUS, "extensionstatus" },
-       { -1, "all" },
-       { 0, "none" },
- };
-@@ -657,11 +664,17 @@
- {
-       struct ast_channel *c = NULL;
-       char *name = astman_get_header(m, "Channel");
--      if (ast_strlen_zero(name)) {
--              astman_send_error(s, m, "No channel specified");
-+      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;
-@@ -760,6 +773,7 @@
- }
-+
- /*! \brief  action_status: Manager "status" command to show channels */
- /* Needs documentation... */
- static int action_status(struct mansession *s, struct message *m)
-@@ -866,32 +880,50 @@
-       char *exten = astman_get_header(m, "Exten");
-       char *context = astman_get_header(m, "Context");
-       char *priority = astman_get_header(m, "Priority");
-+      char *uniqueid = astman_get_header(m, "Uniqueid");
-+      char *uniqueid2 = astman_get_header(m, "ExtraUniqueid");
-+      char *exten2 = astman_get_header(m, "ExtraExten");
-+      char *context2 = astman_get_header(m, "ExtraContext");
-+      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 ((!name || ast_strlen_zero(name)) && (!uniqueid || 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)) {
-               astman_send_error(s, m, "Invalid priority\n");
-               return 0;
-       }
--      chan = ast_get_channel_by_name_locked(name);
-+      if (uniqueid && (!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);
-               astman_send_error(s, m, buf);
-               return 0;
-       }
--      if (!ast_strlen_zero(name2))
-+      if (!ast_strlen_zero(uniqueid2)) {
-+              chan2 = ast_get_channel_by_uniqueid_locked(uniqueid2);
-+              if (!ast_strlen_zero(priority2) && (sscanf(priority2, "%d", &pi2) != 1)) {
-+                  astman_send_error(s, m, "Invalid priority2\n");
-+                  return 0;
-+              }
-+      } else {
-+          if (!ast_strlen_zero(name2))
-               chan2 = ast_get_channel_by_name_locked(name2);
-+      }
-       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)
-@@ -937,15 +969,15 @@
-       struct ast_channel *chan = NULL;
-       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(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, in->callingpres, 
-                       !ast_strlen_zero(in->cid_num) ? in->cid_num : NULL, 
-                       !ast_strlen_zero(in->cid_name) ? 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(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, in->callingpres, 
-                       !ast_strlen_zero(in->cid_num) ? in->cid_num : NULL, 
-                       !ast_strlen_zero(in->cid_name) ? in->cid_name : NULL,
--                      in->vars, in->account, &chan);
-+                      in->vars, in->account, &chan, in->uniqueid);
-       }   
-       if (!res)
-               manager_event(EVENT_FLAG_CALL,
-@@ -956,7 +988,7 @@
-                       "Exten: %s\r\n"
-                       "Reason: %d\r\n"
-                       "Uniqueid: %s\r\n",
--                      in->idtext, in->tech, in->data, in->context, in->exten, reason, chan ? chan->uniqueid : "<null>");
-+                      in->idtext, in->tech, in->data, in->context, in->exten, reason, in->uniqueid ? in->uniqueid : (chan ? chan->uniqueid : "<null>"));
-       else
-               manager_event(EVENT_FLAG_CALL,
-                       "OriginateFailure",
-@@ -966,7 +998,7 @@
-                       "Exten: %s\r\n"
-                       "Reason: %d\r\n"
-                       "Uniqueid: %s\r\n",
--                      in->idtext, in->tech, in->data, in->context, in->exten, reason, chan ? chan->uniqueid : "<null>");
-+                      in->idtext, in->tech, in->data, in->context, in->exten, reason, in->uniqueid ? in->uniqueid : (chan ? chan->uniqueid : "<null>"));
-       /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
-       if (chan)
-@@ -999,6 +1031,7 @@
-       char *priority = astman_get_header(m, "Priority");
-       char *timeout = astman_get_header(m, "Timeout");
-       char *callerid = astman_get_header(m, "CallerID");
-+      char *callingpres = astman_get_header(m, "CallingPres");
-       char *account = astman_get_header(m, "Account");
-       char *app = astman_get_header(m, "Application");
-       char *appdata = astman_get_header(m, "Data");
-@@ -1007,12 +1040,15 @@
-       struct ast_variable *vars = astman_get_variables(m);
-       char *tech, *data;
-       char *l=NULL, *n=NULL;
-+      char *uniqueid;
-       int pi = 0;
-+      int cpresi = 0;
-       int res;
-       int to = 30000;
-       int reason = 0;
-       char tmp[256];
-       char tmp2[256];
-+      char idText[256] = "";
-       
-       pthread_t th;
-       pthread_attr_t attr;
-@@ -1028,6 +1064,10 @@
-               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, '/');
-@@ -1048,6 +1088,7 @@
-               if (ast_strlen_zero(l))
-                       l = NULL;
-       }
-+      uniqueid = ast_alloc_uniqueid();
-       if (ast_true(async)) {
-               struct fast_originate_helper *fast = malloc(sizeof(struct fast_originate_helper));
-               if (!fast) {
-@@ -1068,8 +1109,10 @@
-                       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)) {
-@@ -1079,19 +1122,28 @@
-                       }
-               }
-       } 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(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(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;
- }
-@@ -1565,10 +1617,12 @@
-       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;
- }
-diff -urN asterisk-1.2.10.orig/pbx/pbx_spool.c asterisk-1.2.10/pbx/pbx_spool.c
---- asterisk-1.2.10.orig/pbx/pbx_spool.c       2006-02-11 19:15:00.000000000 +0100
-+++ asterisk-1.2.10/pbx/pbx_spool.c    2006-07-31 14:13:08.000000000 +0200
-@@ -259,11 +259,11 @@
-       if (!ast_strlen_zero(o->app)) {
-               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);
-+              res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, 0, o->cid_num, o->cid_name, o->vars, o->account, NULL, NULL);
-       } 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);
--              res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL);
-+              res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, 0, o->cid_num, o->cid_name, o->vars, o->account, NULL, NULL);
-       }
-       if (res) {
-               ast_log(LOG_NOTICE, "Call failed to go through, reason %d\n", reason);
-diff -urN asterisk-1.2.10.orig/pbx.c asterisk-1.2.10/pbx.c
---- asterisk-1.2.10.orig/pbx.c 2006-06-18 23:03:58.000000000 +0200
-+++ asterisk-1.2.10/pbx.c      2006-07-31 14:13:08.000000000 +0200
-@@ -353,7 +353,8 @@
-       
-       { "Hangup", pbx_builtin_hangup,
-       "Hang up the calling channel",
--      "  Hangup(): This application will hang up the calling channel.\n"
-+      "  Hangup(Cause): Unconditionally hangs up a given channel by returning -1 always.\n" 
-+      "                 If cause is given, it will set the hangup cause accordingly.\n" 
-       },
-       { "NoOp", pbx_builtin_noop,
-@@ -1883,7 +1884,7 @@
-       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;
-       struct ast_state_cb *cblist;
-@@ -1911,11 +1912,11 @@
-                       
-                       /* 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;
-                       break;
-@@ -2156,7 +2157,7 @@
-                               /* Notify with -1 and remove all callbacks */
-                               cbprev = cblist;            
-                               cblist = cblist->next;
--                              cbprev->callback(list->exten->parent->name, list->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data);
-+                              cbprev->callback(list->exten->parent->name, list->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data, NULL, NULL);
-                               free(cbprev);
-                       }
-                       list->callbacks = NULL;
-@@ -3777,7 +3778,7 @@
-                       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 {
-@@ -4981,7 +4982,7 @@
-       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(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;
-@@ -4991,7 +4992,7 @@
-       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(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid);
-               if (channel) {
-                       *channel = chan;
-                       if (chan)
-@@ -5093,7 +5094,7 @@
-                       goto outgoing_exten_cleanup;
-               }       
-               memset(as, 0, sizeof(struct async_stat));
--              chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
-+              chan = ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, uniqueid);
-               if (channel) {
-                       *channel = chan;
-                       if (chan)
-@@ -5139,7 +5140,7 @@
-       pthread_t t;
- };
--static void *ast_pbx_run_app(void *data)
-+void *ast_pbx_run_app(void *data)
- {
-       struct app_tmp *tmp = data;
-       struct ast_app *app;
-@@ -5155,7 +5156,7 @@
-       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(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 async_stat *as;
-@@ -5175,7 +5176,7 @@
-               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(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 */
-                               ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name);
-@@ -5262,7 +5263,8 @@
-                       goto outgoing_app_cleanup;
-               }
-               memset(as, 0, sizeof(struct async_stat));
--              chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
-+              chan = __ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid);
-+//            chan = ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, uniqueid);
-               if (!chan) {
-                       free(as);
-                       res = -1;
-@@ -5551,6 +5553,9 @@
-  */
- static int pbx_builtin_hangup(struct ast_channel *chan, void *data)
- {
-+        /* Copy the hangup cause as specified */
-+        if (data)
-+             chan->hangupcause = atoi(data);
-       /* Just return non-zero and it will hang up */
-       if (!chan->hangupcause)
-               chan->hangupcause = AST_CAUSE_NORMAL_CLEARING;
-@@ -6207,6 +6212,9 @@
-                       return -1;
-               }
-       }
-+      if (chan->_state != AST_STATE_UP) {
-+          ast_answer(chan);
-+      }
-       return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options);
- }
-@@ -6214,8 +6222,12 @@
- {
-       int res = 0;
--      if (data)
-+      if (data) {
-+              if (chan->_state != AST_STATE_UP) {
-+                  ast_answer(chan);
-+              }
-               res = ast_say_digit_str(chan, (char *)data, "", chan->language);
-+      }
-       return res;
- }
-       
-@@ -6223,8 +6235,12 @@
- {
-       int res = 0;
--      if (data)
-+      if (data) {
-+              if (chan->_state != AST_STATE_UP) {
-+                  ast_answer(chan);
-+              }
-               res = ast_say_character_str(chan, (char *)data, "", chan->language);
-+      }
-       return res;
- }
-       
-@@ -6232,8 +6248,12 @@
- {
-       int res = 0;
--      if (data)
-+      if (data) {
-+              if (chan->_state != AST_STATE_UP) {
-+                  ast_answer(chan);
-+              }
-               res = ast_say_phonetic_str(chan, (char *)data, "", chan->language);
-+      }
-       return res;
- }
-       
-diff -urN asterisk-1.2.10.orig/res/Makefile asterisk-1.2.10/res/Makefile
---- asterisk-1.2.10.orig/res/Makefile  2005-11-29 19:24:39.000000000 +0100
-+++ asterisk-1.2.10/res/Makefile       2006-07-31 14:13:08.000000000 +0200
-@@ -11,7 +11,7 @@
- # the GNU General Public License
- #
--MODS=res_indications.so res_monitor.so res_adsi.so res_agi.so res_features.so
-+MODS=res_indications.so res_monitor.so res_adsi.so res_agi.so res_features.so res_watchdog.so
- ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/odbcinst.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/odbcinst.h),)
-   ifneq (${OSARCH},FreeBSD)
-diff -urN asterisk-1.2.10.orig/res/res_agi.c asterisk-1.2.10/res/res_agi.c
---- asterisk-1.2.10.orig/res/res_agi.c 2006-07-12 15:54:10.000000000 +0200
-+++ asterisk-1.2.10/res/res_agi.c      2006-07-31 14:13:08.000000000 +0200
-@@ -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.
-@@ -74,16 +77,19 @@
- 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"
-@@ -92,6 +98,8 @@
- " hangup, or 0 on non-hangup exit. \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 'show agi' to list available agi commands\n";
- static int agidebug = 0;
-@@ -225,13 +233,14 @@
-       return 0;
- }
--static int launch_script(char *script, char *argv[], int *fds, int *efd, int *opid)
-+static int 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;
-@@ -276,6 +285,33 @@
-                       return -1;
-               }
-       }
-+      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 -1;
-+              }
-+              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 -1;
-+              }
-+      }
-       pid = fork();
-       if (pid < 0) {
-               ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
-@@ -293,15 +329,19 @@
-               } else {
-                       close(STDERR_FILENO + 1);
-               }
-+              if (efd2) {
-+                      dup2(audio2[1], STDERR_FILENO + 2);
-+              } else {
-+                      close(STDERR_FILENO + 2);
-+              }
-               
-               /* unblock important signal handlers */
-               if (sigfillset(&signal_set) || pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
-                       ast_log(LOG_WARNING, "unable to unblock signals for AGI script: %s\n", strerror(errno));
-                       exit(1);
-               }
--
-               /* 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 */
-@@ -317,6 +357,9 @@
-       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]);
-@@ -325,6 +368,9 @@
-               /* [PHM 12/18/03] */
-               close(audio[0]);
-       }
-+      if (efd2) {
-+              close(audio2[1]);
-+      }
-       *opid = pid;
-       return 0;
-@@ -355,7 +401,7 @@
-       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 : "");
-@@ -387,7 +433,7 @@
-               return RESULT_SHOWUSAGE;
-       if (sscanf(argv[3], "%d", &to) != 1)
-               return RESULT_SHOWUSAGE;
--      res = ast_waitfordigit_full(chan, to, agi->audio, agi->ctrl);
-+      res = ast_waitfordigit_full(chan, to, agi->audio_out, agi->ctrl);
-       fdprintf(agi->fd, "200 result=%d\n", res);
-       if (res >= 0)
-               return RESULT_SUCCESS;
-@@ -563,7 +609,7 @@
-               else
-                       return RESULT_FAILURE;
-       }
--      res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
-+      res = ast_waitstream_full(chan, argv[3], agi->audio_out, agi->ctrl);
-       /* this is to check for if ast_waitstream closed the stream, we probably are at
-        * the end of the stream, return that amount, else check for the amount */
-       sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length;
-@@ -623,7 +669,7 @@
-                 else
-                         return RESULT_FAILURE;
-         }
--        res = ast_waitstream_full(chan, argv[3], agi->audio, agi->ctrl);
-+        res = ast_waitstream_full(chan, argv[3], agi->audio_out, agi->ctrl);
-         /* this is to check for if ast_waitstream closed the stream, we probably are at
-          * the end of the stream, return that amount, else check for the amount */
-         sample_offset = (chan->stream)?ast_tellstream(fs):max_length;
-@@ -635,7 +681,7 @@
-       /* If the user didnt press a key, wait for digitTimeout*/
-       if (res == 0 ) {
--              res = ast_waitfordigit_full(chan, timeout, agi->audio, agi->ctrl);
-+              res = ast_waitfordigit_full(chan, timeout, agi->audio_out, agi->ctrl);
-               /* Make sure the new result is in the escape digits of the GET OPTION */
-               if ( !strchr(edigits,res) )
-                       res=0;
-@@ -662,7 +708,7 @@
-               return RESULT_SHOWUSAGE;
-       if (sscanf(argv[2], "%d", &num) != 1)
-               return RESULT_SHOWUSAGE;
--      res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio, agi->ctrl);
-+      res = ast_say_number_full(chan, num, argv[3], chan->language, (char *) NULL, agi->audio_out, agi->ctrl);
-       if (res == 1)
-               return RESULT_SUCCESS;
-       fdprintf(agi->fd, "200 result=%d\n", res);
-@@ -682,7 +728,7 @@
-       if (sscanf(argv[2], "%d", &num) != 1)
-               return RESULT_SHOWUSAGE;
--      res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
-+      res = ast_say_digit_str_full(chan, argv[2], argv[3], chan->language, agi->audio_out, agi->ctrl);
-       if (res == 1) /* New command */
-               return RESULT_SUCCESS;
-       fdprintf(agi->fd, "200 result=%d\n", res);
-@@ -699,7 +745,7 @@
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
--      res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
-+      res = ast_say_character_str_full(chan, argv[2], argv[3], chan->language, agi->audio_out, agi->ctrl);
-       if (res == 1) /* New command */
-               return RESULT_SUCCESS;
-       fdprintf(agi->fd, "200 result=%d\n", res);
-@@ -789,7 +835,7 @@
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
--      res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio, agi->ctrl);
-+      res = ast_say_phonetic_str_full(chan, argv[2], argv[3], chan->language, agi->audio_out, agi->ctrl);
-       if (res == 1) /* New command */
-               return RESULT_SUCCESS;
-       fdprintf(agi->fd, "200 result=%d\n", res);
-@@ -816,7 +862,7 @@
-               max = atoi(argv[4]); 
-       else
-               max = 1024;
--      res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio, agi->ctrl);
-+      res = ast_app_getdata_full(chan, argv[2], data, max, timeout, agi->audio_out, agi->ctrl);
-       if (res == 2)                   /* New command */
-               return RESULT_SUCCESS;
-       else if (res == 1)
-@@ -1854,7 +1900,12 @@
-       int ms;
-       int returnstatus = 0;
-       struct ast_frame *f;
-+      struct ast_frame fr;
-       char buf[2048];
-+      char audiobuf[2048];
-+      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) */
-@@ -1868,10 +1919,22 @@
-               return -1;
-       }
-       setlinebuf(readf);
--      setup_env(chan, request, agi->fd, (agi->audio > -1));
-+      if (agi->audio_out > -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 = RETRY;
-                       /* Idle the channel until we get a command */
-@@ -1882,13 +1945,24 @@
-                               break;
-                       } else {
-                               /* If it's voice, write it to the audio pipe */
--                              if ((agi->audio > -1) && (f->frametype == AST_FRAME_VOICE)) {
-+                              if ((agi->audio_out > -1) && (f->frametype == AST_FRAME_VOICE)) {
-                                       /* Write, ignoring errors */
--                                      write(agi->audio, f->data, f->datalen);
-+                                      write(agi->audio_out, f->data, f->datalen);
-                               }
-                               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) {
-+                      //    ast_log(LOG_NOTICE, "read %d bytes of audio\n", audiobytes);
-+                          fr.frametype = AST_FRAME_VOICE;
-+                          fr.subclass = AST_FORMAT_SLINEAR;
-+                          fr.datalen = audiobytes;
-+                          fr.data = audiobuf;
-+                          ast_write(chan, &fr);
-+                      }
-+                  } else {
-                       retry = RETRY;
-                       if (!fgets(buf, sizeof(buf), readf)) {
-                               /* Program terminated */
-@@ -1910,6 +1984,7 @@
-                       if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) {
-                               break;
-                       }
-+                  }
-               } else {
-                       if (--retry <= 0) {
-                               ast_log(LOG_WARNING, "No channel, no fd?\n");
-@@ -2016,6 +2091,7 @@
-       int argc = 0;
-       int fds[2];
-       int efd = -1;
-+      int efd2 = -1;
-       int pid;
-         char *stringp;
-       AGI agi;
-@@ -2041,15 +2117,18 @@
-               }
-       }
- #endif
--      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.fd = fds[1];
-               agi.ctrl = fds[0];
--              agi.audio = efd;
-+              agi.audio_out = efd;
-+              agi.audio_in = efd2;
-               res = run_agi(chan, argv[0], &agi, pid, dead);
-               close(fds[1]);
-               if (efd > -1)
-                       close(efd);
-+              if (efd2 > -1)
-+                      close(efd2);
-       }
-       LOCAL_USER_REMOVE(u);
-       return res;
-@@ -2083,6 +2162,35 @@
-       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)
- {
-       return agi_exec_full(chan, data, 0, 1);
-@@ -2112,6 +2220,7 @@
-       ast_cli_unregister(&dumpagihtml);
-       ast_cli_unregister(&cli_debug);
-       ast_cli_unregister(&cli_no_debug);
-+      ast_unregister_application(xapp);
-       ast_unregister_application(eapp);
-       ast_unregister_application(deadapp);
-       return ast_unregister_application(app);
-@@ -2125,6 +2234,7 @@
-       ast_cli_register(&cli_no_debug);
-       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);
- }
-diff -urN asterisk-1.2.10.orig/res/res_features.c asterisk-1.2.10/res/res_features.c
---- asterisk-1.2.10.orig/res/res_features.c    2006-05-23 19:15:23.000000000 +0200
-+++ asterisk-1.2.10/res/res_features.c 2006-08-02 09:55:40.000000000 +0200
-@@ -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.
-@@ -56,6 +60,7 @@
- #include "asterisk/utils.h"
- #include "asterisk/adsi.h"
- #include "asterisk/monitor.h"
-+#include "asterisk/indications.h"
- #ifdef __AST_DEBUG_MALLOC
- static void FREE(void *ptr)
-@@ -73,6 +78,7 @@
- #define AST_MAX_WATCHERS 256
- static char *parkedcall = "ParkedCall";
-+static char *holdedcall = "HoldedCall";
- /* No more than 45 seconds parked before you do something with them */
- static int parkingtime = DEFAULT_PARK_TIME;
-@@ -132,6 +138,20 @@
- "into the dialplan, although you should include the 'parkedcalls'\n"
- "context.\n";
-+static char *autoanswerlogin = "AutoanswerLogin";
-+
-+static char *synopsis3 = "Log in for autoanswer";
-+
-+static char *descrip3 = "AutoanswerLogin(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(exten):"
-+"Used to autoanswer a call for an extension.\n";
-+
- static struct ast_app *monitor_app=NULL;
- static int monitor_ok=1;
-@@ -150,12 +170,51 @@
-       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;
-+      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;
-+static struct holdeduser *holdlist;
-+
- AST_MUTEX_DEFINE_STATIC(parking_lock);
-+AST_MUTEX_DEFINE_STATIC(holding_lock);
-+
- static pthread_t parking_thread;
-+static pthread_t holding_thread;
-+
- STANDARD_LOCAL_USER;
- LOCAL_USER_DECL;
-@@ -165,6 +224,12 @@
-       return parking_ext;
- }
-+char *ast_parking_con(void)
-+{
-+      return parking_con;
-+}
-+
-+
- char *ast_pickup_ext(void)
- {
-       return pickup_ext;
-@@ -362,10 +427,11 @@
-               "Timeout: %ld\r\n"
-               "CallerID: %s\r\n"
-               "CallerIDName: %s\r\n"
-+              "Unqiueid: %s\r\n\r\n"
-               ,pu->parkingnum, pu->chan->name, peer ? peer->name : ""
-               ,(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL)
-               ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "<unknown>")
--              ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>")
-+              ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>"), pu->chan->uniqueid
-               );
-       if (peer) {
-@@ -418,7 +484,8 @@
-               ast_copy_string(chan->context, rchan->context, sizeof(chan->context));
-               ast_copy_string(chan->exten, rchan->exten, sizeof(chan->exten));
-               chan->priority = rchan->priority;
--
-+              /* might be dirty but we want trackable channels */
-+              strncpy(chan->uniqueid, rchan->uniqueid, sizeof(chan->uniqueid) - 1);
-               /* Make the masq execute */
-               f = ast_read(chan);
-               if (f)
-@@ -906,7 +973,7 @@
- }
- /* find a feature by name */
--static struct ast_call_feature *find_feature(char *name)
-+struct ast_call_feature *ast_find_feature(char *name)
- {
-       struct ast_call_feature *tmp;
-@@ -916,10 +983,21 @@
-                       break;
-       }
-       AST_LIST_UNLOCK(&feature_list);
--
-       return tmp;
- }
-+struct ast_call_feature *ast_find_builtin_feature(char *name)
-+{
-+      int x = 0;
-+
-+      for (x = 0; x < FEATURES_COUNT; x++) {
-+              if (!strcasecmp(name, builtin_features[x].sname)) {
-+                  return &builtin_features[x];
-+              } 
-+      }
-+      return NULL;
-+}
-+
- /* exec an app by feature */
- static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
- {
-@@ -1018,7 +1096,7 @@
-                       return res;
-               
-               while ((tok = strsep(&tmp, "#")) != NULL) {
--                      feature = find_feature(tok);
-+                      feature = ast_find_feature(tok);
-                       
-                       if (feature) {
-                               /* Feature is up for consideration */
-@@ -1071,7 +1149,7 @@
-                       /* while we have a feature */
-                       while (NULL != (tok = strsep(&tmp, "#"))) {
--                              if ((feature = find_feature(tok))) {
-+                              if ((feature = ast_find_feature(tok))) {
-                                       if (ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
-                                               if (ast_test_flag(feature, AST_FEATURE_FLAG_CALLER))
-                                                       ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
-@@ -1096,7 +1174,7 @@
-       struct ast_frame *f = NULL;
-       int res = 0, ready = 0;
-       
--      if ((chan = ast_request(type, format, data, &cause))) {
-+      if ((chan = ast_request(type, format, data, &cause, NULL))) {
-               ast_set_callerid(chan, cid_num, cid_name, cid_num);
-               ast_channel_inherit_variables(caller, chan);    
-               if (!ast_call(chan, data, timeout)) {
-@@ -1549,9 +1627,10 @@
-                                       "Channel: %s\r\n"
-                                       "CallerID: %s\r\n"
-                                       "CallerIDName: %s\r\n"
-+                                      "Uniqueid: %s\r\n\r\n"
-                                       ,pu->parkingnum, pu->chan->name
-                                       ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "<unknown>")
--                                      ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>")
-+                                      ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>"), pu->chan->uniqueid
-                                       );
-                               if (option_verbose > 1) 
-@@ -1594,9 +1673,10 @@
-                                                               "Channel: %s\r\n"
-                                                               "CallerID: %s\r\n"
-                                                               "CallerIDName: %s\r\n"
-+                                                              "Uniqueid: %s\r\n\r\n"
-                                                               ,pu->parkingnum, pu->chan->name
-                                                               ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "<unknown>")
--                                                              ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>")
-+                                                              ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>"), pu->chan->uniqueid
-                                                               );
-                                                       /* There's a problem, hang them up*/
-@@ -1683,6 +1763,282 @@
-       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);
-+              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);
-+      if (chan) {
-+              /* Let us keep track of the channel name */
-+              snprintf(chan->name, sizeof (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 */
-+              strncpy(chan->uniqueid, rchan->uniqueid, sizeof(chan->uniqueid) - 1);
-+              /* 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 localuser *u;
-+      char *uniqueid = (char *)data;
-+      LOCAL_USER_ADD(u);
-+          res = ast_retrieve_call(chan, uniqueid);
-+      LOCAL_USER_REMOVE(u);
-+      return res;
-+}
-+
- static int park_exec(struct ast_channel *chan, void *data)
- {
-       int res=0;
-@@ -1731,9 +2087,10 @@
-                       "From: %s\r\n"
-                       "CallerID: %s\r\n"
-                       "CallerIDName: %s\r\n"
-+                      "Uniqueid: %s\r\n\r\n"
-                       ,pu->parkingnum, pu->chan->name, chan->name
-                       ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "<unknown>")
--                      ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>")
-+                      ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "<unknown>"), pu->chan->uniqueid
-                       );
-               free(pu);
-@@ -1901,12 +2258,13 @@
-                       "Timeout: %ld\r\n"
-                       "CallerID: %s\r\n"
-                       "CallerIDName: %s\r\n"
-+                      "Uniqueid: %s\r\n"
-                       "%s"
-                       "\r\n"
-                         ,cur->parkingnum, cur->chan->name
-                         ,(long)cur->start.tv_sec + (long)(cur->parkingtime/1000) - (long)time(NULL)
-                       ,(cur->chan->cid.cid_num ? cur->chan->cid.cid_num : "")
--                      ,(cur->chan->cid.cid_name ? cur->chan->cid.cid_name : "")
-+                      ,(cur->chan->cid.cid_name ? cur->chan->cid.cid_name : ""), cur->chan->uniqueid
-                       ,idText);
-             cur = cur->next;
-@@ -1922,6 +2280,416 @@
-         return RESULT_SUCCESS;
- }
-+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 char showautoanswer_help[] =
-+"Usage: show autoanswer\n"
-+"       Lists currently logged in autoanswr channels.\n";
-+
-+static struct ast_cli_entry showautoanswer =
-+{ { "show", "autoanswer", NULL }, handle_autoanswer, "Lists autoanswer channels", 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);
-+      if (chan) {
-+              /* Let us keep track of the channel name */
-+              snprintf(chan->name, sizeof (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;
-+              /* 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 localuser *u;
-+      LOCAL_USER_ADD(u);
-+      if (!data) {
-+              ast_log(LOG_WARNING, "AutoanswerLogin requires an argument (extension number)\n");
-+              return -1;
-+      }
-+      res = ast_masq_autoanswer_login(chan, data);
-+      LOCAL_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);
-+              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 localuser *u;
-+      struct ast_channel *peer=NULL;
-+      struct aauser *pu, *pl=NULL;
-+      struct ast_bridge_config config;
-+      char *s, *stringp, *aacontext, *aaexten = NULL;
-+      char datastring[80];
-+
-+      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";
-+              }
-+      }
-+
-+      LOCAL_USER_ADD(u);
-+      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;
-+      }
-+      LOCAL_USER_REMOVE(u);
-+      return res;
-+}
-+
- int ast_pickup_call(struct ast_channel *chan)
- {
-@@ -2076,7 +2844,7 @@
-                       }
-                       {
--                              struct ast_call_feature *feature=find_feature(var->name);
-+                              struct ast_call_feature *feature = ast_find_feature(var->name);
-                               int mallocd=0;
-                               
-                               if (!feature) {
-@@ -2138,6 +2906,7 @@
- }
- int reload(void) {
-+      autoanswer_reregister_extensions();
-       return load_config();
- }
-@@ -2151,14 +2920,22 @@
-       if ((res = load_config()))
-               return res;
-       ast_cli_register(&showparked);
-+      ast_cli_register(&showautoanswer);
-       ast_cli_register(&showfeatures);
-       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);
-       if (!res) {
-               ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
-       }
-+      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);
-+      if (!res)
-+              res = ast_register_application(autoanswer, autoanswer_exec, synopsis4, descrip4);
-       return res;
- }
-@@ -2169,7 +2946,11 @@
-       ast_manager_unregister("ParkedCalls");
-       ast_cli_unregister(&showfeatures);
-+      ast_cli_unregister(&showautoanswer);
-       ast_cli_unregister(&showparked);
-+      ast_unregister_application(autoanswer);
-+      ast_unregister_application(autoanswerlogin);
-+      ast_unregister_application(holdedcall);
-       ast_unregister_application(parkcall);
-       return ast_unregister_application(parkedcall);
- }
-diff -urN asterisk-1.2.10.orig/res/res_monitor.c asterisk-1.2.10/res/res_monitor.c
---- asterisk-1.2.10.orig/res/res_monitor.c     2006-03-02 20:05:40.000000000 +0100
-+++ asterisk-1.2.10/res/res_monitor.c  2006-07-31 14:13:08.000000000 +0200
-@@ -90,7 +90,7 @@
- /* 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];
-@@ -122,6 +122,11 @@
-               }
-               memset(monitor, 0, sizeof(struct ast_channel_monitor));
-+              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;
-@@ -257,6 +262,8 @@
-               if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) {
-                       char tmp[1024];
-                       char tmp2[1024];
-+                      char tmp3[1024];
-+                      int result;
-                       char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format;
-                       char *name = chan->monitor->filename_base;
-                       int directory = strchr(name, '/') ? 1 : 0;
-@@ -278,9 +285,19 @@
-                               snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s/%s-\"* ) &",tmp, dir ,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);
-+                      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);
-@@ -392,7 +409,7 @@
-               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);
-@@ -428,19 +445,30 @@
- {
-       struct ast_channel *c = NULL;
-       char *name = astman_get_header(m, "Channel");
-+      char *uniqueid = astman_get_header(m, "Uniqueid");
-       char *fname = astman_get_header(m, "File");
-       char *format = astman_get_header(m, "Format");
-       char *mix = astman_get_header(m, "Mix");
-+      char *target_url = astman_get_header(m, "TargetURL");
-+      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;
-       }
--      c = ast_get_channel_by_name_locked(name);
--      if (!c) {
-+      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;
-+          }
-       }
-       if (ast_strlen_zero(fname)) {
-@@ -457,7 +485,7 @@
-               if ((d=strchr(fname, '/'))) *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_mutex_unlock(&c->lock);
-@@ -483,16 +511,26 @@
- {
-       struct ast_channel *c = NULL;
-       char *name = astman_get_header(m, "Channel");
-+      char *uniqueid = astman_get_header(m, "Uniqueid");
-       int res;
--      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;
-       }
--      c = ast_get_channel_by_name_locked(name);
--      if (!c) {
-+      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_mutex_unlock(&c->lock);
-       if (res) {
-diff -urN asterisk-1.2.10.orig/res/res_watchdog.c asterisk-1.2.10/res/res_watchdog.c
---- asterisk-1.2.10.orig/res/res_watchdog.c    1970-01-01 01:00:00.000000000 +0100
-+++ asterisk-1.2.10/res/res_watchdog.c 2006-08-10 14:07:14.000000000 +0200
-@@ -0,0 +1,149 @@
-+/*
-+ * 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 <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/lock.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/adsi.h>
-+
-+static struct watchdog_pvt *watchdogs = NULL;
-+
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+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", 1);
-+      }
-+      usleep(woof->interval * 1000);
-+    }
-+    return NULL;
-+}
-+
-+
-+int load_module(void)
-+{
-+      int res = 0;
-+      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;
-+}
-+
-+
-+int unload_module(void)
-+{
-+      struct watchdog_pvt *dogs, *woof;
-+      STANDARD_HANGUP_LOCALUSERS;
-+      dogs = watchdogs;
-+      while (dogs) {
-+          pthread_cancel(dogs->watchdog_thread);
-+          close(dogs->fd);
-+          woof = dogs->next;
-+          free(dogs);
-+          dogs = woof;
-+      }
-+      return 0;
-+}
-+
-+char *description(void)
-+{
-+      return "Watchdog Resource";
-+}
-+
-+int usecount(void)
-+{
-+      return 1;
-+}
-+
-+char *key()
-+{
-+      return ASTERISK_GPL_KEY;
-+}
-diff -urN asterisk-1.2.10.orig/rtp.c asterisk-1.2.10/rtp.c
---- asterisk-1.2.10.orig/rtp.c 2006-07-13 20:44:17.000000000 +0200
-+++ asterisk-1.2.10/rtp.c      2006-07-31 14:16:56.000000000 +0200
-@@ -445,6 +445,11 @@
-       struct rtpPayloadType rtpPT;
-       
-       len = sizeof(sin);
-+
-+      /* XXX SYMPTON CURE, DIRTY FIX, CHECK, BEGIN */
-+      if (!rtp)
-+          return &null_frame;
-+      /* XXX SYMPTON CURE, DIRTY FIX, CHECK, END */
-       
-       /* Cache where the header will go */
-       res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
diff --git a/src/patches/capi4k-utils-2004-10-06_ppp-2.4.3.patch b/src/patches/capi4k-utils-2004-10-06_ppp-2.4.3.patch
deleted file mode 100644 (file)
index 5c0e0a4..0000000
+++ /dev/null
@@ -1,947 +0,0 @@
-diff -Naur capi4k-utils.old/pppdcapiplugin/Makefile capi4k-utils/pppdcapiplugin/Makefile
---- capi4k-utils.old/pppdcapiplugin/Makefile   Mon Feb 23 18:30:39 2004
-+++ capi4k-utils/pppdcapiplugin/Makefile       Wed Nov 24 22:19:36 2004
-@@ -18,7 +18,7 @@
- PPPSRCDIRS=/src/isdn/pppd
- ifeq ($(PPPVERSIONS),)
--PPPVERSIONS = 2.3.11 2.4.0 2.4.1 2.4.1b1 2.4.1b2 2.4.2b3 2.4.2
-+PPPVERSIONS = 2.3.11 2.4.0 2.4.1 2.4.1b1 2.4.1b2 2.4.2b3 2.4.2 2.4.3
- endif
- PEERDIR=${DESTDIR}/etc/ppp/peers/isdn
-diff -Naur capi4k-utils.old/pppdcapiplugin/ppp-2.4.3/Makefile capi4k-utils/pppdcapiplugin/ppp-2.4.3/Makefile
---- capi4k-utils.old/pppdcapiplugin/ppp-2.4.3/Makefile Thu Jan  1 01:00:00 1970
-+++ capi4k-utils/pppdcapiplugin/ppp-2.4.3/Makefile     Sun May 18 21:11:16 2003
-@@ -0,0 +1,14 @@
-+# Makefile for the capiplugin for pppd(8).
-+#
-+# Copyright 2000 Carsten Paeth (calle@calle.in-berlin.de)
-+# Copyright 2000 AVM GmbH Berlin (info@avm.de)
-+#
-+#  This program 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.
-+
-+PLUGINDIR=${DESTDIR}/usr/lib/pppd/$(PPPVERSION)
-+
-+include $(TOPDIR)/Rules.make
-+
-diff -Naur capi4k-utils.old/pppdcapiplugin/ppp-2.4.3/pppd/patchlevel.h capi4k-utils/pppdcapiplugin/ppp-2.4.3/pppd/patchlevel.h
---- capi4k-utils.old/pppdcapiplugin/ppp-2.4.3/pppd/patchlevel.h        Thu Jan  1 01:00:00 1970
-+++ capi4k-utils/pppdcapiplugin/ppp-2.4.3/pppd/patchlevel.h    Sat Nov 13 12:08:02 2004
-@@ -0,0 +1,4 @@
-+/* $Id: capi4k-utils-2004-10-06_ppp-2.4.3.patch,v 1.1.2.1 2004/11/24 23:27:29 gespinasse Exp $ */
-+
-+#define VERSION               "2.4.3"
-+#define DATE          "13 November 2004"
-diff -Naur capi4k-utils.old/pppdcapiplugin/ppp-2.4.3/pppd/pppd.h capi4k-utils/pppdcapiplugin/ppp-2.4.3/pppd/pppd.h
---- capi4k-utils.old/pppdcapiplugin/ppp-2.4.3/pppd/pppd.h      Thu Jan  1 01:00:00 1970
-+++ capi4k-utils/pppdcapiplugin/ppp-2.4.3/pppd/pppd.h  Sat Nov 13 12:02:22 2004
-@@ -0,0 +1,905 @@
-+/*
-+ * pppd.h - PPP daemon global declarations.
-+ *
-+ * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in
-+ *    the documentation and/or other materials provided with the
-+ *    distribution.
-+ *
-+ * 3. The name "Carnegie Mellon University" must not be used to
-+ *    endorse or promote products derived from this software without
-+ *    prior written permission. For permission or any legal
-+ *    details, please contact
-+ *      Office of Technology Transfer
-+ *      Carnegie Mellon University
-+ *      5000 Forbes Avenue
-+ *      Pittsburgh, PA  15213-3890
-+ *      (412) 268-4387, fax: (412) 268-7395
-+ *      tech-transfer@andrew.cmu.edu
-+ *
-+ * 4. Redistributions of any form whatsoever must retain the following
-+ *    acknowledgment:
-+ *    "This product includes software developed by Computing Services
-+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
-+ *
-+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
-+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY 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.
-+ *
-+ * $Id: capi4k-utils-2004-10-06_ppp-2.4.3.patch,v 1.1.2.1 2004/11/24 23:27:29 gespinasse Exp $
-+ */
-+
-+/*
-+ * TODO:
-+ */
-+
-+#ifndef __PPPD_H__
-+#define __PPPD_H__
-+
-+#include <stdio.h>            /* for FILE */
-+#include <limits.h>           /* for NGROUPS_MAX */
-+#include <sys/param.h>                /* for MAXPATHLEN and BSD4_4, if defined */
-+#include <sys/types.h>                /* for u_int32_t, if defined */
-+#include <sys/time.h>         /* for struct timeval */
-+#include <net/ppp_defs.h>
-+#include "patchlevel.h"
-+
-+#if defined(__STDC__)
-+#include <stdarg.h>
-+#define __V(x)        x
-+#else
-+#include <varargs.h>
-+#define __V(x)        (va_alist) va_dcl
-+#define const
-+#define volatile
-+#endif
-+
-+#ifdef INET6
-+#include "eui64.h"
-+#endif
-+
-+/*
-+ * Limits.
-+ */
-+
-+#define NUM_PPP               1       /* One PPP interface supported (per process) */
-+#define MAXWORDLEN    1024    /* max length of word in file (incl null) */
-+#define MAXARGS               1       /* max # args to a command */
-+#define MAXNAMELEN    256     /* max length of hostname or name for auth */
-+#define MAXSECRETLEN  256     /* max length of password or secret */
-+
-+/*
-+ * Option descriptor structure.
-+ */
-+
-+typedef unsigned char bool;
-+
-+enum opt_type {
-+      o_special_noarg = 0,
-+      o_special = 1,
-+      o_bool,
-+      o_int,
-+      o_uint32,
-+      o_string,
-+      o_wild
-+};
-+
-+typedef struct {
-+      char    *name;          /* name of the option */
-+      enum opt_type type;
-+      void    *addr;
-+      char    *description;
-+      unsigned int flags;
-+      void    *addr2;
-+      int     upper_limit;
-+      int     lower_limit;
-+      const char *source;
-+      short int priority;
-+      short int winner;
-+} option_t;
-+
-+/* Values for flags */
-+#define OPT_VALUE     0xff    /* mask for presupplied value */
-+#define OPT_HEX               0x100   /* int option is in hex */
-+#define OPT_NOARG     0x200   /* option doesn't take argument */
-+#define OPT_OR                0x400   /* OR in argument to value */
-+#define OPT_INC               0x800   /* increment value */
-+#define OPT_A2OR      0x800   /* for o_bool, OR arg to *(u_char *)addr2 */
-+#define OPT_PRIV      0x1000  /* privileged option */
-+#define OPT_STATIC    0x2000  /* string option goes into static array */
-+#define OPT_LLIMIT    0x4000  /* check value against lower limit */
-+#define OPT_ULIMIT    0x8000  /* check value against upper limit */
-+#define OPT_LIMITS    (OPT_LLIMIT|OPT_ULIMIT)
-+#define OPT_ZEROOK    0x10000 /* 0 value is OK even if not within limits */
-+#define OPT_HIDE      0x10000 /* for o_string, print value as ?????? */
-+#define OPT_A2LIST    0x10000 /* for o_special, keep list of values */
-+#define OPT_A2CLRB    0x10000 /* o_bool, clr val bits in *(u_char *)addr2 */
-+#define OPT_NOINCR    0x20000 /* value mustn't be increased */
-+#define OPT_ZEROINF   0x40000 /* with OPT_NOINCR, 0 == infinity */
-+#define OPT_PRIO      0x80000 /* process option priorities for this option */
-+#define OPT_PRIOSUB   0x100000 /* subsidiary member of priority group */
-+#define OPT_ALIAS     0x200000 /* option is alias for previous option */
-+#define OPT_A2COPY    0x400000 /* addr2 -> second location to rcv value */
-+#define OPT_ENABLE    0x800000 /* use *addr2 as enable for option */
-+#define OPT_A2CLR     0x1000000 /* clear *(bool *)addr2 */
-+#define OPT_PRIVFIX   0x2000000 /* user can't override if set by root */
-+#define OPT_INITONLY  0x4000000 /* option can only be set in init phase */
-+#define OPT_DEVEQUIV  0x8000000 /* equiv to device name */
-+#define OPT_DEVNAM    (OPT_INITONLY | OPT_DEVEQUIV)
-+#define OPT_A2PRINTER 0x10000000 /* *addr2 is a fn for printing option */
-+#define OPT_A2STRVAL  0x20000000 /* *addr2 points to current string value */
-+#define OPT_NOPRINT   0x40000000 /* don't print this option at all */
-+
-+#define OPT_VAL(x)    ((x) & OPT_VALUE)
-+
-+/* Values for priority */
-+#define OPRIO_DEFAULT 0       /* a default value */
-+#define OPRIO_CFGFILE 1       /* value from a configuration file */
-+#define OPRIO_CMDLINE 2       /* value from the command line */
-+#define OPRIO_SECFILE 3       /* value from options in a secrets file */
-+#define OPRIO_ROOT    100     /* added to priority if OPT_PRIVFIX && root */
-+
-+#ifndef GIDSET_TYPE
-+#define GIDSET_TYPE   gid_t
-+#endif
-+
-+/* Structure representing a list of permitted IP addresses. */
-+struct permitted_ip {
-+    int               permit;         /* 1 = permit, 0 = forbid */
-+    u_int32_t base;           /* match if (addr & mask) == base */
-+    u_int32_t mask;           /* base and mask are in network byte order */
-+};
-+
-+/*
-+ * Unfortunately, the linux kernel driver uses a different structure
-+ * for statistics from the rest of the ports.
-+ * This structure serves as a common representation for the bits
-+ * pppd needs.
-+ */
-+struct pppd_stats {
-+    unsigned int      bytes_in;
-+    unsigned int      bytes_out;
-+    unsigned int      pkts_in;
-+    unsigned int      pkts_out;
-+};
-+
-+/* Used for storing a sequence of words.  Usually malloced. */
-+struct wordlist {
-+    struct wordlist   *next;
-+    char              *word;
-+};
-+
-+/* An endpoint discriminator, used with multilink. */
-+#define MAX_ENDP_LEN  20      /* maximum length of discriminator value */
-+struct epdisc {
-+    unsigned char     class;
-+    unsigned char     length;
-+    unsigned char     value[MAX_ENDP_LEN];
-+};
-+
-+/* values for epdisc.class */
-+#define EPD_NULL      0       /* null discriminator, no data */
-+#define EPD_LOCAL     1
-+#define EPD_IP                2
-+#define EPD_MAC               3
-+#define EPD_MAGIC     4
-+#define EPD_PHONENUM  5
-+
-+typedef void (*notify_func) __P((void *, int));
-+
-+struct notifier {
-+    struct notifier *next;
-+    notify_func           func;
-+    void          *arg;
-+};
-+
-+/*
-+ * Global variables.
-+ */
-+
-+extern int    hungup;         /* Physical layer has disconnected */
-+extern int    ifunit;         /* Interface unit number */
-+extern char   ifname[];       /* Interface name */
-+extern char   hostname[];     /* Our hostname */
-+extern u_char outpacket_buf[]; /* Buffer for outgoing packets */
-+extern int    devfd;          /* fd of underlying device */
-+extern int    fd_ppp;         /* fd for talking PPP */
-+extern int    phase;          /* Current state of link - see values below */
-+extern int    baud_rate;      /* Current link speed in bits/sec */
-+extern char   *progname;      /* Name of this program */
-+extern int    redirect_stderr;/* Connector's stderr should go to file */
-+extern char   peer_authname[];/* Authenticated name of peer */
-+extern int    auth_done[NUM_PPP]; /* Methods actually used for auth */
-+extern int    privileged;     /* We were run by real-uid root */
-+extern int    need_holdoff;   /* Need holdoff period after link terminates */
-+extern char   **script_env;   /* Environment variables for scripts */
-+extern int    detached;       /* Have detached from controlling tty */
-+extern GIDSET_TYPE groups[NGROUPS_MAX];       /* groups the user is in */
-+extern int    ngroups;        /* How many groups valid in groups */
-+extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */
-+extern int    link_stats_valid; /* set if link_stats is valid */
-+extern unsigned       link_connect_time; /* time the link was up for */
-+extern int    using_pty;      /* using pty as device (notty or pty opt.) */
-+extern int    log_to_fd;      /* logging to this fd as well as syslog */
-+extern bool   log_default;    /* log_to_fd is default (stdout) */
-+extern char   *no_ppp_msg;    /* message to print if ppp not in kernel */
-+extern volatile int status;   /* exit status for pppd */
-+extern bool   devnam_fixed;   /* can no longer change devnam */
-+extern int    unsuccess;      /* # unsuccessful connection attempts */
-+extern int    do_callback;    /* set if we want to do callback next */
-+extern int    doing_callback; /* set if this is a callback */
-+extern int    error_count;    /* # of times error() has been called */
-+extern char   ppp_devnam[MAXPATHLEN];
-+extern char     remote_number[MAXNAMELEN]; /* Remote telephone number, if avail. */
-+extern int      ppp_session_number; /* Session number (eg PPPoE session) */
-+extern int    fd_devnull;     /* fd open to /dev/null */
-+
-+extern int    listen_time;    /* time to listen first (ms) */
-+extern bool   doing_multilink;
-+extern bool   multilink_master;
-+extern bool   bundle_eof;
-+extern bool   bundle_terminating;
-+
-+extern struct notifier *pidchange;   /* for notifications of pid changing */
-+extern struct notifier *phasechange; /* for notifications of phase changes */
-+extern struct notifier *exitnotify;  /* for notification that we're exiting */
-+extern struct notifier *sigreceived; /* notification of received signal */
-+extern struct notifier *ip_up_notifier; /* IPCP has come up */
-+extern struct notifier *ip_down_notifier; /* IPCP has gone down */
-+extern struct notifier *auth_up_notifier; /* peer has authenticated */
-+extern struct notifier *link_down_notifier; /* link has gone down */
-+extern struct notifier *fork_notifier;        /* we are a new child process */
-+
-+/* Values for do_callback and doing_callback */
-+#define CALLBACK_DIALIN               1       /* we are expecting the call back */
-+#define CALLBACK_DIALOUT      2       /* we are dialling out to call back */
-+
-+/*
-+ * Variables set by command-line options.
-+ */
-+
-+extern int    debug;          /* Debug flag */
-+extern int    kdebugflag;     /* Tell kernel to print debug messages */
-+extern int    default_device; /* Using /dev/tty or equivalent */
-+extern char   devnam[MAXPATHLEN];     /* Device name */
-+extern int    crtscts;        /* Use hardware flow control */
-+extern bool   modem;          /* Use modem control lines */
-+extern int    inspeed;        /* Input/Output speed requested */
-+extern u_int32_t netmask;     /* IP netmask to set on interface */
-+extern bool   lockflag;       /* Create lock file to lock the serial dev */
-+extern bool   nodetach;       /* Don't detach from controlling tty */
-+extern bool   updetach;       /* Detach from controlling tty when link up */
-+extern char   *initializer;   /* Script to initialize physical link */
-+extern char   *connect_script; /* Script to establish physical link */
-+extern char   *disconnect_script; /* Script to disestablish physical link */
-+extern char   *welcomer;      /* Script to welcome client after connection */
-+extern char   *ptycommand;    /* Command to run on other side of pty */
-+extern int    maxconnect;     /* Maximum connect time (seconds) */
-+extern char   user[MAXNAMELEN];/* Our name for authenticating ourselves */
-+extern char   passwd[MAXSECRETLEN];   /* Password for PAP or CHAP */
-+extern bool   auth_required;  /* Peer is required to authenticate */
-+extern bool   persist;        /* Reopen link after it goes down */
-+extern bool   uselogin;       /* Use /etc/passwd for checking PAP */
-+extern char   our_name[MAXNAMELEN];/* Our name for authentication purposes */
-+extern char   remote_name[MAXNAMELEN]; /* Peer's name for authentication */
-+extern bool   explicit_remote;/* remote_name specified with remotename opt */
-+extern bool   demand;         /* Do dial-on-demand */
-+extern char   *ipparam;       /* Extra parameter for ip up/down scripts */
-+extern bool   cryptpap;       /* Others' PAP passwords are encrypted */
-+extern int    idle_time_limit;/* Shut down link if idle for this long */
-+extern int    holdoff;        /* Dead time before restarting */
-+extern bool   holdoff_specified; /* true if user gave a holdoff value */
-+extern bool   notty;          /* Stdin/out is not a tty */
-+extern char   *pty_socket;    /* Socket to connect to pty */
-+extern char   *record_file;   /* File to record chars sent/received */
-+extern bool   sync_serial;    /* Device is synchronous serial device */
-+extern int    maxfail;        /* Max # of unsuccessful connection attempts */
-+extern char   linkname[MAXPATHLEN]; /* logical name for link */
-+extern bool   tune_kernel;    /* May alter kernel settings as necessary */
-+extern int    connect_delay;  /* Time to delay after connect script */
-+extern int    max_data_rate;  /* max bytes/sec through charshunt */
-+extern int    req_unit;       /* interface unit number to use */
-+extern bool   multilink;      /* enable multilink operation */
-+extern bool   noendpoint;     /* don't send or accept endpt. discrim. */
-+extern char   *bundle_name;   /* bundle name for multilink */
-+extern bool   dump_options;   /* print out option values */
-+extern bool   dryrun;         /* check everything, print options, exit */
-+extern int    child_wait;     /* # seconds to wait for children at end */
-+
-+#ifdef MAXOCTETS
-+extern unsigned int maxoctets;             /* Maximum octetes per session (in bytes) */
-+extern int       maxoctets_dir;      /* Direction :
-+                                    0 - in+out (default)
-+                                    1 - in 
-+                                    2 - out
-+                                    3 - max(in,out) */
-+extern int       maxoctets_timeout;  /* Timeout for check of octets limit */
-+#define PPP_OCTETS_DIRECTION_SUM        0
-+#define PPP_OCTETS_DIRECTION_IN         1
-+#define PPP_OCTETS_DIRECTION_OUT        2
-+#define PPP_OCTETS_DIRECTION_MAXOVERAL  3
-+/* same as previos, but little different on RADIUS side */
-+#define PPP_OCTETS_DIRECTION_MAXSESSION 4     
-+#endif
-+
-+#ifdef PPP_FILTER
-+extern struct bpf_program pass_filter;   /* Filter for pkts to pass */
-+extern struct bpf_program active_filter; /* Filter for link-active pkts */
-+#endif
-+
-+#ifdef MSLANMAN
-+extern bool   ms_lanman;      /* Use LanMan password instead of NT */
-+                              /* Has meaning only with MS-CHAP challenges */
-+#endif
-+
-+/* Values for auth_pending, auth_done */
-+#define PAP_WITHPEER  0x1
-+#define PAP_PEER      0x2
-+#define CHAP_WITHPEER 0x4
-+#define CHAP_PEER     0x8
-+#define EAP_WITHPEER  0x10
-+#define EAP_PEER      0x20
-+
-+/* Values for auth_done only */
-+#define CHAP_MD5_WITHPEER     0x40
-+#define CHAP_MD5_PEER         0x80
-+#define CHAP_MS_SHIFT         8       /* LSB position for MS auths */
-+#define CHAP_MS_WITHPEER      0x100
-+#define CHAP_MS_PEER          0x200
-+#define CHAP_MS2_WITHPEER     0x400
-+#define CHAP_MS2_PEER         0x800
-+
-+extern char *current_option;  /* the name of the option being parsed */
-+extern int  privileged_option;        /* set iff the current option came from root */
-+extern char *option_source;   /* string saying where the option came from */
-+extern int  option_priority;  /* priority of current options */
-+
-+/*
-+ * Values for phase.
-+ */
-+#define PHASE_DEAD            0
-+#define PHASE_INITIALIZE      1
-+#define PHASE_SERIALCONN      2
-+#define PHASE_DORMANT         3
-+#define PHASE_ESTABLISH               4
-+#define PHASE_AUTHENTICATE    5
-+#define PHASE_CALLBACK                6
-+#define PHASE_NETWORK         7
-+#define PHASE_RUNNING         8
-+#define PHASE_TERMINATE               9
-+#define PHASE_DISCONNECT      10
-+#define PHASE_HOLDOFF         11
-+#define PHASE_MASTER          12
-+
-+/*
-+ * The following struct gives the addresses of procedures to call
-+ * for a particular protocol.
-+ */
-+struct protent {
-+    u_short protocol;         /* PPP protocol number */
-+    /* Initialization procedure */
-+    void (*init) __P((int unit));
-+    /* Process a received packet */
-+    void (*input) __P((int unit, u_char *pkt, int len));
-+    /* Process a received protocol-reject */
-+    void (*protrej) __P((int unit));
-+    /* Lower layer has come up */
-+    void (*lowerup) __P((int unit));
-+    /* Lower layer has gone down */
-+    void (*lowerdown) __P((int unit));
-+    /* Open the protocol */
-+    void (*open) __P((int unit));
-+    /* Close the protocol */
-+    void (*close) __P((int unit, char *reason));
-+    /* Print a packet in readable form */
-+    int  (*printpkt) __P((u_char *pkt, int len,
-+                        void (*printer) __P((void *, char *, ...)),
-+                        void *arg));
-+    /* Process a received data packet */
-+    void (*datainput) __P((int unit, u_char *pkt, int len));
-+    bool enabled_flag;                /* 0 iff protocol is disabled */
-+    char *name;                       /* Text name of protocol */
-+    char *data_name;          /* Text name of corresponding data protocol */
-+    option_t *options;                /* List of command-line options */
-+    /* Check requested options, assign defaults */
-+    void (*check_options) __P((void));
-+    /* Configure interface for demand-dial */
-+    int  (*demand_conf) __P((int unit));
-+    /* Say whether to bring up link for this pkt */
-+    int  (*active_pkt) __P((u_char *pkt, int len));
-+};
-+
-+/* Table of pointers to supported protocols */
-+extern struct protent *protocols[];
-+
-+/*
-+ * This struct contains pointers to a set of procedures for
-+ * doing operations on a "channel".  A channel provides a way
-+ * to send and receive PPP packets - the canonical example is
-+ * a serial port device in PPP line discipline (or equivalently
-+ * with PPP STREAMS modules pushed onto it).
-+ */
-+struct channel {
-+      /* set of options for this channel */
-+      option_t *options;
-+      /* find and process a per-channel options file */
-+      void (*process_extra_options) __P((void));
-+      /* check all the options that have been given */
-+      void (*check_options) __P((void));
-+      /* get the channel ready to do PPP, return a file descriptor */
-+      int  (*connect) __P((void));
-+      /* we're finished with the channel */
-+      void (*disconnect) __P((void));
-+      /* put the channel into PPP `mode' */
-+      int  (*establish_ppp) __P((int));
-+      /* take the channel out of PPP `mode', restore loopback if demand */
-+      void (*disestablish_ppp) __P((int));
-+      /* set the transmit-side PPP parameters of the channel */
-+      void (*send_config) __P((int, u_int32_t, int, int));
-+      /* set the receive-side PPP parameters of the channel */
-+      void (*recv_config) __P((int, u_int32_t, int, int));
-+      /* cleanup on error or normal exit */
-+      void (*cleanup) __P((void));
-+      /* close the device, called in children after fork */
-+      void (*close) __P((void));
-+};
-+
-+extern struct channel *the_channel;
-+
-+/*
-+ * Prototypes.
-+ */
-+
-+/* Procedures exported from main.c. */
-+void set_ifunit __P((int));   /* set stuff that depends on ifunit */
-+void detach __P((void));      /* Detach from controlling tty */
-+void die __P((int));          /* Cleanup and exit */
-+void quit __P((void));                /* like die(1) */
-+void novm __P((char *));      /* Say we ran out of memory, and die */
-+void timeout __P((void (*func)(void *), void *arg, int s, int us));
-+                              /* Call func(arg) after s.us seconds */
-+void untimeout __P((void (*func)(void *), void *arg));
-+                              /* Cancel call to func(arg) */
-+void record_child __P((int, char *, void (*) (void *), void *));
-+pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */
-+int  device_script __P((char *cmd, int in, int out, int dont_wait));
-+                              /* Run `cmd' with given stdin and stdout */
-+pid_t run_program __P((char *prog, char **args, int must_exist,
-+                     void (*done)(void *), void *arg));
-+                              /* Run program prog with args in child */
-+void reopen_log __P((void));  /* (re)open the connection to syslog */
-+void print_link_stats __P((void)); /* Print stats, if available */
-+void reset_link_stats __P((int)); /* Reset (init) stats when link goes up */
-+void update_link_stats __P((int)); /* Get stats at link termination */
-+void script_setenv __P((char *, char *, int));        /* set script env var */
-+void script_unsetenv __P((char *));           /* unset script env var */
-+void new_phase __P((int));    /* signal start of new phase */
-+void add_notifier __P((struct notifier **, notify_func, void *));
-+void remove_notifier __P((struct notifier **, notify_func, void *));
-+void notify __P((struct notifier *, int));
-+int  ppp_send_config __P((int, int, u_int32_t, int, int));
-+int  ppp_recv_config __P((int, int, u_int32_t, int, int));
-+void remove_pidfiles __P((void));
-+void lock_db __P((void));
-+void unlock_db __P((void));
-+
-+/* Procedures exported from tty.c. */
-+void tty_init __P((void));
-+
-+/* Procedures exported from utils.c. */
-+void log_packet __P((u_char *, int, char *, int));
-+                              /* Format a packet and log it with syslog */
-+void print_string __P((char *, int,  void (*) (void *, char *, ...),
-+              void *));       /* Format a string for output */
-+int slprintf __P((char *, int, char *, ...));         /* sprintf++ */
-+int vslprintf __P((char *, int, char *, va_list));    /* vsprintf++ */
-+size_t strlcpy __P((char *, const char *, size_t));   /* safe strcpy */
-+size_t strlcat __P((char *, const char *, size_t));   /* safe strncpy */
-+void dbglog __P((char *, ...));       /* log a debug message */
-+void info __P((char *, ...)); /* log an informational message */
-+void notice __P((char *, ...));       /* log a notice-level message */
-+void warn __P((char *, ...)); /* log a warning message */
-+void error __P((char *, ...));        /* log an error message */
-+void fatal __P((char *, ...));        /* log an error message and die(1) */
-+void init_pr_log __P((char *, int));  /* initialize for using pr_log */
-+void pr_log __P((void *, char *, ...));       /* printer fn, output to syslog */
-+void end_pr_log __P((void));  /* finish up after using pr_log */
-+void dump_packet __P((const char *, u_char *, int));
-+                              /* dump packet to debug log if interesting */
-+ssize_t complete_read __P((int, void *, size_t));
-+                              /* read a complete buffer */
-+
-+/* Procedures exported from auth.c */
-+void link_required __P((int));          /* we are starting to use the link */
-+void link_terminated __P((int));  /* we are finished with the link */
-+void link_down __P((int));      /* the LCP layer has left the Opened state */
-+void upper_layers_down __P((int));/* take all NCPs down */
-+void link_established __P((int)); /* the link is up; authenticate now */
-+void start_networks __P((int));   /* start all the network control protos */
-+void continue_networks __P((int)); /* start network [ip, etc] control protos */
-+void np_up __P((int, int));     /* a network protocol has come up */
-+void np_down __P((int, int));   /* a network protocol has gone down */
-+void np_finished __P((int, int)); /* a network protocol no longer needs link */
-+void auth_peer_fail __P((int, int));
-+                              /* peer failed to authenticate itself */
-+void auth_peer_success __P((int, int, int, char *, int));
-+                              /* peer successfully authenticated itself */
-+void auth_withpeer_fail __P((int, int));
-+                              /* we failed to authenticate ourselves */
-+void auth_withpeer_success __P((int, int, int));
-+                              /* we successfully authenticated ourselves */
-+void auth_check_options __P((void));
-+                              /* check authentication options supplied */
-+void auth_reset __P((int));   /* check what secrets we have */
-+int  check_passwd __P((int, char *, int, char *, int, char **));
-+                              /* Check peer-supplied username/password */
-+int  get_secret __P((int, char *, char *, char *, int *, int));
-+                              /* get "secret" for chap */
-+int  get_srp_secret __P((int unit, char *client, char *server, char *secret,
-+    int am_server));
-+int  auth_ip_addr __P((int, u_int32_t));
-+                              /* check if IP address is authorized */
-+int  auth_number __P((void)); /* check if remote number is authorized */
-+int  bad_ip_adrs __P((u_int32_t));
-+                              /* check if IP address is unreasonable */
-+
-+/* Procedures exported from demand.c */
-+void demand_conf __P((void)); /* config interface(s) for demand-dial */
-+void demand_block __P((void));        /* set all NPs to queue up packets */
-+void demand_unblock __P((void)); /* set all NPs to pass packets */
-+void demand_discard __P((void)); /* set all NPs to discard packets */
-+void demand_rexmit __P((int));        /* retransmit saved frames for an NP */
-+int  loop_chars __P((unsigned char *, int)); /* process chars from loopback */
-+int  loop_frame __P((unsigned char *, int)); /* should we bring link up? */
-+
-+/* Procedures exported from multilink.c */
-+#ifdef HAVE_MULTILINK
-+void mp_check_options __P((void)); /* Check multilink-related options */
-+int  mp_join_bundle __P((void));  /* join our link to an appropriate bundle */
-+void mp_exit_bundle __P((void));  /* have disconnected our link from bundle */
-+void mp_bundle_terminated __P((void));
-+char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */
-+int  str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */
-+#else
-+#define mp_bundle_terminated()        /* nothing */
-+#define mp_exit_bundle()      /* nothing */
-+#define doing_multilink               0
-+#define multilink_master      0
-+#endif
-+
-+/* Procedures exported from sys-*.c */
-+void sys_init __P((void));    /* Do system-dependent initialization */
-+void sys_cleanup __P((void)); /* Restore system state before exiting */
-+int  sys_check_options __P((void)); /* Check options specified */
-+void sys_close __P((void));   /* Clean up in a child before execing */
-+int  ppp_available __P((void));       /* Test whether ppp kernel support exists */
-+int  get_pty __P((int *, int *, char *, int));        /* Get pty master/slave */
-+int  open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */
-+int  tty_establish_ppp __P((int));  /* Turn serial port into a ppp interface */
-+void tty_disestablish_ppp __P((int)); /* Restore port to normal operation */
-+void generic_disestablish_ppp __P((int dev_fd)); /* Restore device setting */
-+int  generic_establish_ppp __P((int dev_fd)); /* Make a ppp interface */
-+void make_new_bundle __P((int, int, int, int)); /* Create new bundle */
-+int  bundle_attach __P((int));        /* Attach link to existing bundle */
-+void cfg_bundle __P((int, int, int, int)); /* Configure existing bundle */
-+void destroy_bundle __P((void)); /* Tell driver to destroy bundle */
-+void clean_check __P((void)); /* Check if line was 8-bit clean */
-+void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */
-+void restore_tty __P((int));  /* Restore port's original parameters */
-+void setdtr __P((int, int));  /* Raise or lower port's DTR line */
-+void output __P((int, u_char *, int)); /* Output a PPP packet */
-+void wait_input __P((struct timeval *));
-+                              /* Wait for input, with timeout */
-+void add_fd __P((int));               /* Add fd to set to wait for */
-+void remove_fd __P((int));    /* Remove fd from set to wait for */
-+int  read_packet __P((u_char *)); /* Read PPP packet */
-+int  get_loop_output __P((void)); /* Read pkts from loopback */
-+void tty_send_config __P((int, u_int32_t, int, int));
-+                              /* Configure i/f transmit parameters */
-+void tty_set_xaccm __P((ext_accm));
-+                              /* Set extended transmit ACCM */
-+void tty_recv_config __P((int, u_int32_t, int, int));
-+                              /* Configure i/f receive parameters */
-+int  ccp_test __P((int, u_char *, int, int));
-+                              /* Test support for compression scheme */
-+void ccp_flags_set __P((int, int, int));
-+                              /* Set kernel CCP state */
-+int  ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */
-+int  get_idle_time __P((int, struct ppp_idle *));
-+                              /* Find out how long link has been idle */
-+int  get_ppp_stats __P((int, struct pppd_stats *));
-+                              /* Return link statistics */
-+void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */
-+int  netif_get_mtu __P((int));      /* Get PPP interface MTU */
-+int  sifvjcomp __P((int, int, int, int));
-+                              /* Configure VJ TCP header compression */
-+int  sifup __P((int));                /* Configure i/f up for one protocol */
-+int  sifnpmode __P((int u, int proto, enum NPmode mode));
-+                              /* Set mode for handling packets for proto */
-+int  sifdown __P((int));      /* Configure i/f down for one protocol */
-+int  sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t));
-+                              /* Configure IPv4 addresses for i/f */
-+int  cifaddr __P((int, u_int32_t, u_int32_t));
-+                              /* Reset i/f IP addresses */
-+#ifdef INET6
-+int  sif6addr __P((int, eui64_t, eui64_t));
-+                              /* Configure IPv6 addresses for i/f */
-+int  cif6addr __P((int, eui64_t, eui64_t));
-+                              /* Remove an IPv6 address from i/f */
-+#endif
-+int  sifdefaultroute __P((int, u_int32_t, u_int32_t));
-+                              /* Create default route through i/f */
-+int  cifdefaultroute __P((int, u_int32_t, u_int32_t));
-+                              /* Delete default route through i/f */
-+int  sifproxyarp __P((int, u_int32_t));
-+                              /* Add proxy ARP entry for peer */
-+int  cifproxyarp __P((int, u_int32_t));
-+                              /* Delete proxy ARP entry for peer */
-+u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */
-+int  lock __P((char *));      /* Create lock file for device */
-+int  relock __P((int));               /* Rewrite lock file with new pid */
-+void unlock __P((void));      /* Delete previously-created lock file */
-+void logwtmp __P((const char *, const char *, const char *));
-+                              /* Write entry to wtmp file */
-+int  get_host_seed __P((void));       /* Get host-dependent random number seed */
-+int  have_route_to __P((u_int32_t)); /* Check if route to addr exists */
-+#ifdef PPP_FILTER
-+int  set_filters __P((struct bpf_program *pass, struct bpf_program *active));
-+                              /* Set filter programs in kernel */
-+#endif
-+#ifdef IPX_CHANGE
-+int  sipxfaddr __P((int, unsigned long, unsigned char *));
-+int  cipxfaddr __P((int));
-+#endif
-+int  get_if_hwaddr __P((u_char *addr, char *name));
-+char *get_first_ethernet __P((void));
-+
-+/* Procedures exported from options.c */
-+int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */
-+int  parse_args __P((int argc, char **argv));
-+                              /* Parse options from arguments given */
-+int  options_from_file __P((char *filename, int must_exist, int check_prot,
-+                          int privileged));
-+                              /* Parse options from an options file */
-+int  options_from_user __P((void)); /* Parse options from user's .ppprc */
-+int  options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */
-+int  options_from_list __P((struct wordlist *, int privileged));
-+                              /* Parse options from a wordlist */
-+int  getword __P((FILE *f, char *word, int *newlinep, char *filename));
-+                              /* Read a word from a file */
-+void option_error __P((char *fmt, ...));
-+                              /* Print an error message about an option */
-+int int_option __P((char *, int *));
-+                              /* Simplified number_option for decimal ints */
-+void add_options __P((option_t *)); /* Add extra options */
-+void check_options __P((void));       /* check values after all options parsed */
-+int  override_value __P((const char *, int, const char *));
-+                              /* override value if permitted by priority */
-+void print_options __P((void (*) __P((void *, char *, ...)), void *));
-+                              /* print out values of all options */
-+
-+int parse_dotted_ip __P((char *, u_int32_t *));
-+
-+/*
-+ * Hooks to enable plugins to change various things.
-+ */
-+extern int (*new_phase_hook) __P((int));
-+extern int (*idle_time_hook) __P((struct ppp_idle *));
-+extern int (*holdoff_hook) __P((void));
-+extern int (*pap_check_hook) __P((void));
-+extern int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp,
-+                               struct wordlist **paddrs,
-+                               struct wordlist **popts));
-+extern void (*pap_logout_hook) __P((void));
-+extern int (*pap_passwd_hook) __P((char *user, char *passwd));
-+extern int (*allowed_address_hook) __P((u_int32_t addr));
-+extern void (*ip_up_hook) __P((void));
-+extern void (*ip_down_hook) __P((void));
-+extern void (*ip_choose_hook) __P((u_int32_t *));
-+
-+extern int (*chap_check_hook) __P((void));
-+extern int (*chap_passwd_hook) __P((char *user, char *passwd));
-+
-+/* Let a plugin snoop sent and received packets.  Useful for L2TP */
-+extern void (*snoop_recv_hook) __P((unsigned char *p, int len));
-+extern void (*snoop_send_hook) __P((unsigned char *p, int len));
-+
-+/*
-+ * Inline versions of get/put char/short/long.
-+ * Pointer is advanced; we assume that both arguments
-+ * are lvalues and will already be in registers.
-+ * cp MUST be u_char *.
-+ */
-+#define GETCHAR(c, cp) { \
-+      (c) = *(cp)++; \
-+}
-+#define PUTCHAR(c, cp) { \
-+      *(cp)++ = (u_char) (c); \
-+}
-+
-+
-+#define GETSHORT(s, cp) { \
-+      (s) = *(cp)++ << 8; \
-+      (s) |= *(cp)++; \
-+}
-+#define PUTSHORT(s, cp) { \
-+      *(cp)++ = (u_char) ((s) >> 8); \
-+      *(cp)++ = (u_char) (s); \
-+}
-+
-+#define GETLONG(l, cp) { \
-+      (l) = *(cp)++ << 8; \
-+      (l) |= *(cp)++; (l) <<= 8; \
-+      (l) |= *(cp)++; (l) <<= 8; \
-+      (l) |= *(cp)++; \
-+}
-+#define PUTLONG(l, cp) { \
-+      *(cp)++ = (u_char) ((l) >> 24); \
-+      *(cp)++ = (u_char) ((l) >> 16); \
-+      *(cp)++ = (u_char) ((l) >> 8); \
-+      *(cp)++ = (u_char) (l); \
-+}
-+
-+#define INCPTR(n, cp) ((cp) += (n))
-+#define DECPTR(n, cp) ((cp) -= (n))
-+
-+/*
-+ * System dependent definitions for user-level 4.3BSD UNIX implementation.
-+ */
-+
-+#define TIMEOUT(r, f, t)      timeout((r), (f), (t), 0)
-+#define UNTIMEOUT(r, f)               untimeout((r), (f))
-+
-+#define BCOPY(s, d, l)                memcpy(d, s, l)
-+#define BZERO(s, n)           memset(s, 0, n)
-+#define       BCMP(s1, s2, l)         memcmp(s1, s2, l)
-+
-+#define PRINTMSG(m, l)                { info("Remote message: %0.*v", l, m); }
-+
-+/*
-+ * MAKEHEADER - Add Header fields to a packet.
-+ */
-+#define MAKEHEADER(p, t) { \
-+    PUTCHAR(PPP_ALLSTATIONS, p); \
-+    PUTCHAR(PPP_UI, p); \
-+    PUTSHORT(t, p); }
-+
-+/*
-+ * Exit status values.
-+ */
-+#define EXIT_OK                       0
-+#define EXIT_FATAL_ERROR      1
-+#define EXIT_OPTION_ERROR     2
-+#define EXIT_NOT_ROOT         3
-+#define EXIT_NO_KERNEL_SUPPORT        4
-+#define EXIT_USER_REQUEST     5
-+#define EXIT_LOCK_FAILED      6
-+#define EXIT_OPEN_FAILED      7
-+#define EXIT_CONNECT_FAILED   8
-+#define EXIT_PTYCMD_FAILED    9
-+#define EXIT_NEGOTIATION_FAILED       10
-+#define EXIT_PEER_AUTH_FAILED 11
-+#define EXIT_IDLE_TIMEOUT     12
-+#define EXIT_CONNECT_TIME     13
-+#define EXIT_CALLBACK         14
-+#define EXIT_PEER_DEAD                15
-+#define EXIT_HANGUP           16
-+#define EXIT_LOOPBACK         17
-+#define EXIT_INIT_FAILED      18
-+#define EXIT_AUTH_TOPEER_FAILED       19
-+#ifdef MAXOCTETS
-+#define EXIT_TRAFFIC_LIMIT    20
-+#endif
-+#define EXIT_CNID_AUTH_FAILED 21
-+
-+/*
-+ * Debug macros.  Slightly useful for finding bugs in pppd, not particularly
-+ * useful for finding out why your connection isn't being established.
-+ */
-+#ifdef DEBUGALL
-+#define DEBUGMAIN     1
-+#define DEBUGFSM      1
-+#define DEBUGLCP      1
-+#define DEBUGIPCP     1
-+#define DEBUGIPV6CP   1
-+#define DEBUGUPAP     1
-+#define DEBUGCHAP     1
-+#endif
-+
-+#ifndef LOG_PPP                       /* we use LOG_LOCAL2 for syslog by default */
-+#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \
-+  || defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \
-+  || defined(DEBUGCHAP) || defined(DEBUG) || defined(DEBUGIPV6CP)
-+#define LOG_PPP LOG_LOCAL2
-+#else
-+#define LOG_PPP LOG_DAEMON
-+#endif
-+#endif /* LOG_PPP */
-+
-+#ifdef DEBUGMAIN
-+#define MAINDEBUG(x)  if (debug) dbglog x
-+#else
-+#define MAINDEBUG(x)
-+#endif
-+
-+#ifdef DEBUGSYS
-+#define SYSDEBUG(x)   if (debug) dbglog x
-+#else
-+#define SYSDEBUG(x)
-+#endif
-+
-+#ifdef DEBUGFSM
-+#define FSMDEBUG(x)   if (debug) dbglog x
-+#else
-+#define FSMDEBUG(x)
-+#endif
-+
-+#ifdef DEBUGLCP
-+#define LCPDEBUG(x)   if (debug) dbglog x
-+#else
-+#define LCPDEBUG(x)
-+#endif
-+
-+#ifdef DEBUGIPCP
-+#define IPCPDEBUG(x)  if (debug) dbglog x
-+#else
-+#define IPCPDEBUG(x)
-+#endif
-+
-+#ifdef DEBUGIPV6CP
-+#define IPV6CPDEBUG(x)  if (debug) dbglog x
-+#else
-+#define IPV6CPDEBUG(x)
-+#endif
-+
-+#ifdef DEBUGUPAP
-+#define UPAPDEBUG(x)  if (debug) dbglog x
-+#else
-+#define UPAPDEBUG(x)
-+#endif
-+
-+#ifdef DEBUGCHAP
-+#define CHAPDEBUG(x)  if (debug) dbglog x
-+#else
-+#define CHAPDEBUG(x)
-+#endif
-+
-+#ifdef DEBUGIPXCP
-+#define IPXCPDEBUG(x) if (debug) dbglog x
-+#else
-+#define IPXCPDEBUG(x)
-+#endif
-+
-+#ifndef SIGTYPE
-+#if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE)
-+#define SIGTYPE void
-+#else
-+#define SIGTYPE int
-+#endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */
-+#endif /* SIGTYPE */
-+
-+#ifndef MIN
-+#define MIN(a, b)     ((a) < (b)? (a): (b))
-+#endif
-+#ifndef MAX
-+#define MAX(a, b)     ((a) > (b)? (a): (b))
-+#endif
-+
-+#ifndef offsetof
-+#define offsetof(type, member) ((size_t) &((type *)0)->member)
-+#endif
-+
-+#endif /* __PPP_H__ */
diff --git a/src/patches/fritz-dsl-gcc-4-fix.patch b/src/patches/fritz-dsl-gcc-4-fix.patch
deleted file mode 100644 (file)
index 437f89d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
---- src/tools.h~       2007-01-02 18:28:19.000000000 +0100
-+++ src/tools.h        2007-01-06 18:12:16.000000000 +0100
-@@ -71,12 +71,12 @@
- /*---------------------------------------------------------------------------*\
- \*---------------------------------------------------------------------------*/
--static inline unsigned long atomic_xchg (
-+/* static inline unsigned long atomic_xchg (
-       volatile atomic_t *     v, 
-       unsigned                value
- ) {
-       return __xchg (value, &v->counter, sizeof (unsigned));
--} /* atomic_xchg */
-+} */ /* atomic_xchg */
- /*---------------------------------------------------------------------------*\
- \*---------------------------------------------------------------------------*/
diff --git a/src/patches/fritz-fcdslusb-owner.patch b/src/patches/fritz-fcdslusb-owner.patch
deleted file mode 100644 (file)
index d85dd19..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
---- main.c~    2005-08-05 00:00:00.000000000 +0200
-+++ main.c     2007-01-06 19:00:26.000000000 +0100
-@@ -77,8 +77,14 @@
- static struct usb_driver usb_driver = {
--      .owner =        THIS_MODULE,
--      .name =         TARGET,
-+#ifndef OLD_USB_DRIVER
-+       .driver = {
-+#endif
-+               .owner =        THIS_MODULE,
-+               .name =         TARGET,
-+#ifndef OLD_USB_DRIVER
-+       },
-+#endif
-       .id_table =     usb_id_table,
-       .probe =        usb_probe,
-       .disconnect =   usb_disconnect,
diff --git a/src/patches/ibod-config.patch b/src/patches/ibod-config.patch
deleted file mode 100644 (file)
index 6c92ddc..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- isdn4k-utils-07022001/ibod.h.orig  Wed Nov  1 21:06:07 2000
-+++ isdn4k-utils-07022001/ibod.h       Wed Nov  1 21:06:29 2000
-@@ -10,7 +10,7 @@
- #define STAYUP                        0
- #define STAYUP_TIME           30
--#define IBOD_DEFAULT_DIR      "/etc/ppp"
-+#define IBOD_DEFAULT_DIR      "/etc/isdn"
- #define MAX_STR_LEN           512
- #define ISDN_INFO_DEV         "/dev/isdninfo"
- #define ISDN_CTLR_DEV         "/dev/isdnctrl"
diff --git a/src/patches/isdn4k-utils-0202131200-true.patch b/src/patches/isdn4k-utils-0202131200-true.patch
deleted file mode 100644 (file)
index 33ef17c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- isdn4k-utils/imon/imon.c.orig      Fri Feb 22 17:24:54 2002
-+++ isdn4k-utils/imon/imon.c   Fri Feb 22 17:28:00 2002
-@@ -63,6 +63,10 @@
- #include <linux/isdn.h>
-+#ifndef TRUE
-+#define TRUE 1
-+#endif
-+
- #define KEY_Q                81
- #define KEY_q               113
diff --git a/src/patches/isdn4k-utils-CVS-2004-11-18-autoconf25x.patch b/src/patches/isdn4k-utils-CVS-2004-11-18-autoconf25x.patch
deleted file mode 100644 (file)
index fa8dd31..0000000
+++ /dev/null
@@ -1,564 +0,0 @@
---- isdn4k-utils-CVS-2004-11-18/vbox/configure.in.ac25x        1998-11-23 10:18:04.000000000 +0100
-+++ isdn4k-utils-CVS-2004-11-18/vbox/configure.in      2004-11-18 17:47:52.638741078 +0100
-@@ -17,9 +17,9 @@
- AC_PREFIX_DEFAULT()
--AC_DEFINE_UNQUOTED(PACKAGE, "${PACKAGE}")
--AC_DEFINE_UNQUOTED(VERSION, "${VERSION}")
--AC_DEFINE_UNQUOTED(VERDATE, "${VERDATE}")
-+AC_DEFINE_UNQUOTED(PACKAGE, "${PACKAGE}", [package])
-+AC_DEFINE_UNQUOTED(VERSION, "${VERSION}", [version])
-+AC_DEFINE_UNQUOTED(VERDATE, "${VERDATE}", [verdate])
- AC_SUBST(PACKAGE)
- AC_SUBST(VERSION)
-@@ -87,7 +87,7 @@
- AC_MSG_RESULT(${VBOX_SPOOLDIR})
--AC_DEFINE_UNQUOTED(SPOOLDIR, "${VBOX_SPOOLDIR}")
-+AC_DEFINE_UNQUOTED(SPOOLDIR, "${VBOX_SPOOLDIR}", [spool dir])
- AC_SUBST(VBOX_SPOOLDIR)
-    dnl #===============#
-@@ -105,7 +105,7 @@
- AC_MSG_RESULT(${VBOX_LOGDIR})
--AC_DEFINE_UNQUOTED(LOGFILEDIR, "${VBOX_LOGDIR}")
-+AC_DEFINE_UNQUOTED(LOGFILEDIR, "${VBOX_LOGDIR}", [log dir])
- AC_SUBST(VBOX_LOGDIR)
-    dnl #===============#
-@@ -123,7 +123,7 @@
- AC_MSG_RESULT(${VBOX_PIDDIR})
--AC_DEFINE_UNQUOTED(PIDFILEDIR, "${VBOX_PIDDIR}")
-+AC_DEFINE_UNQUOTED(PIDFILEDIR, "${VBOX_PIDDIR}", [pid dir])
- AC_SUBST(VBOX_PIDDIR)
-    dnl #================#
-@@ -141,7 +141,7 @@
- AC_MSG_RESULT(${VBOX_LCKDIR})
--AC_DEFINE_UNQUOTED(LCKFILEDIR, "${VBOX_LCKDIR}")
-+AC_DEFINE_UNQUOTED(LCKFILEDIR, "${VBOX_LCKDIR}", [lock dir])
- AC_SUBST(VBOX_LCKDIR)
-    dnl #===================#
-@@ -159,7 +159,7 @@
- AC_MSG_RESULT(${ISDN_GLOBAL_CONFIG})
--AC_DEFINE_UNQUOTED(I4LCONFDIR, "${ISDN_GLOBAL_CONFIG}")
-+AC_DEFINE_UNQUOTED(I4LCONFDIR, "${ISDN_GLOBAL_CONFIG}", [global config])
- dnl #------------------------------------------------------------------------#
- dnl # Check and optimize compiler flags:                                     #
---- isdn4k-utils-CVS-2004-11-18/vbox/acinclude.m4.ac25x        2002-07-06 02:11:19.000000000 +0200
-+++ isdn4k-utils-CVS-2004-11-18/vbox/acinclude.m4      2004-11-18 17:47:52.639740930 +0100
-@@ -49,23 +49,23 @@
-          cos,
-          AC_CHECK_LIB(dl,
-             dlerror,
--            [AC_CHECK_LIB(${gnd_1st_tcl_lib_test},
-+            AC_CHECK_LIB(${gnd_1st_tcl_lib_test},
-                Tcl_CreateInterp,
-                LINK_TCL_LIBS="${gnd_tcl_lib_dir} -l${gnd_1st_tcl_lib_test} -lm -ldl",
--               [AC_CHECK_LIB(${gnd_2nd_tcl_lib_test},
-+               AC_CHECK_LIB(${gnd_2nd_tcl_lib_test},
-                   Tcl_CreateInterp,
-                   LINK_TCL_LIBS="${gnd_tcl_lib_dir} -l${gnd_2nd_tcl_lib_test} -lm -ldl",
--                  [AC_CHECK_LIB(${gnd_3rd_tcl_lib_test},
-+                  AC_CHECK_LIB(${gnd_3rd_tcl_lib_test},
-                      Tcl_CreateInterp,
-                      LINK_TCL_LIBS="${gnd_tcl_lib_dir} -l${gnd_3rd_tcl_lib_test} -lm -ldl",
-                      ,
-                      ${gnd_tcl_lib_dir} -lm -ldl
--                  )],
-+                  ),
-                   ${gnd_tcl_lib_dir} -lm -ldl
--               )],
-+               ),
-                ${gnd_tcl_lib_dir} -lm -ldl
--            )],
--         )],
-+            ),
-+         ),
-       )
-       if (test "${LINK_TCL_LIBS}" != "")
-@@ -154,7 +154,7 @@
-          AC_CHECK_LIB(ncurses,
-             resizeterm,
--            AC_DEFINE(HAVE_RESIZETERM)
-+            AC_DEFINE(HAVE_RESIZETERM, 1, [have resizeterm])
- )
-       fi
---- isdn4k-utils-CVS-2004-11-18/vbox/aclocal.m4.ac25x  2002-07-06 02:11:19.000000000 +0200
-+++ isdn4k-utils-CVS-2004-11-18/vbox/aclocal.m4        2004-11-18 17:47:52.640740782 +0100
-@@ -61,23 +61,23 @@
-          cos,
-          [AC_CHECK_LIB(dl,
-             dlerror,
--            [AC_CHECK_LIB(${gnd_1st_tcl_lib_test},
-+            AC_CHECK_LIB(${gnd_1st_tcl_lib_test},
-                Tcl_CreateInterp,
-                LINK_TCL_LIBS="${gnd_tcl_lib_dir} -l${gnd_1st_tcl_lib_test} -lm -ldl",
--               [AC_CHECK_LIB(${gnd_2nd_tcl_lib_test},
-+               AC_CHECK_LIB(${gnd_2nd_tcl_lib_test},
-                   Tcl_CreateInterp,
-                   LINK_TCL_LIBS="${gnd_tcl_lib_dir} -l${gnd_2nd_tcl_lib_test} -lm -ldl",
--                  [AC_CHECK_LIB(${gnd_3rd_tcl_lib_test},
-+                  AC_CHECK_LIB(${gnd_3rd_tcl_lib_test},
-                      Tcl_CreateInterp,
-                      LINK_TCL_LIBS="${gnd_tcl_lib_dir} -l${gnd_3rd_tcl_lib_test} -lm -ldl",
-                      ,
-                      ${gnd_tcl_lib_dir} -lm -ldl
--                  )],
-+                  ),
-                   ${gnd_tcl_lib_dir} -lm -ldl
--               )],
-+               ),
-                ${gnd_tcl_lib_dir} -lm -ldl
--            )],
--         )],
-+            ),
-+         ),
-       )
-       if (test "${LINK_TCL_LIBS}" != "")
-@@ -103,15 +103,7 @@
-                HAVE_TCL_INCL="y"
-                LINK_TCL_INCL="${gnd_tcl_inc_dir}"
--            fi
--         else
--            AC_MSG_CHECKING("for tcl header in /usr/include/tcl8.3/tcl.h")
--            if (test -e "/usr/include/tcl8.3/tcl.h")
--            then
--               AC_MSG_RESULT("yes")
--               HAVE_TCL_INCL="y"
--               LINK_TCL_INCL="-I/usr/include/tcl8.3"
--            else
-+                      else
-                AC_MSG_RESULT("no")
-             fi
-          fi
---- isdn4k-utils-CVS-2004-11-18/ipppd/configure.in.ac25x       2004-08-30 16:56:36.000000000 +0200
-+++ isdn4k-utils-CVS-2004-11-18/ipppd/configure.in     2004-11-18 17:55:56.899083430 +0100
-@@ -17,21 +17,21 @@
- AC_PROG_CC
- dnl Checks for libraries.
--AC_CHECK_LIB(bsd, daemon,HAVE_LIBBSD=1; AC_DEFINE(HAVE_LIBBSD),
-+AC_CHECK_LIB(bsd, daemon,HAVE_LIBBSD=1; AC_DEFINE(HAVE_LIBBSD,1,[libbsd]),
-       [AC_MSG_WARN(Could not find libbsd, build disabled)])
- dnl Replace `main' with a function in -lcrypt:
--AC_CHECK_LIB(crypt, main,HAVE_LIBCRYPT=1; AC_DEFINE(HAVE_LIBCRYPT))
--AC_CHECK_LIB(des, des_ecb_encrypt, HAVE_LIBDES=1; AC_DEFINE(HAVE_LIBDES))
--AC_CHECK_LIB(ssl, DES_ecb_encrypt, HAVE_LIBSSL=1; AC_DEFINE(HAVE_LIBSSL))
-+AC_CHECK_LIB(crypt, main,HAVE_LIBCRYPT=1; AC_DEFINE(HAVE_LIBCRYPT,1,[libcrypt]))
-+AC_CHECK_LIB(des, des_ecb_encrypt, HAVE_LIBDES=1; AC_DEFINE(HAVE_LIBDES,1,[libdes]))
-+AC_CHECK_LIB(ssl, DES_ecb_encrypt, HAVE_LIBSSL=1; AC_DEFINE(HAVE_LIBSSL,1,[libssl]))
- dnl Checks for header files.
- AC_HEADER_STDC
- AC_HEADER_SYS_WAIT
- AC_CHECK_HEADERS(fcntl.h limits.h paths.h sys/file.h sys/ioctl.h sys/time.h syslog.h unistd.h)
--AC_CHECK_HEADER(shadow.h, HAVE_SHADOW_H=1; AC_DEFINE(HAVE_SHADOW_H))
--AC_CHECK_HEADER(linux/isdn_lzscomp.h, HAVE_LZSCOMP_H=1; AC_DEFINE(HAVE_LZSCOMP_H))
--AC_CHECK_HEADER(pcap-bpf.h, [HAVE_PCAP_BPF_H=1; AC_DEFINE(HAVE_PCAP_BPF_H)],
--      [AC_CHECK_HEADER(net/bpf.h, [HAVE_NET_BPF_H=1; AC_DEFINE(HAVE_NET_BPF_H)],
-+AC_CHECK_HEADER(shadow.h, HAVE_SHADOW_H=1; AC_DEFINE(HAVE_SHADOW_H,1,[have shadow.h]))
-+AC_CHECK_HEADER(linux/isdn_lzscomp.h, HAVE_LZSCOMP_H=1; AC_DEFINE(HAVE_LZSCOMP_H,1,[isdn_lzscomp.h]))
-+AC_CHECK_HEADER(pcap-bpf.h, [HAVE_PCAP_BPF_H=1; AC_DEFINE(HAVE_PCAP_BPF_H,1,[pcap-bpf.h])],
-+      [AC_CHECK_HEADER(net/bpf.h, [HAVE_NET_BPF_H=1; AC_DEFINE(HAVE_NET_BPF_H,1,[net/bpf.h])],
-               [AC_MSG_ERROR(Could not find pcap header file)])])
- dnl Checks for typedefs, structures, and compiler characteristics.
-@@ -51,62 +51,63 @@
- AC_ARG_WITH(sbin,
-       [  --with-sbin=DIR         Set directory where ipppd is istalled. [/sbin]],
-       CONFIG_SBINDIR="${withval}"
--      AC_DEFINE(CONFIG_SBINDIR,"${withval}"),
-+      AC_DEFINE(CONFIG_SBINDIR,"${withval}",[sbin dir]),
- )
- dnl Optional man directory
- AC_ARG_WITH(sbin,
-       [  --with-man=DIR          Set manpage directory. [/usr/man]],
-       CONFIG_MANDIR="${withval}"
--      AC_DEFINE(CONFIG_MANDIR,"${withval}"),
-+      AC_DEFINE(CONFIG_MANDIR,"${withval}",[man dir]),
- )
- dnl Optional /var/run directory
- AC_ARG_WITH(sbin,
-       [  --with-varrun=DIR       Set directory for .pid files. [/var/run]],
-       CONFIG_RUNDIR="${withval}"
--      AC_DEFINE(CONFIG_RUNDIR,"${withval}"),
-+      AC_DEFINE(CONFIG_RUNDIR,"${withval}",[/var/run dir]),
- )
- dnl Optional MSCHAP
- AC_ARG_ENABLE(mschap,
-       [  --enable-mschap         Enable Microsoft chap authentication [no]],
-       CONFIG_IPPPD_MSCHAP="y"
--      AC_DEFINE(CONFIG_IPPPD_MSCHAP,"y"),
-+      AC_DEFINE(CONFIG_IPPPD_MSCHAP,"y",[support M$-chap]),
- )
- dnl Optional RADIUS
- AC_ARG_ENABLE(radius,
-       [  --enable-radius         Enable RADIUS authentication [no]],
-       CONFIG_IPPPD_RADIUS="y"
--      AC_DEFINE(CONFIG_IPPPD_RADIUS,"y"),
-+      AC_DEFINE(CONFIG_IPPPD_RADIUS,"y",[support radius]),
- )
- dnl Optional radiusclient config file
- AC_ARG_WITH(radiusclient_config,
-       [  --with-radiusclient=FILE Set filename for radiusclient configuration],
-       RADIUS_CLIENT_CONFIG_FILE="${withval}"
--      AC_DEFINE(RADIUS_CLIENT_CONFIG_FILE,"${withval}"),
-+      AC_DEFINE(RADIUS_CLIENT_CONFIG_FILE,"${withval}",[radius config]),
- )
- dnl Optional RADIUS_WTMP_LOGGING
- AC_ARG_ENABLE(radius_wtmp_logging,
-       [  --enable-radius-wtmp       Enable RADIUS_WTMP_LOGGING authentication [no]],
-       CONFIG_IPPPD_RADIUS_WTMP_LOGGING="y"
--      AC_DEFINE(CONFIG_IPPPD_RADIUS_WTMP_LOGGING,"y"),
-+      AC_DEFINE(CONFIG_IPPPD_RADIUS_WTMP_LOGGING,"y",[radius logging]),
- )
- dnl Optional DEBUGGING
- AC_ARG_ENABLE(debug,
-       [  --enable-debug          Enable debugging [no]],
-       CONFIG_IPPPD_DEBUGFLAGS="-DDEBUGALL"
--      AC_DEFINE(CONFIG_IPPPD_DEBUGFLAGS,"-DDEBUGALL"),
-+      AC_DEFINE(CONFIG_IPPPD_DEBUGFLAGS,"-DDEBUGALL",[options]),
- )
- AC_ARG_ENABLE(ippp-filter,
-       [  --enable-ippp-filter    Enable IPPP Filters (needs kernel supports) [no]],
-       CONFIG_IPPP_FILTER="y"
-       AC_DEFINE(CONFIG_IPPP_FILTER,"y"),
-+      AC_DEFINE(CONFIG_IPPP_FILTER,"y", [ipppd filter]),
- )
- AC_SUBST(I4LVERSION)
---- isdn4k-utils-CVS-2004-11-18/isdnlog/configure.in.ac25x     2004-10-28 03:53:29.000000000 +0200
-+++ isdn4k-utils-CVS-2004-11-18/isdnlog/configure.in   2004-11-18 17:47:52.642740487 +0100
-@@ -79,45 +79,46 @@
- dnl To make it possible to set variables in policy.h
- dnl they have to be defined with AC_DEFINE...
- dnl
--AC_DEFINE_UNQUOTED(OLDCONFDIR,"$OLDCONFDIR")
--AC_DEFINE_UNQUOTED(OLDCONFFILE,"$OLDCONFFILE")
--AC_DEFINE_UNQUOTED(DATADIR,"$datadir")
--AC_DEFINE_UNQUOTED(SERV_PORT,$SERV_PORT)
--AC_DEFINE_UNQUOTED(USERFILE,"$USERFILE")
--AC_DEFINE_UNQUOTED(LOGFILE,"$LOGFILE")
--AC_DEFINE_UNQUOTED(CHARGEFILE,"$CHARGEFILE")
--AC_DEFINE_UNQUOTED(RELOADCMD,"$RELOADCMD")
--AC_DEFINE_UNQUOTED(STOPCMD,"$STOPCMD")
--AC_DEFINE_UNQUOTED(REBOOTCMD,"$REBOOTCMD")
-+AC_DEFINE_UNQUOTED(OLDCONFDIR,"$OLDCONFDIR", [old config dir])
-+AC_DEFINE_UNQUOTED(OLDCONFFILE,"$OLDCONFFILE", [old config file])
-+AC_DEFINE_UNQUOTED(DATADIR,"$datadir", [data dir])
-+AC_DEFINE_UNQUOTED(SERV_PORT,$SERV_PORT, [server port])
-+AC_DEFINE_UNQUOTED(USERFILE,"$USERFILE", [user file])
-+AC_DEFINE_UNQUOTED(LOGFILE,"$LOGFILE", [log file])
-+AC_DEFINE_UNQUOTED(CHARGEFILE,"$CHARGEFILE", [charge file])
-+AC_DEFINE_UNQUOTED(RELOADCMD,"$RELOADCMD", [reload command])
-+AC_DEFINE_UNQUOTED(STOPCMD,"$STOPCMD", [stop command])
-+AC_DEFINE_UNQUOTED(REBOOTCMD,"$REBOOTCMD", [reboot command])
-+
- if test "$CONFIG_ISDN_LOG_DE" = "y" ; then
-       NATION="de"
-       NATION_MACRO="ISDN_DE"
--      AC_DEFINE(ISDN_DE)
-+      AC_DEFINE(ISDN_DE, 1, [German ISDN])
- fi
- if test "$CONFIG_ISDN_LOG_AT" = "y" ; then
-       NATION="at"
-       NATION_MACRO="ISDN_AT"
--      AC_DEFINE(ISDN_AT)
-+      AC_DEFINE(ISDN_AT, 1, [Austrian ISDN])
- fi
- if test "$CONFIG_ISDN_LOG_CH" = "y" ; then
-       NATION="ch"
-       NATION_MACRO="ISDN_CH"
--      AC_DEFINE(ISDN_CH)
-+      AC_DEFINE(ISDN_CH, 1, [Swiss ISDN])
- fi
- if test "$CONFIG_ISDN_LOG_NL" = "y" ; then
-       NATION="nl"
-       NATION_MACRO="ISDN_NL"
--      AC_DEFINE(ISDN_NL)
-+      AC_DEFINE(ISDN_NL, 1, [Dutch ISDN])
- fi
- if test "$CONFIG_ISDN_LOG_LU" = "y" ; then
-       NATION="lu"
-       NATION_MACRO="ISDN_LU"
--      AC_DEFINE(ISDN_LU)
-+      AC_DEFINE(ISDN_LU, 1, [Luxembourg ISDN])
- fi
- if test "$CONFIG_ISDN_LOG_XX" = "y" ; then
-       NATION=$CONFIG_ISDN_LOG_CC
-       NATION_MACRO="ISDN_XX"
--      AC_DEFINE(ISDN_XX)
-+      AC_DEFINE(ISDN_XX, 1, [Other country])
- fi
- dnl Checks for programs.
-@@ -130,17 +131,17 @@
- dnl Checks for libraries.
- if test -e tools/cdb/i4l_cdb.c  ; then
--    AC_DEFINE(USE_CDB)
-+    AC_DEFINE(USE_CDB, 1, [Use CDB])
-     CDBEXTRALIBS="tools/cdb/i4l_cdb.a"
-     DBEXT=".cdb"
-     RDBEXT=".cdb"
-     AC_MSG_RESULT(Using 'cdb' as database)
- else
--AC_CHECK_LIB(gdbm, gdbm_open, DBMLIB=-lgdbm; AC_DEFINE(HAVE_LIBGDBM),
--      [AC_CHECK_LIB(dbm, dbm_open, DBMLIB=-ldbm; AC_DEFINE(HAVE_LIBDBM),
--              [AC_CHECK_LIB(db, dbm_open, DBMLIB=-ldb; AC_DEFINE(HAVE_LIBDB))])])
-+AC_CHECK_LIB(gdbm, gdbm_open, DBMLIB=-lgdbm; AC_DEFINE(HAVE_LIBGDBM, 1, [Use libgdbm]),
-+      AC_CHECK_LIB(dbm, dbm_open, DBMLIB=-ldbm; AC_DEFINE(HAVE_LIBDBM, 1, [Use libdbm]),
-+              AC_CHECK_LIB(db, dbm_open, DBMLIB=-ldb; AC_DEFINE(HAVE_LIBDB, 1, [use libdb]))))
- fi
--AC_DEFINE_UNQUOTED(RDBEXT,"$RDBEXT")
-+AC_DEFINE_UNQUOTED(RDBEXT,"$RDBEXT",[rdb extension])
- dnl log database support
- AC_CHECK_POSTGRES
-@@ -158,7 +159,7 @@
- dnl Manual config
- AC_ARG_WITH(isdnlib,
-       [  --with-isdnlib=DIR      Set isdn library [../lib]],
--      LIBISDNDIR=$withval; AC_DEFINE_UNQUOTED(LIBISDNDIR,"$withval"))
-+      LIBISDNDIR=$withval; AC_DEFINE_UNQUOTED(LIBISDNDIR,"$withval",[libisdn dir]))
- AC_ARG_WITH(area-lib,
-       [  --with-area-lib=STRING  Set area library type [area]],
-       ALIB=$withval)
-@@ -167,16 +168,16 @@
-       CHARGECOUNTRY=$withval)
- AC_ARG_WITH(oldconfdir,
-       [  --with-oldconfdir=DIR   Set old config directory [/etc/isdnlog]],
--      OLDCONFDIR=$withval; AC_DEFINE_UNQUOTED(OLDCONFDIR,"$withval"))
-+      OLDCONFDIR=$withval; AC_DEFINE_UNQUOTED(OLDCONFDIR,"$withval", [old config dir]))
- AC_ARG_WITH(oldconf,
-       [  --with-oldconf=NAME     Set old config file name [isdnlog.conf]],
--      OLDCONFFILE=$withval; AC_DEFINE_UNQUOTED(OLDCONFFILE,"$withval"))
-+      OLDCONFFILE=$withval; AC_DEFINE_UNQUOTED(OLDCONFFILE,"$withval", [old config file]))
- AC_ARG_WITH(datadir,
-         [  --with-datadir=DIR      Set data directory [/usr/lib/isdn]],
--        datadir=$withval; AC_DEFINE_UNQUOTED(DATADIR,"$withval"))
-+        datadir=$withval; AC_DEFINE_UNQUOTED(DATADIR,"$withval", [data dir]))
- AC_ARG_WITH(sport,
-       [  --with-sport=INT        Set server port [20011]],
--      SERV_PORT=$withval; AC_DEFINE_UNQUOTED(SERV_PORT,$withval))
-+      SERV_PORT=$withval; AC_DEFINE_UNQUOTED(SERV_PORT,$withval, [server port]))
- dnl Checks for typedefs, structures, and compiler characteristics.
- AC_C_CONST
-@@ -196,28 +197,28 @@
- if test "$ALIB" = "area" ; then
-       LIBAREA=1
--      AC_DEFINE(LIBAREA)
-+      AC_DEFINE(LIBAREA, 1, [libarea])
- fi
- case "$CHARGECOUNTRY" in
-       DE)
-               NATION="de"
-               NATION_MACRO="ISDN_DE"
--              AC_DEFINE(ISDN_DE)
-+              AC_DEFINE(ISDN_DE, 1, [German ISDN])
-               ;;
-       AT)
-               NATION="at"
-               NATION_MACRO="ISDN_AT"
--              AC_DEFINE(ISDN_AT)
-+              AC_DEFINE(ISDN_AT, 1, [Austrian ISDN])
-               ;;
-       CH)
-               NATION="ch"
-               NATION_MACRO="ISDN_CH"
--              AC_DEFINE(ISDN_CH)
-+              AC_DEFINE(ISDN_CH, 1, [Swiss ISDN])
-               ;;
-       NL)
-               NATION="nl"
-               NATION_MACRO="ISDN_NL"
--              AC_DEFINE(ISDN_NL)
-+              AC_DEFINE(ISDN_NL, 1, [Dutch ISDN])
-               ;;
- esac
---- isdn4k-utils-CVS-2004-11-18/isdnlog/aclocal.m4.ac25x       2002-07-19 21:03:55.000000000 +0200
-+++ isdn4k-utils-CVS-2004-11-18/isdnlog/aclocal.m4     2004-11-18 17:47:52.643740339 +0100
-@@ -45,13 +45,13 @@
-       if test "$pqdir" != "no" ; then
-               AC_MSG_RESULT("yes")
-               POSTGRES=1
--              AC_DEFINE_UNQUOTED(POSTGRES,1)
-+              AC_DEFINE_UNQUOTED(POSTGRES,1,[postgres support])
-       else
-               AC_MSG_RESULT("no POSTGRES DISABLED")
-               pqdir=""
-       fi
-       POSTGRESDIR="$pqdir"
--      AC_DEFINE_UNQUOTED(POSTGRESDIR,"$pqdir")
-+      AC_DEFINE_UNQUOTED(POSTGRESDIR,"$pqdir",[postgres dir])
-       AC_SUBST(POSTGRES)
-       AC_SUBST(POSTGRESDIR)
- ])
-@@ -108,13 +108,13 @@
-       if test "$mydir" != "no" ; then
-               AC_MSG_RESULT("yes")
-               MYSQLDB=1
--              AC_DEFINE_UNQUOTED(MYSQLDB,1)
-+              AC_DEFINE_UNQUOTED(MYSQLDB,1,[MySQL support])
-       else
-               AC_MSG_RESULT("no MYSQL DISABLED")
-               mydir=""
-       fi
-       MYSQLDIR="$mydir"
--      AC_DEFINE_UNQUOTED(MYSQLDIR,"$mydir")
-+      AC_DEFINE_UNQUOTED(MYSQLDIR,"$mydir",[MySQL dir])
-       AC_SUBST(MYSQLDB)
-       AC_SUBST(MYSQLDIR)
- ])
-@@ -134,7 +134,7 @@
-       if test "$oradir" != "no" ; then
-               AC_MSG_RESULT("yes")
-               ORACLE=1
--              AC_DEFINE_UNQUOTED(ORACLE,1)
-+              AC_DEFINE_UNQUOTED(ORACLE,1,[oracle support, unsupported])
-       else
-               AC_MSG_RESULT("no ORACLE DISABLED")
-       fi
---- isdn4k-utils-CVS-2004-11-18/vbox3/configure.in.ac25x       1998-11-10 19:36:19.000000000 +0100
-+++ isdn4k-utils-CVS-2004-11-18/vbox3/configure.in     2004-11-18 17:47:52.644740191 +0100
-@@ -17,11 +17,9 @@
- ## programs ###############################################################
- AC_PROG_CC
--AC_PROG_CC_WORKS
--AC_PROG_CC_GNU
- AC_PROG_RANLIB
--AM_PROG_INSTALL
-+AC_PROG_INSTALL
- ## libraries ##############################################################
---- isdn4k-utils-CVS-2004-11-18/vbox3/vboxgetty/Makefile.am.ac25x      1998-11-10 19:36:25.000000000 +0100
-+++ isdn4k-utils-CVS-2004-11-18/vbox3/vboxgetty/Makefile.am    2004-11-18 17:47:52.644740191 +0100
-@@ -12,7 +12,7 @@
- ## vboxgetty ##############################################################
--DEFS                 += -DSYSCONFDIR='"$(sysconfdir)"' -DPKGDATADIR='"$(pkgdatadir)"' -DLOGDIR='"$(packagelogdir)"' -DLOCKDIR='"$(packagelockdir)"' -DPIDDIR='"$(packagepiddir)"'
-+DEFS                  = -DSYSCONFDIR='"$(sysconfdir)"' -DPKGDATADIR='"$(pkgdatadir)"' -DLOGDIR='"$(packagelogdir)"' -DLOCKDIR='"$(packagelockdir)"' -DPIDDIR='"$(packagepiddir)"'
- INCLUDES              = $(all_includes) $(tcl_include)
---- isdn4k-utils-CVS-2004-11-18/isdnctrl/configure.in.ac25x    2002-07-19 23:23:54.000000000 +0200
-+++ isdn4k-utils-CVS-2004-11-18/isdnctrl/configure.in  2004-11-18 17:47:52.645740043 +0100
-@@ -30,21 +30,21 @@
- AC_ARG_WITH(sbin,
-       [  --with-sbin=DIR         Set dir where binary is istalled. [/sbin]],
-       CONFIG_SBINDIR="${withval}"
--      AC_DEFINE(CONFIG_SBINDIR,"${withval}"),
-+      AC_DEFINE(CONFIG_SBINDIR,"${withval}",[sbin dir]),
- )
- dnl Optional man directory
- AC_ARG_WITH(man,
-       [  --with-man=DIR          Set manpage dir. [/usr/man]],
-       CONFIG_MANDIR="${withval}"
--      AC_DEFINE(CONFIG_MANDIR,"${withval}"),
-+      AC_DEFINE(CONFIG_MANDIR,"${withval}",[man dir]),
- )
- dnl Optional config-file-option
- AC_ARG_ENABLE(cfile,
-       [  --enable-cfile          Enable configfile option [no]],
-       CONFIG_ISDNCTRL_CONF=y
--      AC_DEFINE(CONFIG_ISDNCTRL_CONF,y),
-+      AC_DEFINE(CONFIG_ISDNCTRL_CONF,y,[enable config file]),
- )
- AC_SUBST(INSTALL)
---- isdn4k-utils-CVS-2004-11-18/imon/configure.in.ac25x        2002-07-19 21:03:53.000000000 +0200
-+++ isdn4k-utils-CVS-2004-11-18/imon/configure.in      2004-11-18 17:47:52.646739895 +0100
-@@ -38,14 +38,14 @@
- AC_ARG_WITH(sbin,
-       [  --with-sbin=DIR         Set dir where binary is istalled. [/sbin]],
-       CONFIG_SBINDIR="${withval}"
--      AC_DEFINE(CONFIG_SBINDIR,"${withval}"),
-+      AC_DEFINE(CONFIG_SBINDIR,"${withval}",[kernel directory]),
- )
- dnl Optional man directory
- AC_ARG_WITH(man,
--      [  --with-man=DIR          Set manpage dir. [/usr/man]],
-+      [  --with-man=DIR          Set manpage dir. [/usr/share/man]],
-       CONFIG_MANDIR="${withval}"
--      AC_DEFINE(CONFIG_MANDIR,"${withval}"),
-+      AC_DEFINE(CONFIG_MANDIR,"${withval}",[man directory]),
- )
- AC_SUBST(INSTALL)
---- isdn4k-utils-CVS-2004-11-18/eicon/configure.in.ac25x       2002-07-19 20:42:01.000000000 +0200
-+++ isdn4k-utils-CVS-2004-11-18/eicon/configure.in     2004-11-18 17:47:52.646739895 +0100
-@@ -35,21 +35,21 @@
- AC_ARG_WITH(firmware,
-       [  --with-firmware=DIR     Set dir where firmware istalled. [/usr/lib/isdn]],
-       CONFIG_DATADIR="${withval}"
--      AC_DEFINE(CONFIG_DATADIR,"${withval}"),
-+      AC_DEFINE(CONFIG_DATADIR,"${withval}",[data dir]),
- )
- dnl Optional sbin directory
- AC_ARG_WITH(sbin,
-       [  --with-sbin=DIR         Set dir where binary is istalled. [/sbin]],
-       CONFIG_SBINDIR="${withval}"
--      AC_DEFINE(CONFIG_SBINDIR,"${withval}"),
-+      AC_DEFINE(CONFIG_SBINDIR,"${withval}",[sbin dir]),
- )
- dnl Optional man directory
- AC_ARG_WITH(man,
-       [  --with-man=DIR          Set manpage dir. [/usr/man]],
-       CONFIG_MANDIR="${withval}"
--      AC_DEFINE(CONFIG_MANDIR,"${withval}"),
-+      AC_DEFINE(CONFIG_MANDIR,"${withval}",[man dir]),
- )
- dnl Check, if user wants dump option for debugging
-@@ -58,10 +58,10 @@
-       CONFIG_EICONCTRL_DEBUG="y"
- )
--AC_DEFINE(HAVE_XLOG)
-+AC_DEFINE(HAVE_XLOG,1,[define if you have xlog])
- AC_SUBST(HAVE_XLOG)
--AC_DEFINE(HAVE_TRACE)
-+AC_DEFINE(HAVE_TRACE,1,[define if you have trace])
- AC_SUBST(HAVE_TRACE)
- AC_SUBST(HAVE_NPCI)
diff --git a/src/patches/isdn4k-utils-CVS-2006-02-13-cleanup.patch b/src/patches/isdn4k-utils-CVS-2006-02-13-cleanup.patch
deleted file mode 100644 (file)
index 09a3118..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-*** ./icn/icnctrl.c.old        2002-11-27 14:30:43.000000000 +0000
---- ./icn/icnctrl.c    2002-11-27 14:31:10.000000000 +0000
-***************
-*** 223,229 ****
-       icn_cdef newcard;
-  
-       cmd = strrchr(argv[0], '/');
-!      cmd = (cmd == NULL) ? argv[0] : ++cmd;
-       if (argc > 1) {
-               if (!strcmp(argv[1], "-d")) {
-                       strcpy(ioctl_s.drvid, argv[2]);
---- 223,229 ----
-       icn_cdef newcard;
-  
-       cmd = strrchr(argv[0], '/');
-!      cmd = (cmd == NULL) ? argv[0] : (cmd + 1);
-       if (argc > 1) {
-               if (!strcmp(argv[1], "-d")) {
-                       strcpy(ioctl_s.drvid, argv[2]);
-*** ./isdnlog/isdnlog/processor.c.old  2002-11-27 14:27:28.000000000 +0000
---- ./isdnlog/isdnlog/processor.c      2002-11-27 14:27:41.000000000 +0000
-***************
-*** 3497,3503 ****
-       isdn_net_ioctl_phone netdvX_phone;
-  #endif
-    }     phone;
-!   auto          int rc, chan, l1, l2, lmin, lmax, ldiv, match;
-  
-    if ((iflst = fopen("/proc/net/dev", "r")) == NULL)
-      return(-1);
---- 3497,3503 ----
-       isdn_net_ioctl_phone netdvX_phone;
-  #endif
-    }     phone;
-!   auto          int rc, chan = 0, l1, l2, lmin, lmax, ldiv, match;
-  
-    if ((iflst = fopen("/proc/net/dev", "r")) == NULL)
-      return(-1);
-*** ./isdnlog/isdnrep/isdnbill.c.old   2002-11-27 14:30:11.000000000 +0000
---- ./isdnlog/isdnrep/isdnbill.c       2002-11-27 14:30:22.000000000 +0000
-***************
-*** 874,880 ****
-  #endif
-    auto     char     s[BUFSIZ], sx[BUFSIZ];
-    auto     int      i, l, col, day, lday = UNKNOWN, month, lmonth = UNKNOWN;
-!   auto     double   dur;
-    auto     char    *version;
-    auto     char    *myname = basename(argv[0]);
-    auto     int      opt, go, s0, indent;
---- 874,880 ----
-  #endif
-    auto     char     s[BUFSIZ], sx[BUFSIZ];
-    auto     int      i, l, col, day, lday = UNKNOWN, month, lmonth = UNKNOWN;
-!   auto     double   dur = 0.0;
-    auto     char    *version;
-    auto     char    *myname = basename(argv[0]);
-    auto     int      opt, go, s0, indent;
-*** ./isdnlog/isdnrep/isdnrep.c.old    2002-11-27 14:29:13.000000000 +0000
---- ./isdnlog/isdnrep/isdnrep.c        2002-11-27 14:29:50.000000000 +0000
-***************
-*** 2593,2599 ****
-  {
-    static char String[256];
-    one_call *tmp_call;
-!   int RetCode;
-  
-  
-    if (bill)
---- 2593,2599 ----
-  {
-    static char String[256];
-    one_call *tmp_call;
-!   int RetCode = 0;
-  
-  
-    if (bill)
-*** ./isdnlog/tools/zone.c.old 2002-11-27 14:28:01.000000000 +0000
---- ./isdnlog/tools/zone.c     2002-11-27 14:28:11.000000000 +0000
-***************
-*** 531,537 ****
-                       char *p = value.dptr;
-                       char to[10];
-                       US count;
-!                      int ito;
-                       unsigned char z=0;
-                       if (sthp->cc) /* if areacodes */
-                               /* here is since 1.00 a zero-terminated strring */
---- 531,537 ----
-                       char *p = value.dptr;
-                       char to[10];
-                       US count;
-!                      int ito = 0;
-                       unsigned char z=0;
-                       if (sthp->cc) /* if areacodes */
-                               /* here is since 1.00 a zero-terminated strring */
-*** ./loop/loopctrl.c.old      2002-11-27 14:32:08.000000000 +0000
---- ./loop/loopctrl.c  2002-11-27 14:32:23.000000000 +0000
-***************
-*** 175,181 ****
-       isdnloop_sdef startparm;
-  
-       cmd = strrchr(argv[0], '/');
-!      cmd = (cmd == NULL) ? argv[0] : ++cmd;
-       if (argc > 1) {
-               if (!strcmp(argv[1], "-d")) {
-                       strcpy(ioctl_s.drvid, argv[2]);
---- 175,181 ----
-       isdnloop_sdef startparm;
-  
-       cmd = strrchr(argv[0], '/');
-!      cmd = (cmd == NULL) ? argv[0] : (cmd + 1);
-       if (argc > 1) {
-               if (!strcmp(argv[1], "-d")) {
-                       strcpy(ioctl_s.drvid, argv[2]);
---- eicon/eiconctrl.c.orig     2006-04-19 16:16:02.000000000 +0200
-+++ eicon/eiconctrl.c  2006-04-19 16:17:25.000000000 +0200
-@@ -1970,7 +1970,7 @@
-                               val = strtol(p, &q, 16);
-                               p = q;
-                               val = strtol(p, &q, 16);
--                              (unsigned short) *buffer = (unsigned short) val;
-+                              *buffer = (unsigned short) val;
-                               pos = 2;
-                               while ((p != q) && (*q != 0)) {
-                                       p = q;
diff --git a/src/patches/isdn4k-utils-CVS-2006-07-20-pppd-2.4.4.patch b/src/patches/isdn4k-utils-CVS-2006-07-20-pppd-2.4.4.patch
deleted file mode 100644 (file)
index 64918c0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- isdn4k-utils-CVS-2006-07-20/pppdcapiplugin/Makefile.me     2006-07-19 16:43:45.000000000 +0200
-+++ isdn4k-utils-CVS-2006-07-20/pppdcapiplugin/Makefile        2006-07-19 16:43:59.000000000 +0200
-@@ -18,7 +18,7 @@
- PPPSRCDIRS=/src/isdn/pppd
- ifeq ($(PPPVERSIONS),)
--PPPVERSIONS = 2.4.3
-+PPPVERSIONS = 2.4.3 2.4.4
- endif
- PEERDIR=${DESTDIR}/etc/ppp/peers/isdn
diff --git a/src/patches/isdn4k-utils-CVS-2006-07-20-redhat.patch b/src/patches/isdn4k-utils-CVS-2006-07-20-redhat.patch
deleted file mode 100644 (file)
index ff1fc6d..0000000
+++ /dev/null
@@ -1,967 +0,0 @@
---- isdn4k-utils-CVS-2003-09-23/act2000/Makefile.in.redhat     2002-07-19 21:03:49.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/act2000/Makefile.in    2003-09-30 17:44:24.000000000 +0200
-@@ -5,8 +5,8 @@
- #
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -O2
--INCLUDES              = -I.
-+CFLAGS                        = $(RPM_OPT_FLAGS)
-+INCLUDES              = -I.
- DEFS                  =
- LDFLAGS                       = -L../lib @LIBS@
- PROGRAM                       = actctrl
-@@ -18,9 +18,9 @@
- MANDIR                        = @CONFIG_MANDIR@
- MAN8DIR                       = $(MANDIR)/man8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_DATA  = $(INSTALL) -o 0 -g 0 -m 0644
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_DATA  = $(INSTALL) -m 0644
-+INSTALL_MAN           = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- CC                            = @CC@
---- isdn4k-utils-CVS-2003-09-23/areacode/Makefile.in.redhat    1999-06-19 11:39:59.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/areacode/Makefile.in   2003-09-30 17:44:24.000000000 +0200
-@@ -12,7 +12,7 @@
-       # only ones that _really_ exist on _every_ system.
-       #
-       BUILDOPTS   := $(DATAOPTS)
--      INSTALLOPTS := $(DATAOPTS) INSTALL="install -o 0 -g 0 -m 644"
-+      INSTALLOPTS := $(DATAOPTS) INSTALL="install -m 644"
- endif
- all: .depend
---- isdn4k-utils-CVS-2003-09-23/avmb1/Makefile.in.redhat       2002-07-19 21:03:50.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/avmb1/Makefile.in      2003-09-30 17:44:24.000000000 +0200
-@@ -5,7 +5,7 @@
- #
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -O2
-+CFLAGS                        = $(RPM_OPT_FLAGS)
- LDFLAGS                       = -L../lib @LIBS@
- INCLUDES              = -I.
- PROGRAMS              = avmcapictrl
-@@ -15,8 +15,8 @@
- MANDIR                        = @CONFIG_MANDIR@
- MAN8DIR                       = $(MANDIR)/man8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_MAN           = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- CC                            = @CC@
---- isdn4k-utils-CVS-2003-09-23/capifax/Makefile.am.redhat     2000-03-03 16:54:12.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/capifax/Makefile.am    2003-09-30 17:44:24.000000000 +0200
-@@ -8,7 +8,7 @@
-                         stamp-h.in
- INCLUDES = -I../capi20 $(all_includes)
--CFLAGS = -Wall -O2
-+CFLAGS = -Wall $(RPM_OPT_FLAGS)
- LDFLAGS = -L../capi20/.libs -L../capi20 $(all_libraries)
- LDADD = -lcapi20
---- isdn4k-utils-CVS-2003-09-23/capiinfo/Makefile.am.redhat    2000-10-20 19:14:20.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/capiinfo/Makefile.am   2003-09-30 17:44:24.000000000 +0200
-@@ -8,7 +8,7 @@
-                         stamp-h.in comperr
- INCLUDES = -I../capi20 $(all_includes)
--CFLAGS = -Wall -O2
-+CFLAGS = -Wall $(RPM_OPT_FLAGS)
- LDFLAGS = -L../capi20/.libs -L../capi20 $(all_libraries)
- LDADD = -lcapi20
---- isdn4k-utils-CVS-2003-09-23/capiinit/Makefile.am.redhat    2000-03-17 17:19:43.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/capiinit/Makefile.am   2003-09-30 17:44:24.000000000 +0200
-@@ -8,7 +8,7 @@
-                         stamp-h.in comperr core
- INCLUDES = $(all_includes)
--CFLAGS = -Wall -O2 -D_GNU_SOURCE # -g
-+CFLAGS = -Wall -D_GNU_SOURCE $(RPM_OPT_FLAGS)
- LDFLAGS = $(all_libraries)
- LDADD = 
---- isdn4k-utils-CVS-2003-09-23/divertctrl/Makefile.in.redhat  2002-07-19 21:03:51.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/divertctrl/Makefile.in 2003-09-30 17:44:24.000000000 +0200
-@@ -5,16 +5,16 @@
- #
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -O2
--INCLUDES              = -I.
-+CFLAGS                        = -Wall $(RPM_OPT_FLAGS)
-+INCLUDES              = -I.
- DEFS                  =
- LDFLAGS                       = -L../lib @LIBS@
- PROGRAM                       = divertctrl
- MODULES                       = divertctrl.o
- MANPAGE                       = divertctrl.8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_MAN           = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- ifeq (../.config,$(wildcard ../.config))
---- isdn4k-utils-CVS-2003-09-23/doc/Makefile.in.redhat 1999-12-24 15:14:50.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/doc/Makefile.in        2003-09-30 17:44:24.000000000 +0200
-@@ -9,7 +9,7 @@
- SED                           = @SED@
- MANDIR                        = @CONFIG_MANDIR@
- MANPAGES              = ttyI.4 isdninfo.4 isdn_audio.4 isdnctrl.4 isdn_cause.7
--INSTALL_MAN           = @INSTALL@ -o 0 -g 0 -m 0644
-+INSTALL_MAN           = @INSTALL@ -m 0644
- prefix                        = @prefix@
- %.1: %.man
---- isdn4k-utils-CVS-2003-09-23/eicon/Makefile.in.redhat       2002-07-19 20:42:01.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/eicon/Makefile.in      2003-09-30 17:44:24.000000000 +0200
-@@ -7,8 +7,8 @@
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -O2 -DUNIX -DLINUX
--INCLUDES              = -I. -Iinclude
-+CFLAGS                        = -Wall -DUNIX -DLINUX $(RPM_OPT_FLAGS)
-+INCLUDES              = -I. -Iinclude
- LDFLAGS                       = -L../lib @LIBS@
- PROGRAMS              = 
- PROGRAM                       = eiconctrl
-@@ -22,9 +22,9 @@
- DATA_DIR              = @CONFIG_DATADIR@
- MANDIR                        = @CONFIG_MANDIR@
- MAN8DIR                       = $(MANDIR)/man8
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_DATA  = $(INSTALL) -o 0 -g 0 -m 0644
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_DATA  = $(INSTALL) -m 0644
-+INSTALL_MAN           = $(INSTALL) -m 0644
- CC                            = @CC@
- COPTS                 = -DDATADIR=\"$(shell echo $(DESTDIR)$(DATA_DIR))\"
---- isdn4k-utils-CVS-2003-09-23/hisax/Makefile.in.redhat       2002-07-19 21:03:51.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/hisax/Makefile.in      2003-09-30 17:44:24.000000000 +0200
-@@ -6,7 +6,7 @@
- #
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -O2 -I.
-+CFLAGS                        = -Wall $(RPM_OPT_FLAGS) -I.
- LDFLAGS                       = -L../lib @LIBS@
- PROGRAMS              =
- MODULES                       = hisaxctrl.o
-@@ -16,9 +16,9 @@
- DATADIR                       = @CONFIG_DATADIR@
- MANDIR                        = @CONFIG_MANDIR@
- MAN8DIR                       = $(MANDIR)/man8
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_DATA  = $(INSTALL) -o 0 -g 0 -m 0644
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_DATA  = $(INSTALL) -m 0644
-+INSTALL_MAN           = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- ifeq ("@CONFIG_HISAXCTRL@","y")
---- isdn4k-utils-CVS-2003-09-23/icn/Makefile.in.redhat 2002-07-19 21:03:52.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/icn/Makefile.in        2003-09-30 17:44:24.000000000 +0200
-@@ -5,8 +5,8 @@
- #
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -O2
--INCLUDES              = -I.
-+CFLAGS                        = -Wall $(RPM_OPT_FLAGS)
-+INCLUDES              = -I.
- DEFS                  =
- LDFLAGS                       = -L../lib @LIBS@
- PROGRAM                       = icnctrl
-@@ -17,9 +17,9 @@
- DATADIR                       = @CONFIG_DATADIR@
- MANDIR                        = @CONFIG_MANDIR@
- MAN8DIR                       = $(MANDIR)/man8
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_DATA  = $(INSTALL) -o 0 -g 0 -m 0644
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_DATA  = $(INSTALL) -m 0644
-+INSTALL_MAN           = $(INSTALL) -m 0644
- CC                            = @CC@
- COPTS                 =
---- isdn4k-utils-CVS-2003-09-23/imon/Makefile.in.redhat        2002-07-19 21:03:53.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/imon/Makefile.in       2003-09-30 17:44:24.000000000 +0200
-@@ -7,8 +7,8 @@
- #
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -O2
--INCLUDES              = -I.
-+CFLAGS                        = -Wall $(RPM_OPT_FLAGS)
-+INCLUDES              = -I.
- LDFLAGS                       = -L../lib @LIBS@
- PROGRAM                       = imon
- MODULES                       = imon.o
-@@ -18,8 +18,8 @@
- SBINDIR                       = @CONFIG_SBINDIR@
- MAN8DIR                       = $(MANDIR)/man8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_MAN           = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- CC                            = @CC@
---- isdn4k-utils-CVS-2003-09-23/imontty/Makefile.redhat        2002-07-19 23:23:53.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/imontty/Makefile       2003-09-30 17:44:24.000000000 +0200
-@@ -15,14 +15,14 @@
-       # Manual config standalone
-       #
-       CONFIG_SBINDRIR := /sbin
--      MAN8DIR         := /usr/man/man8
-+      MAN8DIR         := /usr/share/man/man8
- endif
- INSTALL=install
--INSTALL_MAN=$(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_MAN=$(INSTALL) -m 0644
- MANPAGE=imontty.8
--CCFLAGS=-O2
-+CCFLAGS=$(RPM_OPT_FLAGS)
- #CCFLAGS=-I$(ISDN_INCLUDE) -g
- # nothing to change behind this line
-@@ -34,13 +34,6 @@
- imontty: imontty.c imontty.h
-       cc $(CCFLAGS) -o imontty imontty.c
--rootperm:
--      @echo 'main(int argc,char**argv){unlink(argv[0]);return(getuid()==0);}'>g
--      @if gcc -x c -o G g && rm -f g && ./G ; then \
--              echo -e "\n\n      Need root permission for (de)installation!\n\n"; \
--              exit 1; \
--      fi
--
- imontty.8: imontty.8.in
-       MANDATE=`grep CHECKIN $< | awk '{print $$4}'`; \
-       sed \
-@@ -52,10 +45,10 @@
-       mkdir -p $(DESTDIR)$(MAN8DIR)
-       $(INSTALL_MAN) $< $(DESTDIR)$(MAN8DIR)/$(MANPAGE)
--install: $(PROGS) rootperm install-man
--      install -s -o 0 -g 0 -m 0755 $(PROGS) $(DESTDIR)$(CONFIG_SBINDIR)
-+install: $(PROGS) install-man
-+      install -m 0755 $(PROGS) $(DESTDIR)$(CONFIG_SBINDIR)
--uninstall: rootperm
-+uninstall:
-       for i in $(PROGS) ; do rm -f $(DESTDIR)$(CONFIG_SBINDIR)/$$i; done
- clean:
---- isdn4k-utils-CVS-2003-09-23/ipppstats/Makefile.in.redhat   2002-07-19 21:03:54.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/ipppstats/Makefile.in  2003-09-30 17:44:24.000000000 +0200
-@@ -6,14 +6,14 @@
- MANDIR       = @CONFIG_MANDIR@
- CC           = @CC@
- INSTALL      = @INSTALL@
--INSTALL_SBIN = $(INSTALL) -m 755 -o 0 -g 0
--INSTALL_DATA = $(INSTALL) -m 644 -o 0 -g 0
--INSTALL_DIR  = $(INSTALL) -m 755 -o 0 -g 0 -d
-+INSTALL_SBIN = $(INSTALL) -m 755
-+INSTALL_DATA = $(INSTALL) -m 644
-+INSTALL_DIR  = $(INSTALL) -m 755 -d
- PPPSTATSRCS  = ipppstats.c
- PPPSTATOBJS  = ipppstats.o
--CFLAGS       = -fomit-frame-pointer -O2
-+CFLAGS       = $(RPM_OPT_FLAGS)
- all: ipppstats
---- isdn4k-utils-CVS-2003-09-23/iprofd/Makefile.in.redhat      2002-07-19 23:23:53.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/iprofd/Makefile.in     2003-09-30 17:44:24.000000000 +0200
-@@ -5,8 +5,8 @@
- #
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -O2
--INCLUDES              = -I.
-+CFLAGS                        = -Wall $(RPM_OPT_FLAGS)
-+INCLUDES              = -I.
- LDFLAGS                       = -L../lib @LIBS@
- PROGRAM                       = iprofd
- MODULES                       = iprofd.o
-@@ -15,8 +15,8 @@
- MANDIR                        = @CONFIG_MANDIR@
- MAN8DIR                       = $(MANDIR)/man8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_MAN           = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- CC                            = @CC@
---- isdn4k-utils-CVS-2003-09-23/isdnctrl/Makefile.in.redhat    2002-07-19 23:23:54.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/isdnctrl/Makefile.in   2003-09-30 17:44:24.000000000 +0200
-@@ -5,8 +5,8 @@
- #
- #
- SHELL                   = /bin/sh
--CFLAGS                        = -Wall -O2
--INCLUDES              = -I.
-+CFLAGS                        = -Wall $(RPM_OPT_FLAGS)
-+INCLUDES              = -I.
- LDFLAGS                       = @LIBS@ 
- PROGRAM                       = isdnctrl
- MODULES                       = isdnctrl.o
-@@ -15,8 +15,8 @@
- MANDIR                        = @CONFIG_MANDIR@
- MAN8DIR                       = $(MANDIR)/man8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_MAN           = $(INSTALL) -m 0644
- CC                            = @CC@ -DVERSION=\"@I4LVERSION@\"
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
---- isdn4k-utils-CVS-2003-09-23/isdnlog/samples/callerid.conf.redhat   2000-09-08 10:55:51.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/isdnlog/samples/callerid.conf  2003-09-30 17:44:24.000000000 +0200
-@@ -2,38 +2,31 @@
- # 
- # More information: See the isdnlog documentation
-+#INTERFACE = ippp0      # Isdn network interface. This information  is  required
-+                        # with the "-hx" / hangup="value" option.
-+
-+
- [MSN]
- NUMBER = 4711
- ALIAS  = Phone
- SI     = 1
- ZONE   = 1
--START = {
--  [FLAG]
--  FLAGS = I|O|R|C|B|A|E|H
--  PROGRAM = /bin/myprog \$1 \$2 \$3 Phone
--}
-+#START = {
-+#  [FLAG]
-+#  FLAGS = I|O|R|C|B|A|E|H
-+#  PROGRAM = /bin/myprog \$1 \$2 \$3 Phone
-+#}
- [MSN]
- NUMBER = 4711
- ALIAS  = HDLC
- SI     = 7
- ZONE   = 1
--START = {
--  [FLAG]
--  FLAGS = I|O|R|C|B|A|E|
--  PROGRAM = /bin/myprog \$1 \$2 \$3 HDLC @/home/user1/parameter
--}
--
--[MSN]
--NUMBER = 4712
--ALIAS  = Modem
--SI     = 1
--ZONE   = 1
--START = {
--  [FLAG]
--  FLAGS = I|O|R|C|B|A|E|H
--  PROGRAM = /bin/myprog \$1 \$2 \$3 Modem
--}
-+#START = {
-+#  [FLAG]
-+#  FLAGS = I|O|R|C|B|A|E|
-+#  PROGRAM = /bin/myprog \$1 \$2 \$3 HDLC @/home/user1/parameter
-+#}
- [NUMBER]
- NUMBER = 01910
---- isdn4k-utils-CVS-2003-09-23/isdnlog/tools/cdb/Makefile.in.redhat   2000-08-15 17:16:23.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/isdnlog/tools/cdb/Makefile.in  2003-09-30 17:44:24.000000000 +0200
-@@ -20,7 +20,7 @@
- BINDIR:=$(DESTDIR)@prefix@/bin
- INCDIR:=$(DESTDIR)@prefix@/include
--CFLAGS:=-Wall -O2
-+CFLAGS:=-Wall $(RPM_OPT_FLAGS)
- all: depend $(FILES)
-@@ -46,7 +46,7 @@
-       install -d -m0755 $(MAN1DIR) $(MAN3DIR) $(LIBDIR) $(BINDIR) \
-               $(INCDIR)
--install:
-+install: install-dirs
-       install -m0755 $(BINS) $(BINDIR)
-       install -m0644 $(MAN1) $(MAN1DIR)
-       install -m0644 $(MAN3) $(MAN3DIR)
---- isdn4k-utils-CVS-2003-09-23/isdnlog/tools/dest/Makefile.in.redhat  2003-07-25 23:23:15.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/isdnlog/tools/dest/Makefile.in 2003-09-30 17:44:24.000000000 +0200
-@@ -6,7 +6,7 @@
- -include ../../../.config
- BZIP2                 = @BZIP2@
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -g
-+CFLAGS                        = -Wall $(RPM_OPT_FLAGS)
- INCLUDES              =
- LDFLAGS                       = @DBMLIB@
- export DBEXT          = @DBEXT@
-@@ -20,9 +20,9 @@
- SBINDIR                       = @CONFIG_SBINDIR@
- MAN8DIR                       = $(MANDIR)/man8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM               = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
--INSTALL_DATA          = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM               = $(INSTALL) -m 0750
-+INSTALL_MAN           = $(INSTALL) -m 0644
-+INSTALL_DATA          = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- DATADIR                       = @datadir@
---- isdn4k-utils-CVS-2003-09-23/isdnlog/tools/telrate/Makefile.in.redhat       1999-12-24 15:17:08.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/isdnlog/tools/telrate/Makefile.in      2003-09-30 17:44:24.000000000 +0200
-@@ -8,8 +8,8 @@
- CGIDIR                = @CGIDIR@
- TELDIR                = @TELDIR@
- INSTALL               = @INSTALL@
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0755
--INSTALL_FILE  = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0755
-+INSTALL_FILE  = $(INSTALL) -m 0644
- FILES = index.html info.html *.jpg *.gif tt.js
---- isdn4k-utils-CVS-2003-09-23/isdnlog/tools/zone/Makefile.in.redhat  2003-03-11 14:08:00.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/isdnlog/tools/zone/Makefile.in 2003-09-30 17:44:24.000000000 +0200
-@@ -5,7 +5,7 @@
- #
- BZIP2                 = @BZIP2@
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -g
-+CFLAGS                        = -Wall $(RPM_OPT_FLAGS)
- INCLUDES              =
- LDFLAGS                       = @DBMLIB@
- CDBEXTRALIBS          = @CDBEXTRALIBS@
-@@ -20,8 +20,8 @@
- SBINDIR                       = @CONFIG_SBINDIR@
- MAN8DIR                       = $(MANDIR)/man8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM               = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM               = $(INSTALL) -m 0750
-+INSTALL_MAN           = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- #CC                   = @CC@ -V2.7.2.3
---- isdn4k-utils-CVS-2003-09-23/isdnlog/Makefile.in.redhat     2003-08-26 21:46:11.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/isdnlog/Makefile.in    2003-09-30 17:44:24.000000000 +0200
-@@ -1542,10 +1542,10 @@
- # autoconf isdnlog specific stuff
- #
- INSTALL                       := @INSTALL@
--INSTALL_DIR           := $(INSTALL) -m 0755 -o 0 -g 0 -d
--INSTALL_SBIN          := $(INSTALL) -m 0700 -o 0 -g 0
--INSTALL_BIN           := $(INSTALL) -m 0755 -o 0 -g 0
--INSTALL_DATA          := $(INSTALL) -m 0644 -o 0 -g 0
-+INSTALL_DIR           := $(INSTALL) -m 0755 -d
-+INSTALL_SBIN          := $(INSTALL) -m 0700
-+INSTALL_BIN           := $(INSTALL) -m 0755
-+INSTALL_DATA          := $(INSTALL) -m 0644
- BZIP2                   := @BZIP2@
- BUNZIP2                 := $(BZIP2) -f -d
-@@ -1600,9 +1600,9 @@
- SUBDIRS     += $(LIBISDNDIR)
- endif
--# export CFLAGS  = -Wall -pipe -O6 -fomit-frame-pointer -fforce-mem -fforce-addr -funroll-loops -fstrength-reduce
-+# export CFLAGS  = -Wall -pipe -frame-pointer -fforce-mem -fforce-addr -funroll-loops -fstrength-reduce
--export CFLAGS  = -Wall -pipe
-+export CFLAGS  = -Wall $(RPM_OPT_FLAGS)
- ifndef _CC
- export _CC  = gcc
- endif
-@@ -1837,8 +1837,7 @@
-               echo ""; echo 'Do "make (un)install" as root!' ;echo ""; false; \
-       fi
--uninstall: rootperm
--              if ps x | fgrep $(ISDNLOG) >/dev/null; then kill `cat $(RUNDIR)/isdnlog.isdnctrl0.pid` 2>/dev/null; fi
-+uninstall:
-               rm -f   $(DESTDIR)$(SBINDIR)/$(ISDNLOG) \
-                       $(DESTDIR)$(BINDIR)/$(ISDNREP)  \
-                       $(DESTDIR)$(BINDIR)/$(ISDNCONF)
-@@ -1859,7 +1858,7 @@
-                       $(DESTDIR)$(DATADIR)/dest.cdb
--installdirs: rootperm
-+installdirs:
-               $(INSTALL_DIR) $(DESTDIR)$(I4LCONFDIR)
-               $(INSTALL_DIR) $(DESTDIR)$(BINDIR)
-               $(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
-@@ -1868,7 +1867,7 @@
-               $(INSTALL_DIR) $(DESTDIR)$(MAN8DIR)
-               $(INSTALL_DIR) $(DESTDIR)$(DATADIR)
--install: all rootperm installdirs install-conf install-data install-progs
-+install: all installdirs install-conf install-data install-progs
- install-old-conf:
-               @if [ -n "$(DESTDIR)$(OLDCONFDIR)" -a "$(DESTDIR)$(OLDCONFDIR)" != '/' ] ; then \
---- isdn4k-utils-CVS-2003-09-23/lib/Makefile.in.redhat 1999-12-12 18:22:36.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/lib/Makefile.in        2003-09-30 17:44:24.000000000 +0200
-@@ -11,7 +11,7 @@
-       # Install as root with numeric Id's, since these are the
-       # only ones that _really_ exist on _every_ system.
-       #
--      INSTALLOPTS += INSTALL= install -o 0 -g 0 -m 644
-+      INSTALLOPTS += INSTALL= install -m 644
- endif
- all: .depend
---- isdn4k-utils-CVS-2003-09-23/loop/Makefile.in.redhat        2002-07-19 21:03:56.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/loop/Makefile.in       2003-09-30 17:44:24.000000000 +0200
-@@ -5,16 +5,16 @@
- #
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -O2
--INCLUDES              = -I.
-+CFLAGS                        = -Wall $(RPM_OPT_FLAGS)
-+INCLUDES              = -I.
- DEFS                  =
- LDFLAGS                       = -L../lib @LIBS@
- PROGRAM                       = loopctrl
- MODULES                       = loopctrl.o
- MANPAGE                       = loopctrl.8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM       = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM       = $(INSTALL) -m 0750
-+INSTALL_MAN           = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- ifeq (../.config,$(wildcard ../.config))
---- isdn4k-utils-CVS-2003-09-23/pcbit/Makefile.in.redhat       2002-07-19 21:03:57.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/pcbit/Makefile.in      2003-09-30 17:44:24.000000000 +0200
-@@ -5,8 +5,8 @@
- #
- #
- SHELL                 = /bin/sh
--CFLAGS                        = -Wall -Wstrict-prototypes -O2 -g
--INCLUDES              = -I. -DDEBUG 
-+CFLAGS                        = -Wall -Wstrict-prototypes $(RPM_OPT_FLAGS)
-+INCLUDES              = -I. -DDEBUG
- LDFLAGS                       = -L../lib @LIBS@
- PROGRAM                       = pcbitctl
- MODULES                       = pcbitctl.o convhexbin.o
-@@ -15,8 +15,8 @@
- MANDIR                        = @CONFIG_MANDIR@
- MAN8DIR                       = $(MANDIR)/man8
- INSTALL                       = @INSTALL@
--INSTALL_PROGRAM               = $(INSTALL) -o 0 -g 0 -m 0750
--INSTALL_MAN           = $(INSTALL) -o 0 -g 0 -m 0644
-+INSTALL_PROGRAM               = $(INSTALL) -m 0750
-+INSTALL_MAN           = $(INSTALL) -m 0644
- prefix                        = @prefix@
- exec_prefix           = @exec_prefix@
- CC                            = @CC@
---- isdn4k-utils-CVS-2003-09-23/pppdcapiplugin/ppp-2.4.1/Makefile.redhat       2001-05-01 14:43:50.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/pppdcapiplugin/ppp-2.4.1/Makefile      2003-09-30 17:44:24.000000000 +0200
-@@ -8,7 +8,7 @@
- #  as published by the Free Software Foundation; either version
- #  2 of the License, or (at your option) any later version.
--PLUGINDIR=${DESTDIR}/usr/lib/pppd/$(PPPVERSION)
-+PLUGINDIR=${DESTDIR}/$(LIBDIR)/pppd/$(PPPVERSION)
- include $(TOPDIR)/Rules.make
---- isdn4k-utils-CVS-2003-09-23/rcapid/Makefile.am.redhat      2002-07-19 23:23:54.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/rcapid/Makefile.am     2003-09-30 17:44:24.000000000 +0200
-@@ -8,7 +8,7 @@
-                         stamp-h.in comperr
- INCLUDES = -I../capi20 $(all_includes)
--CFLAGS = -Wall -O2
-+CFLAGS = -Wall $(RPM_OPT_FLAGS)
- LDFLAGS = -L../capi20/.libs -L../capi20 $(all_libraries)
- LDADD = -lcapi20
---- isdn4k-utils-CVS-2003-09-23/vbox/examples/vboxd.conf.example.redhat        1997-04-28 18:51:29.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/vbox/examples/vboxd.conf.example       2003-09-30 17:44:24.000000000 +0200
-@@ -5,7 +5,7 @@
- # login (server startup) time. If access is 'yes' the host can login
- # and count messages without special access.
--L:localhost:Y
-+#L:localhost:Y
- L:*:N
- # Full access list
-@@ -13,7 +13,7 @@
- # All hosts in the full access list (begins with 'A') are checked if the
- # server gets the 'login' command.
--A:localhost:RW:michael:xxx:/var/spool/vbox/michael:incoming
--A:localhost:RW:nicole:xxx:/var/spool/vbox/nicole:incoming
-+#A:localhost:RW:michael:xxx:/var/spool/vbox/michael:incoming
-+#A:localhost:RW:nicole:xxx:/var/spool/vbox/nicole:incoming
- A:*:!:!:!:!:!
---- isdn4k-utils-CVS-2003-09-23/vbox/examples/vboxgetty.conf.example.redhat    1997-10-22 22:46:58.000000000 +0200
-+++ isdn4k-utils-CVS-2003-09-23/vbox/examples/vboxgetty.conf.example   2003-09-30 17:44:24.000000000 +0200
-@@ -20,18 +20,18 @@
- # Settings for port ttyI6
--port /dev/ttyI6
--  modeminit           ATZ&B512&E7830022
--  user                        nicole
--  group                       users
--  spooldir            /var/spool/vbox/nicole
-+#port /dev/ttyI6
-+#  modeminit          ATZ&B512&E7830022
-+#  user                       nicole
-+#  group                      users
-+#  spooldir           /var/spool/vbox/nicole
- # Settings for port ttyI7
--port /dev/ttyI7
--  modeminit           ATZ&B512&E7850413
--  user                        michael
--  group                       users
--  spooldir            /var/spool/vbox/michael
-+#port /dev/ttyI7
-+#  modeminit          ATZ&B512&E7850413
-+#  user                       michael
-+#  group                      users
-+#  spooldir           /var/spool/vbox/michael
---- isdn4k-utils-CVS-2003-09-23/vbox/Makefile.in.redhat        2002-01-31 21:05:40.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/vbox/Makefile.in       2003-09-30 17:44:24.000000000 +0200
-@@ -14,33 +14,33 @@
- # [*] Program to install binaries to the sbin directory (eg vboxgetty):      #
- #----------------------------------------------------------------------------#
--INSTALL_SBIN  = @INSTALL@ -m 750 -o root -g root -s
-+INSTALL_SBIN  = @INSTALL@ -m 750
- #----------------------------------------------------------------------------#
- # [*] Program to install binaries to the bin directory (eg vboxconvert):     #
- #----------------------------------------------------------------------------#
--INSTALL_BIN   = @INSTALL@ -m 755 -o root -g root -s
-+INSTALL_BIN   = @INSTALL@ -m 755
- #----------------------------------------------------------------------------#
- # [*] Program to install bash scripts to the bin directory (eg vboxplay):    #
- #----------------------------------------------------------------------------#
--INSTALL_SHBIN = @INSTALL@ -m 755 -o root -g root
-+INSTALL_SHBIN = @INSTALL@ -m 755
- #----------------------------------------------------------------------------#
- # [*] Program to install binaries to the bin directory and set the suid bit  #
- #     (eg vboxbeep):                                                         #
- #----------------------------------------------------------------------------#
--INSTALL_UBIN  = @INSTALL@ -m 4755 -o root -g root -s
-+INSTALL_UBIN  = @INSTALL@ -m 4755
- #----------------------------------------------------------------------------#
- # [*] Program to install configurations to sysconf directory                 #
- #     (eg vboxgetty.conf):                                                   #
- #----------------------------------------------------------------------------#
--INSTALL_SYSCONF       = @INSTALL@ -m 640 -o root -g root
-+INSTALL_SYSCONF       = @INSTALL@ -m 640
- #----------------------------------------------------------------------------#
- # [*] Program to create missing directories:                                 #
---- isdn4k-utils-CVS-2003-09-23/xisdnload/Imakefile.redhat     1998-03-08 19:54:01.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/xisdnload/Imakefile    2003-09-30 17:44:24.000000000 +0200
-@@ -21,7 +21,7 @@
-            OBJS = xisdnload.o
-  OSMAJORVERSION = OSMajorVersion
-  OSMINORVERSION = OSMinorVersion
--      DEFINES = -DOSMAJORVERSION=$(OSMAJORVERSION) -DOSMINORVERSION=$(OSMINORVERSION) -DREGEX_NUMBER
-+      DEFINES = -D_GNU_SOURCE -DOSMAJORVERSION=$(OSMAJORVERSION) -DOSMINORVERSION=$(OSMINORVERSION) -DREGEX_NUMBER
- AllTarget(xisdnload)
- NormalProgramTarget(xisdnload,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),NullParameter)
---- isdn4k-utils-CVS-2003-09-23/.config.rpm.redhat     1998-11-23 13:12:04.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/.config.rpm    2003-09-30 17:59:55.000000000 +0200
-@@ -5,16 +5,16 @@
- #
- # Code maturity level options
- #
--CONFIG_EXPERIMENTAL=y
-+# CONFIG_EXPERIMENTAL is not set
- #
- # General configuration
- #
- CONFIG_BUILDX11=y
--CONFIG_KERNELDIR='/usr/src/linux'
-+CONFIG_KERNELDIR='/usr/src/linux'
- CONFIG_BINDIR='/usr/bin'
--CONFIG_SBINDIR='/sbin'
--CONFIG_MANDIR='/usr/man'
-+CONFIG_SBINDIR='/usr/sbin'
-+CONFIG_MANDIR='/usr/share/man'
- CONFIG_RUNDIR='/var/run'
- CONFIG_LOCKDIR='/var/lock'
- CONFIG_LOCKFILE='LCK..'
-@@ -23,11 +23,9 @@
- CONFIG_CALLERIDFILE='callerid.conf'
- CONFIG_USERCONFFILE='~/.isdn'
- CONFIG_COUNTRYCODE='49'
--CONFIG_AREACODE=''
-+CONFIG_AREACODE='9999'
- CONFIG_COUNTRY_PREFIX='+'
- CONFIG_AREA_PREFIX='0'
--CONFIG_DATADIR='/usr/lib/isdn'
--CONFIG_LIB_AREACODE=y
- #
- # Runtime configuration tools
-@@ -36,18 +34,20 @@
- CONFIG_ISDNCTRL_CONF=y
- CONFIG_ISDNCTRL_TIMRU=y
- CONFIG_IPROFD=y
-+CONFIG_DIVERTCTRL=y
- #
- # Card configuration tools
- #
--# CONFIG_TELESCTRL is not set
-+CONFIG_TELESCTRL=y
- CONFIG_HISAXCTRL=y
- CONFIG_ICNCTRL=y
- # CONFIG_ICNCTRL_DEBUG is not set
- CONFIG_PCBITCTL=y
- CONFIG_AVMCAPICTRL=y
-+CONFIG_EICONCTRL=y
- CONFIG_LOOPCTRL=y
--CONFIG_LOOPCTRL_LOOPDIR='/usr/src/linux/drivers/isdn/isdnloop'
-+CONFIG_LOOPCTRL_LOOPDIR='/usr/src/linux-2.4/drivers/isdn/isdnloop'
- # CONFIG_LOOPCTRL_DEBUG is not set
- #
-@@ -64,14 +64,20 @@
- CONFIG_ISDNLOG_USERFILE='isdnlog.users'
- CONFIG_ISDNLOG_CHARGEFILE='charge.dat'
- CONFIG_ISDNLOG_LOGFILE='/var/log/isdn.log'
--CONFIG_ISDNLOG_RELOADCMD='reload'
--CONFIG_ISDNLOG_STOPCMD='stop'
-+CONFIG_ISDNLOG_RELOADCMD='/etc/rc.d/init.d/isdn restart'
-+CONFIG_ISDNLOG_STOPCMD='/etc/rc.d/init.d/isdn stop'
- CONFIG_ISDNLOG_REBOOTCMD='/sbin/reboot'
- CONFIG_ISDNLOG_OLDI4LCONFDIR='/etc/isdnlog'
- CONFIG_ISDNLOG_OLDI4LCONFFILE='isdnlog.conf'
- # CONFIG_ISDNLOG_POSTGRES is not set
- # CONFIG_ISDNLOG_MYSQLDB is not set
-+# CONFIG_ISDNLOG_ORACLE is not set
- CONFIG_ISDN_LOG_DE=y
-+CONFIG_ISDN_LOG_CC_DE=y
-+CONFIG_ISDN_LOG_DEST_DE=y
-+# CONFIG_ISDN_LOG_DEST_AT is not set
-+# CONFIG_ISDN_LOG_DEST_NL is not set
-+# CONFIG_ISDN_LOG_DEST_CH is not set
- CONFIG_IPPPSTATS=y
- CONFIG_XISDNLOAD=y
- CONFIG_XMONISDN=y
-@@ -79,8 +85,8 @@
- #
- # Options for xmonisdn
- #
--CONFIG_XMONISDN_UPCMD='/sbin/netup'
--CONFIG_XMONISDN_DOWNCMD='/sbin/netdown'
-+CONFIG_XMONISDN_UPCMD='/sbin/ifup'
-+CONFIG_XMONISDN_DOWNCMD='/sbin/ifdown'
- #
- # Applications
-@@ -94,23 +100,22 @@
- VBOX_LOGDIR='/var/log/vbox'
- VBOX_PIDDIR='/var/run'
- VBOX_LOCKDIR='/var/lock'
--VBOX_DOCDIR='/usr/doc/vbox'
--VBOX_TCL='tcl8.0'
-+VBOX_DOCDIR='/usr/share/doc/vbox'
-+VBOX_TCL='tcl8.3'
-+# VBOX_SUSPEND_ID is not set
- CONFIG_IPPPD=y
- #
- # Options for ipppd
- #
--CONFIG_IPPPD_MSCHAP=y
-+# CONFIG_IPPPD_MSCHAP is not set
-+CONFIG_IPPP_FILTER=y
- # CONFIG_IPPPD_RADIUS is not set
- # CONFIG_RADIUS_WTMP_LOGGING is not set
- RADIUS_CLIENT_CONFIG_FILE=''
- CONFIG_CAPIFAX=y
- CONFIG_RCAPID=y
--#
--# Documentation
--#
--CONFIG_GENMAN=y
--CONFIG_FAQ=y
--CONFIG_FAQDIR='/usr/doc/faq/isdn4linux'
-+# CAPI plugins
-+CONFIG_PPPDCAPIPLUGIN=y
-+
---- isdn4k-utils-CVS-2003-09-23/ipppd/ccp.c.redhat     2000-11-12 17:06:42.000000000 +0100
-+++ isdn4k-utils-CVS-2003-09-23/ipppd/ccp.c    2004-01-20 19:14:07.000000000 +0100
-@@ -41,7 +41,7 @@
- #include "compressions.h"
--#if 0
-+#if HAVE_LZSCOMP_H
- #include <linux/isdn_lzscomp.h>
- #else
- #include "../ipppcomp/isdn_lzscomp.h"
---- isdn4k-utils-CVS-2004-11-18/pppdcapiplugin/Makefile.redhat 2004-02-14 16:02:46.000000000 +0100
-+++ isdn4k-utils-CVS-2004-11-18/pppdcapiplugin/Makefile        2004-11-18 16:48:54.848276370 +0100
-@@ -12,13 +12,13 @@
- export CAPIINC=$(TOPDIR)/../capi20
- export CAPILIB=$(TOPDIR)/../capi20
- export INSTALL=$(TOPDIR)/install-sh -c
--export INSTALLDATA=$(TOPDIR)/install-sh -c -o root -m 600
-+export INSTALLDATA=$(TOPDIR)/install-sh -c -m 600
- export MKDIR=$(TOPDIR)/mkinstalldirs
- PPPSRCDIRS=/src/isdn/pppd
- ifeq ($(PPPVERSIONS),)
--PPPVERSIONS = 2.3.11 2.4.0 2.4.1 2.4.1b1 2.4.1b2 2.4.2b3 2.4.2 2.4.3
-+PPPVERSIONS = 2.4.3
- endif
- PEERDIR=${DESTDIR}/etc/ppp/peers/isdn
-@@ -62,7 +62,7 @@
-       done
- install-man:
--      for i in ${DESTDIR}/usr/share/man ${DESTDIR}/usr/man; do \
-+      for i in ${DESTDIR}/usr/share/man ; do \
-               if [ -d $$i/man8 ] ; then \
-                       echo $(INSTALLDATA) capiplugin.8 $$i/man8; \
-                       $(INSTALLDATA) capiplugin.8 $$i/man8; \
---- isdn4k-utils-CVS-2004-11-18/Makefile.redhat        2004-08-30 16:06:42.000000000 +0200
-+++ isdn4k-utils-CVS-2004-11-18/Makefile       2004-12-01 22:19:13.193347501 +0100
-@@ -16,8 +16,8 @@
- # Following line is important for lib and isdnlog (sl).
- export ROOTDIR=$(shell pwd)
--ifeq (.config,$(wildcard .config))
--include .config
-+ifeq (.config.h,$(wildcard .config.h))
-+include .config.h
- do-it-all:      subtargets
- else
- CONFIGURATION = config
-@@ -130,16 +130,10 @@
-               exit 1; \
-       fi
--install: rootperm
-+install:
-       set -e; for i in `echo $(SUBDIRS)`; do $(MAKE) -C $$i install; done
--      @if [ -c $(DESTDIR)/dev/isdnctrl0 ] && ls -l $(DESTDIR)/dev/isdnctrl0 | egrep "[[:space:]]45,[[:space:]]+64[[:space:]]" > /dev/null; \
--      then \
--              /bin/echo -e '(some) ISDN devices already exist, not creating them.\nUse scripts/makedev.sh manually if necessary.'; \
--      else \
--              sh scripts/makedev.sh $(DESTDIR) ; \
--      fi
--uninstall: rootperm
-+uninstall:
-       set -e; for i in `echo $(SUBDIRS)`; do $(MAKE) -C $$i uninstall; done
- #
-@@ -202,7 +196,7 @@
-       @set -e; for i in `echo $(BUILD_ONLY) $(SUBDIRS)`; do \
-               if [ -x $$i/configure ] ; then \
-                       /bin/echo -e "\nRunning configure in $$i ...\n"; sleep 1; \
--                      (cd $$i; ./configure --sbindir=$(CONFIG_SBINDIR) --bindir=$(CONFIG_BINDIR) --mandir=$(CONFIG_MANDIR) --datadir=$(CONFIG_DATADIR) || $(MAKE) -C ../ ERRDIR=$$i cfgerror); \
-+                      (cd $$i; ./configure --sbindir=$(CONFIG_SBINDIR) --bindir=$(CONFIG_BINDIR) --mandir=$(CONFIG_MANDIR) --libdir=$(LIBDIR) --datadir=$(CONFIG_DATADIR) --enable-ippp-filter || $(MAKE) -C ../ ERRDIR=$$i cfgerror); \
-               elif [ -f $$i/Makefile.in ] ; then \
-                       /bin/echo -e "\nRunning make -f Makefile.in config in $$i ...\n"; sleep 1; \
-                       $(MAKE) -C $$i -f Makefile.in config; \
---- isdn4k-utils-CVS-2005-02-16/ipppd/Makefile.in.redhat       2004-08-30 16:56:36.000000000 +0200
-+++ isdn4k-utils-CVS-2005-02-16/ipppd/Makefile.in      2005-02-16 18:42:54.119955183 +0100
-@@ -15,10 +15,10 @@
- MANDIR        := @CONFIG_MANDIR@
- CC            := @CC@
- INSTALL       := @INSTALL@
--INSTALL_DIR   := $(INSTALL) -m 0755 -o 0 -g 0 -d
--INSTALL_SBIN  := $(INSTALL) -m 0700 -o 0 -g 0
--INSTALL_BIN   := $(INSTALL) -m 0755 -o 0 -g 0
--INSTALL_DATA  := $(INSTALL) -m 0644 -o 0 -g 0
-+INSTALL_DIR   := $(INSTALL) -m 0755 -d
-+INSTALL_SBIN  := $(INSTALL) -m 0700 
-+INSTALL_BIN   := $(INSTALL) -m 0755
-+INSTALL_DATA  := $(INSTALL) -m 0644
- RADIUS_CLIENT_CONFIG_FILE := @RADIUS_CLIENT_CONFIG_FILE@
- ifeq (@CONFIG_IPPPD_MSCHAP@,y)
-@@ -73,7 +73,7 @@
- DEBUG_FLAGS   = @CONFIG_IPPPD_DEBUGFLAGS@
- COMPILE_FLAGS = 
--CFLAGS        = -O2 -fomit-frame-pointer -Wall
-+CFLAGS        = $(RPM_OPT_FLAGS)
- VER           = 2.2.0
- # it's a hack
---- isdn4k-utils-CVS-2005-02-16/isdnlog/tools/Makefile.cflags  2005-02-16 18:53:15.393382578 +0100
-+++ isdn4k-utils-CVS-2005-02-16/isdnlog/tools/Makefile 2005-02-16 18:53:51.914999474 +0100
-@@ -1,4 +1,4 @@
--CC=gcc -m486 -O2 -Wall -DSTANDALONE -I. -I.. -I../isdnlog -I../connect -I../../lib
-+CC=gcc $(RPM_OPT_FLAGS) -DSTANDALONE -I. -I.. -I../isdnlog -I../connect -I../../lib
- #CC=gcc -m486 -O2 -g -pg -Wall -DSTANDALONE -I. -I.. -I../isdnlog
- all: rate-at
---- isdn4k-utils-CVS-2005-02-16/lib/Makefile.cflags    2005-02-16 19:04:04.338731270 +0100
-+++ isdn4k-utils-CVS-2005-02-16/lib/Makefile   2005-02-16 19:04:24.150811068 +0100
-@@ -28,7 +28,7 @@
- # USER CONFIGURATION AREA
- ######################################################################
--CFLAGS      = -g -Wall -pipe #-O6
-+CFLAGS      = $(RPM_OPT_FLAGS)
- DEFS        =
- ifndef _CC
- export _CC  = gcc
diff --git a/src/patches/isdn4k-utils-capiinit.patch b/src/patches/isdn4k-utils-capiinit.patch
deleted file mode 100644 (file)
index 7593d07..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
---- isdn4k-utils.orig/capiinit/capiinit.c      2006-04-18 19:27:03.689945766 +0200
-+++ isdn4k-utils/capiinit/capiinit.c   2006-04-18 19:36:53.130636890 +0200
-@@ -1251,6 +1251,7 @@
-       if (check_procfs() < 0) return -1;
-       if (check_for_kernelcapi() < 0) return -1;
-       if (check_for_capi() < 0) return -1;
-+      sleep(5); /* wait until the device node is created successfully by udev */
-       if (check_for_devcapi() < 0) return -1;
-       if (check_for_capifs() < 0) return 0; /* only warning */
-       if (check_for_capifs_mounted() < 0) return -1;
---- isdn4k-utils.orig/capiinit/capi.conf       2006-04-18 19:37:43.515250539 +0200
-+++ isdn4k-utils/capiinit/capi.conf    2006-04-18 19:37:53.953559630 +0200
-@@ -1,10 +1,10 @@
- # card                file    proto   io      irq     mem     cardnr  options
- #b1isa                b1.t4   DSS1    0x150   7       -       -       P2P
--b1pci         b1.t4   DSS1    -       -       -       -
--c4            c4.bin  DSS1    -       -       -       -
--c4            -       DSS1    -       -       -       -
--c4            -       DSS1    -       -       -       -       P2P
--c4            -       DSS1    -       -       -       -       P2P
-+#b1pci                b1.t4   DSS1    -       -       -       -
-+#c4           c4.bin  DSS1    -       -       -       -
-+#c4           -       DSS1    -       -       -       -
-+#c4           -       DSS1    -       -       -       -       P2P
-+#c4           -       DSS1    -       -       -       -       P2P
- #c2           c2.bin  DSS1    -       -       -       -
- #c2           -       DSS1    -       -       -       -
- #t1isa                t1.t4   DSS1    0x340   9       -       0
---- isdn4k-utils-CVS-2003-09-23/capiinit/capiinit.c.capi       2006-04-18 20:53:22.437430551 +0200
-+++ isdn4k-utils-CVS-2003-09-23/capiinit/capiinit.c    2006-04-19 11:50:56.385891286 +0200
-@@ -1495,8 +1496,8 @@
-               unload_module("capiutil");
-               if ((mp = mounted("capifs")) != 0 && strcmp(mp, "/dev/capi") == 0)
-                       system("umount /dev/capi");
--              if (filesystem_available("capifs"))
--                      unload_filesystem("capifs");
-+              /*if (filesystem_available("capifs"))
-+                      unload_filesystem("capifs"); */
-       }
-       if (cardname && cname[0] == 0) {
-               fprintf(stderr,"ERROR: card \"%s\"  not found\n", cardname);
diff --git a/src/patches/isdn4k-utils-statfs.patch b/src/patches/isdn4k-utils-statfs.patch
deleted file mode 100644 (file)
index 7c6b2c3..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
---- isdn4k-utils-CVS-2005-03-09/vbox/src/vboxgetty.c.old       2000-11-30 16:35:20.000000000 +0100
-+++ isdn4k-utils-CVS-2005-03-09/vbox/src/vboxgetty.c   2005-04-20 16:30:31.000000000 +0200
-@@ -434,7 +434,7 @@
- static int check_spool_space(unsigned long need)
- {
-       struct statfs stat;
--      unsigned long have;
-+      unsigned long long have;
-       log(L_DEBUG, "Checking free space on \"%s\"...\n", setup.spool);
-@@ -449,7 +449,7 @@
-       {
-               have = (stat.f_bfree * stat.f_bsize);
--              log_line(L_JUNK, "%ld bytes available; %ld bytes needed... ", have, need);
-+              log_line(L_JUNK, "%lld bytes available; %ld bytes needed... ", have, need);
-               if (have >= need)
-               {
---- isdn4k-utils-CVS-2005-03-09/eurofile/src/wuauth/extensions.h.old   2005-04-20 16:35:37.000000000 +0200
-+++ isdn4k-utils-CVS-2005-03-09/eurofile/src/wuauth/extensions.h       2005-04-20 16:37:02.000000000 +0200
-@@ -42,3 +42,8 @@
- #define ARG8    entry->arg[8]
- #define ARG9    entry->arg[9]
- #define ARG     entry->arg
-+
-+#if defined(HAVE_STATVFS) || defined(HAVE_SYS_VFS) || defined (HAVE_SYS_MOUNT)
-+unsigned long long getSize(s);
-+#endif
-+
---- isdn4k-utils-CVS-2005-03-09/eurofile/src/wuauth/extensions.c.old   2005-04-20 16:20:17.000000000 +0200
-+++ isdn4k-utils-CVS-2005-03-09/eurofile/src/wuauth/extensions.c       2005-04-20 16:24:56.000000000 +0200
-@@ -154,7 +154,7 @@
- }
- #if defined(HAVE_STATVFS)
--int getSize(s)
-+unsigned long long getSize(s)
- char *s;
- {
-     int c;
-@@ -163,10 +163,10 @@
-     if (( c = statvfs(s, &buf)) != 0)
-         return(0);
--    return(buf.f_bavail * buf.f_frsize / 1024);
-+    return((unsigned long long)(buf.f_bavail * buf.f_frsize / 1024));
- }
- #elif defined(HAVE_SYS_VFS) || defined (HAVE_SYS_MOUNT)
--int getSize(s)
-+unsigned long long getSize(s)
- char *s;
- {
-     int c;
-@@ -175,7 +175,7 @@
-     if (( c = statfs(s, &buf)) != 0)
-         return(0);
--    return(buf.f_bavail * buf.f_bsize / 1024);
-+    return((unsigned long long)(buf.f_bavail * buf.f_bsize / 1024));
- }
- #endif
-@@ -236,7 +236,7 @@
-             case 'F':
- #if defined(HAVE_STATVFS) || defined(HAVE_SYS_VFS) || defined(HAVE_SYS_MOUNT)
--                sprintf(outptr, "%lu", getSize("."));
-+                sprintf(outptr, "%llu",(unsigned long long)getSize("."));
- #endif
-                 break;
---- isdn4k-utils-CVS-2005-03-09/eurofile/src/wuauth/divfunc.c.old      2001-03-01 15:59:14.000000000 +0100
-+++ isdn4k-utils-CVS-2005-03-09/eurofile/src/wuauth/divfunc.c  2005-04-20 16:34:26.000000000 +0200
-@@ -121,7 +121,7 @@
-             case 'F':
- #if defined(HAVE_STATVFS) || defined(HAVE_SYS_VFS) || defined(HAVE_SYS_MOUNT)
--                sprintf(outptr, "%lu", getSize("."));
-+                sprintf(outptr, "%llu",(unsigned long long)getSize("."));
- #endif
-                 break;
diff --git a/src/patches/libpri.patch b/src/patches/libpri.patch
deleted file mode 100644 (file)
index bb80e75..0000000
+++ /dev/null
@@ -1,6458 +0,0 @@
-diff -urN libpri-1.2.3.orig/Makefile libpri-1.2.3/Makefile
---- libpri-1.2.3.orig/Makefile 2006-04-30 17:17:47.000000000 +0200
-+++ libpri-1.2.3/Makefile      2006-07-27 17:45:09.000000000 +0200
-@@ -27,6 +27,13 @@
- # Uncomment if you want libpri to count number of Q921/Q931 sent/received
- #LIBPRI_COUNTERS=-DLIBPRI_COUNTERS
-+# Uncomment if you want libpri to always keep layer 2 up
-+#LAYER2ALWAYSUP=-DLAYER2ALWAYSUP
-+
-+# Uncomment if you want libpri to hangup a call to an NT (p2mp) port if one
-+# device sends a RELEASE COMPLETE with cause 17
-+#FASTBUSYONBUSY=-DFASTBUSYONBUSY
-+
- CC=gcc
- OSARCH=$(shell uname -s)
-@@ -38,7 +45,7 @@
- DYNAMIC_LIBRARY=libpri.so.1.0
- STATIC_OBJS=copy_string.o pri.o q921.o prisched.o q931.o pri_facility.o
- DYNAMIC_OBJS=copy_string.lo pri.lo q921.lo prisched.lo q931.lo pri_facility.lo
--CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS)
-+CFLAGS=-Wall -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS) $(LAYER2ALWAYSUP) $(FASTBUSYONBUSY) -DRELAX_TRB
- INSTALL_PREFIX=$(DESTDIR)
- INSTALL_BASE=/usr
- SOFLAGS = -Wl,-hlibpri.so.1.0
-diff -urN libpri-1.2.3.orig/README libpri-1.2.3/README
---- libpri-1.2.3.orig/README   2006-02-15 18:59:38.000000000 +0100
-+++ libpri-1.2.3/README        2006-01-18 12:28:07.000000000 +0100
-@@ -1,6 +1,7 @@
--libpri: An implementation of Primary Rate ISDN
--
--Written by Mark Spencer <markster@digium.com>
-+libpri: An implementation of Primate Rate ISDN (and BRI ISDN)
-+ 
-+Written by Mark Spencer <markster@linux-support.net>
-+Modified for BRI support by Klaus-Peter Junghanns <kpj@junghanns.net>
- What is libpri?
- ===============
-@@ -9,6 +10,7 @@
- based on the Bellcore specification SR-NWT-002343 for National ISDN.  As of
- May 12, 2001, it has been tested work with NI-2, Nortel DMS-100, and 
- Lucent 5E Custom protocols on switches from Nortel and Lucent.
-+The BRI and euroISDN modifications are based on ETS 300 102-1.
- What is the license for libpri?
- ===============================
-@@ -22,9 +24,8 @@
- or the GPL of libpri.
- If you wish to use libpri in an application for which the GPL is not 
--appropriate (e.g. a proprietary embedded system), licenses for libpri 
--under more flexible terms can be readily obtained through Digium, Inc. 
--at reasonable cost.
-+appropriate (e.g. a proprietary embedded system), then you have to use
-+a non-standard compliant version without BRI support.
- How do I report bugs or contribute?
-diff -urN libpri-1.2.3.orig/TODO libpri-1.2.3/TODO
---- libpri-1.2.3.orig/TODO     2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/TODO  2006-01-18 12:28:07.000000000 +0100
-@@ -2,9 +2,7 @@
- -- D-Channel Backup
- -- Test against 4e
--Q.921:
---- Support unnumbered information frames
--
- Q.931:
---- Locking Shift IE
---- Implement the 11 missing Q.931 timers
-+-- Locking Shift IE (you did that already, didnt you??)
-+-- Implement the 10 missing Q.931 timers
-+-- more facilities
-diff -urN libpri-1.2.3.orig/libpri.h libpri-1.2.3/libpri.h
---- libpri-1.2.3.orig/libpri.h 2006-04-27 18:08:39.000000000 +0200
-+++ libpri-1.2.3/libpri.h      2006-07-11 11:34:59.000000000 +0200
-@@ -5,6 +5,8 @@
-  *
-  * Copyright (C) 2001, Linux Support Services, Inc.
-  * All Rights Reserved.
-+ * Copyright (C) 2003-2006 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj@junghanns.net>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -26,8 +28,12 @@
- #define _LIBPRI_H
- /* Node types */
--#define PRI_NETWORK           1
-+#define PRI_NETWORK           1       /* PTP modes, default for PRI */
- #define PRI_CPE                       2
-+#define BRI_NETWORK_PTMP      3       /* PTMP modes, default for BRI */
-+#define BRI_CPE_PTMP          4       
-+#define BRI_NETWORK           5       /* PTP modes */
-+#define BRI_CPE                       6       
- /* Debugging */
- #define PRI_DEBUG_Q921_RAW            (1 << 0)        /* Show raw HDLC frames */
-@@ -76,6 +82,12 @@
- #define PRI_EVENT_NOTIFY              16      /* Notification received */
- #define PRI_EVENT_PROGRESS            17      /* When we get CALL_PROCEEDING or PROGRESS */
- #define PRI_EVENT_KEYPAD_DIGIT                18      /* When we receive during ACTIVE state */
-+#define PRI_EVENT_HOLD_REQ    19      /* R */
-+#define PRI_EVENT_RETRIEVE_REQ  20
-+#define PRI_EVENT_SUSPEND_REQ   21    /* park */
-+#define PRI_EVENT_RESUME_REQ    22    /* unpark */
-+#define PRI_EVENT_DISPLAY_RECEIVED    23
-+#define PRI_EVENT_FACILITY    24      /* Facility */
- /* Simple states */
- #define PRI_STATE_DOWN                0
-@@ -250,11 +262,17 @@
- #define PRI_NSF_ATT_MULTIQUEST         0xF0
- #define PRI_NSF_CALL_REDIRECTION_SERVICE       0xF7
-+#ifdef RELAX_TRB
-+#define PRI_RELAX_TRB
-+#endif
-+
-+typedef struct q921_call q921_call;
- typedef struct q931_call q931_call;
- typedef struct pri_event_generic {
-       /* Events with no additional information fall in this category */
-       int e;
-+      int tei;
- } pri_event_generic;
- typedef struct pri_event_error {
-@@ -273,18 +291,19 @@
-       int cref;
-       int progress;
-       int progressmask;
--      q931_call *call;
-       char useruserinfo[260];         /* User->User info */
-+      q931_call *call;
- } pri_event_ringing;
- typedef struct pri_event_answer {
-       int e;
-       int channel;
-+      int tei;                                /* belongs to this tei */
-       int cref;
-       int progress;
-       int progressmask;
--      q931_call *call;
-       char useruserinfo[260];         /* User->User info */
-+      q931_call *call;
- } pri_event_answer;
- typedef struct pri_event_facname {
-@@ -302,32 +321,37 @@
-       int e;
-       int channel;                            /* Channel requested */
-       int callingpres;                        /* Presentation of Calling CallerID */
--      int callingplanani;                     /* Dialing plan of Calling entity ANI */
-+      int callingpresuser;                    /* Presentation of Calling CallerID */
-       int callingplan;                        /* Dialing plan of Calling entity */
--      char callingani[256];           /* Calling ANI */
--      char callingnum[256];           /* Calling number */
-+      int callingplanuser;                    /* Dialing plan of Calling entity */
-+      int callingplanani;                     /* Dialing plan of Calling entity ANI */
-+      char callingnum[256];           /* Calling number, network provided */
-+      char callingani[256];           /* Calling number, user provided */
-       char callingname[256];          /* Calling name (if provided) */
-       int calledplan;                         /* Dialing plan of Called number */
-       int ani2;                   /* ANI II */
-       char callednum[256];            /* Called number */
--      char redirectingnum[256];       /* Redirecting number */
--      char redirectingname[256];      /* Redirecting name */
--      int redirectingreason;          /* Reason for redirect */
-+      char redirectingnum[256];               /* Redirecting number */
-+      char redirectingname[256];              /* Redirecting name */
-+      int redirectingreason;                  /* Reason for redirect */
-       int callingplanrdnis;                   /* Dialing plan of Redirecting Number */
--      char useruserinfo[260];         /* User->User info */
-+      char useruserinfo[260];                 /* User->User info */
-       int flexible;                           /* Are we flexible with our channel selection? */
-       int cref;                                       /* Call Reference Number */
-       int ctype;                                      /* Call type (see PRI_TRANS_CAP_* */
--      int layer1;                                     /* User layer 1 */
-+      int layer1;                             /* User layer 1 */
-       int complete;                           /* Have we seen "Complete" i.e. no more number? */
-       q931_call *call;                        /* Opaque call pointer */
--      char callingsubaddr[256];       /* Calling parties subaddress */
-+      int tei;                                /* belongs to this tei */
-+      char callingsubaddr[256];               /* Calling parties subaddress */
-       int progress;
-       int progressmask;
-       char origcalledname[256];
-       char origcallednum[256];
-       int callingplanorigcalled;              /* Dialing plan of Originally Called Number */
-       int origredirectingreason;
-+      char lowlayercompat[16];
-+      char highlayercompat[4];
- } pri_event_ring;
- typedef struct pri_event_hangup {
-@@ -335,6 +359,8 @@
-       int channel;                            /* Channel requested */
-       int cause;
-       int cref;
-+      int tei;
-+      int inband_progress;
-       q931_call *call;                        /* Opaque call pointer */
-       long aoc_units;                         /* Advise of Charge number of charged units */
-       char useruserinfo[260];         /* User->User info */
-@@ -375,20 +401,80 @@
-       char digits[64];
- } pri_event_keypad_digit;
-+typedef struct pri_event_hold_req {
-+      int e;
-+      int channel;
-+      int cref;
-+      int tei;
-+      q931_call *call;
-+} pri_event_hold_req;
-+
-+/* euroisdn faciltiy fun */
-+typedef struct pri_event_facility_req {
-+      int e;
-+      int channel;
-+      int cref;
-+      int tei;
-+      int operation;
-+      char forwardnum[256];           /* Redirection destination */
-+      q931_call *call;
-+} pri_event_facility_req;
-+
-+typedef struct pri_event_retrieve_req {
-+      int e;
-+      int channel;
-+      int cref;
-+      int tei;
-+      q931_call *call;
-+} pri_event_retrieve_req;
-+
-+typedef struct pri_event_suspend_req {
-+      int e;
-+      int channel;
-+      int cref;
-+      int tei;
-+      q931_call *call;
-+      char callid[10];
-+} pri_event_suspend_req;
-+
-+typedef struct pri_event_resume_req {
-+      int e;
-+      int channel;
-+      int cref;
-+      int tei;
-+      q931_call *call;
-+      char callid[10];
-+} pri_event_resume_req;
-+
-+typedef struct pri_event_display {
-+      int e;
-+      int channel;            
-+      int cref;                       
-+      q931_call *call;
-+      char text[256];
-+} pri_event_display;
-+
-+
- typedef union {
-       int e;
-       pri_event_generic gen;          /* Generic view */
-       pri_event_restart restart;      /* Restart view */
-       pri_event_error   err;          /* Error view */
-       pri_event_facname facname;      /* Caller*ID Name on Facility */
-+      pri_event_facility_req facility;        /* sservices */
-       pri_event_ring    ring;         /* Ring */
-       pri_event_hangup  hangup;       /* Hang up */
-       pri_event_ringing ringing;      /* Ringing */
--      pri_event_ringing answer;       /* Answer */
-+      pri_event_answer  answer;       /* Answer */
-       pri_event_restart_ack restartack;       /* Restart Acknowledge */
-       pri_event_proceeding  proceeding;       /* Call proceeding & Progress */
-       pri_event_setup_ack   setup_ack;        /* SETUP_ACKNOWLEDGE structure */
-       pri_event_notify notify;                /* Notification */
-+      pri_event_hold_req hold_req;
-+      pri_event_retrieve_req retrieve_req;
-+      pri_event_suspend_req suspend_req;
-+      pri_event_resume_req resume_req;
-+      pri_event_display display;
-       pri_event_keypad_digit digit;                   /* Digits that come during a call */
- } pri_event;
-@@ -403,7 +489,9 @@
-    channel operating in HDLC mode with FCS computed by the fd's driver.  Also it
-    must be NON-BLOCKING! Frames received on the fd should include FCS.  Nodetype 
-    must be one of PRI_NETWORK or PRI_CPE.  switchtype should be PRI_SWITCH_* */
--extern struct pri *pri_new(int fd, int nodetype, int switchtype);
-+extern struct pri *pri_new(int fd, int nodetype, int switchtype, int span);
-+
-+extern void pri_shutdown(struct pri *pri);
- /* Create D-channel just as above with user defined I/O callbacks and data */
- extern struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata);
-@@ -427,6 +515,9 @@
- /* Enable transmission support of Facility IEs on the pri */
- extern void pri_facility_enable(struct pri *pri);
-+/* Set file descriptor for debugging to a file */
-+extern void pri_set_debug_fd(struct pri *pri, int fd);
-+
- /* Run PRI on the given D-channel, taking care of any events that
-    need to be handled.  If block is set, it will block until an event
-    occurs which needs to be handled */
-@@ -463,6 +554,12 @@
- /* Send a digit in overlap mode */
- extern int pri_information(struct pri *pri, q931_call *call, char digit);
-+/* Send a INFO msg with display ie  */
-+extern int pri_information_display(struct pri *pri, q931_call *call, char *display);
-+
-+/* add a display ie to a call, so it can be sent with the next message */
-+extern int pri_add_display(struct pri *pri, q931_call *call, char *display);
-+
- /* Answer the incomplete(call without called number) call on the given channel.
-    Set non-isdn to non-zero if you are not connecting to ISDN equipment */
- extern int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn);
-@@ -471,6 +568,35 @@
-    Set non-isdn to non-zero if you are not connecting to ISDN equipment */
- extern int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
-+extern int pri_deflect(struct pri *pri, q931_call *call, char *destination);
-+
-+/* Ack a HOLD_REQ */
-+extern int pri_hold_acknowledge(struct pri *pri, q931_call *call);
-+
-+/* Reject a HOLD_REQ */
-+extern int pri_hold_reject(struct pri *pri, q931_call *call);
-+
-+/* Ack a RETRIEVE_REQ */
-+extern int pri_retrieve_acknowledge(struct pri *pri, q931_call *call, int channel);
-+
-+/* Reject a RETRIEVE_REQ */
-+extern int pri_retrieve_reject(struct pri *pri, q931_call *call);
-+
-+/* Ack a SUSPEND_REQ */
-+extern int pri_suspend_acknowledge(struct pri *pri, q931_call *call, char *display);
-+
-+/* Reject a SUSPEND_REQ */
-+extern int pri_suspend_reject(struct pri *pri, q931_call *call, char *display);
-+
-+/* Reject a RESUME_REQ */
-+extern int pri_resume_reject(struct pri *pri, q931_call *call, char *display);
-+
-+/* Ack a RESUME_REQ */
-+extern int pri_resume_acknowledge(struct pri *pri, q931_call *call, int channel, char *display);
-+
-+/* Send a Facility Message */
-+extern int pri_facility(struct pri *pri, q931_call *call, int operation, char *arguments);
-+
- /* Set CRV reference for GR-303 calls */
-@@ -479,14 +605,14 @@
- /* backwards compatibility for those who don't use asterisk with libpri */
- #define pri_release(a,b,c) \
--      pri_hangup(a,b,c)
-+      pri_hangup(a,b,c, -1)
- #define pri_disconnect(a,b,c) \
--      pri_hangup(a,b,c)
-+      pri_hangup(a,b,c, -1)
- /* Hangup a call */
- #define PRI_HANGUP
--extern int pri_hangup(struct pri *pri, q931_call *call, int cause);
-+extern int pri_hangup(struct pri *pri, q931_call *call, int cause, int aocunits);
- #define PRI_DESTROYCALL
- extern void pri_destroycall(struct pri *pri, q931_call *call);
-@@ -519,14 +645,13 @@
- extern void pri_sr_free(struct pri_sr *sr);
- extern int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
--extern int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1);
-+extern int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1, char *llc);
- extern int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
- extern int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
- extern int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);
- #define PRI_USER_USER_TX
- /* Set the user user field.  Warning!  don't send binary data accross this field */
- extern void pri_sr_set_useruser(struct pri_sr *sr, char *userchars);
--
- extern void pri_call_set_useruser(q931_call *sr, char *userchars);
- extern int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req);
-@@ -547,8 +672,8 @@
- /* Override message and error stuff */
- #define PRI_NEW_SET_API
--extern void pri_set_message(void (*__pri_error)(struct pri *pri, char *));
--extern void pri_set_error(void (*__pri_error)(struct pri *pri, char *));
-+extern void pri_set_message(void (*__pri_error)(char *, int span));
-+extern void pri_set_error(void (*__pri_error)(char *, int span));
- /* Set overlap mode */
- #define PRI_SET_OVERLAPDIAL
-diff -urN libpri-1.2.3.orig/pri.c libpri-1.2.3/pri.c
---- libpri-1.2.3.orig/pri.c    2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/pri.c 2006-07-11 12:39:20.000000000 +0200
-@@ -1,24 +1,14 @@
- /*
-  * libpri: An implementation of Primary Rate ISDN
-  *
-- * Written by Mark Spencer <markster@digium.com>
-+ * Written by Mark Spencer <markster@linux-suppot.net>
-  *
-- * Copyright (C) 2001-2005, Digium
-- * All Rights Reserved.
-+ * This program is confidential ( <- I dont think so! )
-  *
-- * This program 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 program 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 program; if not, write to the Free Software
-- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
-+ * Copyright (C) 2001, Linux Support Services, Inc.
-+ * All Rights Reserved.
-+ * Copyright (C) 2003-2006 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj@junghanns.net>
-  *
-  */
-@@ -48,6 +38,14 @@
-               return "Network";
-       case PRI_CPE:
-               return "CPE";
-+      case BRI_NETWORK:
-+              return "Network";
-+      case BRI_CPE:
-+              return "CPE";
-+      case BRI_NETWORK_PTMP:
-+              return "Network (PtMP)";
-+      case BRI_CPE_PTMP:
-+              return "CPE (PtMP)";
-       default:
-               return "Invalid value";
-       }
-@@ -187,7 +185,7 @@
-       return res;
- }
--static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata)
-+static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int span)
- {
-       struct pri *p;
-       p = malloc(sizeof(struct pri));
-@@ -207,6 +205,8 @@
-               p->master = master;
-               p->callpool = &p->localpool;
-               pri_default_timers(p, switchtype);
-+              p->debugfd = -1;
-+              p->span = span;
- #ifdef LIBPRI_COUNTERS
-               p->q921_rxcount = 0;
-               p->q921_txcount = 0;
-@@ -217,7 +217,7 @@
-                       p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-                       p->sapi = Q921_SAPI_GR303_EOC;
-                       p->tei = Q921_TEI_GR303_EOC_OPS;
--                      p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL);
-+                      p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, span);
-                       if (!p->subchannel) {
-                               free(p);
-                               p = NULL;
-@@ -226,7 +226,7 @@
-                       p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-                       p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
-                       p->tei = Q921_TEI_GR303_TMC_CALLPROC;
--                      p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL);
-+                      p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, span);
-                       if (!p->subchannel) {
-                               free(p);
-                               p = NULL;
-@@ -242,7 +242,7 @@
-               }
-               /* Start Q.921 layer, Wait if we're the network */
-               if (p)
--                      q921_start(p, p->localtype == PRI_CPE);
-+                      q921_start(p, p->localtype == PRI_CPE, 0);
-       }
-       return p;
- }
-@@ -262,15 +262,16 @@
- {
-       /* Restart Q.921 layer */
-       if (pri) {
--              q921_reset(pri);
--              q921_start(pri, pri->localtype == PRI_CPE);     
-+// XXX                q921_reset(pri);
-+//            q921_start(pri, pri->localtype == PRI_CPE);     
-       }
-       return 0;
- }
--struct pri *pri_new(int fd, int nodetype, int switchtype)
-+
-+struct pri *pri_new(int fd, int nodetype, int switchtype, int span)
- {
--      return __pri_new(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL);
-+      return __pri_new(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, span);
- }
- struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata)
-@@ -279,7 +280,7 @@
-               io_read = __pri_read;
-       if (!io_write)
-               io_write = __pri_write;
--      return __pri_new(fd, nodetype, switchtype, NULL, io_read, io_write, userdata);
-+      return __pri_new(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, -1);
- }
- void *pri_get_userdata(struct pri *pri)
-@@ -443,6 +444,15 @@
-       return;
- }
-+void pri_set_debug_fd(struct pri *pri, int fd)
-+{
-+      if (!pri)
-+              return;
-+      pri->debugfd = fd;
-+      if (pri->subchannel)
-+              pri_set_debug_fd(pri->subchannel, fd);
-+}
-+
- int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
- {
-       if (!pri || !call)
-@@ -478,6 +488,21 @@
-       return q931_notify(pri, call, channel, info);
- }
-+int pri_information_display(struct pri *pri, q931_call *call, char *display)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_information_display(pri, call, display);
-+}
-+
-+int pri_add_display(struct pri *pri, q931_call *call, char *display)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_add_display(pri, call, display);
-+}
-+
-+
- void pri_destroycall(struct pri *pri, q931_call *call)
- {
-       if (pri && call)
-@@ -499,6 +524,76 @@
-       return q931_connect(pri, call, channel, nonisdn);
- }
-+int pri_hold_acknowledge(struct pri *pri, q931_call *call)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_hold_acknowledge(pri, call);
-+}
-+
-+int pri_hold_reject(struct pri *pri, q931_call *call)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_hold_reject(pri, call);
-+}
-+
-+int pri_retrieve_acknowledge(struct pri *pri, q931_call *call, int channel)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_retrieve_acknowledge(pri, call, channel);
-+}
-+
-+int pri_retrieve_reject(struct pri *pri, q931_call *call)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_retrieve_reject(pri, call);
-+}
-+
-+int pri_suspend_acknowledge(struct pri *pri, q931_call *call, char *display)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_suspend_acknowledge(pri, call, display);
-+}
-+
-+int pri_suspend_reject(struct pri *pri, q931_call *call, char *display)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_suspend_reject(pri, call, display);
-+}
-+
-+int pri_resume_reject(struct pri *pri, q931_call *call, char *display)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_resume_reject(pri, call, display);
-+}
-+
-+int pri_resume_acknowledge(struct pri *pri, q931_call *call, int channel, char *display)
-+{
-+      if (!pri || !call)
-+              return -1;
-+      return q931_resume_acknowledge(pri, call, channel, display);
-+}
-+
-+int pri_facility(struct pri *pri, q931_call *call, int operation, char *arguments)
-+{
-+      if (!pri || !call)
-+              return -1;
-+//    return q931_facility(pri, call, operation, arguments);
-+      return q931_facility(pri, call);
-+}
-+
-+int pri_deflect(struct pri *pri, q931_call *call, char *destination)
-+{
-+    add_call_deflection_facility_ie(pri, call, destination);
-+    return q931_facility(pri, call);
-+}
-+
- #if 0
- /* deprecated routines, use pri_hangup */
- int pri_release(struct pri *pri, q931_call *call, int cause)
-@@ -541,14 +636,35 @@
-       return 0;
- }
--int pri_hangup(struct pri *pri, q931_call *call, int cause)
-+int pri_hangup(struct pri *pri, q931_call *call, int cause, int aocunits)
- {
-+      int res=0;
-       if (!pri || !call)
-               return -1;
-       if (cause == -1)
-               /* normal clear cause */
-               cause = 16;
--      return q931_hangup(pri, call, cause);
-+      if ((cause == 34 || cause == 44 || cause == 82 || cause == 1 || cause == 81 || cause == 17) && (call->ourcallstate == Q931_CALL_STATE_ACTIVE)) {
-+          pri_error(pri, "Cause code %d not allowed when disconnecting an active call. Changing to cause 16.\n", cause);
-+          cause = 16;
-+      }
-+
-+      if (aocunits > -1) {
-+          call->aoc_units = aocunits;
-+      }
-+      
-+      if (pri->localtype == BRI_NETWORK_PTMP) {
-+          res = q921_hangup(pri, call, 127);
-+          if (res) {
-+              // q921_setup might give a HANGUP_ACK, if nobody got the call
-+              q931_hangup(pri, call, cause);
-+              return res;
-+          } else {
-+              return q931_hangup(pri, call, cause);
-+          }
-+      } else {
-+          return q931_hangup(pri, call, cause);
-+      }
- }
- int pri_reset(struct pri *pri, int channel)
-@@ -688,15 +804,15 @@
-       return q931_setup(pri, c, &req);
- }     
--static void (*__pri_error)(struct pri *pri, char *stuff);
--static void (*__pri_message)(struct pri *pri, char *stuff);
-+static void (*__pri_error)(char *stuff,int span);
-+static void (*__pri_message)(char *stuff,int span);
--void pri_set_message(void (*func)(struct pri *pri, char *stuff))
-+void pri_set_message(void (*func)(char *stuff,int span))
- {
-       __pri_message = func;
- }
--void pri_set_error(void (*func)(struct pri *pri, char *stuff))
-+void pri_set_error(void (*func)(char *stuff,int span))
- {
-       __pri_error = func;
- }
-@@ -708,10 +824,14 @@
-       va_start(ap, fmt);
-       vsnprintf(tmp, sizeof(tmp), fmt, ap);
-       va_end(ap);
--      if (__pri_message)
--              __pri_message(pri, tmp);
--      else
--              fputs(tmp, stdout);
-+      if (__pri_message && pri) {
-+          if (pri->debugfd >= 0)
-+              write(pri->debugfd, tmp, strlen(tmp));
-+          else
-+              __pri_message(tmp, pri->span);
-+      } else {
-+          fputs(tmp, stdout);
-+      }
- }
- void pri_error(struct pri *pri, char *fmt, ...)
-@@ -721,10 +841,14 @@
-       va_start(ap, fmt);
-       vsnprintf(tmp, sizeof(tmp), fmt, ap);
-       va_end(ap);
--      if (__pri_error)
--              __pri_error(pri, tmp);
--      else
--              fputs(tmp, stderr);
-+      if (__pri_error && pri) {
-+          if (pri->debugfd >= 0)
-+              write(pri->debugfd, tmp, strlen(tmp));
-+          else 
-+              __pri_error(tmp, pri->span);
-+      } else {
-+          fputs(tmp, stderr);
-+      }
- }
- /* Set overlap mode */
-@@ -765,11 +889,13 @@
-       }
-       len += sprintf(buf + len, "Q921 Outstanding: %d\n", q921outstanding);
- #endif
--      len += sprintf(buf + len, "Window Length: %d/%d\n", pri->windowlen, pri->window);
--      len += sprintf(buf + len, "Sentrej: %d\n", pri->sentrej);
--      len += sprintf(buf + len, "SolicitFbit: %d\n", pri->solicitfbit);
--      len += sprintf(buf + len, "Retrans: %d\n", pri->retrans);
--      len += sprintf(buf + len, "Busy: %d\n", pri->busy);
-+      if (pri->localtype != BRI_NETWORK_PTMP) {
-+          len += sprintf(buf + len, "Window Length: %d/%d\n", pri->windowlen[0], pri->window[0]);
-+          len += sprintf(buf + len, "Sentrej: %d\n", pri->sentrej[0]);
-+          len += sprintf(buf + len, "SolicitFbit: %d\n", pri->solicitfbit[0]);
-+          len += sprintf(buf + len, "Retrans: %d\n", pri->retrans[0]);
-+          len += sprintf(buf + len, "Busy: %d\n", pri->busy[0]);
-+      }
-       len += sprintf(buf + len, "Overlap Dial: %d\n", pri->overlapdial);
-       len += sprintf(buf + len, "T200 Timer: %d\n", pri->timers[PRI_TIMER_T200]);
-       len += sprintf(buf + len, "T203 Timer: %d\n", pri->timers[PRI_TIMER_T203]);
-@@ -778,6 +904,7 @@
-       len += sprintf(buf + len, "T313 Timer: %d\n", pri->timers[PRI_TIMER_T313]);
-       len += sprintf(buf + len, "N200 Counter: %d\n", pri->timers[PRI_TIMER_N200]);
-+
-       return strdup(buf);
- }
-@@ -819,10 +946,11 @@
-       return 0;
- }
--int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1)
-+int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1, char *llc)
- {
-       sr->transmode = transmode;
-       sr->userl1 = userl1;
-+      sr->llc = llc;
-       return 0;
- }
-@@ -851,3 +979,14 @@
-       sr->redirectingreason = reason;
-       return 0;
- }
-+
-+void pri_shutdown(struct pri *pri)
-+{
-+#ifndef LAYER2ALWAYSUP
-+#ifndef RELAX_TRB
-+    if ((pri->localtype == BRI_NETWORK) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_CPE_PTMP)) {
-+      q921_reset(pri, pri->tei, 1);
-+    }
-+#endif
-+#endif
-+}
-diff -urN libpri-1.2.3.orig/pri_facility.c libpri-1.2.3/pri_facility.c
---- libpri-1.2.3.orig/pri_facility.c   2006-02-14 00:06:02.000000000 +0100
-+++ libpri-1.2.3/pri_facility.c        2006-06-06 14:26:01.000000000 +0200
-@@ -1,26 +1,17 @@
--/*
-- * libpri: An implementation of Primary Rate ISDN
-- *
-- * Written by Matthew Fredrickson <creslin@digium.com>
-- *
-- * Copyright (C) 2004-2005, Digium
-- * All Rights Reserved.
-- *
-- * This program 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 program 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 program; if not, write to the Free Software
-- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
-- *
-- */
-+/* 
-+   This file and it's contents are licensed under the terms and conditions
-+   of the GNU Public License.  See http://www.gnu.org for details.
-+   
-+   Routines for dealing with facility messages and their respective
-+   components (ROSE)
-+
-+   by Matthew Fredrickson <creslin@digium.com>
-+   Copyright (C) 2004-2005 Digium, Inc
-+
-+   Copyright (C) 2005-2006 Junghanns.NET GmbH
-+   Klaus-Peter Junghanns <kpj@junghanns.net>
-+    
-+*/
- #include "compat.h"
- #include "libpri.h"
-@@ -208,9 +199,9 @@
-       if (datalen > buflen) {
-               /* Truncate */
-               datalen = buflen;
-+              memcpy(namebuf, comp->data, datalen);
-       }
--      memcpy(namebuf, comp->data, datalen);
--      return res + 2;
-+      return res;
- }
- int asn1_string_encode(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len)
-@@ -305,12 +296,55 @@
-                       return -1;
-               value->ton = ton;
--              return res + 3;
-+              return res + 2;
-       } while(0);
-       return -1;
- }
-+static int rose_cd_destination_decode(struct pri *pri, q931_call *call, unsigned char *data, int len) 
-+{
-+      unsigned char *vdata = data;
-+      struct rose_component *comp1 = NULL, *comp2 = NULL;
-+      int pos1 = 0, pos2, sublen2;
-+
-+      if (pri->debug & PRI_DEBUG_AOC)
-+              dump_apdu (pri, data, len);
-+
-+      do {
-+              GET_COMPONENT(comp1, pos1, vdata, len); 
-+              CHECK_COMPONENT(comp1, ASN1_SEQUENCE, "!! Invalid CD destination argument. Expected Sequence (0x30) but Received 0x%02X\n");
-+              SUB_COMPONENT(comp1, pos1);
-+              GET_COMPONENT(comp1, pos1, vdata, len);
-+              switch (comp1->type) {
-+                      case (ASN1_SEQUENCE | ASN1_CONSTRUCTOR):
-+                              sublen2 = comp1->len; 
-+                              pos2 = pos1;
-+                              comp2 = comp1;
-+                              SUB_COMPONENT(comp2, pos2);
-+                              do {
-+                                      GET_COMPONENT(comp2, pos2, vdata, len);
-+                                      switch (comp2->type) {
-+                                              case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0):
-+                                                      memcpy(call->redirectingnum, comp2->data, comp2->len);
-+                                                      call->redirectingnum[comp2->len] = '\0';
-+                                                      return 0;
-+                                                      break;
-+                                              default:
-+                                                      pri_message(pri, "!! Don't know how to handle 0x%02X in CD destination argument\n", comp2->type);
-+                                      }
-+                                      NEXT_COMPONENT(comp2, pos2);
-+                              } while (pos2 < sublen2);
-+                              break;
-+                      default:
-+                              pri_message(pri, "!! Invalid CD destination argument. Expected Sequence (0x30) or Object Identifier (0x81/0x01) but received 0x%02X\n", comp1->type);
-+              }
-+              NEXT_COMPONENT(comp1, pos1);
-+      } while (pos1 < len);
-+
-+      return 0;
-+}
-+
- static int rose_address_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
- {
-       int i = 0;
-@@ -375,11 +409,10 @@
-                       pri_message(pri, "!! Unknown Party number component received 0x%X\n", comp->type);
-                       return -1;
-               }
--              ASN1_FIXUP_LEN(comp, res);
-               NEXT_COMPONENT(comp, i);
-               if(i < len)
-                       pri_message(pri, "!! not all information is handled from Address component\n");
--              return res + 2;
-+              return res;
-       }
-       while (0);
-@@ -389,7 +422,6 @@
- static int rose_presented_number_unscreened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
- {
-       int i = 0;
--      int size = 0;
-       struct rose_component *comp = NULL;
-       unsigned char *vdata = data;
-@@ -404,9 +436,7 @@
-               switch(comp->type) {
-               case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0):           /* [0] presentationAllowedNumber */
-                       value->pres = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
--                      size = rose_address_decode(pri, call, comp->data, comp->len, value);
--                      ASN1_FIXUP_LEN(comp, size);
--                      return size + 2;
-+                      return rose_address_decode(pri, call, comp->data, comp->len, value) + 2;
-               case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1):              /* [1] IMPLICIT presentationRestricted */
-                       if (comp->len != 0) { /* must be NULL */
-                               pri_error(pri, "!! Invalid PresentationRestricted component received (len != 0)\n");
-@@ -423,9 +453,7 @@
-                       return 2;
-               case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):           /* [3] presentationRestrictedNumber */
-                       value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
--                      size = rose_address_decode(pri, call, comp->data, comp->len, value) + 2;
--                      ASN1_FIXUP_LEN(comp, size);
--                      return size + 2;
-+                      return rose_address_decode(pri, call, comp->data, comp->len, value) + 2;
-               default:
-                       pri_message(pri, "Invalid PresentedNumberUnscreened component 0x%X\n", comp->type);
-               }
-@@ -436,7 +464,7 @@
-       return -1;
- }
--static int rose_diverting_leg_information2_decode(struct pri *pri, q931_call *call, struct rose_component *sequence, int len)
-+static int rose_diverting_leg_information2_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
- {
-       int i = 0;
-       int diversion_counter;
-@@ -445,21 +473,9 @@
-       struct addressingdataelements_presentednumberunscreened divertingnr;
-       struct addressingdataelements_presentednumberunscreened originalcallednr;
-       struct rose_component *comp = NULL;
--      unsigned char *vdata = sequence->data;
-+      unsigned char *vdata = data;
-       int res = 0;
--      /* Data checks */
--      if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
--              pri_message(pri, "Invalid DivertingLegInformation2Type argument\n");
--              return -1;
--      }
--
--      if (sequence->len == ASN1_LEN_INDEF) {
--              len -= 4; /* For the 2 extra characters at the end
--                           * and two characters of header */
--      } else
--              len -= 2;
--
-       do {
-               /* diversionCounter stuff */
-               GET_COMPONENT(comp, i, vdata, len);
-@@ -477,20 +493,18 @@
-       
-               if(pri->debug & PRI_DEBUG_APDU)
-                       pri_message(pri, "    Redirection reason: %d, total diversions: %d\n", diversion_reason, diversion_counter);
--              pri_message(NULL, "Length of message is %d\n", len);
-               for(; i < len; NEXT_COMPONENT(comp, i)) {
-                       GET_COMPONENT(comp, i, vdata, len);
--                      switch(comp->type) {
--                      case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0):
-+                      switch(comp->type & ASN1_TYPE_MASK) {
-+                      case ASN1_TAG_0:
-                               call->origredirectingreason = redirectingreason_for_q931(pri, comp->data[0]);
-                               if (pri->debug & PRI_DEBUG_APDU)
-                                       pri_message(pri, "    Received reason for original redirection %d\n", call->origredirectingreason);
-                               break;
--                      case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1):
-+                      case ASN1_TAG_1:                /* divertingnr: presentednumberunscreened */
-                               res = rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, &divertingnr);
-                               /* TODO: Fix indefinite length form hacks */
--                              ASN1_FIXUP_LEN(comp, res);
-                               comp->len = res;
-                               if (res < 0)
-                                       return -1;
-@@ -499,43 +513,33 @@
-                                       pri_message(pri, "      ton = %d, pres = %d, npi = %d\n", divertingnr.ton, divertingnr.pres, divertingnr.npi);
-                               }
-                               break;
--                      case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2):
-+                      case ASN1_TAG_2:                /* originalCalledNr: PresentedNumberUnscreened */
-                               res = rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, &originalcallednr);
-                               if (res < 0)
-                                       return -1;
--                              ASN1_FIXUP_LEN(comp, res);
-                               comp->len = res;
-                               if (pri->debug & PRI_DEBUG_APDU) {
-                                       pri_message(pri, "    Received originalcallednr '%s'\n", originalcallednr.partyaddress);
-                                       pri_message(pri, "      ton = %d, pres = %d, npi = %d\n", originalcallednr.ton, originalcallednr.pres, originalcallednr.npi);
-                               }
-                               break;
--                      case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):
--                              res = asn1_name_decode(comp->data, comp->len, redirectingname, sizeof(redirectingname));
--                              if (res < 0)
--                                      return -1;
--                              ASN1_FIXUP_LEN(comp, res);
--                              comp->len = res;
-+                      case ASN1_TAG_3:
-+                              comp->len = asn1_name_decode(comp->data, comp->len, redirectingname, sizeof(redirectingname));
-                               if (pri->debug & PRI_DEBUG_APDU)
-                                       pri_message(pri, "    Received RedirectingName '%s'\n", redirectingname);
-                               break;
--                      case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4):
--                              res = asn1_name_decode(comp->data, comp->len, origcalledname, sizeof(origcalledname));
--                              if (res < 0)
--                                      return -1;
--                              ASN1_FIXUP_LEN(comp, res);
--                              comp->len = res;
-+                      case ASN1_TAG_4:
-+                              comp->len = asn1_name_decode(comp->data, comp->len, origcalledname, sizeof(origcalledname));
-                               if (pri->debug & PRI_DEBUG_APDU)
-                                       pri_message(pri, "    Received Originally Called Name '%s'\n", origcalledname);
-                               break;
-                       default:
--                              if (comp->type == 0 && comp->len == 0) {
--                                      break; /* Found termination characters */
--                              }
-                               pri_message(pri, "!! Invalid DivertingLegInformation2 component received 0x%X\n", comp->type);
-                               return -1;
-                       }
-               }
-+              if (i < len)
-+                      return -1;      /* Aborted before */
-               if (divertingnr.pres >= 0) {
-                       call->redirectingplan = divertingnr.npi;
-@@ -548,15 +552,19 @@
-                       call->origcalledpres = originalcallednr.pres;
-                       libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum));
-               }
--              libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname));
--              libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname));
-+              if (strlen(redirectingname) > 0) {
-+                      libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname));
-+              }
-+              if (strlen(origcalledname) > 0) {
-+                      libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname));
-+              }
-               return 0;
-       }
-       while (0);
-       return -1;
- }
--                              
-+
- static int rose_diverting_leg_information2_encode(struct pri *pri, q931_call *call)
- {
-       int i = 0, j, compsp = 0;
-@@ -694,6 +702,64 @@
-       return 0;
- }
-+/* Call deflection */
-+int add_call_deflection_facility_ie(struct pri *pri, q931_call *c, char *destination) {
-+    int i = 0, j, compsp = 0;
-+    struct rose_component *comp, *compstk[10];
-+    unsigned char buffer[256];
-+
-+    buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_ROSE);
-+    /* invoke */
-+    ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
-+    ASN1_PUSH(compstk, compsp, comp);
-+
-+    ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
-+    ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, ROSE_CALLDEFLECTION); 
-+
-+    /* Argument sequence */
-+    ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
-+    ASN1_PUSH(compstk, compsp, comp);
-+
-+    /* arg.Address */
-+    ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
-+    ASN1_PUSH(compstk, compsp, comp);
-+    
-+#ifndef CD_UNLIKE_IN_CAPI
-+    /* arg.address.PartyNumber */
-+
-+    
-+    j = asn1_string_encode((ASN1_CONTEXT_SPECIFIC|ASN1_TAG_0), &buffer[i], sizeof(buffer)-i, 20, destination, strlen(destination));
-+    if (j<0) return -1;
-+    i += j;
-+#else
-+    /* using PublicPartyNumber instead */
-+    ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE | ASN1_CONTEXT_SPECIFIC| ASN1_TAG_1), buffer, i);
-+    ASN1_PUSH(compstk, compsp, comp);
-+    /* ToN: unknown */
-+    ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0);
-+    j = asn1_string_encode(0x80, &buffer[i], sizeof(buffer)-i, 20, destination, strlen(destination));
-+    if(j<0) return -1;
-+    i += j;
-+    /* close PublicPartyNumber */
-+    ASN1_FIXUP(compstk, compsp, buffer, i);
-+#endif
-+
-+    /* close Address */
-+    ASN1_FIXUP(compstk, compsp, buffer, i);
-+
-+    /* add boolean */
-+    ASN1_ADD_BYTECOMP(comp, ASN1_BOOLEAN, buffer, i, 0);
-+
-+    /* Fix length of stacked components */
-+    while(compsp > 0) {
-+        ASN1_FIXUP(compstk, compsp, buffer, i);
-+    }
-+    if (pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL))
-+                     return -1;
-+   
-+        return 0;
-+}
-+
- /* Sending callername information functions */
- static int add_callername_facility_ies(struct pri *pri, q931_call *c, int cpe)
- {
-@@ -936,7 +1002,7 @@
-               CHECK_COMPONENT(comp, ASN1_ENUMERATED, "!! Invalid AOC Charging Request argument. Expected Enumerated (0x0A) but Received 0x%02X\n");
-               ASN1_GET_INTEGER(comp, chargingcase);                           
-               if (chargingcase >= 0 && chargingcase <= 2) {
--                      if (pri->debug & PRI_DEBUG_APDU)
-+//                    if (pri->debug & PRI_DEBUG_APDU)
-                               pri_message(pri, "Channel %d/%d, Call %d  - received AOC charging request - charging case: %i\n", 
-                                       call->ds1no, call->channelno, call->cr, chargingcase);
-               } else {
-@@ -1054,7 +1120,7 @@
-       return 0;
- }
--static int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long chargedunits)
-+int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long chargedunits, int msgtype)
- {
-       /* sample data: [ 91 a1 12 02 02 3a 78 02 01 24 30 09 30 07 a1 05 30 03 02 01 01 ] */
-       int i = 0, res = 0, compsp = 0;
-@@ -1108,18 +1174,20 @@
-               dump_apdu (pri, buffer, i);
-               
-       /* code below is untested */
--      res = pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL);
-+      res = pri_call_apdu_queue(c, msgtype, buffer, i, NULL, NULL);
-       if (res) {
-               pri_message(pri, "Could not queue ADPU in facility message\n");
-               return -1;
-       }
--      /* Remember that if we queue a facility IE for a facility message we
--       * have to explicitly send the facility message ourselves */
--      res = q931_facility(c->pri, c);
--      if (res) {
-+      if (msgtype == Q931_FACILITY) {
-+          /* Remember that if we queue a facility IE for a facility message we
-+           * have to explicitly send the facility message ourselves */
-+          res = q931_facility(c->pri, c);
-+          if (res) {
-               pri_message(pri, "Could not schedule facility message for call %d\n", c->cr);
-               return -1;
-+          }
-       }
-       return 0;
-@@ -1152,13 +1220,15 @@
-               NEXT_COMPONENT(comp, i);
-               /* No argument - return with error */
--              if (i >= len) 
-+              if ((i >= len) && (operation_tag != ROSE_EXPLICIT_CALL_TRANSFER))
-                       return -1;
--              /* Arguement Tag */
--              GET_COMPONENT(comp, i, vdata, len);
--              if (!comp->type)
--                      return -1;
-+              if (operation_tag != ROSE_EXPLICIT_CALL_TRANSFER) {
-+                  /* Arguement Tag */
-+                  GET_COMPONENT(comp, i, vdata, len);
-+                  if (!comp->type)
-+                      return -1;
-+              }
-               if (pri->debug & PRI_DEBUG_APDU)
-                       pri_message(pri, "  [ Handling operation %d ]\n", operation_tag);
-@@ -1182,7 +1252,11 @@
-               case ROSE_DIVERTING_LEG_INFORMATION2:
-                       if (pri->debug & PRI_DEBUG_APDU)
-                               pri_message(pri, "  Handle DivertingLegInformation2\n");
--                      return rose_diverting_leg_information2_decode(pri, call, comp, len-i);
-+                      if (comp->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
-+                              pri_message(pri, "Invalid DivertingLegInformation2Type argument\n");
-+                              return -1;
-+                      }
-+                      return rose_diverting_leg_information2_decode(pri, call, comp->data, comp->len);
-               case ROSE_AOC_NO_CHARGING_INFO_AVAILABLE:
-                       if (pri->debug & PRI_DEBUG_APDU) {
-                               pri_message(pri, "ROSE %i: AOC No Charging Info Available - not handled!", operation_tag);
-@@ -1210,6 +1284,7 @@
-                       }
-                       return -1;
-               case ROSE_AOC_AOCD_CHARGING_UNIT:
-+//                    return aoc_aoce_charging_unit_decode(pri, call, (u_int8_t *)comp, comp->len + 2);
-                       if (pri->debug & PRI_DEBUG_APDU) {
-                               pri_message(pri, "ROSE %i: AOC-D Charging Unit - not handled!", operation_tag);
-                               dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
-@@ -1224,7 +1299,7 @@
-               case ROSE_AOC_AOCE_CHARGING_UNIT:
-                       return aoc_aoce_charging_unit_decode(pri, call, (u_int8_t *)comp, comp->len + 2);
-                       if (0) { /* the following function is currently not used - just to make the compiler happy */
--                              aoc_aoce_charging_unit_encode(pri, call, call->aoc_units); /* use this function to forward the aoc-e on a bridged channel */ 
-+                              aoc_aoce_charging_unit_encode(pri, call, call->aoc_units, 1); /* use this function to forward the aoc-e on a bridged channel */ 
-                               return 0;
-                       }
-               case ROSE_AOC_IDENTIFICATION_OF_CHARGE:
-@@ -1233,6 +1308,22 @@
-                               dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
-                       }
-                       return -1;
-+              case ROSE_CALLDEFLECTION:
-+                      call->facility = operation_tag;
-+                      return rose_cd_destination_decode(pri, call, (u_int8_t *)comp, comp->len + 2);
-+                      return -1;
-+              case ROSE_EXPLICIT_CALL_TRANSFER:
-+                      call->facility = operation_tag;
-+                      if (pri->debug & PRI_DEBUG_APDU) {
-+                              pri_message(pri, "ROSE %i: received ECT execute!", operation_tag);
-+                      }
-+                      return 0;
-+              case ROSE_MALICIOUS_CID:
-+//                    call->facility = operation_tag;
-+//                    if (pri->debug & PRI_DEBUG_APDU) {
-+                              pri_message(pri, "ROSE %i: received MALICIOUS CID!", operation_tag);
-+ //                   }
-+                      return 0;
-               default:
-                       if (pri->debug & PRI_DEBUG_APDU) {
-                               pri_message(pri, "!! Unable to handle ROSE operation %d", operation_tag);
-diff -urN libpri-1.2.3.orig/pri_facility.h libpri-1.2.3/pri_facility.h
---- libpri-1.2.3.orig/pri_facility.h   2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/pri_facility.h        2006-04-15 21:35:05.000000000 +0200
-@@ -34,7 +34,7 @@
- /* Operation ID values */
- /* Q.952 ROSE operations (Diverting) */
- #define ROSE_DIVERTING_LEG_INFORMATION1               18
--#define ROSE_DIVERTING_LEG_INFORMATION2               0x15
-+#define ROSE_DIVERTING_LEG_INFORMATION2               15
- #define ROSE_DIVERTING_LEG_INFORMATION3               19
- /* Q.956 ROSE operations (Advice Of Charge) */
- #define ROSE_AOC_NO_CHARGING_INFO_AVAILABLE   26
-@@ -48,11 +48,15 @@
- #define ROSE_AOC_IDENTIFICATION_OF_CHARGE     37
- /* Q.SIG operations */
- #define SS_CNID_CALLINGNAME                                   0
--#define SS_DIVERTING_LEG_INFORMATION2         21
-+#define SS_DIVERTING_LEG_INFORMATION2         22
- #define SS_MWI_ACTIVATE                                               80
- #define SS_MWI_DEACTIVATE                                     81
- #define SS_MWI_INTERROGATE                                    82
-+#define ROSE_CALLDEFLECTION                   0x0D
-+#define ROSE_EXPLICIT_CALL_TRANSFER           0x06
-+#define ROSE_MALICIOUS_CID                    0x31
-+
- /* ROSE definitions and data structures */
- #define INVOKE_IDENTIFIER                     0x02
- #define INVOKE_LINKED_IDENTIFIER      0x80
-@@ -180,12 +184,6 @@
-                       (variable) = ((variable) << 8) | (component)->data[comp_idx]; \
-       } while (0)
--#define ASN1_FIXUP_LEN(component, size) \
--      do { \
--              if ((component)->len == ASN1_LEN_INDEF) \
--                      size += 2; \
--      } while (0)
--
- #define ASN1_ADD_SIMPLE(component, comptype, ptr, idx) \
-       do { \
-               (component) = (struct rose_component *)&((ptr)[(idx)]); \
-@@ -260,4 +258,8 @@
- /* Adds the "standard" ADPUs to a call */
- extern int pri_call_add_standard_apdus(struct pri *pri, q931_call *call);
-+extern int add_call_deflection_facility_ie(struct pri *pri, q931_call *c, char *destination);
-+
-+extern int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long chargedunits, int send_facility_message);
-+
- #endif /* _PRI_FACILITY_H */
-diff -urN libpri-1.2.3.orig/pri_internal.h libpri-1.2.3/pri_internal.h
---- libpri-1.2.3.orig/pri_internal.h   2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/pri_internal.h        2006-04-15 21:57:19.000000000 +0200
-@@ -5,6 +5,8 @@
-  *
-  * Copyright (C) 2001, Linux Support Services, Inc.
-  * All Rights Reserved.
-+ * Copyright (C) 2003-2006 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj@junghanns.net>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -30,7 +32,10 @@
- struct pri_sched {
-       struct timeval when;
-       void (*callback)(void *data);
-+      void (*callback2)(void *data, int);
-       void *data;
-+      char hasdata2;
-+      int data2;
- };
- struct q921_frame;
-@@ -38,8 +43,15 @@
- enum q931_mode;
- /* No more than 128 scheduled events */
-+/* XXX is this sufficient for nfs ??? */
- #define MAX_SCHED 128
-+/* this can be freely configured to support more devices .... ok, 63 would be max! */
-+#define Q921_MAX_TEIS 16
-+
-+/* dynamically allocated TEIs start here */
-+#define Q921_TEI_BASE 64
-+
- #define MAX_TIMERS 32
- struct pri {
-@@ -51,6 +63,7 @@
-       struct pri *master;             /* Master channel if appropriate */
-       struct pri_sched pri_sched[MAX_SCHED];  /* Scheduled events */
-       int debug;                      /* Debug stuff */
-+      int debugfd;
-       int state;                      /* State of D-channel */
-       int switchtype;         /* Switch type */
-       int nsf;                /* Network-Specific Facility (if any) */
-@@ -62,25 +75,42 @@
-       int protodisc;
-       
-       /* Q.921 State */
--      int q921_state; 
--      int window;                     /* Max window size */
--      int windowlen;          /* Fullness of window */
--      int v_s;                        /* Next N(S) for transmission */
--      int v_a;                        /* Last acknowledged frame */
--      int v_r;                        /* Next frame expected to be received */
--      int v_na;                       /* What we've told our peer we've acknowledged */
--      int solicitfbit;        /* Have we sent an I or S frame with the F-bit set? */
--      int retrans;            /* Retransmissions */
--      int sentrej;            /* Are we in reject state */
--      
-+      int q921_state[Q921_MAX_TEIS];  
-+      char dchanup;
-+      
-+      /* TEI registry */
-+              char q921_teis[Q921_MAX_TEIS];
-+
-+              char q921_tei_check[Q921_MAX_TEIS];
-+              unsigned short q921_tei_check_ri[Q921_MAX_TEIS];
-+      
-+      unsigned int ri; 
-+  
-+      int busy[Q921_MAX_TEIS];                        /* Peer is busy */
-+   
-+      int window[Q921_MAX_TEIS];                      /* Max window size */
-+      int windowlen[Q921_MAX_TEIS];           /* Fullness of window */
-+      int v_s[Q921_MAX_TEIS];                 /* Next N(S) for transmission */
-+      int v_a[Q921_MAX_TEIS];                 /* Last acknowledged frame */
-+      int v_r[Q921_MAX_TEIS];                 /* Next frame expected to be received */
-+      int v_na[Q921_MAX_TEIS];                        /* What we've told our peer we've acknowledged */
-+      int solicitfbit[Q921_MAX_TEIS]; /* Have we sent an I or S frame with the F-bit set? */
-+      int retrans[Q921_MAX_TEIS];             /* Retransmissions */
-+      int sabme_retrans[Q921_MAX_TEIS];               /* Retransmissions */
-+  
-+      int sentrej[Q921_MAX_TEIS];             /* Are we in reject state */
-+      
-+      /* Various timers */
-+      int sabme_timer[Q921_MAX_TEIS];
-+      int t203_timer[Q921_MAX_TEIS];
-+      int t202_timer[Q921_MAX_TEIS];
-+
-+      int t201_timer[Q921_MAX_TEIS];
-+      int t200_timer[Q921_MAX_TEIS];
-+ 
-+
-       int cref;                       /* Next call reference value */
-       
--      int busy;                       /* Peer is busy */
--
--      /* Various timers */
--      int sabme_timer;        /* SABME retransmit */
--      int t203_timer;         /* Max idle time */
--      int t200_timer;         /* T-200 retransmission timer */
-       /* All ISDN Timer values */
-       int timers[MAX_TIMERS];
-@@ -89,8 +119,8 @@
-       int schedev;
-       pri_event ev;           /* Static event thingy */
-       
--      /* Q.921 Re-transmission queue */
--      struct q921_frame *txqueue;
-+      /* Q.921 (Re)transmission queue */
-+      struct q921_frame *txqueue[Q921_MAX_TEIS];
-       
-       /* Q.931 calls */
-       q931_call **callpool;
-@@ -109,6 +139,9 @@
-       unsigned char last_invoke;      /* Last ROSE invoke ID */
-       unsigned char sendfacility;
-+
-+      int span; /* our fellow pri lives on this zaptel span */
-+
- };
- struct pri_sr {
-@@ -118,6 +151,7 @@
-       int nonisdn;
-       char *caller;
-       int callerplan;
-+      int callerplanani;
-       char *callername;
-       int callerpres;
-       char *called;
-@@ -130,6 +164,7 @@
-       int redirectingreason;
-       int justsignalling;
-       char *useruserinfo;
-+      char *llc;
- };
- /* Internal switch types */
-@@ -167,8 +202,13 @@
-       
-       int alive;                      /* Whether or not the call is alive */
-       int acked;                      /* Whether setup has been acked or not */
-+      int con_acked;                  /* Whether CONNECT has been CONNECT_ACKNOWLEDGEd or not */
-       int sendhangupack;      /* Whether or not to send a hangup ack */
-       int proc;                       /* Whether we've sent a call proceeding / alerting */
-+      int alert;                      /* Whether we've sent an alerting */
-+ 
-+      int tei;
-+      q921_call *phones;
-       
-       int ri;                         /* Restart Indicator (Restart Indicator IE) */
-@@ -202,15 +242,18 @@
-       int callerplan;
-       int callerplanani;
-       int callerpres;                 /* Caller presentation */
--      char callerani[256];    /* Caller */
--      char callernum[256];
-+      int callerplanuser;
-+      int callerpresuser;                     /* Caller presentation */
-+      char callernum[256];    /* Calling Number (network provided) */
-+      char callerani[256];    /* Calling Number, (user provided) */
-+
-       char callername[256];
--      char digitbuf[64];              /* Buffer for digits that come in KEYPAD_FACILITY */
-+      char digitbuf[64];      /* Buffer for digits that come in KEYPAD_FACILITY */
-       int ani2;               /* ANI II */
-       
--      int calledplan;
-+      int  calledplan;
-       int nonisdn;
-       char callednum[256];    /* Called Number */
-       int complete;                   /* no more digits coming */
-@@ -225,23 +268,36 @@
-       char redirectingnum[256];       /* Number of redirecting party */
-       char redirectingname[256];      /* Name of redirecting party */
-+      int t303timer;          
-+      int t303running;                
-+
-       /* Filled in cases of multiple diversions */
-       int origcalledplan;
-       int origcalledpres;
--      int origredirectingreason;      /* Original reason for redirect (in cases of multiple redirects) */
-+      int origredirectingreason;      /* Original reason for redirect (in cases of multiple redirects) */
-       char origcalledname[256];       /* Original name of person being called */
--      char origcallednum[256];        /* Orignal number of person being called */
-+      char origcallednum[256];                /* Orignal number of person being called */
--      int useruserprotocoldisc;
-+        int useruserprotocoldisc;
-       char useruserinfo[256];
-       char callingsubaddr[256];       /* Calling parties sub address */
-+
-+      char callid[10];        /* call identity for SUSPEND/RESUME */
-+      char digits[256];       /* additional digits received via info msgs (cpn or keypad) */
-+      char display[256];      /* display ie received in info msgs or for sending */
-+ 
-+      /* euroisdn facility fun */
-+      int facility; /* FACILTIY received */
-+      int aoc;
-       
-       long aoc_units;                         /* Advice of Charge Units */
-+      char llc[16]; /* low layer compatibility */
-       struct apdu_event *apdus;       /* APDU queue for call */
- };
- extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
-+extern int pri_schedule_event2(struct pri *pri, int ms, void (*function)(void *data, int data2), void *data, int data2);
- extern pri_event *pri_schedule_run(struct pri *pri);
-@@ -250,7 +306,7 @@
- extern pri_event *pri_mkerror(struct pri *pri, char *errstr);
- extern void pri_message(struct pri *pri, char *fmt, ...);
--
-+  
- extern void pri_error(struct pri *pri, char *fmt, ...);
- void libpri_copy_string(char *dst, const char *src, size_t size);
-diff -urN libpri-1.2.3.orig/pri_q921.h libpri-1.2.3/pri_q921.h
---- libpri-1.2.3.orig/pri_q921.h       2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/pri_q921.h    2006-04-15 21:57:24.000000000 +0200
-@@ -5,6 +5,8 @@
-  *
-  * Copyright (C) 2001, Linux Support Services, Inc.
-  * All Rights Reserved.
-+ * Copyright (C) 2003-2006 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj@junghanns.net>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -47,6 +49,13 @@
- #define Q921_FRAMETYPE_S      0x1
- #define Q921_TEI_GROUP                                127
-+#define Q921_TEI_ID_REQUEST   0x1
-+#define Q921_TEI_ID_ASSIGNED  0x2
-+#define Q921_TEI_ID_DENIED    0x3
-+#define Q921_TEI_ID_CHK_REQ   0x4
-+#define Q921_TEI_ID_CHK_RES   0x5
-+#define Q921_TEI_ID_REMOVE    0x6
-+#define Q921_TEI_ID_VERIFY    0x7
- #define Q921_TEI_GR303_EOC_PATH                       0
- #define Q921_TEI_GR303_EOC_OPS                        4
- #define Q921_TEI_GR303_TMC_SWITCHING          0
-@@ -164,12 +173,14 @@
- extern void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx);
- /* Bring up the D-channel */
--extern void q921_start(struct pri *pri, int now);
-+extern void q921_start(struct pri *pri, int now, int tei);
--extern void q921_reset(struct pri *pri);
-+extern void q921_reset(struct pri *pri, int tei, int discard);
- extern pri_event *q921_receive(struct pri *pri, q921_h *h, int len);
--extern int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr);
-+extern int q921_transmit_uframe(struct pri *pri, void *buf, int len, int cr, int tei);
-+
-+extern int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr, int tei);
- #endif
-diff -urN libpri-1.2.3.orig/pri_q931.h libpri-1.2.3/pri_q931.h
---- libpri-1.2.3.orig/pri_q931.h       2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/pri_q931.h    2006-04-15 21:57:29.000000000 +0200
-@@ -5,6 +5,8 @@
-  *
-  * Copyright (C) 2001, Linux Support Services, Inc.
-  * All Rights Reserved.
-+ * Copyright (C) 2003-2006 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj@junghanns.net>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -190,6 +192,10 @@
- #define Q931_IE_CODESET(x)            ((x) >> 8)
- #define Q931_IE_IE(x)                 ((x) & 0xff)
- #define Q931_FULL_IE(codeset, ie)     (((codeset) << 8) | ((ie) & 0xff))
-+#define Q931_IE_MAX_LEN                       257
-+
-+// BRI+
-+#define Q931_COLP     0x4c
- #define Q931_DISPLAY                                  0x28
- #define Q931_IE_SEGMENTED_MSG                 0x00
-@@ -218,6 +224,8 @@
- #define Q931_IE_USER_USER                             0x7E
- #define Q931_IE_ESCAPE_FOR_EXT                        0x7F
-+#define Q931_IE_SPECIAL               0x02
-+
- /* Call state stuff */
- #define Q931_CALL_STATE_NULL                          0
-@@ -243,7 +251,7 @@
- /* EuroISDN  */
- #define Q931_SENDING_COMPLETE         0xa1
--extern int q931_receive(struct pri *pri, q931_h *h, int len);
-+extern int q931_receive(struct pri *pri, q931_h *h, int len, int tei);
- extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
-@@ -257,6 +265,10 @@
- extern int q931_information(struct pri *pri, q931_call *call, char digit);
-+extern int q931_information_display(struct pri *pri, q931_call *call, char *display);
-+
-+extern int q931_add_display(struct pri *pri, q931_call *call, char *display);
-+
- extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn);
- extern int q931_release(struct pri *pri, q931_call *call, int cause);
-@@ -265,6 +277,10 @@
- extern int q931_hangup(struct pri *pri, q931_call *call, int cause);
-+extern int q921_hangup(struct pri *pri, q931_call *c, int tei);
-+
-+extern int q921_handle_hangup(struct pri *pri, q931_call *c, int tei);
-+
- extern int q931_restart(struct pri *pri, int channel);
- extern int q931_facility(struct pri *pri, q931_call *call);
-@@ -279,5 +295,23 @@
- extern void q931_dump(struct pri *pri, q931_h *h, int len, int txrx);
- extern void __q931_destroycall(struct pri *pri, q931_call *c);
-+ 
-+extern int q931_hold_acknowledge(struct pri *pri, q931_call *c);
-+
-+extern int q931_hold_reject(struct pri *pri, q931_call *c);
-+
-+extern int q931_retrieve_acknowledge(struct pri *pri, q931_call *c, int channel);
-       
-+extern int q931_retrieve_reject(struct pri *pri, q931_call *c);
-+
-+extern int q931_suspend_acknowledge(struct pri *pri, q931_call *c, char *display);
-+
-+extern int q931_suspend_reject(struct pri *pri, q931_call *c, char *display);
-+
-+extern int q931_resume_reject(struct pri *pri, q931_call *c, char *display);
-+
-+extern int q931_resume_acknowledge(struct pri *pri, q931_call *c, int channel, char *display);
-+
-+//extern int q931_facility(struct pri *pri, q931_call *c, int operation, char *arguments);
-+
- #endif
-diff -urN libpri-1.2.3.orig/pri_timers.h libpri-1.2.3/pri_timers.h
---- libpri-1.2.3.orig/pri_timers.h     2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/pri_timers.h  2006-01-18 12:28:07.000000000 +0100
-@@ -27,17 +27,17 @@
- /* -1 means we dont currently support the timer/counter */
- #define PRI_TIMERS_DEFAULT {  3,      /* N200 */ \
--                              -1,     /* N201 */ \
--                              -1,     /* N202 */ \
-+                              260,    /* N201 */ \
-+                              3,      /* N202 */ \
-                               7,      /* K */ \
-                               1000,   /* T200 */ \
--                              -1,     /* T201 */ \
--                              -1,     /* T202 */ \
-+                              2000,   /* T201 */ \
-+                              5000,   /* T202 */ \
-                               10000,  /* T203 */ \
-                               -1,     /* T300 */ \
-                               -1,     /* T301 */ \
-                               -1,     /* T302 */ \
--                              -1,     /* T303 */ \
-+                              4000,   /* T303 */ \
-                               -1,     /* T304 */ \
-                               30000,  /* T305 */ \
-                               -1,     /* T306 */ \
-diff -urN libpri-1.2.3.orig/pridump.c libpri-1.2.3/pridump.c
---- libpri-1.2.3.orig/pridump.c        2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/pridump.c     2006-01-18 12:28:07.000000000 +0100
-@@ -1,9 +1,9 @@
- /*
-  * libpri: An implementation of Primary Rate ISDN
-  *
-- * Written by Mark Spencer <markster@digium.com>
-+ * Written by Mark Spencer <markster@linux-support.net>
-  *
-- * Copyright (C) 2001-2005, Digium
-+ * Copyright (C) 2001, Linux Support Services, Inc.
-  * All Rights Reserved.
-  *
-  * This program is free software; you can redistribute it and/or modify
-diff -urN libpri-1.2.3.orig/prisched.c libpri-1.2.3/prisched.c
---- libpri-1.2.3.orig/prisched.c       2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/prisched.c    2006-04-15 21:57:42.000000000 +0200
-@@ -1,10 +1,12 @@
- /*
-  * libpri: An implementation of Primary Rate ISDN
-  *
-- * Written by Mark Spencer <markster@digium.com>
-+ * Written by Mark Spencer <markster@linux-support.net>
-  *
-- * Copyright (C) 2001-2005, Digium
-+ * Copyright (C) 2001, Linux Support Services, Inc.
-  * All Rights Reserved.
-+ * Copyright (C) 2003-2006 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj@junghanns.net>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -22,10 +24,9 @@
-  *
-  */
--#include <stdio.h>
--
- #include "libpri.h"
- #include "pri_internal.h"
-+#include <stdio.h>
- static int maxsched = 0;
-@@ -36,7 +37,7 @@
-       int x;
-       struct timeval tv;
-       for (x=1;x<MAX_SCHED;x++)
--              if (!pri->pri_sched[x].callback)
-+              if ((!pri->pri_sched[x].callback2) && (!pri->pri_sched[x].callback))
-                       break;
-       if (x == MAX_SCHED) {
-               pri_error(pri, "No more room in scheduler\n");
-@@ -53,7 +54,39 @@
-       }
-       pri->pri_sched[x].when = tv;
-       pri->pri_sched[x].callback = function;
-+      pri->pri_sched[x].callback2 = NULL;
-       pri->pri_sched[x].data = data;
-+      pri->pri_sched[x].hasdata2 = 0;
-+      pri->pri_sched[x].data2 = 0;
-+      return x;
-+}
-+
-+int pri_schedule_event2(struct pri *pri, int ms, void (*function)(void *data, int data2), void *data, int data2)
-+{
-+      int x;
-+      struct timeval tv;
-+      for (x=1;x<MAX_SCHED;x++)
-+              if ((!pri->pri_sched[x].callback2) && (!pri->pri_sched[x].callback))
-+                      break;
-+      if (x == MAX_SCHED) {
-+              pri_error(pri, "No more room in scheduler\n");
-+              return -1;
-+      }
-+      if (x > maxsched)
-+              maxsched = x;
-+      gettimeofday(&tv, NULL);
-+      tv.tv_sec += ms / 1000;
-+      tv.tv_usec += (ms % 1000) * 1000;
-+      if (tv.tv_usec > 1000000) {
-+              tv.tv_usec -= 1000000;
-+              tv.tv_sec += 1;
-+      }
-+      pri->pri_sched[x].when = tv;
-+      pri->pri_sched[x].callback = NULL;
-+      pri->pri_sched[x].callback2 = function;
-+      pri->pri_sched[x].data = data;
-+      pri->pri_sched[x].hasdata2 = 1;
-+      pri->pri_sched[x].data2 = data2;
-       return x;
- }
-@@ -65,7 +98,7 @@
-       if (pri->subchannel)
-               closest = pri_schedule_next(pri->subchannel);
-       for (x=1;x<MAX_SCHED;x++) {
--              if (pri->pri_sched[x].callback && 
-+              if ((pri->pri_sched[x].callback || pri->pri_sched[x].callback2) && 
-                       (!closest || (closest->tv_sec > pri->pri_sched[x].when.tv_sec) ||
-                               ((closest->tv_sec == pri->pri_sched[x].when.tv_sec) && 
-                                (closest->tv_usec > pri->pri_sched[x].when.tv_usec))))
-@@ -76,26 +109,38 @@
- static pri_event *__pri_schedule_run(struct pri *pri, struct timeval *tv)
- {
--      int x;
--      void (*callback)(void *);
--      void *data;
-+      int x;
-+      void (*callback)(void *);
-+      void (*callback2)(void *, int);
-+      void *data;
-+      int data2;
-       pri_event *e;
-+
-       if (pri->subchannel) {
-               if ((e = __pri_schedule_run(pri->subchannel, tv))) {
-                       return e;
-               }
-       }
-       for (x=1;x<MAX_SCHED;x++) {
--              if (pri->pri_sched[x].callback &&
-+              if ((pri->pri_sched[x].callback || pri->pri_sched[x].callback2) &&
-                       ((pri->pri_sched[x].when.tv_sec < tv->tv_sec) ||
-                        ((pri->pri_sched[x].when.tv_sec == tv->tv_sec) &&
-                         (pri->pri_sched[x].when.tv_usec <= tv->tv_usec)))) {
-                               pri->schedev = 0;
-                               callback = pri->pri_sched[x].callback;
-+                              callback2 = pri->pri_sched[x].callback2;
-                               data = pri->pri_sched[x].data;
-+                              data2 = pri->pri_sched[x].data2;
-                               pri->pri_sched[x].callback = NULL;
-+                              pri->pri_sched[x].callback2 = NULL;
-                               pri->pri_sched[x].data = NULL;
--                              callback(data);
-+                              pri->pri_sched[x].data2 = 0;
-+                              if (pri->pri_sched[x].hasdata2 == 1) {
-+                                  pri->pri_sched[x].hasdata2 = 0;
-+                                  callback2(data, data2);
-+                              } else {
-+                                  callback(data);
-+                              }
-             if (pri->schedev)
-                   return &pri->ev;
-           }
-@@ -116,4 +161,6 @@
-       if ((id >= MAX_SCHED) || (id < 0)) 
-               pri_error(pri, "Asked to delete sched id %d???\n", id);
-       pri->pri_sched[id].callback = NULL;
-+      pri->pri_sched[id].callback2 = NULL;
- }
-+
-diff -urN libpri-1.2.3.orig/pritest.c libpri-1.2.3/pritest.c
---- libpri-1.2.3.orig/pritest.c        2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.3/pritest.c     2006-01-18 12:28:07.000000000 +0100
-@@ -1,9 +1,9 @@
- /*
-  * libpri: An implementation of Primary Rate ISDN
-  *
-- * Written by Mark Spencer <markster@digium.com>
-+ * Written by Mark Spencer <markster@linux-support.net>
-  *
-- * Copyright (C) 2001-2005, Digium
-+ * Copyright (C) 2001, Linux Support Services, Inc.
-  * All Rights Reserved.
-  *
-  * This program is free software; you can redistribute it and/or modify
-@@ -51,8 +51,8 @@
- #define PRI_DEF_NODETYPE      PRI_CPE
- #define PRI_DEF_SWITCHTYPE    PRI_SWITCH_NI2
--#define MAX_CHAN              32
--#define       DCHANNEL_TIMESLOT       16
-+#define MAX_CHAN              3
-+#define       DCHANNEL_TIMESLOT       3
- static int offset = 0;
-@@ -60,7 +60,7 @@
- static void do_channel(ZAP *z)
- {
-       /* This is the part that runs on a given channel */
--      zap_playf(z, "raw.ulaw", 0);
-+      zap_playf(z, "raw.alaw", 0);
- }
- struct pri_chan {
-@@ -76,6 +76,14 @@
-               return PRI_CPE;
-       if (!strcasecmp(node, "network"))
-               return PRI_NETWORK;
-+      if (!strcasecmp(node, "bri_cpe_ptmp"))
-+              return BRI_CPE_PTMP;
-+      if (!strcasecmp(node, "bri_network_ptmp"))
-+              return BRI_NETWORK_PTMP;
-+      if (!strcasecmp(node, "bri_cpe"))
-+              return BRI_CPE;
-+      if (!strcasecmp(node, "bri_network"))
-+              return BRI_NETWORK;
-       return -1;
- }
-@@ -285,6 +293,10 @@
-               }
-               
-               break;
-+      case PRI_EVENT_HANGUP_REQ:
-+              printf("-- Hanging up channel %d\n", e->hangup.channel);
-+              hangup_channel(e->hangup.channel);
-+              break;
-       default:
-               fprintf(stderr, "--!! Unknown PRI event %d\n", e->e);
-       }
-diff -urN libpri-1.2.3.orig/q921.c libpri-1.2.3/q921.c
---- libpri-1.2.3.orig/q921.c   2005-12-06 22:35:50.000000000 +0100
-+++ libpri-1.2.3/q921.c        2006-08-01 09:55:53.000000000 +0200
-@@ -1,10 +1,12 @@
- /*
-  * libpri: An implementation of Primary Rate ISDN
-  *
-- * Written by Mark Spencer <markster@digium.com>
-+ * Written by Mark Spencer <markster@linux-support.net>
-  *
-- * Copyright (C) 2001-2005, Digium
-+ * Copyright (C) 2001, Linux Support Services, Inc.
-  * All Rights Reserved.
-+ * Copyright (C) 2003-2006 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj@junghanns.net>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -21,7 +23,7 @@
-  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
-  *
-  */
--
-+ 
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
-@@ -50,19 +52,24 @@
-       (hf).h.tei = (pri)->tei; \
- } while(0)
--static void reschedule_t203(struct pri *pri);
-+static void reschedule_t203(struct pri *pri, int tei);
-+static void q921_flush_txqueue(struct pri *pri, int tei, int devnull);
-+static void q921_send_teiverify(struct pri *pri,int tei);
--static void q921_discard_retransmissions(struct pri *pri)
-+static void q921_discard_retransmissions(struct pri *pri, int tei)
- {
-       struct q921_frame *f, *p;
--      f = pri->txqueue;
-+      int teio = tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+      
-+      f = pri->txqueue[teio];
-       while(f) {
--              p = f;
--              f = f->next;
--              /* Free frame */
--              free(p);
-+          p = f;
-+          f = f->next;
-+          /* Free frame */
-+          free(p);
-       }
--      pri->txqueue = NULL;
-+        pri->txqueue[teio] = NULL;
- }
- static int q921_transmit(struct pri *pri, q921_h *h, int len) 
-@@ -88,11 +95,15 @@
-               pri_error(pri, "Short write: %d/%d (%s)\n", res, len + 2, strerror(errno));
-               return -1;
-       }
--      reschedule_t203(pri);
-+      if (pri->localtype == BRI_CPE_PTMP) {
-+          reschedule_t203(pri, pri->tei);
-+      } else if (h->h.tei != Q921_TEI_GROUP) {
-+          reschedule_t203(pri, h->h.tei);
-+      }
-       return 0;
- }
--static void q921_send_ua(struct pri *pri, int pfbit)
-+static void q921_send_ua(struct pri *pri, int pfbit, int tei)
- {
-       q921_h h;
-       Q921_INIT(pri, h);
-@@ -100,6 +111,7 @@
-       h.u.m2 = 0;             /* M2 = 0 */
-       h.u.p_f = pfbit;        /* Final bit on */
-       h.u.ft = Q921_FRAMETYPE_U;
-+      h.h.tei = tei;
-       switch(pri->localtype) {
-       case PRI_NETWORK:
-               h.h.c_r = 0;
-@@ -107,6 +119,19 @@
-       case PRI_CPE:
-               h.h.c_r = 1;
-               break;
-+      case BRI_NETWORK_PTMP:
-+              h.h.c_r = 0;
-+              break;
-+      case BRI_CPE_PTMP:
-+              h.h.tei = pri->tei;
-+              h.h.c_r = 1;
-+              break;
-+      case BRI_NETWORK:
-+              h.h.c_r = 0;
-+              break;
-+      case BRI_CPE:
-+              h.h.c_r = 1;
-+              break;
-       default:
-               pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype);
-               return;
-@@ -116,18 +141,364 @@
-       q921_transmit(pri, &h, 3);
- }
--static void q921_send_sabme_now(void *vpri);
-+/*
-+static void q921_send_disconnect(struct pri *pri, int pfbit, int tei) {
-+      q921_h h;
-+      Q921_INIT(pri, h);
-+      h.u.m3 = 2;
-+      h.u.m2 = 0;
-+      h.u.p_f = pfbit;
-+      h.u.ft = Q921_FRAMETYPE_U;
-+      h.h.tei = tei;
-+      switch(pri->localtype) {
-+      case PRI_NETWORK:
-+              h.h.c_r = 0;
-+              break;
-+      case PRI_CPE:
-+              h.h.c_r = 1;
-+              break;
-+      case BRI_NETWORK_PTMP:
-+              h.h.c_r = 0;
-+              break;
-+      case BRI_CPE_PTMP:
-+              h.h.tei = pri->tei;
-+              h.h.c_r = 1;
-+              break;
-+      case BRI_NETWORK:
-+              h.h.c_r = 0;
-+              break;
-+      case BRI_CPE:
-+              h.h.c_r = 1;
-+              break;
-+      default:
-+              pri_error(pri, "Don't know how to disconnect on a type %d node\n", pri->localtype);
-+              return;
-+      }
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+              pri_message(pri, "Sending Disconnect\n");
-+      q921_transmit(pri, &h, 3);
-+ }
-+*/
--static void q921_send_sabme(void *vpri, int now)
-+static void q921_send_dm(struct pri *pri, int pfbit, int tei)
-+{
-+      q921_h h;
-+      Q921_INIT(pri, h);
-+      h.u.m3 = 0;             /* M3 = 0 */
-+      h.u.m2 = 3;             /* M2 = 3 */
-+      h.u.p_f = pfbit;        /* Final bit on */
-+      h.u.ft = Q921_FRAMETYPE_U;
-+      h.h.tei = tei;
-+      switch(pri->localtype) {
-+      case PRI_NETWORK:
-+              h.h.c_r = 0;
-+              break;
-+      case PRI_CPE:
-+              h.h.c_r = 1;
-+              break;
-+      case BRI_NETWORK_PTMP:
-+              h.h.c_r = 0;
-+              break;
-+      case BRI_CPE_PTMP:
-+              h.h.tei = pri->tei;
-+              h.h.c_r = 1;
-+              break;
-+      case BRI_NETWORK:
-+              h.h.c_r = 0;
-+              break;
-+      case BRI_CPE:
-+              h.h.c_r = 1;
-+              break;
-+      default:
-+              pri_error(pri, "Don't know how to DM on a type %d node\n", pri->localtype);
-+              return;
-+      }
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+              pri_message(pri, "Sending DM\n");
-+      q921_transmit(pri, &h, 3);
-+}
-+   
-+static void q921_send_teireq(void *vpri) {
-+    struct pri *pri = vpri;
-+    unsigned short ri=0x6464;
-+    q921_u *f;
-+    ri = rand();
-+
-+    if (pri->localtype != BRI_CPE_PTMP) {
-+      pri_error(pri, "TEI req for non-ptmp???\n"); 
-+      return;
-+    }
-+    if (pri->t202_timer[0]) { 
-+      pri_schedule_del(pri, pri->t202_timer[0]);
-+      pri->t202_timer[0] = 0;
-+    }
-+    if (pri->sabme_retrans[0]++ > (pri->timers[PRI_TIMER_N202])) {
-+      /* delete txqueue */
-+      q921_flush_txqueue(pri, 0, 1);
-+      /* N202 retransmissions, activation of layer 2 failed, tell upper layer, start again */
-+      pri->schedev = 1;
-+      pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
-+      pri->ev.gen.tei = 0;
-+      pri->sabme_retrans[0] = 0;
-+      q921_send_teiverify(pri, 127);
-+#ifdef RELAX_TRB
-+      pri->t202_timer[0] = pri_schedule_event(pri, pri->timers[PRI_TIMER_T202] + 3000, q921_send_teireq, pri);
-+#endif
-+      return;
-+    }
-+ 
-+    pri->t202_timer[0] = pri_schedule_event(pri, pri->timers[PRI_TIMER_T202], q921_send_teireq, pri);
-+  
-+    pri->ri = ri;
-+    f = malloc(sizeof(q921_u) + 5 + 2);
-+    memset(f,0x0,sizeof(q921_u) + 5 + 2);
-+    if (f) {
-+      f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
-+        f->h.tei = Q921_TEI_GROUP;
-+      f->h.c_r = 0;   
-+        f->h.ea1 = 0; 
-+        f->h.ea2 = 1; 
-+        f->m2 = 0;
-+        f->m3 = 0;
-+        f->ft = Q921_FRAMETYPE_U;
-+        f->data[0] = 0xf;
-+        f->data[1] = ri >> 8;
-+        f->data[2] = ri & 0xff;
-+        f->data[3] = Q921_TEI_ID_REQUEST;
-+        f->data[4] = 0xff;
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+          pri_message(pri, "Sending TEI Request ri=%d\n",ri);
-+      q921_transmit(pri,(q921_h *)&(f->h),8);
-+    }
-+}
-+  
-+static void q921_send_teiassign(struct pri *pri,int ri,int tei) {
-+    q921_u *f;
-+  
-+    if (pri->localtype != BRI_NETWORK_PTMP) {
-+      pri_error(pri, "TEI assign for non-ptmp???\n"); 
-+      return;
-+    }
-+  
-+    f = malloc(sizeof(q921_u) + 5 + 2);
-+    memset(f,0x0,sizeof(q921_u) + 5 + 2);
-+    if (f) {
-+      f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
-+      f->h.tei = Q921_TEI_GROUP;
-+      f->h.c_r = 1;   
-+      f->h.ea1 = 0;   
-+      f->h.ea2 = 1;   
-+      f->m2 = 0;
-+      f->m3 = 0;
-+      f->ft = Q921_FRAMETYPE_U;
-+      f->data[0] = 0xf;
-+      f->data[1] = ri >> 8;
-+      f->data[2] = ri & 0xff;
-+      f->data[3] = Q921_TEI_ID_ASSIGNED;
-+      f->data[4] = (tei << 1) | 0x1;
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                  pri_message(pri, "Sending TEI assign ri=%d tei=%d\n",ri,tei);
-+      q921_transmit(pri,(q921_h *)&(f->h),8);
-+      free(f);
-+    } else {
-+      pri_error(pri, "q921_send_teiassign: failed to malloc f!\n");
-+    }
-+}
-+  
-+static void q921_send_teichkresp(struct pri *pri,int tei) {
-+    q921_u *f;
-+    unsigned short ri=0x6464;
-+    ri = rand();
-+  
-+    if (pri->localtype != BRI_CPE_PTMP) {
-+      pri_error(pri, "TEI check response for non-ptmp???\n"); 
-+      return;
-+    }
-+  
-+    f = malloc(sizeof(q921_u) + 5 + 2);
-+    memset(f,0x0,sizeof(q921_u) + 5 + 2);
-+    if (f) {
-+      f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
-+      f->h.tei = Q921_TEI_GROUP;
-+      f->h.c_r = 0; // command u->n   
-+      f->h.ea1 = 0;   
-+      f->h.ea2 = 1;   
-+      f->m2 = 0;
-+      f->m3 = 0;
-+      f->ft = Q921_FRAMETYPE_U;
-+      f->data[0] = 0xf;
-+      f->data[1] = ri >> 8;
-+      f->data[2] = ri & 0xff;
-+      f->data[3] = Q921_TEI_ID_CHK_RES;
-+      f->data[4] = (tei << 1) | 0x1;
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                  pri_message(pri, "Sending TEI check resp ri=%d tei=%d\n",ri,tei);
-+      q921_transmit(pri,(q921_h *)&(f->h),8);
-+      free(f);
-+    }
-+}
-+
-+static void q921_send_teichkreq(struct pri *pri,int tei) {
-+    q921_u *f;
-+    unsigned short ri=0x6464;
-+    ri = rand();
-+  
-+    if (pri->localtype != BRI_NETWORK_PTMP) {
-+      pri_error(pri, "TEI check response for non-ptmp???\n"); 
-+      return;
-+    }
-+  
-+    f = malloc(sizeof(q921_u) + 5 + 2);
-+    memset(f,0x0,sizeof(q921_u) + 5 + 2);
-+    if (f) {
-+      f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
-+      f->h.tei = Q921_TEI_GROUP;
-+      f->h.c_r = 1; // command u->n   
-+      f->h.ea1 = 0;   
-+      f->h.ea2 = 1;   
-+      f->m2 = 0;
-+      f->m3 = 0;
-+      f->ft = Q921_FRAMETYPE_U;
-+      f->data[0] = 0xf;
-+      f->data[1] = 0;
-+      f->data[2] = 0;
-+      f->data[3] = Q921_TEI_ID_CHK_REQ;
-+      f->data[4] = (tei << 1) | 0x1;
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                  pri_message(pri, "Sending TEI check request ri=%d tei=%d\n",ri,tei);
-+      q921_transmit(pri,(q921_h *)&(f->h),8);
-+      free(f);
-+    }
-+}
-+ 
-+static void q921_send_teiverify(struct pri *pri,int tei) {
-+    q921_u *f;
-+  
-+    if ((pri->localtype != BRI_CPE) && (pri->localtype != BRI_CPE_PTMP)) {
-+      pri_error(pri, "TEI verify for non-ptmp???\n"); 
-+      return;
-+    }
-+  
-+    f = malloc(sizeof(q921_u) + 5 + 2);
-+    memset(f,0x0,sizeof(q921_u) + 5 + 2);
-+    if (f) {
-+      f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
-+      f->h.tei = Q921_TEI_GROUP;
-+      f->h.c_r = 0; // command u->n   
-+      f->h.ea1 = 0;   
-+      f->h.ea2 = 1;   
-+      f->m2 = 0;
-+      f->m3 = 0;
-+      f->ft = Q921_FRAMETYPE_U;
-+      f->data[0] = 0xf;
-+      f->data[1] = 0;
-+      f->data[2] = 0;
-+      f->data[3] = Q921_TEI_ID_VERIFY;
-+      f->data[4] = (tei << 1) | 0x1;
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                  pri_message(pri, "Sending TEI verify tei=%d\n", tei);
-+      q921_transmit(pri,(q921_h *)&(f->h),8);
-+      free(f);
-+    }
-+}
-+
-+  static void q921_send_teiremove(struct pri *pri, int tei) {
-+      q921_u *f;
-+      unsigned short ri=0x6464;
-+      ri = rand();
-+  
-+      if (pri->localtype != BRI_NETWORK_PTMP) {
-+      pri_error(pri, "TEI remove for non-ptmp???\n"); 
-+      return;
-+      }
-+  
-+      f = malloc(sizeof(q921_u) + 5 + 2);
-+      memset(f,0x0,sizeof(q921_u) + 5 + 2);
-+      if (f) {
-+      f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
-+      f->h.tei = Q921_TEI_GROUP;
-+      f->h.c_r = 1;   
-+      f->h.ea1 = 0;   
-+      f->h.ea2 = 1;   
-+      f->m2 = 0;
-+      f->m3 = 0;
-+      f->ft = Q921_FRAMETYPE_U;
-+      f->data[0] = 0xf;
-+      f->data[1] = ri >> 8;
-+      f->data[2] = ri & 0xff;
-+      f->data[3] = Q921_TEI_ID_REMOVE;
-+      f->data[4] = (tei << 1) | 0x1;
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                  pri_message(pri, "Sending TEI remove tei=%d\n",tei);
-+      q921_transmit(pri,(q921_h *)&(f->h),8);
-+      free(f);
-+      }
-+  }
-+  
-+  static void q921_send_teidenied(struct pri *pri, int ri, int tei) {
-+      q921_u *f;
-+  
-+      if (pri->localtype != BRI_NETWORK_PTMP) {
-+      pri_error(pri, "TEI ID denied for non-ptmp???\n"); 
-+      return;
-+      }
-+  
-+      f = malloc(sizeof(q921_u) + 5 + 2);
-+      memset(f,0x0,sizeof(q921_u) + 5 + 2);
-+      if (f) {
-+      f->h.sapi = Q921_SAPI_LAYER2_MANAGEMENT;
-+      f->h.tei = Q921_TEI_GROUP;
-+      f->h.c_r = 1;   
-+      f->h.ea1 = 0;   
-+      f->h.ea2 = 1;   
-+      f->m2 = 0;
-+      f->m3 = 0;
-+      f->ft = Q921_FRAMETYPE_U;
-+      f->data[0] = 0xf;
-+      f->data[1] = ri >> 8;
-+      f->data[2] = ri & 0xff;
-+      f->data[3] = Q921_TEI_ID_DENIED;
-+      f->data[4] = (tei << 1) | 0x1;
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                  pri_message(pri, "Sending TEI ID denied tei=%d\n",tei);
-+      q921_transmit(pri,(q921_h *)&(f->h),8);
-+      free(f);
-+      }
-+  }
-+  
-+ 
-+static void q921_send_sabme_now(void *vpri, int tei);
-+  
-+static void q921_send_sabme(void *vpri, int now, int tei)
- {
-       struct pri *pri = vpri;
-       q921_h h;
--      pri_schedule_del(pri, pri->sabme_timer);
--      pri->sabme_timer = 0;
--      pri->sabme_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], q921_send_sabme_now, pri);
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+  
-+      if (pri->sabme_timer[teio]) {
-+          pri_schedule_del(pri, pri->sabme_timer[teio]);
-+          pri->sabme_timer[teio] = 0;
-+      }
-+      pri->sabme_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], q921_send_sabme_now, pri, tei);
-       if (!now)
-               return;
-+      if (pri->sabme_retrans[teio]++ > (pri->timers[PRI_TIMER_N202])) {
-+          /* delete txqueue */
-+          q921_flush_txqueue(pri, tei, 1);
-+          /* N202 retransmissions, activation of layer 2 failed, tell upper layer, start again */
-+          pri->schedev = 1;
-+          pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
-+          pri->ev.gen.tei = tei;
-+          pri->sabme_retrans[teio] = 0;
-+#ifdef RELAX_TRB
-+          pri->sabme_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200] + 3000, q921_send_sabme_now, pri, tei);
-+#endif
-+          return;
-+      }
-       Q921_INIT(pri, h);
-+      // XXX
-+      h.h.tei = tei;
-       h.u.m3 = 3;     /* M3 = 3 */
-       h.u.m2 = 3;     /* M2 = 3 */
-       h.u.p_f = 1;    /* Poll bit set */
-@@ -139,25 +510,42 @@
-       case PRI_CPE:
-               h.h.c_r = 0;
-               break;
-+      case BRI_NETWORK_PTMP:
-+              h.h.c_r = 1;
-+              break;
-+      case BRI_CPE_PTMP:
-+              h.h.c_r = 0;
-+              h.h.tei = pri->tei;
-+              break;
-+      case BRI_NETWORK:
-+              h.h.c_r = 1;
-+              break;
-+      case BRI_CPE:
-+              h.h.c_r = 0;
-+              break;
-       default:
--              pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype);
-+              pri_error(pri, "Don't know how to send SABME on a type %d node\n", pri->localtype);
-               return;
-       }
-       if (pri->debug & PRI_DEBUG_Q921_STATE)
-               pri_message(pri, "Sending Set Asynchronous Balanced Mode Extended\n");
-       q921_transmit(pri, &h, 3);
--      pri->q921_state = Q921_AWAITING_ESTABLISH;
-+      pri->q921_state[teio] = Q921_AWAITING_ESTABLISH;
- }
--static void q921_send_sabme_now(void *vpri)
-+static void q921_send_sabme_now(void *vpri, int tei)
- {
--      q921_send_sabme(vpri, 1);
-+      q921_send_sabme(vpri, 1, tei);
- }
--static int q921_ack_packet(struct pri *pri, int num)
-+  
-+
-+static int q921_ack_packet(struct pri *pri, int num, int tei)
- {
-       struct q921_frame *f, *prev = NULL;
--      f = pri->txqueue;
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+      f = pri->txqueue[teio];
-       while(f) {
-               if (f->h.n_s == num) {
-                       /* Cancel each packet as necessary */
-@@ -165,26 +553,26 @@
-                       if (prev)
-                               prev->next = f->next;
-                       else
--                              pri->txqueue = f->next;
-+                              pri->txqueue[teio] = f->next;
-                       if (pri->debug & PRI_DEBUG_Q921_STATE)
--                              pri_message(pri, "-- ACKing packet %d, new txqueue is %d (-1 means empty)\n", f->h.n_s, pri->txqueue ? pri->txqueue->h.n_s : -1);
-+                              pri_message(pri, "-- ACKing packet %d, new txqueue is %d (-1 means empty)\n", f->h.n_s, pri->txqueue[teio] ? pri->txqueue[teio]->h.n_s : -1);
-                       /* Update v_a */
--                      pri->v_a = num;
-+                      pri->v_a[teio] = num;
-                       free(f);
-                       /* Reset retransmission counter if we actually acked something */
--                      pri->retrans = 0;
-+                      pri->retrans[teio] = 0;
-                       /* Decrement window size */
--                      pri->windowlen--;
-+                      pri->windowlen[teio]--;
-                       /* Search for something to send */
--                      f = pri->txqueue;
-+                      f = pri->txqueue[teio];
-                       while(f) {
-                               if (!f->transmitted) {
-                                       /* Send it now... */
-                                       if (pri->debug & PRI_DEBUG_Q921_STATE)
-                                               pri_message(pri, "-- Finally transmitting %d, since window opened up\n", f->h.n_s);
-                                       f->transmitted++;
--                                      pri->windowlen++;
--                                      f->h.n_r = pri->v_r;
-+                                      pri->windowlen[teio]++;
-+                                      f->h.n_r = pri->v_r[teio];
-                                       q921_transmit(pri, (q921_h *)(&f->h), f->len);
-                                       break;
-                               }
-@@ -198,77 +586,136 @@
-       return 0;
- }
--static void t203_expire(void *);
--static void t200_expire(void *);
--static pri_event *q921_dchannel_down(struct pri *pri);
-+static void t203_expire(void *, int tei);
-+static void t200_expire(void *, int tei);
-+static pri_event *q921_dchannel_down(struct pri *pri, int tei);
-+
-+static void reschedule_t203(struct pri *pri, int tei)
-+{
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+      if (pri->t203_timer[teio]) {
-+              pri_schedule_del(pri, pri->t203_timer[teio]);
-+              pri->t203_timer[teio] = 0;
-+              if (pri->q921_state[teio] != Q921_LINK_CONNECTION_RELEASED) {
-+                  if (pri->debug &  PRI_DEBUG_Q921_STATE)
-+                      pri_message(pri, "-- Restarting T203 counter\n");
-+                  /* Nothing to transmit, start the T203 counter instead */
-+                  pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, tei);
-+              }
-+      }
-+}
--static void reschedule_t203(struct pri *pri)
-+static void q921_flush_txqueue(struct pri *pri, int tei, int devnull)
- {
--      if (pri->t203_timer) {
--              pri_schedule_del(pri, pri->t203_timer);
--              if (pri->debug &  PRI_DEBUG_Q921_STATE)
--                      pri_message(pri, "-- Restarting T203 counter\n");
--              /* Nothing to transmit, start the T203 counter instead */
--              pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
-+      struct q921_frame *f, *tmp = NULL;      
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+      f = pri->txqueue[teio];
-+
-+      /* nothing to send */
-+      if (!f) return;
-+
-+      /* transmit all i-frames that were queued up while we were waiting for layer 2 to rise */
-+      while(f) {
-+          if (devnull) {
-+              tmp = f;
-+              f = f->next;
-+              free(tmp);
-+              tmp = NULL;
-+          } else {
-+              if (pri->localtype == BRI_CPE_PTMP) {
-+                  /* update TEI, it might have changed */
-+                  f->h.h.tei = pri->tei;
-+              }
-+              q921_transmit(pri, (q921_h *)&f->h, f->len);
-+              f->transmitted++;
-+              f = f->next;
-+          }
-+      }
-+      
-+      if (devnull) {
-+          pri->txqueue[teio] = NULL;
-+          pri->v_s[teio] = 0;
-+      } else {
-+          if (pri->t200_timer[teio]) {
-+              pri_schedule_del(pri, pri->t200_timer[teio]);
-+              pri->t200_timer[teio] = 0;
-+          }
-+          if (pri->t203_timer[teio]) {
-+              pri_schedule_del(pri, pri->t203_timer[teio]);
-+              pri->t203_timer[teio] = 0;
-+          }
-+          pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-       }
- }
--static pri_event *q921_ack_rx(struct pri *pri, int ack)
-+static pri_event *q921_ack_rx(struct pri *pri, int ack, int tei)
- {
-       int x;
-       int cnt=0;
-       pri_event *ev;
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-       /* Make sure the ACK was within our window */
--      for (x=pri->v_a; (x != pri->v_s) && (x != ack); Q921_INC(x));
-+      for (x=pri->v_a[teio]; (x != pri->v_s[teio]) && (x != ack); Q921_INC(x));
-       if (x != ack) {
-               /* ACK was outside of our window --- ignore */
--              pri_error(pri, "ACK received for '%d' outside of window of '%d' to '%d', restarting\n", ack, pri->v_a, pri->v_s);
--              ev = q921_dchannel_down(pri);
--              q921_start(pri, 1);
-+              pri_error(pri, "ACK received for '%d' outside of window of '%d' to '%d', restarting\n", ack, pri->v_a[teio], pri->v_s[teio]);
-+              ev = q921_dchannel_down(pri, tei);
-+              q921_start(pri, 1, tei);
-               pri->schedev = 1;
-               return ev;
-       }
-       /* Cancel each packet as necessary */
-       if (pri->debug & PRI_DEBUG_Q921_STATE)
--              pri_message(pri, "-- ACKing all packets from %d to (but not including) %d\n", pri->v_a, ack);
--      for (x=pri->v_a; x != ack; Q921_INC(x)) 
--              cnt += q921_ack_packet(pri, x); 
--      if (!pri->txqueue) {
-+              pri_message(pri, "-- ACKing all packets from %d to (but not including) %d\n", pri->v_a[teio], ack);
-+      for (x=pri->v_a[teio]; x != ack; Q921_INC(x)) 
-+              cnt += q921_ack_packet(pri, x, tei);    
-+      if (!pri->txqueue[teio]) {
-+              /* Something was ACK'd.  Stop T200 counter */
-+              if (pri->t200_timer[teio]) {
-+                  pri_schedule_del(pri, pri->t200_timer[teio]);
-+                  pri->t200_timer[teio] = 0;
-+              }
-               if (pri->debug &  PRI_DEBUG_Q921_STATE)
-                       pri_message(pri, "-- Since there was nothing left, stopping T200 counter\n");
--              /* Something was ACK'd.  Stop T200 counter */
--              pri_schedule_del(pri, pri->t200_timer);
--              pri->t200_timer = 0;
-       }
--      if (pri->t203_timer) {
-+      if (pri->t203_timer[teio]) {
-+              pri_schedule_del(pri, pri->t203_timer[teio]);
-+              pri->t203_timer[teio] = 0;
-               if (pri->debug &  PRI_DEBUG_Q921_STATE)
-                       pri_message(pri, "-- Stopping T203 counter since we got an ACK\n");
--              pri_schedule_del(pri, pri->t203_timer);
--              pri->t203_timer = 0;
-       }
--      if (pri->txqueue) {
-+      if (pri->txqueue[teio]) {
-               /* Something left to transmit, Start the T200 counter again if we stopped it */
-+              if (pri->t200_timer[teio]) {
-+                  pri_schedule_del(pri, pri->t200_timer[teio]);
-+                  pri->t200_timer[teio] = 0;
-+              }
-               if (pri->debug &  PRI_DEBUG_Q921_STATE)
--                      pri_message(pri, "-- Something left to transmit (%d), restarting T200 counter\n", pri->txqueue->h.n_s);
--              if (!pri->t200_timer)
--                      pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
-+                      pri_message(pri, "-- Something left to transmit (%d), restarting T200 counter\n", pri->txqueue[teio]->h.n_s);
-+              pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-+
-       } else {
-               if (pri->debug &  PRI_DEBUG_Q921_STATE)
-                       pri_message(pri, "-- Nothing left, starting T203 counter\n");
-               /* Nothing to transmit, start the T203 counter instead */
--              pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
-+              pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, tei);
-       }
-       return NULL;
- }
--static void q921_reject(struct pri *pri, int pf)
-+static void q921_reject(struct pri *pri, int pf, int tei)
- {
-       q921_h h;
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-       Q921_INIT(pri, h);
-       h.s.x0 = 0;     /* Always 0 */
-       h.s.ss = 2;     /* Reject */
-       h.s.ft = 1;     /* Frametype (01) */
--      h.s.n_r = pri->v_r;     /* Where to start retransmission */
-+      h.s.n_r = pri->v_r[teio];       /* Where to start retransmission */
-       h.s.p_f = pf;   
-       switch(pri->localtype) {
-       case PRI_NETWORK:
-@@ -277,23 +724,38 @@
-       case PRI_CPE:
-               h.h.c_r = 1;
-               break;
-+      case BRI_NETWORK_PTMP:
-+              h.h.c_r = 0;
-+              break;
-+      case BRI_CPE_PTMP:
-+              h.h.c_r = 1;
-+              h.h.tei = tei;
-+              break;
-+      case BRI_NETWORK:
-+              h.h.c_r = 0;
-+              break;
-+      case BRI_CPE:
-+              h.h.c_r = 1;
-+              break;
-       default:
--              pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype);
-+              pri_error(pri, "Don't know how to REJECT on a type %d node\n", pri->localtype);
-               return;
-       }
-       if (pri->debug & PRI_DEBUG_Q921_STATE)
--              pri_message(pri, "Sending Reject (%d)\n", pri->v_r);
--      pri->sentrej = 1;
-+              pri_message(pri, "Sending Reject (%d)\n", pri->v_r[teio]);
-+      pri->sentrej[teio] = 1;
-       q921_transmit(pri, &h, 4);
- }
--static void q921_rr(struct pri *pri, int pbit, int cmd) {
-+static void q921_rr(struct pri *pri, int pbit, int cmd, int tei) {
-       q921_h h;
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-       Q921_INIT(pri, h);
-       h.s.x0 = 0;     /* Always 0 */
-       h.s.ss = 0; /* Receive Ready */
-       h.s.ft = 1;     /* Frametype (01) */
--      h.s.n_r = pri->v_r;     /* N/R */
-+      h.s.n_r = pri->v_r[teio];       /* N/R */
-       h.s.p_f = pbit;         /* Poll/Final set appropriately */
-       switch(pri->localtype) {
-       case PRI_NETWORK:
-@@ -308,81 +770,192 @@
-               else
-                       h.h.c_r = 1;
-               break;
-+      case BRI_NETWORK_PTMP:
-+              h.h.tei = tei;
-+              if (cmd)
-+                      h.h.c_r = 1;
-+              else
-+                      h.h.c_r = 0;
-+              break;
-+      case BRI_CPE_PTMP:
-+              h.h.tei = tei;
-+              if (cmd)
-+                      h.h.c_r = 0;
-+              else
-+                      h.h.c_r = 1;
-+              break;
-+      case BRI_NETWORK:
-+              if (cmd)
-+                      h.h.c_r = 1;
-+              else
-+                      h.h.c_r = 0;
-+              break;
-+      case BRI_CPE:
-+              if (cmd)
-+                      h.h.c_r = 0;
-+              else
-+                      h.h.c_r = 1;
-+              break;
-       default:
--              pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype);
-+              pri_error(pri, "Don't know how to RR on a type %d node\n", pri->localtype);
-               return;
-       }
--      pri->v_na = pri->v_r;   /* Make a note that we've already acked this */
-+      pri->v_na[teio] = pri->v_r[teio];       /* Make a note that we've already acked this */
-       if (pri->debug & PRI_DEBUG_Q921_STATE)
--              pri_message(pri, "Sending Receiver Ready (%d)\n", pri->v_r);
-+              pri_message(pri, "Sending Receiver Ready (%d)\n", pri->v_r[teio]);
-       q921_transmit(pri, &h, 4);
- }
--static void t200_expire(void *vpri)
-+static void t200_expire(void *vpri, int tei)
- {
-       struct pri *pri = vpri;
--      if (pri->txqueue) {
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+      if (pri->txqueue[teio]) {
-               /* Retransmit first packet in the queue, setting the poll bit */
-               if (pri->debug & PRI_DEBUG_Q921_STATE)
-                       pri_message(pri, "-- T200 counter expired, What to do...\n");
--              /* Force Poll bit */
--              pri->txqueue->h.p_f = 1;        
--              /* Update nr */
--              pri->txqueue->h.n_r = pri->v_r;
--              pri->v_na = pri->v_r;
--              pri->solicitfbit = 1;
--              pri->retrans++;
-+              if (pri->txqueue[teio]->transmitted) {
-+                  /* Force Poll bit, if this is a retransmission */
-+                  pri->txqueue[teio]->h.p_f = 1;      
-+                  pri->solicitfbit[teio] = 1;
-+                  /* Update nr */
-+                  pri->txqueue[teio]->h.n_r = pri->v_r[teio];
-+                  pri->v_na[teio] = pri->v_r[teio];
-+                  pri->retrans[teio]++;
-+              }
-       /* Up to three retransmissions */
--      if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
-+      if ((pri->retrans[teio] + 1)  <= pri->timers[PRI_TIMER_N200]) {
-          /* Reschedule t200_timer */
-          if (pri->debug & PRI_DEBUG_Q921_STATE)
--            pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue->len);
--              if (pri->busy) 
--                      q921_rr(pri, 1, 1);
--              else {
--                      if (!pri->txqueue->transmitted) 
-+              pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue[teio]->len);
-+              if (pri->busy[teio]) {
-+              // pri_message(pri, "-- q921_rr(pri, 1, 1) \n", tei);
-+                      q921_rr(pri, 1, 1, tei);
-+              } else {
-+                      if (!pri->txqueue[teio]->transmitted)
-                               pri_error(pri, "!! Not good - head of queue has not been transmitted yet\n");
--                      q921_transmit(pri, (q921_h *)&pri->txqueue->h, pri->txqueue->len);
-+                      q921_transmit(pri, (q921_h *)&pri->txqueue[teio]->h, pri->txqueue[teio]->len);
-+          //layer 3
-+                      pri->txqueue[teio]->transmitted++;
-               }
-          if (pri->debug & PRI_DEBUG_Q921_STATE) 
--               pri_message(pri, "-- Rescheduling retransmission (%d)\n", pri->retrans);
--         pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
-+               pri_message(pri, "-- Rescheduling retransmission (%d)\n", pri->retrans[teio]);
-+         pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-       } else {
-          if (pri->debug & PRI_DEBUG_Q921_STATE) 
-                pri_message(pri, "-- Timeout occured, restarting PRI\n");
--         pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
--              pri->t200_timer = 0;
--         q921_dchannel_down(pri);
--         q921_start(pri, 1);
-+         pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
-+               pri->t200_timer[teio] = 0;
-+         q921_dchannel_down(pri, tei);
-+         q921_start(pri, 1, tei);
-          pri->schedev = 1;
-       }
--      } else if (pri->solicitfbit) {
-+      } else if (pri->solicitfbit[teio]) {
-          if (pri->debug & PRI_DEBUG_Q921_STATE)
-             pri_message(pri, "-- Retrying poll with f-bit\n");
--              pri->retrans++;
--              if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
--                      pri->solicitfbit = 1;
--                      q921_rr(pri, 1, 1);
--                      pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
-+              pri->retrans[teio]++;
-+              if (pri->retrans[teio] < pri->timers[PRI_TIMER_N200]) {
-+                      pri->solicitfbit[teio] = 1;
-+                      q921_rr(pri, 1, 1, tei);
-+                      pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-               } else {
-                       if (pri->debug & PRI_DEBUG_Q921_STATE) 
-                               pri_message(pri, "-- Timeout occured, restarting PRI\n");
--                      pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
--                      pri->t200_timer = 0;
--                      q921_dchannel_down(pri);
--                      q921_start(pri, 1);
-+                      pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
-+                      pri->t200_timer[teio] = 0;
-+                      q921_dchannel_down(pri, tei);
-+                      q921_start(pri, 1, tei);
-                       pri->schedev = 1;
-               }
-       } else {
-               pri_error(pri, "T200 counter expired, nothing to send...\n");
--              pri->t200_timer = 0;
-+              pri->t200_timer[teio] = 0;
-+              if (pri->busy[teio]) {
-+                  if ((pri->retrans[teio] + 1) <= pri->timers[PRI_TIMER_N200]) {
-+                      /* poll RR */
-+                      pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-+                      pri->retrans[teio]++;
-+                      q921_rr(pri, 1, 1, tei);
-+                  } else {
-+                      q921_reset(pri, tei, 1);
-+                      q921_start(pri, 1, tei);
-+                  }
-+              }
-       }
- }
--int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr)
-+int q921_transmit_uframe(struct pri *pri, void *buf, int len, int cr, int tei)
-+{
-+      q921_u *uf;
-+      uf = malloc(sizeof(q921_u) + len + 2);
-+      memset(uf,0,sizeof(q921_u) + len + 2);
-+
-+      uf->h.sapi = 0;
-+      uf->h.ea1 = 0;
-+      uf->h.ea2 = 1;
-+      uf->h.tei = tei;
-+      uf->m3 = 0;
-+      uf->m2 = 0;
-+      uf->ft = Q921_FRAMETYPE_U;
-+      switch(pri->localtype) {
-+      case PRI_NETWORK:
-+              uf->h.c_r = 1;
-+              break;
-+      case PRI_CPE:
-+              uf->h.c_r = 0;
-+              break;
-+      case BRI_NETWORK_PTMP:
-+              uf->h.c_r = 1;
-+              break;
-+      case BRI_CPE_PTMP:
-+              uf->h.c_r = 0;
-+              break;
-+      case BRI_NETWORK:
-+              uf->h.c_r = 1;
-+              break;
-+      case BRI_CPE:
-+              uf->h.c_r = 0;
-+              break;
-+      default:
-+              pri_error(pri, "Don't know how to send U frames on a type %d node\n", pri->localtype);
-+              return -1;
-+      }
-+      memcpy(uf->data,buf,len);
-+      q921_transmit(pri, (q921_h*)&(uf->h), 3+len);
-+      free(uf);
-+      return 0;
-+}
-+
-+
-+int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr, int tei)
- {
-       q921_frame *f, *prev=NULL;
--      for (f=pri->txqueue; f; f = f->next) prev = f;
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+      if ((pri->q921_state[teio] == Q921_LINK_CONNECTION_RELEASED) && (!pri->sabme_timer[teio])) {
-+          if (pri->localtype == BRI_CPE_PTMP) {
-+              if (pri->tei > 0) {
-+                  /* p2p datalink is down */
-+                  pri->sabme_retrans[teio] = 0;
-+                  q921_send_sabme_now(pri, pri->tei);
-+                  if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                      pri_message(pri, "Reactivating layer 2\n");
-+              } else {
-+                  /* no tei */
-+                  if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                      pri_message(pri, "reactivating layer 2, sending tei req\n");
-+                  q921_send_teireq(pri);
-+              }
-+          } else if ((pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) {
-+              /* p2p datalink is down */
-+              pri->sabme_retrans[teio] = 0;
-+              q921_send_sabme_now(pri, pri->tei);
-+              if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                  pri_message(pri, "Reactivating layer 2\n");
-+          }
-+      }
-+      for (f=pri->txqueue[teio]; f; f = f->next) prev = f;
-       f = malloc(sizeof(q921_frame) + len + 2);
-       if (f) {
-               memset(f,0,sizeof(q921_frame) + len + 2);
-@@ -400,47 +973,80 @@
-                       else
-                               f->h.h.c_r = 1;
-               break;
-+              case BRI_NETWORK_PTMP:
-+                      f->h.h.tei = tei;
-+                      if (cr)
-+                              f->h.h.c_r = 1;
-+                      else
-+                              f->h.h.c_r = 0;
-+              break;
-+              case BRI_CPE_PTMP:
-+                      f->h.h.tei = pri->tei;
-+                      if (cr)
-+                              f->h.h.c_r = 0;
-+                      else
-+                              f->h.h.c_r = 1;
-+              break;
-+              case BRI_NETWORK:
-+                      if (cr)
-+                              f->h.h.c_r = 1;
-+                      else
-+                              f->h.h.c_r = 0;
-+              break;
-+              case BRI_CPE:
-+                      if (cr)
-+                              f->h.h.c_r = 0;
-+                      else
-+                              f->h.h.c_r = 1;
-+              break;
-               }
-               f->next = NULL;
-               f->transmitted = 0;
-               f->len = len + 4;
-               memcpy(f->h.data, buf, len);
--              f->h.n_s = pri->v_s;
--              f->h.n_r = pri->v_r;
--              pri->v_s++;
--              pri->v_na = pri->v_r;
-+              f->h.n_s = pri->v_s[teio];
-+              f->h.n_r = pri->v_r[teio];
-+              pri->v_s[teio]++;
-+              pri->v_na[teio] = pri->v_r[teio];
-               f->h.p_f = 0;
-               f->h.ft = 0;
-               if (prev)
-                       prev->next = f;
-               else
--                      pri->txqueue = f;
--              /* Immediately transmit unless we're in a recovery state, or the window
--                 size is too big */
--              if (!pri->retrans && !pri->busy) {
--                      if (pri->windowlen < pri->window) {
--                              pri->windowlen++;
-+                      pri->txqueue[teio] = f;
-+
-+              if  ((pri->q921_state[teio] != Q921_LINK_CONNECTION_ESTABLISHED) && ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK))){
-+                  /* no p2p datalink, yet. queue up the iframes... */
-+                  if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                      pri_message(pri, "Layer 3 transmit waiting for layer 2\n");             
-+              } else {
-+                  /* Immediately transmit unless we're in a recovery state, or the window
-+                      size is too big */
-+                  if (!pri->retrans[teio] && !pri->busy[teio]) {
-+                      if (pri->windowlen[teio] < pri->window[teio]) {
-+                              pri->windowlen[teio]++;
-                               q921_transmit(pri, (q921_h *)(&f->h), f->len);
-                               f->transmitted++;
-                       } else {
-                               if (pri->debug & PRI_DEBUG_Q921_STATE)
-                                       pri_message(pri, "Delaying transmission of %d, window is %d/%d long\n", 
--                                              f->h.n_s, pri->windowlen, pri->window);
-+                                              f->h.n_s, pri->windowlen[teio], pri->window[teio]);
-                       }
--              }
--              if (pri->t203_timer) {
-+                  }
-+                  if (pri->t203_timer[teio]) {
-+                      pri_schedule_del(pri, pri->t203_timer[teio]);
-+                      pri->t203_timer[teio] = 0;
-                       if (pri->debug & PRI_DEBUG_Q921_STATE)
-                               pri_message(pri, "Stopping T_203 timer\n");
--                      pri_schedule_del(pri, pri->t203_timer);
--                      pri->t203_timer = 0;
--              }
--              if (!pri->t200_timer) {
-+                  }
-+                  if (!pri->t200_timer[teio]) {
-                       if (pri->debug & PRI_DEBUG_Q921_STATE)
-                               pri_message(pri, "Starting T_200 timer\n");
--                      pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
--              } else
-+                      pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-+                  } else
-                       if (pri->debug & PRI_DEBUG_Q921_STATE)
--                              pri_message(pri, "T_200 timer already going (%d)\n", pri->t200_timer);
-+                              pri_message(pri, "T_200 timer already going (%d)\n", pri->t200_timer[teio]);
-+              }
-               
-       } else {
-               pri_error(pri, "!! Out of memory for Q.921 transmit\n");
-@@ -449,49 +1055,86 @@
-       return 0;
- }
--static void t203_expire(void *vpri)
-+static void t203_expire(void *vpri, int tei)
- {
--      struct pri *pri = vpri;
--      if (pri->q921_state == Q921_LINK_CONNECTION_ESTABLISHED) {
--              if (pri->debug &  PRI_DEBUG_Q921_STATE)
-+      struct pri *pri = vpri;
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+ 
-+      if (pri->q921_state[teio] == Q921_LINK_CONNECTION_ESTABLISHED) {
-+              if (pri->debug &  PRI_DEBUG_Q921_STATE)
-                       pri_message(pri, "T203 counter expired, sending RR and scheduling T203 again\n");
--              /* Solicit an F-bit in the other's RR */
--              pri->solicitfbit = 1;
--              pri->retrans = 0;
--              q921_rr(pri, 1, 1);
--              /* Start timer T200 to resend our RR if we don't get it */
--              pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
-+              /* Solicit an F-bit in the other's RR */
-+              pri->solicitfbit[teio] = 1;
-+              pri->retrans[teio] = 0;
-+              q921_rr(pri, 1, 1, tei);
-+              /* Start timer T200 to resend our RR if we don't get it */
-+              pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-+      } else {
-+              if (pri->debug &  PRI_DEBUG_Q921_STATE)
-+                      pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state[teio]);
-+              pri->t203_timer[teio] = 0;
-+      }
-+}
-+
-+static void q921_start_tei(struct pri *pri, int tei);
-+
-+
-+static void t201_expire(void *vpri, int tei)
-+{
-+      struct pri *pri = vpri;
-+      int teio=tei - Q921_TEI_BASE;
-+      int i = 0;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+      if (tei == Q921_TEI_GROUP) {
-+          for (i=0;i<Q921_MAX_TEIS;i++) {
-+              if (pri->q921_tei_check[i] == 1) {
-+                  pri->q921_tei_check[i] = 0;
-+                  q921_start_tei(pri, Q921_TEI_BASE + i);
-+              }
-+          }
-       } else {
--              if (pri->debug &  PRI_DEBUG_Q921_STATE)
--                      pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state);
--              pri->t203_timer = 0;
-+          if (pri->q921_tei_check[teio] == 1) {
-+              pri->q921_tei_check[teio] = 0;
-+              q921_start_tei(pri, tei);
-+          }
-       }
-+      pri->t201_timer[teio] = 0;
- }
- static pri_event *q921_handle_iframe(struct pri *pri, q921_i *i, int len)
- {
-       int res;
-       pri_event *ev;
-+      int teio= i->h.tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+//    pri_error(pri, "q921_handle_iframe: i->n_s %d pri->v_r[%d] %d \n", i->n_s, teio, pri->v_r[teio]);
-       /* Make sure this is a valid packet */
--      if (i->n_s == pri->v_r) {
-+      if (i->n_s == pri->v_r[teio]) {
-               /* Increment next expected I-frame */
--              Q921_INC(pri->v_r);
-+              Q921_INC(pri->v_r[teio]);
-               /* Handle their ACK */
--              pri->sentrej = 0;
--              ev = q921_ack_rx(pri, i->n_r);
-+              pri->sentrej[teio] = 0;
-+              ev = q921_ack_rx(pri, i->n_r, i->h.tei);
-+              if (ev) {
-+                  pri_error(pri, "q921_handle_iframe: ev = %d \n", ev->e);
-+              }
-               if (ev)
-                       return ev;
-               if (i->p_f) {
-                       /* If the Poll/Final bit is set, immediate send the RR */
--                      q921_rr(pri, 1, 0);
--              } else if (pri->busy) {
--                      q921_rr(pri, 0, 0);
-+                      q921_rr(pri, 1, 0, i->h.tei);
-+              } else if (pri->busy[teio]) {
-+                      q921_rr(pri, 0, 0, i->h.tei);
-+              } else if (pri->t200_timer[teio] && pri->retrans[teio]) {
-+              pri_error(pri, "q921_handle_iframe: sending RR \n");
-+                      q921_rr(pri, 0, 0, i->h.tei);
-               }
-               /* Receive Q.931 data */
--              res = q931_receive(pri, (q931_h *)i->data, len - 4);
-+              res = q931_receive(pri, (q931_h *)i->data, len - 4, i->h.tei);
-               /* Send an RR if one wasn't sent already */
--              if (pri->v_na != pri->v_r) 
--                      q921_rr(pri, 0, 0);
-+              if (pri->v_na[teio] != pri->v_r[teio]) 
-+                      q921_rr(pri, 0, 0,  i->h.tei);
-               if (res == -1) {
-                       return NULL;
-               }
-@@ -500,10 +1143,10 @@
-       } else {
-               /* If we haven't already sent a reject, send it now, otherwise
-                  we are obliged to RR */
--              if (!pri->sentrej)
--                      q921_reject(pri, i->p_f);
-+              if (!pri->sentrej[teio])
-+                      q921_reject(pri, i->p_f, i->h.tei);
-               else if (i->p_f)
--                      q921_rr(pri, 1, 0);
-+                      q921_rr(pri, 1, 0, i->h.tei);
-       }
-       return NULL;
- }
-@@ -641,75 +1284,158 @@
-       };
- }
--static pri_event *q921_dchannel_up(struct pri *pri)
-+static void q921_tei_recovery(struct pri *pri, int tei) {
-+    int i = 0;
-+    int teio=tei - Q921_TEI_BASE;
-+    if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+    for (i=0;i<Q921_MAX_TEIS;i++) {
-+      if ((i + Q921_TEI_BASE == tei) || (tei == Q921_TEI_GROUP)) {
-+          pri->q921_tei_check[i] = 1;
-+      }
-+    }
-+    q921_send_teichkreq(pri, tei);
-+    if (!pri->t201_timer[teio]) {
-+      pri->t201_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T201], t201_expire, pri, tei);
-+    }
-+}
-+/*
-+static void q921_invoke_tei_recovery(void *vpri, int tei) {
-+      struct pri *pri = vpri;
-+      q921_tei_recovery(pri, tei);
-+}
-+*/
-+
-+static pri_event *q921_dchannel_up(struct pri *pri, int tei)
- {
--      /* Reset counters, etc */
--      q921_reset(pri);
-+      // we treat this as MFE
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+
-+      if  (((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) && (pri->txqueue[teio])) {
-+          /* Reset counters, etc */
-+          q921_reset(pri, tei, 0);
-+      } else {
-+          /* Reset counters, discard frames, etc */
-+          q921_reset(pri, tei, 1);
-+      }
-       
-       /* Stop any SABME retransmissions */
--      pri_schedule_del(pri, pri->sabme_timer);
--      pri->sabme_timer = 0;
-+      if (pri->sabme_timer[teio]) {
-+          pri_schedule_del(pri, pri->sabme_timer[teio]);
-+          pri->sabme_timer[teio] = 0;
-+      }
-+      
-+      if (pri->t202_timer[teio]) {
-+          pri_schedule_del(pri, pri->t202_timer[teio]);
-+          pri->t202_timer[teio] = 0;
-+      }
-+      
-+/* neonova test */
-+      if (pri->t203_timer[teio]) {
-+          pri_schedule_del(pri, pri->t203_timer[teio]);
-+          pri->t203_timer[teio] = 0;
-+      }
-       
-       /* Reset any rejects */
--      pri->sentrej = 0;
-+      pri->sentrej[teio] = 0;
-       
-       /* Go into connection established state */
--      pri->q921_state = Q921_LINK_CONNECTION_ESTABLISHED;
--
--      /* Start the T203 timer */
--      pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
-+      pri->q921_state[teio] = Q921_LINK_CONNECTION_ESTABLISHED;
-       
--      /* Report event that D-Channel is now up */
--      pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
--      return &pri->ev;
-+      if  (((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) && (pri->txqueue[teio])) {
-+          /* transmit queued iframes ans start T200 (handled by flush_txqueue) */
-+          q921_flush_txqueue(pri, tei, 0);
-+          /* dont upset upper layers if we reactivate layer 2 */
-+          return NULL;
-+      } else {
-+          /* Start the T203 timer */
-+          pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, tei);
-+          
-+          /* Report event that D-Channel is now up */
-+          pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
-+          pri->ev.gen.tei = tei;
-+          return &pri->ev;
-+      }
- }
--static pri_event *q921_dchannel_down(struct pri *pri)
-+static pri_event *q921_dchannel_down(struct pri *pri, int tei)
- {
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+
-+      pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
-+
-       /* Reset counters, reset sabme timer etc */
--      q921_reset(pri);
-+      if (pri->localtype == BRI_NETWORK_PTMP) {
-+          if (pri->t203_timer[teio]) {
-+              pri_schedule_del(pri, pri->t203_timer[teio]);
-+              pri->t203_timer[teio] = 0;
-+              if (pri->debug & PRI_DEBUG_Q921_STATE) {
-+                      pri_message(pri, "Stopping T_203 timer for TEI %d\n", tei);
-+              }
-+          }
-+      }
-+
-+      q921_reset(pri, tei, 1);
-       
--      /* Report event that D-Channel is now up */
-+      /* Report event that D-Channel is now down */
-       pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
-+      pri->ev.gen.tei = tei;
-       return &pri->ev;
- }
--void q921_reset(struct pri *pri)
-+void q921_reset(struct pri *pri, int tei, int discard)
- {
-+      int teio=tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-       /* Having gotten a SABME we MUST reset our entire state */
--      pri->v_s = 0;
--      pri->v_a = 0;
--      pri->v_r = 0;
--      pri->v_na = 0;
--      pri->window = pri->timers[PRI_TIMER_K];
--      pri->windowlen = 0;
--      pri_schedule_del(pri, pri->sabme_timer);
--      pri_schedule_del(pri, pri->t203_timer);
--      pri_schedule_del(pri, pri->t200_timer);
--      pri->sabme_timer = 0;
--      pri->t203_timer = 0;
--      pri->t200_timer = 0;
--      pri->busy = 0;
--      pri->solicitfbit = 0;
--      pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
--      pri->retrans = 0;
--      pri->sentrej = 0;
-+      if (discard) {
-+          pri->v_s[teio] = 0;
-+      }
-+      pri->v_a[teio] = 0;
-+      pri->v_r[teio] = 0;
-+      pri->v_na[teio] = 0;
-+      pri->window[teio] = pri->timers[PRI_TIMER_K];
-+      pri->windowlen[teio] = 0;
-+      pri_schedule_del(pri, pri->sabme_timer[teio]);
-+      pri_schedule_del(pri, pri->t203_timer[teio]);
-+      pri_schedule_del(pri, pri->t200_timer[teio]);
-+      pri->sabme_timer[teio] = 0;
-+      pri->t203_timer[teio] = 0;
-+      pri->t200_timer[teio] = 0;
-+      pri_schedule_del(pri, pri->t202_timer[teio]);
-+      pri->t202_timer[teio] = 0;
-+      pri_schedule_del(pri, pri->t201_timer[teio]);
-+      pri->t201_timer[teio] = 0;
-+      pri->busy[teio] = 0;
-+      pri->solicitfbit[teio] = 0;
-+      pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
-+      pri->retrans[teio] = 0;
-+      pri->sabme_retrans[teio] = 0;
-+      pri->sentrej[teio] = 0;
-       
--      /* Discard anything waiting to go out */
--      q921_discard_retransmissions(pri);
-+      if (discard) {
-+          /* Discard anything waiting to go out */
-+          q921_discard_retransmissions(pri, tei);
-+      }
- }
-+
- static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
- {
-       q921_frame *f;
-       pri_event *ev;
-       int sendnow;
-+      int tei;
-+      int res=-1;
-+      int teio=h->h.tei - Q921_TEI_BASE;
-+      if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-       switch(h->h.data[0] & Q921_FRAMETYPE_MASK) {
-       case 0:
-       case 2:
--              if (pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED) {
--                      pri_error(pri, "!! Got I-frame while link state %d\n", pri->q921_state);
-+              if (pri->q921_state[teio] != Q921_LINK_CONNECTION_ESTABLISHED) {
-+                      pri_error(pri, "!! Got I-frame while link state %d\n", pri->q921_state[teio]);
-                       return NULL;
-               }
-               /* Informational frame */
-@@ -720,8 +1446,10 @@
-               return q921_handle_iframe(pri, &h->i, len);     
-               break;
-       case 1:
--              if (pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED) {
-+              if (pri->q921_state[teio] != Q921_LINK_CONNECTION_ESTABLISHED) {
-                       pri_error(pri, "!! Got S-frame while link down\n");
-+                      q921_send_dm(pri, 1,  h->h.tei);
-+                      q921_reset(pri, h->h.tei, 1);
-                       return NULL;
-               }
-               if (len < 4) {
-@@ -731,80 +1459,128 @@
-               switch(h->s.ss) {
-               case 0:
-                       /* Receiver Ready */
--                      pri->busy = 0;
-+                      pri->busy[teio] = 0;
-                       /* Acknowledge frames as necessary */
--                      ev = q921_ack_rx(pri, h->s.n_r);
-+                      ev = q921_ack_rx(pri, h->s.n_r, h->h.tei);
-                       if (ev)
-                               return ev;
-                       if (h->s.p_f) {
--                              /* If it's a p/f one then send back a RR in return with the p/f bit set */
--                              if (pri->solicitfbit) {
-+                      /* If it's a p/f one then send back a RR in return with the p/f bit set */
-+//                    pri_error(pri, "-- h->s.pf %d pri->solicitfbit[teio] %d\n", h->s.p_f, pri->solicitfbit[teio]);
-+                              if (pri->solicitfbit[teio]) {
-                                       if (pri->debug & PRI_DEBUG_Q921_STATE) 
-                                               pri_message(pri, "-- Got RR response to our frame\n");
-                               } else {
--                                      if (pri->debug & PRI_DEBUG_Q921_STATE) 
-+                                      if (pri->txqueue[teio]) {
-+                                          q921_flush_txqueue(pri, pri->tei, 0);
-+                                      } else {
-+                                          if (pri->debug & PRI_DEBUG_Q921_STATE) 
-                                               pri_message(pri, "-- Unsolicited RR with P/F bit, responding\n");
--                                              q921_rr(pri, 1, 0);
-+                                              q921_rr(pri, 1, 0, h->h.tei);
-+                                      }
-                               }
--                              pri->solicitfbit = 0;
-+                              pri->solicitfbit[teio] = 0;
-                       }
-                       break;
-       case 1:
-          /* Receiver not ready */
-          if (pri->debug & PRI_DEBUG_Q921_STATE)
-             pri_message(pri, "-- Got receiver not ready\n");
--       if(h->s.p_f) {
--              /* Send RR if poll bit set */
--              q921_rr(pri, h->s.p_f, 0);
-+       if ((pri->localtype != PRI_NETWORK) && (pri->localtype != BRI_NETWORK) && (pri->localtype != BRI_NETWORK_PTMP)) {
-+           if (h->s.p_f && h->s.h.c_r) {
-+//            if (!pri->t200_timer[teio]) {
-+                  /* Send RR if poll bit set */
-+                  q921_rr(pri, h->s.p_f, 0, h->h.tei);
-+//            }
-+          }
-+       } else {
-+           if (h->s.p_f && (!h->s.h.c_r)) {
-+//            if (!pri->t200_timer[teio]) {
-+                  /* Send RR if poll bit set */
-+                  q921_rr(pri, h->s.p_f, 0, h->h.tei);
-+//            }
-+          }
-+       }
-+         pri->busy[teio] = 1;
-+       if (pri->t200_timer[teio]) {
-+          pri_schedule_del(pri, pri->t200_timer[teio]);
-+          pri->t200_timer[teio] = 0;
-        }
--         pri->busy = 1;
--         break;   
-+       pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, h->h.tei);
-+         break;
-       case 2:
-          /* Just retransmit */
-          if (pri->debug & PRI_DEBUG_Q921_STATE)
-             pri_message(pri, "-- Got reject requesting packet %d...  Retransmitting.\n", h->s.n_r);
--         if (h->s.p_f) {
--            /* If it has the poll bit set, send an appropriate supervisory response */
--            q921_rr(pri, 1, 0);
--         }
-                sendnow = 0;
-+// XXX                 
-+      q921_ack_rx(pri, h->s.n_r, h->h.tei);
-+         /* Reset t200 timer if it was somehow going */
-+         if (pri->t200_timer[teio]) {
-+               pri_schedule_del(pri, pri->t200_timer[teio]);
-+               pri->t200_timer[teio] = 0;
-+         }
-          /* Resend the proper I-frame */
--         for(f=pri->txqueue;f;f=f->next) {
-+         for(f=pri->txqueue[teio];f;f=f->next) {
-+//        pri_error(pri, "!! frame n_s %d transmitted %d (searching for %d)!\n", f->h.n_s, f->transmitted, h->s.n_r);
-                if ((sendnow || (f->h.n_s == h->s.n_r)) && f->transmitted) {
-                      /* Matches the request, or follows in our window, and has
-                                           already been transmitted. */
--                                       sendnow = 1;
--                                       pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
--                                   f->h.n_r = pri->v_r;
--                     q921_transmit(pri, (q921_h *)(&f->h), f->len);
-+
-+                   /* multiframe established */
-+                   f->transmitted = 0;
-+                   f->h.n_r = pri->v_r[teio];
-+                  
-+                  if (pri->busy[teio]) {
-+                    pri->busy[teio] = 0;
-+                    sendnow = 0;
-+                   } else {
-+                      f->h.p_f = 0;
-+                      sendnow = 1;
-+                      pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
-+                        q921_transmit(pri, (q921_h *)(&f->h), f->len);
-+                      f->transmitted++;
-+                   }
-                }
-          }
-          if (!sendnow) {
--               if (pri->txqueue) {
--                     /* This should never happen */
--                   if (!h->s.p_f || h->s.n_r) {
-+               if (pri->txqueue[teio]) {
-+                   if (h->s.p_f) {
-+                      q921_rr(pri, 1, 0, h->h.tei);
-+                   } else if (!h->s.p_f || h->s.n_r) {
-                       pri_error(pri, "!! Got reject for frame %d, but we only have others!\n", h->s.n_r);
-                    }
-                } else {
-                      /* Hrm, we have nothing to send, but have been REJ'd.  Reset v_a, v_s, etc */
--                              pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
--                     pri->v_a = h->s.n_r;
--                     pri->v_s = h->s.n_r;
--                     /* Reset t200 timer if it was somehow going */
--                     if (pri->t200_timer) {
--                           pri_schedule_del(pri, pri->t200_timer);
--                           pri->t200_timer = 0;
--                     }
-+/*                            pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
-+                     pri->v_a[teio] = h->s.n_r;
-+                     pri->v_s[teio] = h->s.n_r; */
-                      /* Reset and restart t203 timer */
--                     if (pri->t203_timer)
--                           pri_schedule_del(pri, pri->t203_timer);
--                     pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
-+                     if (pri->t203_timer[teio])
-+                           pri_schedule_del(pri, pri->t203_timer[teio]);
-+                     pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, tei);
-+                   pri->solicitfbit[teio] = 0;
-                }
--         }
-+         } else {
-+          if (h->s.p_f) {
-+              /* If it has the poll bit set (and an iframe was retransmitted), send an appropriate supervisory response */
-+//            q921_rr(pri, 1, 0, h->h.tei);
-+                 /* Reset t200 timer if it was somehow going */
-+                 if (pri->t200_timer[teio]) {
-+                       pri_schedule_del(pri, pri->t200_timer[teio]);
-+                       pri->t200_timer[teio] = 0;
-+                 }
-+                 /* Reset and restart t203 timer */
-+                pri->solicitfbit[teio] = 0;
-+                 if (pri->t203_timer[teio])
-+                       pri_schedule_del(pri, pri->t203_timer[teio]);
-+                 pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, h->h.tei);
-+            }
-+       }
-          break;
-               default:
-                       pri_error(pri, "!! XXX Unknown Supervisory frame ss=0x%02x,pf=%02xnr=%02x vs=%02x, va=%02x XXX\n", h->s.ss, h->s.p_f, h->s.n_r,
--                                      pri->v_s, pri->v_a);
-+                                      pri->v_s[teio], pri->v_a[teio]);
-               }
-               break;
-       case 3:
-@@ -821,8 +1597,16 @@
-                                       if (pri->debug & PRI_DEBUG_Q921_STATE)
-                                               pri_message(pri, "-- Got DM Mode from peer.\n");
-                                       /* Disconnected mode, try again after T200 */
--                                      ev = q921_dchannel_down(pri);
--                                      q921_start(pri, 0);
-+                                      ev = q921_dchannel_down(pri, h->h.tei);
-+                                      if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) {
-+                                          /* release layer 2 */
-+                                      //    pri_error(pri, "got DM, restarting layer 2.\n");
-+                                      //    return NULL;
-+                                          q921_start(pri, 0, h->h.tei);
-+                                      }
-+                                      if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)){
-+                                          q921_start(pri, 0, h->h.tei);
-+                                      }
-                                       return ev;
-                                               
-                               } else {
-@@ -830,21 +1614,153 @@
-                                               pri_message(pri, "-- Ignoring unsolicited DM with p/f set to 0\n");
- #if 0
-                                       /* Requesting that we start */
--                                      q921_start(pri, 0);
-+                                      q921_start(pri, 0, h->h.tei);
- #endif                                        
-                               }
-                               break;
--                      } else if (!h->u.m2) {
--                              pri_message(pri, "XXX Unnumbered Information not implemented XXX\n");
-+                      } else if (h->u.m2 == 0) {
-+                              if (h->u.ft == 3) {
-+                                  switch (h->u.data[0]) { /* Management Entity Identifier  */
-+                                      case 0x0f:
-+                                      /* TEI Procedure */
-+                                      switch (h->u.data[3]) {
-+                                          case Q921_TEI_ID_VERIFY:
-+                                              if (pri->localtype != BRI_NETWORK_PTMP)
-+                                                  break;
-+                                                  if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                                                      pri_message(pri, "got TEI verify for TEI = %d\n",h->u.data[4] >> 1);
-+                                          break;
-+                                          case Q921_TEI_ID_ASSIGNED:
-+                                              if (pri->localtype != BRI_CPE_PTMP)
-+                                                  break;
-+                                              if (pri->tei == (h->u.data[4] >> 1)) {
-+                                                  // TEI already assgined, CHECK_TEI or REMOVE_TEI
-+                                                  pri_error(pri, "Double assgined TEI!\n");
-+                                              }
-+                                              if (pri->ri == ((unsigned short) (h->u.data[1] << 8) + h->u.data[2])) {
-+                                                  if (pri->t202_timer[0]) {
-+                                                      pri_schedule_del(pri, pri->t202_timer[0]);
-+                                                      pri->t202_timer[0] = 0;
-+                                                  }
-+                                                  pri->tei = h->u.data[4] >> 1; 
-+                                                  pri->ri = 0;
-+                                                  if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                                                      pri_message(pri, "received TEI assign TEI = %d ri=%d\n",pri->tei,(unsigned short) (h->u.data[1] << 8) + h->u.data[2]);
-+                                                  pri->sabme_retrans[teio] = 0;
-+                                                  q921_send_sabme_now(pri, pri->tei);
-+                                              }
-+                                          break;
-+                                          case Q921_TEI_ID_REMOVE:
-+                                              if (pri->localtype != BRI_CPE_PTMP)
-+                                                  break;
-+                                              if (((h->u.data[4] >> 1) == Q921_TEI_GROUP) || (pri->tei == (h->u.data[4] >> 1))){ 
-+                                                  if (pri->debug & PRI_DEBUG_Q921_STATE)
-+                                                      pri_message(pri, "received TEI remove TEI = %d\n",pri->tei);
-+                                                  pri->tei = 0;
-+                                                  pri->ri = 0;
-+                                                  // get a new TEI
-+                                                  q921_reset(pri, 0, 1);
-+                                                  q921_send_teireq(pri);
-+                                              }
-+                                          break;
-+                                          case Q921_TEI_ID_REQUEST:
-+                                              if (pri->localtype != BRI_NETWORK_PTMP)
-+                                                  break;
-+                                              
-+                                              tei = h->u.data[4] >> 1;
-+                                              if (tei != Q921_TEI_GROUP) {
-+                                                  pri_message(pri, "got TEI request for unavailable TEI..\n");
-+                                                  q921_send_teidenied(pri,((unsigned int)(h->u.data[1] << 8) + h->u.data[2]),h->u.data[4] >> 1);
-+                                                  break;
-+                                              }
-+                                              
-+                                              for (tei=0;tei<Q921_MAX_TEIS;tei++) {
-+                                                  if (pri->q921_teis[tei] == 0) {
-+                                                      pri->q921_teis[tei] = 1;
-+                                                      break;
-+                                                  }
-+                                              }
-+                                              if (tei < Q921_MAX_TEIS) {
-+                                                  q921_send_teiassign(pri,((unsigned int)(h->u.data[1] << 8) + h->u.data[2]),tei + Q921_TEI_BASE);
-+                                              } else {
-+                                                  pri_error(pri, "no TEI available. starting TEI recovery procedure. dont worry!\n");
-+                                                  q921_tei_recovery(pri, 127);
-+                                                  
-+                                              }
-+                                          break;
-+                                          case Q921_TEI_ID_CHK_REQ:
-+                                              if (pri->localtype != BRI_CPE_PTMP)
-+                                                  break;
-+                                                  if ((((h->u.data[4] >> 1) == Q921_TEI_GROUP) || ((h->u.data[4] >> 1) == 0) || ((h->u.data[4] >> 1) == pri->tei)) && (pri->tei > 0)) {
-+                                                      pri_message(pri, "received TEI check request for TEI = %d\n",h->u.data[4] >> 1);
-+                                                      q921_send_teichkresp(pri, pri->tei);
-+                                                  }
-+                                          break;
-+                                          case Q921_TEI_ID_CHK_RES:
-+                                              if (pri->localtype != BRI_NETWORK_PTMP)
-+                                                  break;
-+                                                  teio = (h->u.data[4] >> 1) - Q921_TEI_BASE;
-+                                                  if ((teio < 0) || (teio >= Q921_MAX_TEIS)) break;
-+                                                  if (pri->q921_tei_check[teio] == 1) {
-+                                                      pri->q921_tei_check_ri[teio] = (h->u.data[1] << 8) + h->u.data[2];
-+                                                      pri->q921_tei_check[teio] = 0;
-+                                                  } else {
-+                                                      // d a t
-+                                                      pri_error(pri, "double assgined tei for tei %d teio %d\n", h->u.data[4] >> 1, teio);
-+                                                      pri->q921_tei_check[teio] = 0;
-+                                                      q921_start_tei(pri, h->u.data[4] >> 1);
-+                                                  }
-+                                          break;
-+                                          default:
-+                                              pri_message(pri, "Ri = %d TEI msg = %x TEI = %x\n", (h->u.data[1] << 8) + h->u.data[2], h->u.data[3], h->u.data[4] >> 1);
-+                                      } 
-+                                      break;
-+                                      case Q931_PROTOCOL_DISCRIMINATOR:
-+                                          if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE)){ 
-+                                              res = q931_receive(pri, (q931_h *)h->u.data, len-3, h->h.tei);
-+                                              /* Send an RR if one wasn't sent already */
-+                                              if (pri->v_na[teio] != pri->v_r[teio]) 
-+                                                  q921_rr(pri, 0, 0, pri->tei);
-+                                              if (res == -1) {
-+                                                  return NULL;
-+                                              }
-+                                              if (res & Q931_RES_HAVEEVENT)
-+                                                  return &pri->ev;
-+                                          }
-+                                      break;
-+                                  }
-+                              } else {
-+                                  pri_message(pri, "XXX Unnumbered Information not implemented XXX\n");
-+                              }
-                       }
-                       break;
-               case 2:
-                       if (pri->debug &  PRI_DEBUG_Q921_STATE)
-                               pri_message(pri, "-- Got Disconnect from peer.\n");
-+#ifndef RELAX_TRB
-+                      if (pri->q921_state[teio] != Q921_LINK_CONNECTION_ESTABLISHED) {
-+                          q921_send_dm(pri, 1, h->h.tei);
-+                          return NULL;
-+                      }
-+#endif
-                       /* Acknowledge */
--                      q921_send_ua(pri, h->u.p_f);
--                      ev = q921_dchannel_down(pri);
--                      q921_start(pri, 0);
-+                      q921_send_ua(pri, h->u.p_f, h->h.tei);
-+                      ev = q921_dchannel_down(pri, h->h.tei);
-+                      if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) {
-+#ifndef LAYER2ALWAYSUP
-+                          /* release layer 2 */
-+                          return NULL;
-+#else
-+                          /* keep layer 2 up */
-+                          if (pri->t203_timer[teio])
-+                              pri_schedule_del(pri, pri->t203_timer[teio]);
-+                          pri->t203_timer[teio] = 0;
-+                          q921_send_sabme(pri, 1, pri->tei);
-+#endif
-+                      }
-+                      if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)){
-+                          q921_start(pri, 0, 0);
-+                      }
-                       return ev;
-               case 3:
-                       if (h->u.m2 == 3) {
-@@ -866,17 +1782,28 @@
-                                       }
-                               }
-                               /* Send Unnumbered Acknowledgement */
--                              q921_send_ua(pri, h->u.p_f);
--                              return q921_dchannel_up(pri);
-+                              q921_send_ua(pri, h->u.p_f, h->h.tei);
-+                              return q921_dchannel_up(pri, h->h.tei);
-                       } else if (h->u.m2 == 0) {
-                                       /* It's a UA */
--                              if (pri->q921_state == Q921_AWAITING_ESTABLISH) {
-+                              if (pri->q921_state[teio] == Q921_AWAITING_ESTABLISH) {
-                                       if (pri->debug & PRI_DEBUG_Q921_STATE) {
-                                               pri_message(pri, "-- Got UA from %s peer  Link up.\n", h->h.c_r ? "cpe" : "network");
-                                       }
--                                      return q921_dchannel_up(pri);
--                              } else 
--                                      pri_error(pri, "!! Got a UA, but i'm in state %d\n", pri->q921_state);
-+                                      return q921_dchannel_up(pri, h->h.tei);
-+                              } else {
-+                                      pri_error(pri, "!! Got a UA, but i'm in state %d\n", pri->q921_state[teio]);
-+                                      if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE)) {
-+                                          q921_reset(pri, h->h.tei, 1);
-+                                          q921_send_teiverify(pri, h->h.tei);
-+                                      } else {
-+                                          /* send DM */
-+                                      //    q921_send_dm(pri, 1, h->h.tei);
-+#ifndef RELAX_TRB
-+                                          q921_reset(pri, h->h.tei, 1);
-+#endif
-+                                      }
-+                              }
-                       } else 
-                               pri_error(pri, "!! Weird frame received (m3=3, m2 = %d)\n", h->u.m2);
-                       break;
-@@ -901,19 +1828,42 @@
-       /* Discard FCS */
-       len -= 2;
-       
--      if (!pri->master && pri->debug & PRI_DEBUG_Q921_DUMP)
--              q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
--
-       /* Check some reject conditions -- Start by rejecting improper ea's */
-       if (h->h.ea1 || !(h->h.ea2))
-               return NULL;
-+      if ((pri->localtype == PRI_CPE) || (pri->localtype == PRI_NETWORK)) {
-+          /* Check for broadcasts - not yet handled (for PRI) */
-+          if (h->h.tei == Q921_TEI_GROUP) {
-+              return NULL;
-+          }
-+      } else if ((pri->localtype == BRI_CPE) || (pri->localtype == BRI_CPE_PTMP)) {
-+          if ((h->h.tei != pri->tei) && (h->h.tei != Q921_TEI_GROUP)) {
-+              return NULL;
-+          }
-+      } else if (pri->localtype == BRI_NETWORK_PTMP) {
-+          /* discard anything from a strange TEI (strange == not assigned by us or the broadcast tei) */
-+          if (((h->h.tei < Q921_TEI_BASE) || (h->h.tei > Q921_TEI_BASE + Q921_MAX_TEIS)) && (h->h.tei != Q921_TEI_GROUP)) {
-+              if (pri->debug & PRI_DEBUG_Q921_DUMP)
-+                  pri_message(pri, "Received a Q.921 message from strange/unassigned TEI %d.\n");
-+              return NULL;
-+          } else {
-+              if ((pri->q921_teis[h->h.tei - Q921_TEI_BASE] != 1) && (h->h.tei != Q921_TEI_GROUP)) {
-+                  if (pri->debug & PRI_DEBUG_Q921_DUMP)
-+                      pri_message(pri, "Received a Q.921 message from unassigned TEI %d.. Sending DM and assigning.\n", h->h.tei);
-+                  // send DM 
-+                  q921_send_dm(pri, 1, h->h.tei);
-+                  pri->q921_teis[h->h.tei - Q921_TEI_BASE] = 1; 
-+              }
-+          }
-+      }    
-+  
-+      if (!pri->master && pri->debug & PRI_DEBUG_Q921_DUMP)
-+              q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
--      /* Check for broadcasts - not yet handled */
--      if (h->h.tei == Q921_TEI_GROUP)
--              return NULL;
-+      if (pri->localtype != BRI_NETWORK_PTMP) {
-       /* Check for SAPIs we don't yet handle */
--      if ((h->h.sapi != pri->sapi) || (h->h.tei != pri->tei)) {
-+          if (((h->h.sapi != pri->sapi) && (h->h.sapi != Q921_SAPI_LAYER2_MANAGEMENT)) || ((h->h.tei != pri->tei) && (h->h.tei != Q921_TEI_GROUP) )) {
- #ifdef PROCESS_SUBCHANNELS
-               /* If it's not us, try any subchannels we have */
-               if (pri->subchannel)
-@@ -921,10 +1871,16 @@
-               else 
- #endif
-                       return NULL;
--
-+          }
-       }
-       ev = __q921_receive_qualified(pri, h, len);
--      reschedule_t203(pri);
-+
-+// Q921_GROUP_TEI
-+      if (pri->localtype == BRI_CPE_PTMP) {
-+          reschedule_t203(pri, pri->tei);
-+      } else {
-+          reschedule_t203(pri, h->h.tei);
-+      }
-       return ev;
- }
-@@ -938,14 +1894,58 @@
-       return e;
- }
--void q921_start(struct pri *pri, int now)
-+static void q921_start_tei(struct pri *pri, int tei)
- {
--      if (pri->q921_state != Q921_LINK_CONNECTION_RELEASED) {
--              pri_error(pri, "!! q921_start: Not in 'Link Connection Released' state\n");
--              return;
-+ int teio=tei - Q921_TEI_BASE;
-+ if (pri->localtype != BRI_NETWORK_PTMP) { return; }
-+ if (((teio < 0) || (teio > Q921_MAX_TEIS))) { teio=0; }
-+ pri->q921_teis[teio] = 0;
-+ q921_send_teiremove(pri, tei);
-+ q921_reset(pri,tei,1);
-+}
-+
-+void q921_start(struct pri *pri, int now, int tei)
-+{
-+      int i=0;
-+/*    if (pri->q921_state != Q921_LINK_CONNECTION_RELEASED) {
-+              pri_error(pri, "!! q921_start: Not in 'Link Connection Released' state\n");
-+              return;
-+      } */
-+      /* Reset our interface */
-+      if (pri->localtype != BRI_NETWORK_PTMP) {
-+          q921_reset(pri,0,1);
-+      }
-+      /* Do the SABME XXX Maybe we should implement T_WAIT? XXX */
-+      if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE) || (pri->localtype == BRI_NETWORK) || (pri->localtype == BRI_CPE)) { 
-+          pri->sabme_retrans[0] = 0;
-+          q921_send_sabme(pri, now, 0);
-+      }
-+      
-+      if (pri->localtype == BRI_NETWORK_PTMP) { 
-+          if (tei == 0) {
-+              // initial start or complete restart
-+              q921_send_teiremove(pri, 127);
-+              pri->dchanup = 0;
-+              for (i=0;i<Q921_MAX_TEIS;i++) {
-+                  q921_start_tei(pri,Q921_TEI_BASE+i);
-+              }
-+              /* clean up those TEIs */
-+//            pri_schedule_event2(pri, 10000, q921_invoke_tei_recovery, pri, 127 );
-+          } else if ((tei >= Q921_TEI_BASE) && (tei < Q921_TEI_BASE + Q921_MAX_TEIS)){
-+              // restart of a single p2p datalink
-+              q921_start_tei(pri,tei);
-+          }
-+      } 
-+      if (pri->localtype == BRI_CPE_PTMP){ 
-+          if (tei == 0) {
-+#ifdef RELAX_TRB
-+              /* let's get a TEI */
-+              q921_send_teireq(pri);
-+#endif
-+          } else {
-+              /* save the planet by recycling */
-+              pri->sabme_retrans[0] = 0;
-+              q921_send_sabme(pri, now, tei);         
-+          }
-       }
--      /* Reset our interface */
--      q921_reset(pri);
--      /* Do the SABME XXX Maybe we should implement T_WAIT? XXX */
--      q921_send_sabme(pri, now);
- }
-diff -urN libpri-1.2.3.orig/q931.c libpri-1.2.3/q931.c
---- libpri-1.2.3.orig/q931.c   2006-04-27 18:08:39.000000000 +0200
-+++ libpri-1.2.3/q931.c        2006-08-01 10:55:05.000000000 +0200
-@@ -1,10 +1,12 @@
- /*
-  * libpri: An implementation of Primary Rate ISDN
-  *
-- * Written by Mark Spencer <markster@digium.com>
-+ * Written by Mark Spencer <markster@linux-support.net>
-  *
-- * Copyright (C) 2001-2005, Digium
-+ * Copyright (C) 2001, Linux Support Services, Inc.
-  * All Rights Reserved.
-+ * Copyright (C) 2003-2006 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj@junghanns.net>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -21,7 +23,7 @@
-  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
-  *
-  */
--
-+ 
- #include "compat.h"
- #include "libpri.h"
- #include "pri_internal.h"
-@@ -31,6 +33,7 @@
- #include <unistd.h>
- #include <stdlib.h>
-+#include <time.h>
- #include <string.h>
- #include <stdio.h>
- #include <limits.h>
-@@ -205,6 +208,14 @@
- #define LOC_INTERNATIONAL_NETWORK     0x7
- #define LOC_NETWORK_BEYOND_INTERWORKING       0xa
-+struct q921_call {
-+ int tei;     
-+ int proc;            
-+ int channel; 
-+ q921_call *next;
-+};
-+
-+
- static char *ie2str(int ie);
- static char *msg2str(int msg);
-@@ -241,6 +252,7 @@
- static void call_init(struct q931_call *c)
- {
-       memset(c, 0, sizeof(*c));
-+      c->con_acked = 0;
-       c->alive = 0;
-       c->sendhangupack = 0;
-       c->forceinvert = -1;    
-@@ -253,8 +265,16 @@
-       c->next = NULL;
-       c->sentchannel = 0;
-       c->newcall = 1;
-+      c->t303timer = 0;
-+      c->t303running = 0;
-+      c->aoc = 0;
-+      c->phones = NULL;
-       c->ourcallstate = Q931_CALL_STATE_NULL;
-       c->peercallstate = Q931_CALL_STATE_NULL;
-+      c->llc[0] = '\0';
-+      c->cause = -1;
-+      c->causecode = -1;
-+      c->causeloc = -1;
- }
- static char *binary(int b, int len) {
-@@ -272,14 +292,17 @@
- {     
-       int x;
-       int pos=0;
--#ifdef NO_BRI_SUPPORT
--      if (!ie->data[0] & 0x20) {
--              pri_error(pri, "!! Not PRI type!?\n");
--              return -1;
-+      if ((pri->localtype != PRI_CPE) && (pri->localtype != PRI_NETWORK)) {
-+ //           pri_error(pri, "!! BRI type %d!?\n",ie->data[0] & 0x03);
-+              call->channelno = ie->data[0] & 0x03;
-+              if (call->channelno == 3) {
-+                  call->channelno = -1; // any channel
-+              }
-+              return 0;
-       }
--#endif
- #ifndef NOAUTO_CHANNEL_SELECTION_SUPPORT
--      switch (ie->data[0] & 3) {
-+      if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
-+          switch (ie->data[0] & 3) {
-               case 0:
-                       call->justsignalling = 1;
-                       break;
-@@ -288,6 +311,7 @@
-               default:
-                       pri_error(pri, "!! Unexpected Channel selection %d\n", ie->data[0] & 3);
-                       return -1;
-+          }
-       }
- #endif
-       if (ie->data[0] & 0x08)
-@@ -349,10 +373,16 @@
-       }
-               
-       /* Start with standard stuff */
--      if (pri->switchtype == PRI_SWITCH_GR303_TMC)
-+      if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
-               ie->data[pos] = 0x69;
--      else
-+      } else {
-+          if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
-               ie->data[pos] = 0xa1;
-+          } else {
-+              // BRI
-+              ie->data[pos] = 0x80;
-+          }
-+      }
-       /* Add exclusive flag if necessary */
-       if (call->chanflags & FLAG_EXCLUSIVE)
-               ie->data[pos] |= 0x08;
-@@ -369,6 +399,7 @@
-       } else
-               pos++;
-       if ((call->channelno > -1) || (call->slotmap != -1)) {
-+          if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
-               /* We'll have the octet 8.2 and 8.3's present */
-               ie->data[pos++] = 0x83;
-               if (call->channelno > -1) {
-@@ -384,11 +415,43 @@
-                       ie->data[pos++] = (call->slotmap & 0xff);
-                       return pos + 2;
-               }
--      }
-+          } else {
-+              // BRI
-+              // pri_error(pri, "channelno %d, ds1no %d data %d\n",call->channelno,call->ds1no,ie->data[pos-1]);
-+              if (pri->localtype == BRI_CPE_PTMP) {
-+                  if (msgtype == Q931_SETUP) {
-+                      // network, you decide!
-+                      if (call->channelno > -1) {
-+ //                       ie->data[pos-1] = 0x83;
-+                          ie->data[pos-1] = 0x80 | call->channelno;
-+                      }
-+                  } else {
-+                      if (call->channelno > -1) {
-+                          ie->data[pos-1] |= call->channelno;
-+                      }
-+                  }
-+              } else {
-+                  if (call->channelno > -1) {
-+                      ie->data[pos-1] |= call->channelno;
-+                  }
-+              }
-+              return pos + 2;
-+          }   
-+         } else {
-+          if (pri->localtype == BRI_CPE) {
-+              ie->data[pos++] = 0x80 | 3;
-+              return pos + 2;
-+          }
-+      }       
-+
-       if (call->ds1no > 0) {
-               /* We're done */
-               return pos + 2;
-       }
-+      if (msgtype == Q931_RESTART_ACKNOWLEDGE) {
-+          /* restart complete interface! */
-+          return 0;
-+      }       
-       pri_error(pri, "!! No channel map, no channel, and no ds1?  What am I supposed to identify?\n");
-       return -1;
- }
-@@ -734,9 +797,13 @@
-       return code2str(pres, press, sizeof(press) / sizeof(press[0]));
- }
--static void q931_get_number(unsigned char *num, int maxlen, unsigned char *src, int len)
-+static void q931_get_number(char *num, int maxlen, unsigned char *src, int len)
- {
--      if ((len < 0) || (len > maxlen - 1)) {
-+      if (len < 0) {
-+          pri_error(NULL, "q931_get_number received invalid len = %d\n", len);
-+          return;
-+      }
-+      if (len > maxlen - 1) {
-               num[0] = 0;
-               return;
-       }
-@@ -746,50 +813,75 @@
- static FUNC_DUMP(dump_called_party_number)
- {
--      unsigned char cnum[256];
--
--      q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
--      pri_message(pri, "%c Called Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d) '%s' ]\n",
--              prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f, cnum);
-+      char cnum[256];
-+      if (len >= 3) {
-+          q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-+          pri_message(pri, "%c Called Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d) '%s' ]\n",
-+                  prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f, cnum);
-+      } else {
-+          pri_error(pri, "Called Number (len=%2d) too short.\n", len);
-+      }
- }
- static FUNC_DUMP(dump_called_party_subaddr)
- {
--      unsigned char cnum[256];
--      q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
--      pri_message(pri, "%c Called Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
--              prefix, len, ie->data[0] >> 7,
--              subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
--              (ie->data[0] & 0x08) >> 3, cnum);
-+      char cnum[256];
-+      if (len >= 3) {
-+          q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-+          pri_message(pri, "%c Called Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
-+              prefix, len, ie->data[0] >> 7,
-+              subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
-+              (ie->data[0] & 0x08) >> 3, cnum);
-+      } else {
-+          pri_error(pri, "Called Party Subaddress (len=%2d) too short.\n", len);
-+      }
- }
- static FUNC_DUMP(dump_calling_party_number)
- {
--      unsigned char cnum[256];
--      if (ie->data[0] & 0x80)
--              q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
--      else
--              q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
--      pri_message(pri, "%c Calling Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)\n", prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
--      if (ie->data[0] & 0x80)
--              pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(0), 0, cnum);
--      else
--              pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f, cnum);
-+      char cnum[256];
-+      if ((ie->data[0] & 0x80) && (len >= 3)) {
-+              q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-+              pri_message(pri, "%c Calling Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)\n", prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
-+              pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(0), 0, cnum);
-+      } else if (len >= 4) {
-+              q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
-+              pri_message(pri, "%c Calling Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)\n", prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
-+              pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f, cnum);
-+      } else {
-+          pri_error(pri, "Calling Party Number (len=%2d) too short.\n", len);
-+      }
- }
- static FUNC_DUMP(dump_calling_party_subaddr)
- {
--      unsigned char cnum[256];
--      q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
--      pri_message(pri, "%c Calling Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
--              prefix, len, ie->data[0] >> 7,
--              subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
--              (ie->data[0] & 0x08) >> 3, cnum);
-+      char cnum[256];
-+      if (len >= 4) {
-+          q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-+          pri_message(pri, "%c Calling Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
-+              prefix, len, ie->data[0] >> 7,
-+              subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
-+              (ie->data[0] & 0x08) >> 3, cnum);
-+      } else {
-+          pri_error(pri, "Calling Party Subaddress (len=%2d) too short.\n", len);
-+      }
-+}
-+
-+static FUNC_DUMP(dump_colp)
-+{
-+      char cnum[256];
-+      if (len >= 4) {
-+          q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
-+          pri_message(pri, "%c COLP (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)\n", prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
-+          pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f, cnum);
-+      } else {
-+          pri_error(pri, "COLP (len=%2d) too short.\n", len);
-+      }
- }
- static FUNC_DUMP(dump_redirecting_number)
- {
--      unsigned char cnum[256];
-+      char cnum[256];
-       int i = 0;
-       /* To follow Q.931 (4.5.1), we must search for start of octet 4 by
-          walking through all bytes until one with ext bit (8) set to 1 */
-@@ -810,13 +902,17 @@
-               }
-       }
-       while(!(ie->data[i++]& 0x80));
--      q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);
--      pri_message(pri, " '%s' ]\n", cnum);
-+      if ((ie->len - i) >= 0) {
-+          q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);
-+          pri_message(pri, " '%s' ]\n", cnum);
-+      } else {
-+          pri_error(pri, "Redirecting Number (len=%2d) too short.\n", len);
-+      }
- }
- static FUNC_DUMP(dump_connected_number)
- {
--      unsigned char cnum[256];
-+      char cnum[256];
-       int i = 0;
-       /* To follow Q.931 (4.5.1), we must search for start of octet 4 by
-          walking through all bytes until one with ext bit (8) set to 1 */
-@@ -833,8 +929,12 @@
-               }
-       }
-       while(!(ie->data[i++]& 0x80));
--      q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);
--      pri_message(pri, " '%s' ]\n", cnum);
-+      if ((ie->len - i) >= 0) {
-+          q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);
-+          pri_message(pri, " '%s' ]\n", cnum);
-+      } else {
-+          pri_error(pri, "Connected Number (len=%2d) too short.\n", len);
-+      }
- }
-@@ -858,7 +958,7 @@
-               }
-       }
-       while(!(ie->data[i++] & 0x80));
--      q931_get_number((unsigned char *) call->redirectingnum, sizeof(call->redirectingnum), ie->data + i, ie->len - i);
-+      q931_get_number(call->redirectingnum, sizeof(call->redirectingnum), ie->data + i, ie->len - i);
-       return 0;
- }
-@@ -866,7 +966,7 @@
- {
-       if (order > 1)
-               return 0;
--      if (call->redirectingnum && *call->redirectingnum) {
-+      if (call->redirectingnum && strlen(call->redirectingnum)) {
-               ie->data[0] = call->redirectingplan;
-               ie->data[1] = call->redirectingpres;
-               ie->data[2] = (call->redirectingreason & 0x0f) | 0x80;
-@@ -878,67 +978,90 @@
- static FUNC_DUMP(dump_redirecting_subaddr)
- {
--      unsigned char cnum[256];
--      q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
--      pri_message(pri, "%c Redirecting Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
--              prefix, len, ie->data[0] >> 7,
--              subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
--              (ie->data[0] & 0x08) >> 3, cnum);
-+      char cnum[256];
-+      if (len >= 4) {
-+          q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
-+          pri_message(pri, "%c Redirecting Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
-+              prefix, len, ie->data[0] >> 7,
-+              subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
-+              (ie->data[0] & 0x08) >> 3, cnum);
-+      } else {
-+          pri_error(pri, "Redirecting Subaddress (len=%2d) too short.\n", len);
-+      }
- }
- static FUNC_RECV(receive_calling_party_subaddr)
- {
-       /* copy digits to call->callingsubaddr */
--      q931_get_number((unsigned char *) call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 1, len - 3);
-+      if (len >= 4) {
-+          q931_get_number(call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 1, len - 3);
-+      } else {
-+          pri_error(call->pri, "Calling Party Subaddress (len=%2d) too short.\n", len);
-+      }
-       return 0;
- }
- static FUNC_RECV(receive_called_party_number)
- {
--      /* copy digits to call->callednum */
--      q931_get_number((unsigned char *) call->callednum, sizeof(call->callednum), ie->data + 1, len - 3);
--      call->calledplan = ie->data[0] & 0x7f;
-+      /* copy digits to call->callednum or call->digits */
-+      if (len >= 3) {
-+          if (msgtype == Q931_INFORMATION) {
-+              q931_get_number(call->digits, sizeof(call->digits), ie->data + 1, len - 3);
-+          } else {
-+              q931_get_number(call->callednum, sizeof(call->callednum), ie->data + 1, len - 3);
-+          }
-+          call->calledplan = ie->data[0] & 0x7f;
-+      } else {
-+          pri_error(call->pri, "Called Party Number (len=%2d) too short.\n", len);
-+      }
-       return 0;
- }
- static FUNC_SEND(transmit_called_party_number)
- {
-       ie->data[0] = 0x80 | call->calledplan;
--      if (*call->callednum)
-+      if (strlen(call->callednum)) 
-               memcpy(ie->data + 1, call->callednum, strlen(call->callednum));
-       return strlen(call->callednum) + 3;
- }
- static FUNC_RECV(receive_calling_party_number)
- {
--      u_int8_t *data;
--      size_t length;
--        
--      if (ie->data[0] & 0x80) {
--              data = ie->data + 1;
--              length = len - 3;
--              call->callerpres = 0; /* PI presentation allowed SI user-provided, not screened */        
--      } else {
--              data = ie->data + 2;
--              length = len - 4;
--              call->callerpres = ie->data[1] & 0x7f;
--      }
--
--      if (call->callerpres == PRES_ALLOWED_NETWORK_NUMBER ||
--              call->callerpres == PRES_PROHIB_NETWORK_NUMBER) {
--              q931_get_number((u_int8_t *)call->callerani, sizeof(call->callerani), data, length);
--              call->callerplanani = ie->data[0] & 0x7f;
--
--              if (!*call->callernum) { /*Copy ANI to CallerID if CallerID is not already set */
--                      libpri_copy_string(call->callernum, call->callerani, sizeof(call->callernum));
--                      call->callerplan = call->callerplanani;
--              }
--              
--      } else {
--              q931_get_number((u_int8_t *)call->callernum, sizeof(call->callernum), data, length);
--              call->callerplan = ie->data[0] & 0x7f;
--      }
-+/// callerani!!
-+      if (strlen(call->callernum)) {
-+          call->callerplanuser = ie->data[0] & 0x7f;
-+      } else {
-+          call->callerplan = ie->data[0] & 0x7f;
-+      }
-+        if (ie->data[0] & 0x80) {
-+        if (len >= 3) {
-+           if (strlen(call->callernum)) {
-+              // got A NUM already (this is not 100% correct, but the network should do it this way to protect bad implementations
-+               q931_get_number(call->callerani, sizeof(call->callerani), ie->data + 1, len - 3);
-+              call->callerpresuser = 0; /* PI presentation allowed
-+                                 SI user-provided, not screened */        
-+          } else {
-+               q931_get_number(call->callernum, sizeof(call->callernum), ie->data + 1, len - 3);
-+               call->callerpres = 0; /* PI presentation allowed
-+                                 SI user-provided, not screened */        
-+          }
-+        } else {
-+              pri_error(call->pri, "Calling Party Number (len=%2d) too short.\n", len);
-+        }
-+        } else {
-+        if (len >= 4) {
-+           if (strlen(call->callernum)) {
-+              q931_get_number(call->callerani, sizeof(call->callerani), ie->data + 2, len - 4);
-+               call->callerpresuser = ie->data[1] & 0x7f;
-+            } else {
-+               q931_get_number(call->callernum, sizeof(call->callernum), ie->data + 2, len - 4);
-+               call->callerpres = ie->data[1] & 0x7f;
-+          }
-+        } else {
-+              pri_error(call->pri, "Calling Party Number (len=%2d) too short.\n", len);
-+        }
-+        }
-       return 0;
- }
-@@ -946,7 +1069,7 @@
- {
-       ie->data[0] = call->callerplan;
-       ie->data[1] = 0x80 | call->callerpres;
--      if (*call->callernum) 
-+      if (strlen(call->callernum)) 
-               memcpy(ie->data + 2, call->callernum, strlen(call->callernum));
-       return strlen(call->callernum) + 4;
- }
-@@ -964,11 +1087,89 @@
- static FUNC_RECV(receive_user_user)
- {        
-         call->useruserprotocoldisc = ie->data[0] & 0xff;
--        if (call->useruserprotocoldisc == 4) /* IA5 */
--          q931_get_number((unsigned char *) call->useruserinfo, sizeof(call->useruserinfo), ie->data + 1, len - 3);
-+        if (call->useruserprotocoldisc == 4) { /* IA5 */
-+          if (len >= 3) {
-+              q931_get_number(call->useruserinfo, sizeof(call->useruserinfo), ie->data + 1, len - 3);
-+          } else {
-+              pri_error(call->pri, "User-User Information (len=%2d) too short.\n", len);
-+          }
-+      }
-       return 0;
- }
-+static FUNC_RECV(receive_call_identity)
-+{
-+      if (len >= 2) {
-+          q931_get_number(call->callid, sizeof(call->callid), ie->data, len - 2);
-+      } else {
-+          pri_error(call->pri, "Call Identity (len=%2d) too short.\n", len);
-+      }
-+      return 0;
-+}
-+  
-+static FUNC_SEND(transmit_call_identity)
-+{
-+      if (strlen(call->callid)) 
-+              memcpy(ie->data , call->callid, strlen(call->callid));
-+      return strlen(call->callednum) + 3;
-+}
-+
-+static FUNC_RECV(receive_high_layer_compat)
-+{
-+      return 0;
-+}
-+  
-+static FUNC_SEND(transmit_high_layer_compat)
-+{
-+    if (call->transcapability != PRI_TRANS_CAP_RESTRICTED_DIGITAL && call->transcapability != PRI_TRANS_CAP_DIGITAL && call->transcapability != PRI_TRANS_CAP_DIGITAL_W_TONES) {
-+      ie->data[0] = 0x91;
-+      ie->data[1] = 0x81;
-+      return 4;
-+    }
-+    return 0;
-+}
-+
-+static FUNC_DUMP(dump_high_layer_compat)
-+{
-+      int x;
-+      pri_message(pri, "%c High-layer compatibilty (len=%2d) [ ", prefix, len);
-+      for (x=0;x<ie->len;x++) 
-+              pri_message(pri, "0x%02X ", ie->data[x]);
-+      pri_message(pri, " ]\n");
-+}
-+
-+
-+static FUNC_RECV(receive_low_layer_compat)
-+{
-+      if (len > 0) {
-+          if (len > 16) {
-+              pri_error(pri, "%d bytes LLC too long\n", len);
-+              call->llc[0] = 0;
-+          } else {
-+              pri_error(pri, "copying %d bytes LLC \n", len);
-+              call->llc[0] = len;
-+              memcpy(call->llc+1, ie->data, len);
-+          }
-+      }
-+      return 0;
-+}
-+  
-+static FUNC_SEND(transmit_low_layer_compat)
-+{
-+    if (call->llc[0] == 0) return 0;
-+    memcpy(ie->data, call->llc + 1, call->llc[0]);
-+    return call->llc[0] + 2;
-+}
-+
-+static FUNC_DUMP(dump_low_layer_compat)
-+{
-+      int x;
-+      pri_message(pri, "%c Low-layer compatibilty (len=%2d) [ ", prefix, len);
-+      for (x=0;x<ie->len;x++) 
-+              pri_message(pri, "0x%02X ", ie->data[x]);
-+      pri_message(pri, " ]\n");
-+}
-+
- static FUNC_SEND(transmit_user_user)
- {        
-       int datalen = strlen(call->useruserinfo);
-@@ -1050,22 +1251,41 @@
-               data++;
-               len--;
-       }
--      q931_get_number((unsigned char *) call->callername, sizeof(call->callername), data, len - 2);
-+      if (msgtype == Q931_SETUP) {
-+          /* we treat display IEs in the SETUP msg as callername */
-+          if (len >= 2) {
-+              q931_get_number(call->callername, sizeof(call->callername), data, len - 2);
-+          } else {
-+              pri_error(call->pri, "Display (len=%2d) too short.\n", len);
-+          }
-+      } else {
-+          /* in other msgs we will pass it as text to chan_zap */
-+          if (len >= 2) {
-+              q931_get_number(call->display, sizeof(call->display), data, len - 2);
-+          } else {
-+              pri_error(call->pri, "Display (len=%2d) too short.\n", len);
-+          }
-+      }
-       return 0;
- }
- static FUNC_SEND(transmit_display)
- {
-       int i;
--      if ((pri->switchtype != PRI_SWITCH_NI1) && (pri->switchtype != PRI_SWITCH_QSIG) 
--                      && *call->callername) {
-+      int cpe = pri->localtype == BRI_CPE || pri->localtype == BRI_CPE_PTMP || pri->localtype == PRI_CPE;
-+      if ((pri->switchtype != PRI_SWITCH_NI1) && (pri->switchtype != PRI_SWITCH_QSIG) && strlen(call->callername) && !cpe) {
-               i = 0;
-               if(pri->switchtype != PRI_SWITCH_EUROISDN_E1) {
-                       ie->data[0] = 0xb1;
-                       ++i;
-               }
--              memcpy(ie->data + i, call->callername, strlen(call->callername));
--              return 2 + i + strlen(call->callername);
-+              if (msgtype == Q931_SETUP_ACKNOWLEDGE) {
-+                  memcpy(ie->data + i, call->display, strlen(call->display));
-+                  return 2 + i + strlen(call->display);
-+              } else {
-+                  memcpy(ie->data + i, call->callername, strlen(call->callername));
-+                  return 2 + i + strlen(call->callername);
-+              }
-       }
-       return 0;
- }
-@@ -1112,6 +1332,111 @@
-       return 0;
- }
-+ #if 0
-+  static FUNC_RECV(receive_facility_kpj)
-+   {
-+      unsigned char cpt_tag, cp_len, invoke_id_tag, invoke_id_len, operation_value_len, operation_value_tag;
-+      unsigned char arg_len = 0;
-+      unsigned char pos = 0;
-+      short invoke_id = 0, operation_value = 0;
-+      if ((ie->data[pos++] & 0x1F) == 0x11) {
-+          /* service discriminator == supplementary services */
-+          cpt_tag = ie->data[pos++] & 0x1F;
-+          cp_len = ie->data[pos++];
-+          switch (cpt_tag) {
-+              case 1: /* invoke */
-+                      invoke_id_tag = ie->data[pos++];
-+                      if (invoke_id_tag != 0x02) {
-+                      //    pri_error(call->pri, "invoke id tag != 0x02\n");
-+                          break;
-+                      }
-+                      invoke_id_len = ie->data[pos++]; // 4
-+                      while (invoke_id_len > 0) {
-+                          invoke_id = (invoke_id << 8) | (ie->data[pos++] & 0xFF);
-+                          invoke_id_len--;
-+                      }
-+                      operation_value_tag = ie->data[pos++];
-+                      if (operation_value_tag != 0x02) {
-+                      //    pri_error(call->pri, "operation value tag != 0x02\n");
-+                          break;
-+                      }
-+                      operation_value_len = ie->data[pos++];
-+                      while (operation_value_len > 0) {
-+                          operation_value = (operation_value << 8) | (ie->data[pos++] & 0xFF);
-+                          operation_value_len--;
-+                      }
-+                      arg_len = ie->len - pos;
-+                      switch (operation_value) {
-+                          case 0x06:  /* ECT execute */
-+                                      call->facility = operation_value;
-+                                      break;
-+                          case 0x0D:  /* call deflection */
-+                                      call->facility = operation_value;
-+                                      /* dirty hack! */
-+                                      arg_len -= 6;
-+                                      if (arg_len > 0) {
-+                                          pos += 6;
-+                                          q931_get_number(call->redirectingnum, sizeof(call->redirectingnum), ie->data + pos, arg_len);
-+                                      }
-+                                      /* now retrieve the number */
-+                                      break;
-+                          case 0x22:  /* AOC-D */
-+                                      break;
-+                          case 0x24:  /* AOC-E */
-+                                      break;
-+                      }
-+                      break;
-+              case 2: /* return result */
-+                      break;
-+              case 3: /* return error */
-+                      break;
-+              case 4: /* reject */
-+                      break;
-+          }
-+      } else {
-+          /* OLD DIRTY ULAW HACK */
-+          if (ie->len < 14) {
-+              pri_error(call->pri, "!! Facility message shorter than 14 bytes\n");
-+              return 0;
-+          }
-+          if (ie->data[13] + 14 == ie->len) {
-+              q931_get_number(call->callername, sizeof(call->callername) - 1, ie->data + 14, ie->len - 14);
-+          } 
-+          call->facility = 0x0;
-+      }
-+      return 0;
-+   }
-+   
-+  static FUNC_SEND(transmit_facility_kpj)
-+  {
-+      int i = 0;
-+      return i;
-+      if (call->aoc && (pri->switchtype == PRI_SWITCH_EUROISDN_E1) && ((pri->localtype == BRI_NETWORK) || (pri->localtype == BRI_NETWORK_PTMP) || (pri->localtype == PRI_NETWORK))) {
-+          ie->data[0] = 0x90;  /* PP remote operations */
-+          ie->data[i++] = 0x00; /* component tag */
-+          ie->data[i++] = 0x02; /* invoke id tag */
-+          ie->data[i++] = 0x02; /* invoke id len */
-+          ie->data[i++] = 0x34; /* invoke id */
-+          ie->data[i++] = 0x56; /* invoke id */
-+          ie->data[i++] = 0x02; /* operation value tag */
-+          ie->data[i++] = 0x01; /* operation value len */
-+          switch (msgtype) {
-+              case Q931_SETUP:
-+                  ie->data[i++] = 0x26; /* operation value AOC-S */
-+                  break;
-+              case Q931_DISCONNECT:
-+                  ie->data[i++] = 0x24; /* operation value AOC-E */
-+                  break;
-+              default:
-+                  ie->data[i++] = 0x22; /* operation value AOC-D */
-+                  break;
-+          }
-+          // ARGUMENTS!       
-+      }
-+  //  return 2 + i;
-+  }
-+#endif
-+
- static FUNC_SEND(transmit_facility)
- {
-       struct apdu_event *tmp;
-@@ -1138,6 +1463,182 @@
-       return i + 2;
- }
-+#if 0
-+static FUNC_SEND(transmit_facility)
-+{
-+      int i = 0, j, first_i, compsp = 0;
-+      struct rose_component *comp, *compstk[10];
-+      unsigned char namelen = strlen(call->callername);
-+
-+      if ((pri->switchtype == PRI_SWITCH_NI2) && (namelen > 15))
-+              namelen = 15; /* According to GR-1367, for NI2 switches it can't be > 15 characters */
-+      if ((namelen > 0) && ((pri->switchtype == PRI_SWITCH_QSIG) ||
-+                      ((pri->switchtype == PRI_SWITCH_NI2) && (pri->localtype == PRI_NETWORK)))) {
-+              do {
-+                      first_i = i;
-+                      ie->data[i] = 0x80 | Q932_PROTOCOL_EXTENSIONS;
-+                      i++;
-+                      /* Interpretation component */
-+                      ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, ie->data, i, 0x00 /* Discard unrecognized invokes */);
-+
-+                      /* Invoke ID */
-+                      ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, ie->data, i);
-+                      ASN1_PUSH(compstk, compsp, comp);
-+
-+                      /* Invoke component contents */
-+                      /*      Invoke ID */
-+                      ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, ie->data, i, ++pri->last_invoke);
-+
-+                      /*      Operation Tag */
-+                      ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, ie->data, i, SS_CNID_CALLINGNAME);
-+
-+                      /* Arugement Tag */
-+                      j = asn1_string_encode(ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE, &ie->data[i], len - i, 15, call->callername, namelen);
-+                      if (j < 0) {
-+                              i = first_i;
-+                              break;
-+                      }
-+                      i += j;
-+
-+                      /* Fix length of stacked components */
-+                      while(compsp > 0) {
-+                              ASN1_FIXUP(compstk, compsp, ie->data, i);
-+                      }
-+              } while (0);
-+      }
-+      if (/*(pri->switchtype == PRI_SWITCH_EUROISDN_E1) &&*/ call->redirectingnum && strlen(call->redirectingnum)) {
-+              if (!(first_i = i)) {
-+                      /* Add protocol information header */
-+                      ie->data[i++] = 0x80 | Q932_PROTOCOL_ROSE;
-+              }
-+
-+              /* ROSE invoke component */
-+              ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, ie->data, i);
-+              ASN1_PUSH(compstk, compsp, comp);
-+
-+              /* ROSE invokeId component */
-+              ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, ie->data, i, ++pri->last_invoke);
-+
-+              /* ROSE operationId component */
-+              ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, ie->data, i, ROSE_DIVERTING_LEG_INFORMATION2);
-+
-+              /* ROSE ARGUMENT component */
-+              ASN1_ADD_SIMPLE(comp, 0x30, ie->data, i);
-+              ASN1_PUSH(compstk, compsp, comp);
-+
-+              /* ROSE DivertingLegInformation2.diversionCounter component */
-+              /* Always is 1 because other isn't available in the current design */
-+              ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, ie->data, i, 1);
-+
-+              /* ROSE DivertingLegInformation2.diversionReason component */
-+              ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, ie->data, i, redirectingreason_from_q931(pri, call->redirectingreason));
-+
-+              /* ROSE DivertingLegInformation2.divertingNr component */
-+              ASN1_ADD_SIMPLE(comp, 0xA1, ie->data, i);
-+              ASN1_PUSH(compstk, compsp, comp);
-+
-+              /* Redirecting information always not screened */
-+              switch(call->redirectingpres) {
-+              case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
-+              case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
-+                      if (call->redirectingnum && strlen(call->redirectingnum)) {
-+                              ASN1_ADD_SIMPLE(comp, 0xA0, ie->data, i);
-+                              ASN1_PUSH(compstk, compsp, comp);
-+
-+                              /* NPI of redirected number is not supported in the current design */
-+                              ASN1_ADD_SIMPLE(comp, 0xA1, ie->data, i);
-+                              ASN1_PUSH(compstk, compsp, comp);
-+
-+                              ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, ie->data, i, typeofnumber_from_q931(pri, call->redirectingplan >> 4));
-+
-+                              j = asn1_string_encode(ASN1_NUMERICSTRING, &ie->data[i], len - i, 20, call->redirectingnum, strlen(call->redirectingnum));
-+                              if (j < 0) {
-+                                      i = first_i;
-+                                      goto finish2;
-+                              }
-+                              i += j;
-+                              ASN1_FIXUP(compstk, compsp, ie->data, i);
-+                              ASN1_FIXUP(compstk, compsp, ie->data, i);
-+                              break;
-+                      }
-+                      /* fall through */
-+              case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
-+              case PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
-+                      ASN1_ADD_SIMPLE(comp, 0x81, ie->data, i);
-+                      break;
-+              /* Don't know how to handle this */
-+              case PRES_ALLOWED_NETWORK_NUMBER:
-+              case PRES_PROHIB_NETWORK_NUMBER:
-+              case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
-+              case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
-+                      ASN1_ADD_SIMPLE(comp, 0x81, ie->data, i);
-+                      break;
-+              default:
-+                      pri_message(pri, "!! Undefined presentation value for redirecting number: %d\n", call->redirectingpres);
-+              case PRES_NUMBER_NOT_AVAILABLE:
-+                      ASN1_ADD_SIMPLE(comp, 0x82, ie->data, i);
-+                      break;
-+              }
-+              ASN1_FIXUP(compstk, compsp, ie->data, i);
-+
-+              /* ROSE DivertingLegInformation2.originalCalledNr component */
-+              /* This information isn't supported by current design - duplicate divertingNr */
-+              ASN1_ADD_SIMPLE(comp, 0xA2, ie->data, i);
-+              ASN1_PUSH(compstk, compsp, comp);
-+
-+              /* Redirecting information always not screened */
-+              switch(call->redirectingpres) {
-+              case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
-+              case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
-+                      if (call->redirectingnum && strlen(call->redirectingnum)) {
-+                              ASN1_ADD_SIMPLE(comp, 0xA0, ie->data, i);
-+                              ASN1_PUSH(compstk, compsp, comp);
-+
-+                              ASN1_ADD_SIMPLE(comp, 0xA1, ie->data, i);
-+                              ASN1_PUSH(compstk, compsp, comp);
-+
-+                              ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, ie->data, i, typeofnumber_from_q931(pri, call->redirectingplan >> 4));
-+
-+                              j = asn1_string_encode(ASN1_NUMERICSTRING, &ie->data[i], len - i, 20, call->redirectingnum, strlen(call->redirectingnum));
-+                              if (j < 0) {
-+                                      i = first_i;
-+                                      goto finish2;
-+                              }
-+                              i += j;
-+                              ASN1_FIXUP(compstk, compsp, ie->data, i);
-+                              ASN1_FIXUP(compstk, compsp, ie->data, i);
-+                              break;
-+                      }
-+                      /* fall through */
-+              case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
-+              case PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
-+                      ASN1_ADD_SIMPLE(comp, 0x81, ie->data, i);
-+                      break;
-+              /* Don't know how to handle this */
-+              case PRES_ALLOWED_NETWORK_NUMBER:
-+              case PRES_PROHIB_NETWORK_NUMBER:
-+              case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
-+              case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
-+                      ASN1_ADD_SIMPLE(comp, 0x81, ie->data, i);
-+                      break;
-+              default:
-+                      pri_message(pri, "!! Undefined presentation value for redirecting number: %d\n", call->redirectingpres);
-+              case PRES_NUMBER_NOT_AVAILABLE:
-+                      ASN1_ADD_SIMPLE(comp, 0x82, ie->data, i);
-+                      break;
-+              }
-+              ASN1_FIXUP(compstk, compsp, ie->data, i);
-+
-+              /* Fix length of stacked components */
-+              while(compsp > 0) {
-+                      ASN1_FIXUP(compstk, compsp, ie->data, i);
-+              }
-+      }
-+finish2:
-+      return (i ? i+2 : 0);
-+}
-+#endif
-+
- static FUNC_RECV(receive_facility)
- {
-       int i = 0;
-@@ -1346,6 +1847,7 @@
-       pri_message(pri, " ]\n");
- }
-+
- static FUNC_DUMP(dump_time_date)
- {
-       pri_message(pri, "%c Time Date (len=%2d) [ ", prefix, len);
-@@ -1366,7 +1868,7 @@
- static FUNC_DUMP(dump_keypad_facility)
- {
--      char tmp[64];
-+      char tmp[64] = "";
-       
-       if (ie->len == 0 || ie->len > sizeof(tmp))
-               return;
-@@ -1377,28 +1879,49 @@
- static FUNC_RECV(receive_keypad_facility)
- {
--      int mylen;
-+      int mylen = 0;
-       if (ie->len == 0)
-               return -1;
-       if (ie->len > (sizeof(call->digitbuf) - 1))
--              mylen = (sizeof(call->digitbuf) - 1);
-+              mylen = sizeof(call->digitbuf) - 1;
-       else
-               mylen = ie->len;
--      memcpy(call->digitbuf, ie->data, mylen);
-+      strncpy(call->digitbuf, (char *) ie->data, mylen);
--      call->digitbuf[mylen] = 0;
-+      /* I must be really neurotic */
-+      call->digitbuf[sizeof(call->digitbuf)-1] = '\0';
-       return 0;
- }
-+static FUNC_RECV(receive_time_date)
-+{
-+    return 0;
-+}
-+
-+static FUNC_SEND(transmit_time_date) {
-+    time_t now;
-+    struct tm *timedate;
-+    time(&now);
-+    timedate = localtime(&now);
-+    ie->data[0] = timedate->tm_year - 100; // 1900+
-+    ie->data[1] = timedate->tm_mon + 1;
-+    ie->data[2] = timedate->tm_mday;
-+    ie->data[3] = timedate->tm_hour;
-+    ie->data[4] = timedate->tm_min;
-+    return 7;
-+}
-+
-+
-+
- static FUNC_DUMP(dump_display)
- {
-       int x, y;
-       char *buf = malloc(len + 1);
--      char tmp[80];
-+      char tmp[80]="";
-       if (buf) {
-               x=y=0;
-               if ((x < ie->len) && (ie->data[x] & 0x80)) {
-@@ -1413,7 +1936,7 @@
-       }
- }
--static void dump_ie_data(unsigned char *c, int len)
-+static void dump_ie_data(struct pri *pri, unsigned char *c, int len)
- {
-       char tmp[1024] = "";
-       int x=0;
-@@ -1423,7 +1946,7 @@
-                   ((*c >= 'a') && (*c <= 'z')) ||
-                   ((*c >= '0') && (*c <= '9'))) {
-                       if (!lastascii) {
--                              if (*tmp) { 
-+                              if (strlen(tmp)) { 
-                                       tmp[x++] = ',';
-                                       tmp[x++] = ' ';
-                               }
-@@ -1435,7 +1958,7 @@
-                       if (lastascii) {
-                               tmp[x++] = '\'';
-                       }
--                      if (*tmp) { 
-+                      if (strlen(tmp)) { 
-                               tmp[x++] = ',';
-                               tmp[x++] = ' ';
-                       }
-@@ -1448,14 +1971,14 @@
-       }
-       if (lastascii)
-               tmp[x++] = '\'';
--      pri_message(NULL, tmp);
-+      pri_message(pri, tmp);
- }
- static FUNC_DUMP(dump_facility)
- {
-       pri_message(pri, "%c Facility (len=%2d, codeset=%d) [ ", prefix, len, Q931_IE_CODESET(full_ie));
--      dump_ie_data(ie->data, ie->len);
--      pri_message(NULL, " ]\n");
-+      dump_ie_data(pri, ie->data, ie->len);
-+      pri_message(pri, " ]\n");
- }
- static FUNC_DUMP(dump_network_spec_fac)
-@@ -1465,7 +1988,7 @@
-               pri_message(pri, code2str(ie->data[1], facilities, sizeof(facilities) / sizeof(facilities[0])));
-       }
-       else
--              dump_ie_data(ie->data, ie->len);
-+              dump_ie_data(pri, ie->data, ie->len);
-       pri_message(pri, " ]\n");
- }
-@@ -1932,8 +2455,8 @@
-       { 1, Q931_REDIRECTING_SUBADDR, "Redirecting Subaddress", dump_redirecting_subaddr },
-       { 0, Q931_TRANSIT_NET_SELECT, "Transit Network Selection" },
-       { 1, Q931_RESTART_INDICATOR, "Restart Indicator", dump_restart_indicator, receive_restart_indicator, transmit_restart_indicator },
--      { 0, Q931_LOW_LAYER_COMPAT, "Low-layer Compatibility" },
--      { 0, Q931_HIGH_LAYER_COMPAT, "High-layer Compatibility" },
-+      { 0, Q931_LOW_LAYER_COMPAT, "Low-layer Compatibility" , dump_low_layer_compat, receive_low_layer_compat, transmit_low_layer_compat },
-+      { 1, Q931_HIGH_LAYER_COMPAT, "High-layer Compatibility" , dump_high_layer_compat, receive_high_layer_compat, transmit_high_layer_compat },
-       { 1, Q931_PACKET_SIZE, "Packet Size" },
-       { 1, Q931_IE_FACILITY, "Facility" , dump_facility, receive_facility, transmit_facility },
-       { 1, Q931_IE_REDIRECTION_NUMBER, "Redirection Number" },
-@@ -1942,11 +2465,11 @@
-       { 1, Q931_IE_INFO_REQUEST, "Feature Request" },
-       { 1, Q931_IE_FEATURE_IND, "Feature Indication" },
-       { 1, Q931_IE_SEGMENTED_MSG, "Segmented Message" },
--      { 1, Q931_IE_CALL_IDENTITY, "Call Identity", dump_call_identity },
-+      { 1, Q931_IE_CALL_IDENTITY, "Call Identity", dump_call_identity, receive_call_identity, transmit_call_identity },
-       { 1, Q931_IE_ENDPOINT_ID, "Endpoint Identification" },
-       { 1, Q931_IE_NOTIFY_IND, "Notification Indicator", dump_notify, receive_notify, transmit_notify },
-       { 1, Q931_DISPLAY, "Display", dump_display, receive_display, transmit_display },
--      { 1, Q931_IE_TIME_DATE, "Date/Time", dump_time_date },
-+      { 1, Q931_IE_TIME_DATE, "Date/Time", dump_time_date, receive_time_date, transmit_time_date },
-       { 1, Q931_IE_KEYPAD_FACILITY, "Keypad Facility", dump_keypad_facility, receive_keypad_facility },
-       { 0, Q931_IE_SIGNAL, "Signal", dump_signal },
-       { 1, Q931_IE_SWITCHHOOK, "Switch-hook" },
-@@ -1954,6 +2477,7 @@
-       { 1, Q931_IE_ESCAPE_FOR_EXT, "Escape for Extension" },
-       { 1, Q931_IE_CALL_STATUS, "Call Status" },
-       { 1, Q931_IE_CHANGE_STATUS, "Change Status" },
-+      { 1, Q931_COLP, "Connect Line ID Presentation", dump_colp},
-       { 1, Q931_IE_CONNECTED_ADDR, "Connected Number", dump_connected_number },
-       { 1, Q931_IE_CONNECTED_NUM, "Connected Number", dump_connected_number },
-       { 1, Q931_IE_ORIGINAL_CALLED_NUMBER, "Original Called Number", dump_redirecting_number, receive_redirecting_number, transmit_redirecting_number },
-@@ -2024,7 +2548,7 @@
- {
-       if ((ie->ie & 0x80) != 0)
-               return 1;
--      else
-+      else 
-               return 2 + ie->len;
- }
-@@ -2054,10 +2578,10 @@
-                       break;
-               case 1:
-                       cr = h->crv[0];
--                      if (cr & 0x80) {
-+              /*      if (cr & 0x80) {
-                               cr &= ~0x80;
-                               cr |= 0x8000;
--                      }
-+                      } */
-                       break;
-               default:
-                       pri_error(NULL, "Call Reference Length not supported: %d\n", h->crlen);
-@@ -2071,14 +2595,14 @@
-       int full_ie = Q931_FULL_IE(codeset, ie->ie);
-       int base_ie;
--      pri_message(NULL, "%c [", prefix);
--      pri_message(NULL, "%02x", ie->ie);
-+      pri_message(pri, "%c [", prefix);
-+      pri_message(pri, "%02x", ie->ie);
-       if (!(ie->ie & 0x80)) {
--              pri_message(NULL, " %02x", ielen(ie)-2);
-+              pri_message(pri, " %02x", ielen(ie)-2);
-               for (x = 0; x + 2 < ielen(ie); ++x)
--                      pri_message(NULL, " %02x", ie->data[x]);
-+                      pri_message(pri, " %02x", ie->data[x]);
-       }
--      pri_message(NULL, "]\n");
-+      pri_message(pri, "]\n");
-       /* Special treatment for shifts */
-       if((full_ie & 0xf0) == Q931_LOCKING_SHIFT)
-@@ -2098,14 +2622,46 @@
-       pri_error(pri, "!! %c Unknown IE %d (len = %d)\n", prefix, base_ie, ielen(ie));
- }
--static q931_call *q931_getcall(struct pri *pri, int cr)
-+static q921_call *q921_getcall(struct pri *pri, struct q931_call *c, int tei)
-+{
-+      q921_call *cur;
-+      cur = c->phones;
-+      while(cur) {
-+          if (cur->tei == tei) {
-+                  return cur;
-+          } 
-+          cur = cur->next;
-+      }
-+      /* No call exists, make a new one */
-+      if (pri->debug & PRI_DEBUG_Q921_STATE)
-+              pri_message(pri, "-- Making new q921 call for cref %d tei %d\n", c->cr, tei);
-+      cur = malloc(sizeof(struct q921_call));
-+      memset(cur, 0, sizeof(cur));
-+      cur->tei = tei;
-+      cur->proc = 0;
-+      cur->channel = -1;
-+      cur->next = c->phones;
-+      c->phones = cur;
-+      return cur;
-+}
-+
-+static q931_call *q931_getcall(struct pri *pri, int cr, int tei)
- {
-       q931_call *cur, *prev;
-       cur = *pri->callpool;
-       prev = NULL;
-       while(cur) {
--              if (cur->cr == cr)
--                      return cur;
-+              if ((pri->localtype == BRI_NETWORK_PTMP) && (tei >= 0)) {
-+                  // hmm...ok, we might be the 1st responding to the setup
-+                  // or it is really our call
-+                  if ((cur->cr == cr) && ((cur->tei == tei) || (cur->tei == 127)))
-+                          return cur;
-+                  // or we might not be the 1st responding, then we need to clone
-+                  // the call struct to hangup properly
-+              } else {
-+                  if (cur->cr == cr)
-+                          return cur;
-+              }
-               prev = cur;
-               cur = cur->next;
-       }
-@@ -2118,6 +2674,7 @@
-               /* Call reference */
-               cur->cr = cr;
-               cur->pri = pri;
-+              cur->tei = tei;
-               /* Append to end of list */
-               if (prev)
-                       prev->next = cur;
-@@ -2133,24 +2690,42 @@
-       do {
-               cur = *pri->callpool;
-               pri->cref++;
--              if (pri->cref > 32767)
--                      pri->cref = 1;
-+              if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
-+                  if (pri->cref > 32767)
-+                          pri->cref = 1;
-+              } else {
-+                  // BRI
-+                  if (pri->cref > 255)
-+                          pri->cref = 1;
-+              }
-               while(cur) {
--                      if (cur->cr == (0x8000 | pri->cref))
--                              break;
-+                      if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
-+                          if (cur->cr == (0x8000 | pri->cref))
-+                                  break;
-+                      } else {
-+                          // BRIs have only 1 bye cref
-+                          if (cur->cr == (0x80 | pri->cref))
-+                                  break;
-+                      }
-                       cur = cur->next;
-               }
-       } while(cur);
--      return q931_getcall(pri, pri->cref | 0x8000);
-+      if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
-+          return q931_getcall(pri, pri->cref | 0x8000, 0);
-+      } else {
-+          // BRI
-+          return q931_getcall(pri, pri->cref | 0x80, 0);
-+      }
- }
--static void q931_destroy(struct pri *pri, int cr, q931_call *c)
-+static void q931_destroy(struct pri *pri, int cr, q931_call *c, int tei)
- {
-       q931_call *cur, *prev;
-       prev = NULL;
-       cur = *pri->callpool;
-       while(cur) {
--              if ((c && (cur == c)) || (!c && (cur->cr == cr))) {
-+//            if ((c && (cur == c)) || (!c && (cur->cr == cr))) {
-+              if ((c && (cur == c)) || (!c && ((cur->cr == cr) && ((pri->localtype != BRI_NETWORK_PTMP) || (cur->tei == tei))))) {
-                       if (prev)
-                               prev->next = cur->next;
-                       else
-@@ -2159,6 +2734,8 @@
-                               pri_message(pri, "NEW_HANGUP DEBUG: Destroying the call, ourstate %s, peerstate %s\n",callstate2str(cur->ourcallstate),callstate2str(cur->peercallstate));
-                       if (cur->retranstimer)
-                               pri_schedule_del(pri, cur->retranstimer);
-+                      if (cur->t303timer)
-+                              pri_schedule_del(pri, cur->t303timer);
-                       pri_call_apdu_queue_cleanup(cur);
-                       free(cur);
-                       return;
-@@ -2169,16 +2746,16 @@
-       pri_error(pri, "Can't destroy call %d!\n", cr);
- }
--static void q931_destroycall(struct pri *pri, int cr)
-+static void q931_destroycall(struct pri *pri, int cr, int tei)
- {
--      return q931_destroy(pri, cr, NULL);
-+      return q931_destroy(pri, cr, NULL, tei);
- }
- void __q931_destroycall(struct pri *pri, q931_call *c) 
- {
-       if (pri && c)
--              q931_destroy(pri,0, c);
-+              q931_destroy(pri,0, c, c->tei);
-       return;
- }
-@@ -2290,6 +2867,10 @@
- {
-       unsigned int x;
-       int full_ie = Q931_FULL_IE(codeset, ie->ie);
-+      if (ielen(ie) > Q931_IE_MAX_LEN) {
-+          pri_error(pri, "!! Invalid IE length %d (len = %d)\n", full_ie, ielen(ie));
-+          return -1;
-+      }
-       if (pri->debug & PRI_DEBUG_Q931_STATE)
-               pri_message(pri, "-- Processing IE %d (cs%d, %s)\n", ie->ie, codeset, ie2str(full_ie));
-       for (x=0;x<sizeof(ies) / sizeof(ies[0]);x++) {
-@@ -2307,21 +2888,36 @@
-       return -1;
- }
--static void init_header(struct pri *pri, q931_call *call, unsigned char *buf, q931_h **hb, q931_mh **mhb, int *len)
-+static void init_header(struct pri *pri, q931_call *call, unsigned char *buf, q931_h **hb, q931_mh **mhb, int *len, int briflag)
- {
-       /* Returns header and message header and modifies length in place */
-       q931_h *h = (q931_h *)buf;
--      q931_mh * mh = (q931_mh *)(h->contents + 2);
-+      q931_mh *mh;
-       h->pd = pri->protodisc;
-       h->x0 = 0;              /* Reserved 0 */
--      h->crlen = 2;   /* Two bytes of Call Reference.  Invert the top bit to make it from our sense */
--      if (call->cr || call->forceinvert) {
-+
-+      if (briflag == 1) {
-+          mh = (q931_mh *)(h->contents + 1);
-+          h->crlen = 1;       /* One bytes of Call Reference.  Invert the top bit to make it from our sense */
-+          if (call->cr || call->forceinvert) {
-+              h->crv[0] = (call->cr ^ 0x80);
-+          } else {
-+              /* Unless of course this has no call reference */
-+              h->crv[0] = 0;
-+          }
-+          *len -= 4;
-+      } else {
-+          mh = (q931_mh *)(h->contents + 2);
-+                  h->crlen = 2;       /* Two bytes of Call Reference.  Invert the top bit to make it from our sense */
-+          if (call->cr || call->forceinvert) {
-               h->crv[0] = ((call->cr ^ 0x8000) & 0xff00) >> 8;
-               h->crv[1] = (call->cr & 0xff);
--      } else {
-+          } else {
-               /* Unless of course this has no call reference */
-               h->crv[0] = 0;
-               h->crv[1] = 0;
-+          }
-+          *len -= 5;
-       }
-       if (pri->subchannel) {
-               /* On GR-303, top bit is always 0 */
-@@ -2330,13 +2926,23 @@
-       mh->f = 0;
-       *hb = h;
-       *mhb = mh;
--      *len -= 5;
--      
- }
--static int q931_xmit(struct pri *pri, q931_h *h, int len, int cr)
-+static int q931_xmit(struct pri *pri, q931_h *h, int len, int cr, int tei)
- {
--      q921_transmit_iframe(pri, h, len, cr);
-+      q931_mh *mh;
-+      if (pri->localtype == BRI_NETWORK_PTMP) {
-+          mh = (q931_mh *)(h->contents + 1);
-+          if (mh->msg == Q931_SETUP) {
-+              q921_transmit_uframe(pri, h, len, cr, tei);
-+          } else {
-+              q921_transmit_iframe(pri, h, len, cr, tei);
-+          }
-+      } else if (pri->localtype == BRI_CPE_PTMP) {
-+          q921_transmit_iframe(pri, h, len, cr, pri->tei);
-+      } else {
-+          q921_transmit_iframe(pri, h, len, cr, tei);
-+      }
-       /* The transmit operation might dump the q921 header, so logging the q931
-          message body after the transmit puts the sections of the message in the
-          right order in the log */
-@@ -2362,7 +2968,11 @@
-       
-       memset(buf, 0, sizeof(buf));
-       len = sizeof(buf);
--      init_header(pri, c, buf, &h, &mh, &len);
-+      if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
-+          init_header(pri, c, buf, &h, &mh, &len, 0);
-+      } else {
-+          init_header(pri, c, buf, &h, &mh, &len, 1);
-+      }
-       mh->msg = msgtype;
-       x=0;
-       codeset = 0;
-@@ -2397,11 +3007,34 @@
-       }
-       /* Invert the logic */
-       len = sizeof(buf) - len;
--      q931_xmit(pri, h, len, 1);
-+      if (pri->localtype == BRI_CPE_PTMP) {
-+          q931_xmit(pri, h, len, 1, pri->tei);
-+      } else {
-+          q931_xmit(pri, h, len, 1, c->tei);
-+      }
-       c->acked = 1;
-       return 0;
- }
-+static int facility_ies[] = { Q931_IE_FACILITY, -1 };
-+
-+#if 0
-+int q931_facility_kpj(struct pri *pri, q931_call *c, int operation, char *arguments)
-+{
-+      switch (operation) {
-+          case 0x26:  c->aoc = 1;
-+                      break;
-+          case 0x24:  c->aoc = 1;
-+                      break;
-+          case 0x22:  c->aoc = 1;
-+                      break;
-+          default:
-+              return -1;
-+      }
-+      return send_message(pri, c, Q931_FACILITY, facility_ies);
-+}
-+#endif
-+
- static int status_ies[] = { Q931_CAUSE, Q931_CALL_STATE, -1 };
- static int q931_status(struct pri *pri, q931_call *c, int cause)
-@@ -2439,17 +3072,45 @@
-       return send_message(pri, c, Q931_INFORMATION, information_ies);
- }
-+static int information_display_ies[] = { Q931_DISPLAY, -1 };
-+
-+int q931_information_display(struct pri *pri, q931_call *c, char *display)
-+{
-+      int res=0;
-+      char temp[256];
-+      if (!display) return -1;
-+      strncpy(temp, c->callername, sizeof(temp));
-+      strncpy(c->callername, display, sizeof(c->callername));
-+      res = send_message(pri, c, Q931_INFORMATION, information_display_ies);
-+      strncpy(c->callername, temp, sizeof(c->callername));
-+      return res;
-+}
-+
-+int q931_add_display(struct pri *pri, q931_call *c, char *display)
-+{
-+      strncpy(c->display, display, sizeof(c->display));
-+      return 0;
-+}
-+
-+/* static int information_special_ies[] = { Q931_IE_SPECIAL, -1 };
-+static int q931_information_special(struct pri *pri, q931_call *c)
-+{
-+      return send_message(pri, c, Q931_FACILITY, information_special_ies);
-+}
-+*/
-+
-+
- static int restart_ack_ies[] = { Q931_CHANNEL_IDENT, Q931_RESTART_INDICATOR, -1 };
- static int restart_ack(struct pri *pri, q931_call *c)
- {
-       c->ourcallstate = Q931_CALL_STATE_NULL;
-       c->peercallstate = Q931_CALL_STATE_NULL;
-+        c->chanflags &= ~FLAG_PREFERRED;
-+        c->chanflags |= FLAG_EXCLUSIVE;
-       return send_message(pri, c, Q931_RESTART_ACKNOWLEDGE, restart_ack_ies);
- }
--static int facility_ies[] = { Q931_IE_FACILITY, -1 };
--
- int q931_facility(struct pri*pri, q931_call *c)
- {
-       return send_message(pri, c, Q931_FACILITY, facility_ies);
-@@ -2463,7 +3124,6 @@
-               if ((info > 0x2) || (info < 0x00))
-                       return 0;
-       }
--
-       if (info >= 0)
-               c->notify = info & 0x7F;
-       else
-@@ -2506,6 +3166,8 @@
- int q931_call_proceeding(struct pri *pri, q931_call *c, int channel, int info)
- {
-+      // never send two PROCEEDINGs!
-+      if (c->proc > 0) return 0;              
-       if (channel) { 
-               c->ds1no = (channel & 0xff00) >> 8;
-               c->ds1explicit = (channel & 0x10000) >> 16;
-@@ -2532,8 +3194,12 @@
- static int alerting_ies[] = { -1 };
- #endif
-+static int alerting_BRI_ies[] = { -1 };
-+
- int q931_alerting(struct pri *pri, q931_call *c, int channel, int info)
- {
-+      // never send two ALERTINGs!
-+      if (c->alert > 0) return 0;             
-       if (!c->proc) 
-               q931_call_proceeding(pri, c, channel, 0);
-       if (info) {
-@@ -2544,14 +3210,130 @@
-               c->progressmask = 0;
-       c->ourcallstate = Q931_CALL_STATE_CALL_RECEIVED;
-       c->peercallstate = Q931_CALL_STATE_CALL_DELIVERED;
-+      c->alert = 1;
-       c->alive = 1;
--      return send_message(pri, c, Q931_ALERTING, alerting_ies);
-+      if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
-+          return send_message(pri, c, Q931_ALERTING, alerting_ies);
-+      } else {
-+          if ((pri->localtype == BRI_NETWORK) || (pri->localtype == BRI_NETWORK_PTMP)) {
-+              return send_message(pri, c, Q931_ALERTING, alerting_ies);
-+          } else {
-+              /* no PROGRESS_INDICATOR for BRI please */
-+              return send_message(pri, c, Q931_ALERTING, alerting_BRI_ies);
-+          }
-+      }
-+}
-+
-+static int hold_acknowledge_ies[] = { -1 };
-+
-+int q931_hold_acknowledge(struct pri *pri, q931_call *c)
-+{
-+      return send_message(pri, c, Q931_HOLD_ACKNOWLEDGE, hold_acknowledge_ies);
-+}
-+
-+static int hold_reject_ies[] = { Q931_CAUSE, -1 };
-+
-+int q931_hold_reject(struct pri *pri, q931_call *c)
-+{
-+      c->cause = 12;
-+      c->causecode = CODE_CCITT;
-+      c->causeloc = LOC_PRIV_NET_LOCAL_USER;
-+      return send_message(pri, c, Q931_HOLD_REJECT, hold_reject_ies);
-+}
-+
-+static int retrieve_acknowledge_ies[] = { Q931_CHANNEL_IDENT, -1 };
-+
-+int q931_retrieve_acknowledge(struct pri *pri, q931_call *c, int channel)
-+{
-+      if (channel)
-+              c->channelno = channel;
-+      c->chanflags &= ~FLAG_PREFERRED;
-+      c->chanflags |= FLAG_EXCLUSIVE;
-+      return send_message(pri, c, Q931_RETRIEVE_ACKNOWLEDGE, retrieve_acknowledge_ies);
-+}
-+
-+static int retrieve_reject_ies[] = { -1 };
-+
-+int q931_retrieve_reject(struct pri *pri, q931_call *c)
-+{
-+      return send_message(pri, c, Q931_RETRIEVE_REJECT, retrieve_reject_ies);
- }
--static int connect_ies[] = {  Q931_CHANNEL_IDENT, Q931_PROGRESS_INDICATOR, -1 };
-+static int suspend_acknowledge_ies[] = { Q931_DISPLAY, -1 };
-+
-+int q931_suspend_acknowledge(struct pri *pri, q931_call *c, char *display)
-+{
-+      char tempcallername[256];
-+      int res;
-+      c->ourcallstate = Q931_CALL_STATE_NULL;
-+      c->peercallstate = Q931_CALL_STATE_NULL;
-+      strncpy(tempcallername,c->callername,sizeof(tempcallername));
-+      strncpy(c->callername,display,sizeof(c->callername));
-+      res = send_message(pri, c, Q931_SUSPEND_ACKNOWLEDGE, suspend_acknowledge_ies);
-+      strncpy(c->callername,tempcallername,sizeof(c->callername));
-+      __q931_destroycall(pri, c);
-+      return res;
-+}
-+
-+static int suspend_reject_ies[] = { Q931_DISPLAY, Q931_CAUSE, -1 };
-+
-+int q931_suspend_reject(struct pri *pri, q931_call *c, char *display)
-+{
-+      char tempcallername[256];
-+      int res;
-+      strncpy(tempcallername,c->callername,sizeof(tempcallername));
-+      strncpy(c->callername,display,sizeof(c->callername));
-+      c->cause = 12;
-+      c->causecode = CODE_CCITT;
-+      c->causeloc = LOC_PRIV_NET_LOCAL_USER;
-+      res = send_message(pri, c, Q931_SUSPEND_REJECT, suspend_reject_ies);
-+      strncpy(c->callername,tempcallername,sizeof(c->callername));
-+      return res;
-+}
-+
-+static int resume_reject_ies[] = { Q931_CAUSE, Q931_DISPLAY,  -1 };
-+
-+int q931_resume_reject(struct pri *pri, q931_call *c, char *display)
-+{
-+      char tempcallername[256];
-+      int res;
-+      c->cause = 12;
-+      c->causecode = CODE_CCITT;
-+      c->causeloc = LOC_PRIV_NET_LOCAL_USER;
-+      strncpy(tempcallername,c->callername,sizeof(tempcallername));
-+      strncpy(c->callername,display,sizeof(c->callername));
-+      res = send_message(pri, c, Q931_RESUME_REJECT, resume_reject_ies);
-+      strncpy(c->callername,tempcallername,sizeof(c->callername));
-+      return res;
-+}
-+
-+static int resume_acknowledge_ies[] = { Q931_CHANNEL_IDENT, Q931_DISPLAY,  -1 };
-+
-+int q931_resume_acknowledge(struct pri *pri, q931_call *c, int channel, char *display)
-+{
-+      char tempcallername[256];
-+      int res;
-+      if (channel)
-+              c->channelno = channel;
-+      c->chanflags &= ~FLAG_PREFERRED;
-+      c->chanflags |= FLAG_EXCLUSIVE;
-+      c->alive = 1;
-+      c->ourcallstate = Q931_CALL_STATE_ACTIVE;
-+      c->peercallstate = Q931_CALL_STATE_ACTIVE;
-+      strncpy(tempcallername,c->callername,sizeof(tempcallername));
-+      strncpy(c->callername,display,sizeof(c->callername));
-+      res = send_message(pri, c, Q931_RESUME_ACKNOWLEDGE, resume_acknowledge_ies);
-+      strncpy(c->callername,tempcallername,sizeof(c->callername));
-+      return res;
-+}
-+
-+
-+static int connect_ies[] = {  Q931_CHANNEL_IDENT, Q931_PROGRESS_INDICATOR, Q931_DISPLAY, -1 };
-+static int connect_NET_ies[] = {  Q931_CHANNEL_IDENT, Q931_PROGRESS_INDICATOR, Q931_IE_TIME_DATE, -1 };
-  
- int q931_setup_ack(struct pri *pri, q931_call *c, int channel, int nonisdn)
- {
-+      int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP;
-       if (channel) { 
-               c->ds1no = (channel & 0xff00) >> 8;
-               c->ds1explicit = (channel & 0x10000) >> 16;
-@@ -2569,9 +3351,39 @@
-       c->ourcallstate = Q931_CALL_STATE_OVERLAP_RECEIVING;
-       c->peercallstate = Q931_CALL_STATE_OVERLAP_SENDING;
-       c->alive = 1;
-+      if (network) {
-+              c->progloc = LOC_PRIV_NET_LOCAL_USER;
-+              c->progcode = CODE_CCITT;
-+              c->progressmask = Q931_PROG_INBAND_AVAILABLE;
-+      }
-       return send_message(pri, c, Q931_SETUP_ACKNOWLEDGE, connect_ies);
- }
-+static void pri_setup_response_timeout(void *data)
-+{
-+      struct q931_call *c = data;
-+      struct pri *pri = NULL;
-+      if (!c) return;
-+      pri = c->pri;
-+      if (!pri) return;
-+      c->alive = 1;
-+      c->cause = PRI_CAUSE_NO_USER_RESPONSE;
-+      if (pri->debug & PRI_DEBUG_Q931_STATE)
-+              pri_message(pri, "No response to SETUP message\n");
-+      pri->schedev = 1;
-+      pri->ev.e = PRI_EVENT_HANGUP;
-+      pri->ev.hangup.channel = c->channelno;
-+      pri->ev.hangup.cref = c->cr;
-+      pri->ev.hangup.aoc_units = -1;
-+      if (c->cause == -1) {
-+          pri->ev.hangup.cause = PRI_CAUSE_SWITCH_CONGESTION;
-+      } else {
-+          pri->ev.hangup.cause = c->cause;
-+      }
-+      pri->ev.hangup.call = c;
-+      q931_hangup(pri, c, c->cause);
-+}
-+
- static void pri_connect_timeout(void *data)
- {
-       struct q931_call *c = data;
-@@ -2624,6 +3436,7 @@
- int q931_connect(struct pri *pri, q931_call *c, int channel, int nonisdn)
- {
-+      int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP;
-       if (channel) { 
-               c->ds1no = (channel & 0xff00) >> 8;
-               c->ds1explicit = (channel & 0x10000) >> 16;
-@@ -2638,22 +3451,37 @@
-               c->progressmask = PRI_PROG_CALLED_NOT_ISDN;
-       } else
-               c->progressmask = 0;
--      c->ourcallstate = Q931_CALL_STATE_CONNECT_REQUEST;
-+      if (network) {
-+              /* WE decide when the call is up and active */
-+              c->ourcallstate = Q931_CALL_STATE_ACTIVE;
-+      } else {
-+          c->ourcallstate = Q931_CALL_STATE_CONNECT_REQUEST;
-+      }
-       c->peercallstate = Q931_CALL_STATE_ACTIVE;
-       c->alive = 1;
-+      c->con_acked = 0;
-       /* Setup timer */
-       if (c->retranstimer)
-               pri_schedule_del(pri, c->retranstimer);
-       c->retranstimer = 0;
--      if ((pri->localtype == PRI_CPE) && (!pri->subchannel))
-+      if (!network && (!pri->subchannel)) {
-+              /* make sure that CPEs get a CONNECT_ACKNOWLEDGE */
-               c->retranstimer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T313], pri_connect_timeout, c);
--      return send_message(pri, c, Q931_CONNECT, connect_ies);
-+      }
-+      if ((pri->localtype != PRI_CPE) && (pri->localtype != BRI_CPE) && (pri->localtype != BRI_CPE_PTMP)) {
-+          // networks may send datetime
-+          return send_message(pri, c, Q931_CONNECT, connect_NET_ies);
-+      } else {
-+          return send_message(pri, c, Q931_CONNECT, connect_ies);
-+      }
- }
-+static int release_aoce_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, Q931_IE_FACILITY, -1 };
- static int release_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, -1 };
- int q931_release(struct pri *pri, q931_call *c, int cause)
- {
-+      int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP;
-       c->ourcallstate = Q931_CALL_STATE_RELEASE_REQUEST;
-       /* c->peercallstate stays the same */
-       if (c->alive) {
-@@ -2669,7 +3497,14 @@
-                       } else {
-                               c->retranstimer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T308], pri_release_finaltimeout, c);
-                       }
--                      return send_message(pri, c, Q931_RELEASE, release_ies);
-+                      if (network && (c->aoc_units > -1)) {
-+                          /* include FACILITY IE for AOC-E */
-+                          aoc_aoce_charging_unit_encode(pri, c , c->aoc_units, Q931_RELEASE);
-+                          c->aoc_units = -1;
-+                          return send_message(pri, c, Q931_RELEASE, release_aoce_ies);
-+                      } else {
-+                          return send_message(pri, c, Q931_RELEASE, release_ies);
-+                      }
-               } else
-                       return send_message(pri, c, Q931_RELEASE_COMPLETE, release_ies); /* Yes, release_ies, not release_complete_ies */
-       } else
-@@ -2681,7 +3516,7 @@
- int q931_restart(struct pri *pri, int channel)
- {
-       struct q931_call *c;
--      c = q931_getcall(pri, 0 | 0x8000);
-+      c = q931_getcall(pri, 0 | 0x8000, 0);
-       if (!c)
-               return -1;
-       if (!channel)
-@@ -2698,10 +3533,12 @@
-       return send_message(pri, c, Q931_RESTART, restart_ies);
- }
-+static int disconnect_aoce_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, Q931_IE_FACILITY, -1 };
- static int disconnect_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, -1 };
- int q931_disconnect(struct pri *pri, q931_call *c, int cause)
- {
-+      int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP;
-       c->ourcallstate = Q931_CALL_STATE_DISCONNECT_REQUEST;
-       c->peercallstate = Q931_CALL_STATE_DISCONNECT_INDICATION;
-       if (c->alive) {
-@@ -2713,14 +3550,27 @@
-               if (c->retranstimer)
-                       pri_schedule_del(pri, c->retranstimer);
-               c->retranstimer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T305], pri_disconnect_timeout, c);
--              return send_message(pri, c, Q931_DISCONNECT, disconnect_ies);
-+              if (network && (c->aoc_units > -1)) {
-+                  /* include FACILITY IE for AOC-E */
-+                  aoc_aoce_charging_unit_encode(pri, c , c->aoc_units, Q931_DISCONNECT);
-+                  c->aoc_units = -1;
-+                  return send_message(pri, c, Q931_DISCONNECT, disconnect_aoce_ies);
-+              } else {
-+                  return send_message(pri, c, Q931_DISCONNECT, disconnect_ies);
-+              }
-       } else
-               return 0;
- }
-+//static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_DISPLAY, Q931_PROGRESS_INDICATOR,
-+//     Q931_IE_SIGNAL, Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_SENDING_COMPLETE, -1 };
-+
- static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY, Q931_IE_USER_USER,
-       Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, -1 };
-+static int setup_bri_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY, Q931_IE_USER_USER,
-+      Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, Q931_HIGH_LAYER_COMPAT, Q931_LOW_LAYER_COMPAT, -1 };
-+
- static int gr303_setup_ies[] =  { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, -1 };
- static int cis_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_CALLED_PARTY_NUMBER, -1 };
-@@ -2728,7 +3578,12 @@
- int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req)
- {
-       int res;
--      
-+
-+      if (pri->localtype == BRI_NETWORK_PTMP) {
-+          c->tei = 127;
-+      } else {
-+          c->tei = 0;
-+      }
-       
-       c->transcapability = req->transmode;
-       c->transmoderate = TRANS_MODE_64_CIRCUIT;
-@@ -2753,6 +3608,7 @@
-               c->chanflags = FLAG_EXCLUSIVE;
-       else if (c->channelno)
-               c->chanflags = FLAG_PREFERRED;
-+      memcpy(c->llc, req->llc, sizeof(c->llc));
-       if (req->caller) {
-               libpri_copy_string(c->callernum, req->caller, sizeof(c->callernum));
-               c->callerplan = req->callerplan;
-@@ -2812,14 +3668,19 @@
-               res = send_message(pri, c, Q931_SETUP, gr303_setup_ies);
-       else if (c->justsignalling)
-               res = send_message(pri, c, Q931_SETUP, cis_setup_ies);
-+      else if (pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP) 
-+              res = send_message(pri, c, Q931_SETUP, setup_bri_ies);
-       else
-               res = send_message(pri, c, Q931_SETUP, setup_ies);
-+
-       if (!res) {
-               c->alive = 1;
-               /* make sure we call PRI_EVENT_HANGUP_ACK once we send/receive RELEASE_COMPLETE */
-               c->sendhangupack = 1;
-               c->ourcallstate = Q931_CALL_STATE_CALL_INITIATED;
-               c->peercallstate = Q931_CALL_STATE_OVERLAP_SENDING;     
-+              c->t303timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T303], pri_setup_response_timeout, c);
-+              c->t303running = 1;
-       }
-       return res;
-       
-@@ -2835,7 +3696,11 @@
-       if (cause > -1) {
-               c->cause = cause;
-               c->causecode = CODE_CCITT;
--              c->causeloc = LOC_PRIV_NET_LOCAL_USER;
-+              if ((pri->localtype == PRI_NETWORK) || (pri->localtype == BRI_NETWORK) || (pri->localtype == BRI_NETWORK_PTMP)) {
-+                  c->causeloc = LOC_PRIV_NET_LOCAL_USER;
-+              } else {
-+                  c->causeloc = LOC_USER;
-+              }
-               /* release_ies has CAUSE in it */
-               res = send_message(pri, c, Q931_RELEASE_COMPLETE, release_ies);
-       } else
-@@ -2860,6 +3725,125 @@
-       return 0;
- }
-+/* here we cleanly hangup the phones that responded to our call but didnt get the call  */
-+int q921_hangup(struct pri *pri, q931_call *c, int tei)
-+{
-+ q921_call *cur,*prev;
-+ int tc;
-+ int ttei;
-+ int res=0;
-+
-+ if (!pri || !c)
-+    return -1;
-+ 
-+ if (pri->localtype != BRI_NETWORK_PTMP){
-+      return 0;
-+ }
-+//    pri_error(pri, "q921_hangup(%d, %d)\n", c->cr, tei);
-+
-+ if (tei == 127) {
-+      tei = c->tei;
-+ }
-+//    pri_error(pri, "tei %d\n", tei);
-+
-+ cur = c->phones;
-+ 
-+ tc = c->cause;
-+ ttei = c->tei;
-+ while (cur) {
-+      if (cur->tei != tei) {
-+          c->cause = PRI_CAUSE_NORMAL_CLEARING;
-+          c->tei = cur->tei;
-+          if (pri->debug & PRI_DEBUG_Q921_STATE)
-+              pri_message(pri, "sending RELEASE for TEI %d\n", cur->tei);
-+          send_message(pri, c, Q931_RELEASE, release_ies);
-+      }
-+      prev = cur;
-+      cur = cur->next;
-+      if (prev) {
-+          free(prev);
-+          prev = NULL;
-+      }
-+ }
-+     c->phones = NULL;
-+     c->tei = ttei;
-+     c->cause = tc;
-+
-+ if (c->tei == 127) {
-+      q931_destroycall(pri, c->cr, c->tei);
-+      // make sure * frees the channel
-+/*    pri_error(pri, "returning PRI_EVENT_HANGUP_ACK\n");
-+      res = Q931_RES_HAVEEVENT;
-+      pri->ev.hangup.channel = c->channelno;
-+      pri->ev.e = PRI_EVENT_HANGUP_ACK;   */
-+ } 
-+ return res; 
-+}
-+
-+/* here we handle release_completes from the phones 
-+    because some (elmeg) phones do not send a disconnect
-+    message when the phone is busy */
-+int q921_handle_hangup(struct pri *pri, q931_call *c, int tei)
-+{
-+     q921_call *cur,*match,*prev=NULL;
-+     int left=0;
-+     int res=0;
-+     
-+     if (!pri || !c)
-+      return -1;
-+ 
-+     if (pri->localtype != BRI_NETWORK_PTMP){
-+      return 0;
-+     }
-+ 
-+     cur = c->phones;
-+     
-+     while (cur) {
-+      if (cur->tei == tei) {
-+          match = cur;
-+          if (prev) {
-+              prev->next = cur->next;
-+              cur = prev;
-+          } else {
-+              c->phones = cur->next;
-+          }
-+          free(match);
-+      }
-+      prev = cur;
-+      if (cur) cur = cur->next;
-+     }
-+ 
-+     cur = c->phones;
-+     
-+     while (cur) {
-+      left++;
-+      cur = cur->next;
-+     }
-+     
-+     // if all phones have signalled busy AND the timer is not running anymore!
-+#ifdef FASTBUSYONBUSY
-+    if ((c->cause == PRI_CAUSE_USER_BUSY) && (c->t303timer)) {
-+          c->t303running = 0;
-+          pri_schedule_del(pri, c->t303timer);
-+    }
-+#endif
-+
-+     if ((left==0) && (c->cause == PRI_CAUSE_USER_BUSY) && (c->t303running == 0)) {
-+ //   pri_error(pri, "q921_handle_hangup(%d, %d, %d)\n", c->cr, tei, c->tei);
-+      // make sure * frees the channel
-+      res = Q931_RES_HAVEEVENT;
-+      pri->ev.hangup.cause = PRI_CAUSE_USER_BUSY;
-+      pri->ev.hangup.channel = c->channelno | (c->ds1no << 8);
-+      pri->ev.hangup.cref = c->cr;                    
-+      pri->ev.hangup.call = c;
-+      pri->ev.hangup.aoc_units = 0;
-+      pri->ev.e = PRI_EVENT_HANGUP; 
-+     } 
-+     return res; 
-+ }
-+
-+ 
-+
- int q931_hangup(struct pri *pri, q931_call *c, int cause)
- {
-       int disconnect = 1;
-@@ -2871,7 +3855,7 @@
-       /* If mandatory IE was missing, insist upon that cause code */
-       if (c->cause == PRI_CAUSE_MANDATORY_IE_MISSING)
-               cause = c->cause;
--      if (cause == 34 || cause == 44 || cause == 82 || cause == 1 || cause == 81) {
-+      if (cause == 34 || cause == 44 || cause == 82 || cause == 1 || cause == 81 || cause == 17) {
-               /* We'll send RELEASE_COMPLETE with these causes */
-               disconnect = 0;
-               release_compl = 1;
-@@ -2885,7 +3869,7 @@
-       case Q931_CALL_STATE_NULL:
-               if (c->peercallstate == Q931_CALL_STATE_NULL)
-                       /* free the resources if we receive or send REL_COMPL */
--                      q931_destroycall(pri, c->cr);
-+                      q931_destroycall(pri, c->cr, c->tei);
-               else if (c->peercallstate == Q931_CALL_STATE_RELEASE_REQUEST)
-                       q931_release_complete(pri,c,cause);
-               break;
-@@ -2911,6 +3895,11 @@
-               /* received SETUP_ACKNOWLEDGE */
-               /* send DISCONNECT in general */
-               if (c->peercallstate != Q931_CALL_STATE_NULL && c->peercallstate != Q931_CALL_STATE_DISCONNECT_REQUEST && c->peercallstate != Q931_CALL_STATE_DISCONNECT_INDICATION && c->peercallstate != Q931_CALL_STATE_RELEASE_REQUEST && c->peercallstate != Q931_CALL_STATE_RESTART_REQUEST && c->peercallstate != Q931_CALL_STATE_RESTART) {
-+                      if (pri->localtype == BRI_NETWORK_PTMP) {
-+                          if (c->tei == 127) {
-+                              break;
-+                          }
-+                      } 
-                       if (disconnect)
-                               q931_disconnect(pri,c,cause);
-                       else if (release_compl)
-@@ -2926,8 +3915,14 @@
-               break;
-       case Q931_CALL_STATE_DISCONNECT_INDICATION:
-               /* received DISCONNECT */
-+              if (pri->localtype == BRI_NETWORK_PTMP) {
-+                  if (c->tei == 127) {
-+                      break;
-+                  }
-+              } 
-               if (c->peercallstate == Q931_CALL_STATE_DISCONNECT_REQUEST) {
-                       c->alive = 1;
-+//                pri_error(pri, "sending release to %d\n", c->tei);
-                       q931_release(pri,c,cause);
-               }
-               break;
-@@ -2941,19 +3936,17 @@
-               pri_error(pri, "q931_hangup shouldn't be called in this state, ourstate %s, peerstate %s\n",callstate2str(c->ourcallstate),callstate2str(c->peercallstate));
-               break;
-       default:
--              pri_error(pri, "We're not yet handling hanging up when our state is %d, contact support@digium.com, ourstate %s, peerstate %s\n",
--                        c->ourcallstate,
--                        callstate2str(c->ourcallstate),
--                        callstate2str(c->peercallstate));
-+              pri_error(pri, "We're not yet handling hanging up when our state is %d, contact support@digium.com, ourstate %s, peerstate %s\n",callstate2str(c->ourcallstate),callstate2str(c->peercallstate));
-               return -1;
-       }
-       /* we did handle hangup properly at this point */
-       return 0;
- }
--int q931_receive(struct pri *pri, q931_h *h, int len)
-+int q931_receive(struct pri *pri, q931_h *h, int len, int tei)
- {
-       q931_mh *mh;
-+      q921_call *l2c;
-       q931_call *c;
-       q931_ie *ie;
-       unsigned int x;
-@@ -2965,6 +3958,7 @@
-       int codeset, cur_codeset;
-       int last_ie[8];
-       struct apdu_event *cur = NULL;
-+      int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP;
-       memset(last_ie, 0, sizeof(last_ie));
-       if (pri->debug & PRI_DEBUG_Q931_DUMP)
-@@ -2978,13 +3972,13 @@
-                  KLUDGE this by changing byte 4 from a 0xf (SERVICE) 
-                  to a 0x7 (SERVICE ACKNOWLEDGE) */
-               h->raw[h->crlen + 2] -= 0x8;
--              q931_xmit(pri, h, len, 1);
-+              q931_xmit(pri, h, len, 1, tei);
-               return 0;
-       } else if (h->pd != pri->protodisc) {
-               pri_error(pri, "Warning: unknown/inappropriate protocol discriminator received (%02x/%d)\n", h->pd, h->pd);
-               return 0;
-       }
--      c = q931_getcall(pri, q931_cr(h));
-+      c = q931_getcall(pri, q931_cr(h), tei);
-       if (!c) {
-               pri_error(pri, "Unable to locate call %d\n", q931_cr(h));
-               return -1;
-@@ -3007,6 +4001,7 @@
-       case Q931_SETUP:
-               if (pri->debug & PRI_DEBUG_Q931_STATE)
-                       pri_message(pri, "-- Processing Q.931 Call Setup\n");
-+              c->tei = tei;
-               c->channelno = -1;
-               c->slotmap = -1;
-               c->chanflags = 0;
-@@ -3027,28 +4022,44 @@
-               c->callername[0] = '\0';
-               c->callerani[0] = '\0';
-               c->callerplanani = -1;
--              c->redirectingplan = -1;
--              c->redirectingpres = -1;
--              c->redirectingreason = -1;
--              c->origcalledplan = -1;
--              c->origcalledpres = -1;
--              c->origredirectingreason = -1;
-+                c->redirectingplan = -1;
-+                c->redirectingpres = -1;
-+                c->redirectingreason = -1;
-+                c->origcalledplan = -1;
-+                c->origcalledpres = -1;
-+                c->origredirectingreason = -1;
-               c->redirectingnum[0] = '\0';
-               c->origcallednum[0] = '\0';
-               c->redirectingname[0] = '\0';
-               c->origcalledname[0] = '\0';
--              c->useruserprotocoldisc = -1; 
-+                c->useruserprotocoldisc = -1; 
-               c->useruserinfo[0] = '\0';
-               c->complete = 0;
-               c->nonisdn = 0;
-               c->aoc_units = -1;
--              /* Fall through */
-+              c->digits[0] = '\0';
-+              c->display[0] = '\0';
-+              c->progress = -1;
-+              c->progressmask = 0;
-+              break;
-       case Q931_CONNECT:
-+              if (c->t303timer) {
-+                  c->t303running = 0;
-+                  pri_schedule_del(pri, c->t303timer);
-+              }
-+              c->useruserinfo[0] = '\0';
-+              c->t303timer = 0;
-+              c->progress = -1;
-+              break;
-       case Q931_ALERTING:
-       case Q931_PROGRESS:
--              c->useruserinfo[0] = '\0';
--              c->cause = -1;
-+              c->useruserinfo[0] = '\0';
-       case Q931_CALL_PROCEEDING:
-+              if (c->t303timer) {
-+                  c->t303running = 0;
-+                  pri_schedule_del(pri, c->t303timer);
-+              }
-+              c->t303timer = 0;
-               c->progress = -1;
-               c->progressmask = 0;
-               break;
-@@ -3059,20 +4070,22 @@
-               break;
-       case Q931_RELEASE:
-       case Q931_DISCONNECT:
--              c->cause = -1;
--              c->causecode = -1;
--              c->causeloc = -1;
--              c->aoc_units = -1;
-+//            c->aoc_units = -1;
-+              c->useruserinfo[0] = '\0';
-               if (c->retranstimer)
-                       pri_schedule_del(pri, c->retranstimer);
-               c->retranstimer = 0;
--              c->useruserinfo[0] = '\0';
-+              if (c->t303timer) {
-+                  c->t303running = 0;
-+                  pri_schedule_del(pri, c->t303timer);
-+              }
-+              c->t303timer = 0;
-               break;
-       case Q931_RELEASE_COMPLETE:
-               if (c->retranstimer)
--                      pri_schedule_del(pri, c->retranstimer);
-+                  pri_schedule_del(pri, c->retranstimer);
-               c->retranstimer = 0;
--              c->useruserinfo[0] = '\0';
-+              c->useruserinfo[0] = '\0';
-       case Q931_STATUS:
-               c->cause = -1;
-               c->causecode = -1;
-@@ -3089,22 +4102,32 @@
-       case Q931_STATUS_ENQUIRY:
-               break;
-       case Q931_SETUP_ACKNOWLEDGE:
-+              if (c->t303timer) {
-+                  c->t303running = 0;
-+                  pri_schedule_del(pri, c->t303timer);
-+              }
-+              c->t303timer = 0;
-               break;
-       case Q931_NOTIFY:
-               break;
-+      case Q931_HOLD:
-+              break;
-+      case Q931_RETRIEVE:
-+              break;
-+      case Q931_RESUME:
-+              c->tei = tei;
-+              break;
-+      case Q931_SUSPEND:
-+              break;
-       case Q931_USER_INFORMATION:
-       case Q931_SEGMENT:
-       case Q931_CONGESTION_CONTROL:
--      case Q931_HOLD:
-       case Q931_HOLD_ACKNOWLEDGE:
-       case Q931_HOLD_REJECT:
--      case Q931_RETRIEVE:
-       case Q931_RETRIEVE_ACKNOWLEDGE:
-       case Q931_RETRIEVE_REJECT:
--      case Q931_RESUME:
-       case Q931_RESUME_ACKNOWLEDGE:
-       case Q931_RESUME_REJECT:
--      case Q931_SUSPEND:
-       case Q931_SUSPEND_ACKNOWLEDGE:
-       case Q931_SUSPEND_REJECT:
-               pri_error(pri, "!! Not yet handling pre-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg);
-@@ -3113,7 +4136,7 @@
-               pri_error(pri, "!! Don't know how to post-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg);
-               q931_status(pri,c, PRI_CAUSE_MESSAGE_TYPE_NONEXIST);
-               if (c->newcall) 
--                      q931_destroycall(pri,c->cr);
-+                      q931_destroycall(pri,c->cr,c->tei);
-               return -1;
-       }
-       memset(mandies, 0, sizeof(mandies));
-@@ -3193,12 +4216,19 @@
-       missingmand = 0;
-       for (x=0;x<MAX_MAND_IES;x++) {
-               if (mandies[x]) {
--                      /* check if there is no channel identification when we're configured as network -> that's not an error */
--                      if (((pri->localtype != PRI_NETWORK) || (mh->msg != Q931_SETUP) || (mandies[x] != Q931_CHANNEL_IDENT)) &&
--                           ((mh->msg != Q931_PROGRESS) || (mandies[x] != Q931_PROGRESS_INDICATOR))) {
--                              pri_error(pri, "XXX Missing handling for mandatory IE %d (cs%d, %s) XXX\n", Q931_IE_IE(mandies[x]), Q931_IE_CODESET(mandies[x]), ie2str(mandies[x]));
--                              missingmand++;
-+                  /* check if there is no channel identification when we're configured as network -> that's not an error */
-+                  if (network) {
-+                      if (((mh->msg == Q931_SETUP) && (mandies[x] == Q931_CHANNEL_IDENT)) ||
-+                           ((mh->msg == Q931_PROGRESS) && (mandies[x] == Q931_PROGRESS_INDICATOR))) {
-+                          /* according to ets 300 102-1 a progress indicator is mandatory, but so what? ;-)  */
-+                      } else {
-+                          pri_error(pri, "XXX Missing handling for mandatory IE %d (cs%d, %s) XXX\n", Q931_IE_IE(mandies[x]), Q931_IE_CODESET(mandies[x]), ie2str(mandies[x]));
-+                          missingmand++;
-                       }
-+                  } else {
-+                      pri_error(pri, "XXX Missing handling for mandatory IE %d (cs%d, %s) XXX\n", Q931_IE_IE(mandies[x]), Q931_IE_CODESET(mandies[x]), ie2str(mandies[x]));
-+                      missingmand++;
-+                  }
-               }
-       }
-       
-@@ -3207,7 +4237,7 @@
-       case Q931_RESTART:
-               if (missingmand) {
-                       q931_status(pri, c, PRI_CAUSE_MANDATORY_IE_MISSING);
--                      q931_destroycall(pri, c->cr);
-+                      q931_destroycall(pri, c->cr, c->tei);
-                       break;
-               }
-               c->ourcallstate = Q931_CALL_STATE_RESTART;
-@@ -3225,6 +4255,7 @@
-               }
-               /* Must be new call */
-               if (!c->newcall) {
-+                      pri_error(pri, "received SETUP message for call that is not a new call (retransmission). \n");
-                       break;
-               }
-               if (c->progressmask & PRI_PROG_CALLER_NOT_ISDN)
-@@ -3242,16 +4273,20 @@
-               pri->ev.ring.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
-               pri->ev.ring.callingpres = c->callerpres;
-               pri->ev.ring.callingplan = c->callerplan;
--              pri->ev.ring.callingplanani = c->callerplanani;
-               pri->ev.ring.callingplanrdnis = c->redirectingplan;
-               pri->ev.ring.callingplanorigcalled = c->origcalledplan;
-               pri->ev.ring.ani2 = c->ani2;
-               libpri_copy_string(pri->ev.ring.callingani, c->callerani, sizeof(pri->ev.ring.callingani));
-+              pri->ev.ring.callingplanani = c->callerplanani;
-               libpri_copy_string(pri->ev.ring.callingnum, c->callernum, sizeof(pri->ev.ring.callingnum));
-               libpri_copy_string(pri->ev.ring.callingname, c->callername, sizeof(pri->ev.ring.callingname));
-               pri->ev.ring.calledplan = c->calledplan;
-               libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr));
--              libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum));
-+              if (!strlen(c->callednum) && strlen(c->digitbuf)) {
-+                  libpri_copy_string(pri->ev.ring.callednum, c->digitbuf, sizeof(pri->ev.ring.callednum));
-+              } else {
-+                  libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum));
-+              }
-               libpri_copy_string(pri->ev.ring.origcalledname, c->origcalledname, sizeof(pri->ev.ring.origcalledname));
-               libpri_copy_string(pri->ev.ring.origcallednum, c->origcallednum, sizeof(pri->ev.ring.origcallednum));
-                 libpri_copy_string(pri->ev.ring.redirectingnum, c->redirectingnum, sizeof(pri->ev.ring.redirectingnum));
-@@ -3261,11 +4296,13 @@
-               pri->ev.ring.redirectingreason = c->redirectingreason;
-               pri->ev.ring.origredirectingreason = c->origredirectingreason;
-               pri->ev.ring.flexible = ! (c->chanflags & FLAG_EXCLUSIVE);
--              pri->ev.ring.cref = c->cr;
-+              pri->ev.ring.tei = c->tei;
-               pri->ev.ring.call = c;
-+              pri->ev.ring.cref = c->cr;
-               pri->ev.ring.layer1 = c->userl1;
-               pri->ev.ring.complete = c->complete; 
-               pri->ev.ring.ctype = c->transcapability;
-+              memcpy(pri->ev.ring.lowlayercompat, c->llc, sizeof(pri->ev.ring.lowlayercompat));
-               pri->ev.ring.redirectingreason = c->redirectingreason;
-               pri->ev.ring.progress = c->progress;
-               pri->ev.ring.progressmask = c->progressmask;
-@@ -3275,6 +4312,9 @@
-                       q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
-                       break;
-               }
-+              if (pri->localtype == BRI_NETWORK_PTMP) {
-+                  l2c = q921_getcall(pri, c, tei);
-+              }
-               c->ourcallstate = Q931_CALL_STATE_CALL_DELIVERED;
-               c->peercallstate = Q931_CALL_STATE_CALL_RECEIVED;
-               pri->ev.e = PRI_EVENT_RINGING;
-@@ -3295,17 +4335,24 @@
-                       q931_status(pri, c, PRI_CAUSE_WRONG_MESSAGE);
-                       break;
-               }
-+              /* TEI got the call */
-+              c->tei = tei;
-               c->ourcallstate = Q931_CALL_STATE_ACTIVE;
-               c->peercallstate = Q931_CALL_STATE_CONNECT_REQUEST;
-               pri->ev.e = PRI_EVENT_ANSWER;
-               pri->ev.answer.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
-               pri->ev.answer.cref = c->cr;
-               pri->ev.answer.call = c;
-+              pri->ev.answer.tei = c->tei;
-               pri->ev.answer.progress = c->progress;
-               pri->ev.answer.progressmask = c->progressmask;
-                 libpri_copy_string(pri->ev.answer.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo));
-               c->useruserinfo[0] = '\0';
-               q931_connect_acknowledge(pri, c);
-+              if (pri->localtype == BRI_NETWORK_PTMP) {
-+                  /* Release all other TEIs */
-+                  q921_hangup(pri, c, tei);
-+              }
-               if (c->justsignalling) {  /* Make sure WE release when we initiatie a signalling only connection */
-                       q931_release(pri, c, PRI_CAUSE_NORMAL_CLEARING);
-                       break;
-@@ -3313,23 +4360,43 @@
-                       return Q931_RES_HAVEEVENT;
-       case Q931_FACILITY:
-               if (c->newcall) {
--                      q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
--                      break;
--              }
--              pri->ev.e = PRI_EVENT_FACNAME;
--              libpri_copy_string(pri->ev.facname.callingname, c->callername, sizeof(pri->ev.facname.callingname));
--              libpri_copy_string(pri->ev.facname.callingnum, c->callernum, sizeof(pri->ev.facname.callingnum));
--              pri->ev.facname.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
--              pri->ev.facname.cref = c->cr;
--              pri->ev.facname.call = c;
--#if 0
--              pri_message(pri, "Sending facility event (%s/%s)\n", pri->ev.facname.callingname, pri->ev.facname.callingnum);
--#endif
-+                      if ((pri->localtype == PRI_CPE) || (pri->localtype == PRI_NETWORK)) {
-+                          q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
-+                      } else {
-+                          // BRI uses the dummy cref for sservices like ccnr
-+                      }
-+                      break;
-+              }
-+              if (c->facility > 0) {
-+                  pri->ev.e = PRI_EVENT_FACILITY;
-+                  pri->ev.facility.channel = c->channelno | (c->ds1no << 8);
-+                  pri->ev.facility.cref = c->cr;
-+                  pri->ev.facility.tei = c->tei;
-+                  pri->ev.facility.call = c; 
-+                  switch (c->facility) {
-+                      case 0x06: /* ECT execute */
-+                              pri->ev.facility.operation = 0x06; 
-+                          break;
-+                      case 0x0D: /* CD */
-+                              pri->ev.facility.operation = 0x0D; 
-+                              libpri_copy_string(pri->ev.facility.forwardnum, c->redirectingnum,  sizeof(pri->ev.facility.forwardnum));
-+                          break;
-+                      default:
-+                              pri->ev.facility.operation = c->facility; 
-+                  }
-+              } else {
-+                  pri->ev.e = PRI_EVENT_FACNAME;
-+                  libpri_copy_string(pri->ev.facname.callingname, c->callername, sizeof(pri->ev.facname.callingname));
-+                  libpri_copy_string(pri->ev.facname.callingnum, c->callernum, sizeof(pri->ev.facname.callingname));
-+                  pri->ev.facname.channel = c->channelno | (c->ds1no << 8);
-+                  pri->ev.facname.cref = c->cr;
-+                  pri->ev.facname.call = c; 
-+              }
-               return Q931_RES_HAVEEVENT;
-       case Q931_PROGRESS:
-               if (missingmand) {
-                       q931_status(pri, c, PRI_CAUSE_MANDATORY_IE_MISSING);
--                      q931_destroycall(pri, c->cr);
-+                      q931_destroycall(pri, c->cr, c->tei);
-                       break;
-               }
-               pri->ev.e = PRI_EVENT_PROGRESS;
-@@ -3347,6 +4414,11 @@
-                       q931_status(pri,c,PRI_CAUSE_WRONG_MESSAGE);
-                       break;
-               }
-+              if (pri->localtype == BRI_NETWORK_PTMP) {
-+                  l2c = q921_getcall(pri, c, tei);
-+                  l2c->proc = 1;
-+                  l2c->channel = c->channelno;
-+              }
-               pri->ev.proceeding.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
-               if (mh->msg == Q931_CALL_PROCEEDING) {
-                       pri->ev.e = PRI_EVENT_PROCEEDING;
-@@ -3364,16 +4436,21 @@
-                       break;
-               }
-               if (c->ourcallstate != Q931_CALL_STATE_CONNECT_REQUEST) {
-+                  if ((c->ourcallstate == Q931_CALL_STATE_ACTIVE) && (c->con_acked == 0) && (network)) {
-+                      /* sending a CONNECT_ACKNOWLEDGE is optional for CPEs */
-+                  } else {
-                       q931_status(pri,c,PRI_CAUSE_WRONG_MESSAGE);
--                      break;
-+                  }
-+                  break;
-               }
-               c->ourcallstate = Q931_CALL_STATE_ACTIVE;
-               c->peercallstate = Q931_CALL_STATE_ACTIVE;
-+              c->con_acked = 1;
-               break;
-       case Q931_STATUS:
-               if (missingmand) {
-                       q931_status(pri, c, PRI_CAUSE_MANDATORY_IE_MISSING);
--                      q931_destroycall(pri, c->cr);
-+                      q931_destroycall(pri, c->cr, c->tei);
-                       break;
-               }
-               if (c->newcall) {
-@@ -3410,31 +4487,70 @@
-                       if (res)
-                               return res;
-               }
--              break;
-+              if (c->peercallstate != c->sugcallstate) {
-+                  pri_error(pri, "updating callstate, peercallstate %d to %d\n", c->peercallstate, c->sugcallstate);
-+//                c->peercallstate = c->sugcallstate;
-+                  c->ourcallstate = c->sugcallstate;
-+                  if (c->sugcallstate != Q931_CALL_STATE_ACTIVE) {
-+                        /* pass hangup to upper layer! */
-+                        if (c->alive) {
-+                                pri->ev.e = PRI_EVENT_HANGUP;
-+                                res = Q931_RES_HAVEEVENT;
-+                                c->alive = 0;
-+                        } else if (c->sendhangupack) {
-+                                res = Q931_RES_HAVEEVENT;
-+                                pri->ev.e = PRI_EVENT_HANGUP_ACK;
-+                                q931_hangup(pri, c, c->cause);
-+                        } else {
-+                                q931_hangup(pri, c, c->cause);
-+                                res = 0;
-+                      if (res)
-+                              return res;
-+                        }
-+                  }
-+                }
-+                break;
-       case Q931_RELEASE_COMPLETE:
--              c->ourcallstate = Q931_CALL_STATE_NULL;
--              c->peercallstate = Q931_CALL_STATE_NULL;
--              pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
--              pri->ev.hangup.cref = c->cr;                    
--              pri->ev.hangup.cause = c->cause;                
--              pri->ev.hangup.call = c;                        
--                libpri_copy_string(pri->ev.hangup.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo));
--              c->useruserinfo[0] = '\0';
--              /* Free resources */
--              if (c->alive) {
--                      pri->ev.e = PRI_EVENT_HANGUP;
--                      res = Q931_RES_HAVEEVENT;
--                      c->alive = 0;
--              } else if (c->sendhangupack) {
--                      res = Q931_RES_HAVEEVENT;
--                      pri->ev.e = PRI_EVENT_HANGUP_ACK;
--                      pri_hangup(pri, c, c->cause);
--              } else
--                      res = 0;
--              if (res)
--                      return res;
--              else
--                      q931_hangup(pri,c,c->cause);
-+              if (pri->localtype != BRI_NETWORK_PTMP) {
-+                  /* only stop the T303 timer if WE are not a BRI PTMP network */
-+                  if (c->t303timer) {
-+                      c->t303running = 0;
-+                      pri_schedule_del(pri, c->t303timer);
-+                      c->t303timer = 0;
-+                  }
-+              }
-+
-+              if ((pri->localtype != BRI_NETWORK_PTMP) || (c->tei == tei)) {
-+                  c->ourcallstate = Q931_CALL_STATE_NULL;
-+                  c->peercallstate = Q931_CALL_STATE_NULL;
-+                  pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
-+                  pri->ev.hangup.cref = c->cr;                        
-+                  pri->ev.hangup.cause = c->cause;                    
-+                  pri->ev.hangup.call = c;                            
-+                  libpri_copy_string(pri->ev.hangup.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo));
-+                  c->useruserinfo[0] = '\0';
-+                  /* Free resources */
-+                  if (c->alive) {
-+                      pri->ev.e = PRI_EVENT_HANGUP;
-+                      res = Q931_RES_HAVEEVENT;
-+                      c->alive = 0;
-+                  } else if (c->sendhangupack) {
-+                      res = Q931_RES_HAVEEVENT;
-+                      pri->ev.e = PRI_EVENT_HANGUP_ACK;
-+                      pri_hangup(pri, c, c->cause, -1);
-+                  } else
-+                      res = 0;
-+                  if (res)
-+                      return res;
-+                  else
-+                      q931_hangup(pri,c,c->cause);
-+              } else {
-+                  // BRI_NET_PTMP
-+                  // ignoring relase_complete
-+                  res = q921_handle_hangup(pri,c,tei);
-+                  if (res)
-+                      return res;
-+              }
-               break;
-       case Q931_RELEASE:
-               if (missingmand) {
-@@ -3450,6 +4566,7 @@
-               pri->ev.e = PRI_EVENT_HANGUP;
-               pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
-               pri->ev.hangup.cref = c->cr;
-+              pri->ev.hangup.tei = c->tei;
-               pri->ev.hangup.cause = c->cause;
-               pri->ev.hangup.call = c;
-               pri->ev.hangup.aoc_units = c->aoc_units;
-@@ -3478,9 +4595,16 @@
-               pri->ev.e = PRI_EVENT_HANGUP_REQ;
-               pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
-               pri->ev.hangup.cref = c->cr;
-+              pri->ev.hangup.tei = c->tei;
-               pri->ev.hangup.cause = c->cause;
-               pri->ev.hangup.call = c;
-               pri->ev.hangup.aoc_units = c->aoc_units;
-+              if (c->progressmask & PRI_PROG_INBAND_AVAILABLE) {
-+                  pri->ev.hangup.inband_progress = 1;
-+              } else {
-+                  pri->ev.hangup.inband_progress = 0;
-+              }
-+              pri->ev.hangup.aoc_units = c->aoc_units;
-               if (c->alive)
-                       return Q931_RES_HAVEEVENT;
-               else
-@@ -3511,7 +4635,7 @@
-               pri->ev.e = PRI_EVENT_INFO_RECEIVED;
-               pri->ev.ring.call = c;
-               pri->ev.ring.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
--              libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum));
-+              libpri_copy_string(pri->ev.ring.callednum, c->digits, sizeof(pri->ev.ring.callednum) );
-               libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr));
-               pri->ev.ring.complete = c->complete;    /* this covers IE 33 (Sending Complete) */
-               return Q931_RES_HAVEEVENT;
-@@ -3531,7 +4655,6 @@
-               pri->ev.e = PRI_EVENT_SETUP_ACK;
-               pri->ev.setup_ack.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
-               pri->ev.setup_ack.call = c;
--
-               cur = c->apdus;
-               while (cur) {
-                       if (!cur->sent && cur->message == Q931_FACILITY) {
-@@ -3547,19 +4670,53 @@
-               pri->ev.notify.channel = c->channelno;
-               pri->ev.notify.info = c->notify;
-               return Q931_RES_HAVEEVENT;
-+      case Q931_HOLD:
-+              pri->ev.e = PRI_EVENT_HOLD_REQ;
-+              pri->ev.hold_req.call = c;
-+              pri->ev.hold_req.cref = c->cr;
-+              pri->ev.hold_req.tei = c->tei;
-+              pri->ev.hold_req.channel = c->channelno;
-+              return Q931_RES_HAVEEVENT;
-+              break;
-+      case Q931_RETRIEVE:
-+              pri->ev.e = PRI_EVENT_RETRIEVE_REQ;
-+              pri->ev.retrieve_req.call = c;
-+              pri->ev.retrieve_req.cref = c->cr;
-+              pri->ev.retrieve_req.tei = c->tei;
-+              pri->ev.retrieve_req.channel = c->channelno;
-+              return Q931_RES_HAVEEVENT;
-+              break;
-+      case Q931_SUSPEND:
-+              pri->ev.e = PRI_EVENT_SUSPEND_REQ;
-+              pri->ev.suspend_req.call = c;
-+              pri->ev.suspend_req.cref = c->cr;
-+              pri->ev.suspend_req.tei = c->tei;
-+              pri->ev.suspend_req.channel = c->channelno;
-+              strncpy(pri->ev.suspend_req.callid, c->callid, sizeof(pri->ev.suspend_req.callid) - 1);
-+              return Q931_RES_HAVEEVENT;
-+              break;
-+      case Q931_RESUME:
-+              if (pri->localtype == BRI_NETWORK_PTMP) {
-+                  l2c = q921_getcall(pri, c, tei);
-+              }
-+              c->newcall = 0;
-+              pri->ev.e = PRI_EVENT_RESUME_REQ;
-+              pri->ev.resume_req.call = c;
-+              pri->ev.resume_req.cref = c->cr;
-+              pri->ev.resume_req.tei = c->tei;
-+              pri->ev.resume_req.channel = c->channelno;
-+              strncpy(pri->ev.resume_req.callid, c->callid, sizeof(pri->ev.resume_req.callid) - 1);
-+              return Q931_RES_HAVEEVENT;
-+              break;
-       case Q931_USER_INFORMATION:
-       case Q931_SEGMENT:
-       case Q931_CONGESTION_CONTROL:
--      case Q931_HOLD:
-       case Q931_HOLD_ACKNOWLEDGE:
-       case Q931_HOLD_REJECT:
--      case Q931_RETRIEVE:
-       case Q931_RETRIEVE_ACKNOWLEDGE:
-       case Q931_RETRIEVE_REJECT:
--      case Q931_RESUME:
-       case Q931_RESUME_ACKNOWLEDGE:
-       case Q931_RESUME_REJECT:
--      case Q931_SUSPEND:
-       case Q931_SUSPEND_ACKNOWLEDGE:
-       case Q931_SUSPEND_REJECT:
-               pri_error(pri, "!! Not yet handling post-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg);
-@@ -3569,7 +4726,7 @@
-               pri_error(pri, "!! Don't know how to post-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg);
-               q931_status(pri,c, PRI_CAUSE_MESSAGE_TYPE_NONEXIST);
-               if (c->newcall) 
--                      q931_destroycall(pri,c->cr);
-+                      q931_destroycall(pri,c->cr,c->tei);
-               return -1;
-       }
-       return 0;
diff --git a/src/patches/zaphfc_0.3.0-PRE-1o_florz-12.diff b/src/patches/zaphfc_0.3.0-PRE-1o_florz-12.diff
deleted file mode 100644 (file)
index 7d8fa4b..0000000
+++ /dev/null
@@ -1,1293 +0,0 @@
-diff -urN bristuff-0.3.0-PRE-1o/zaphfc/Makefile zaphfc_0.3.0-PRE-1o_florz-12/Makefile
---- bristuff-0.3.0-PRE-1o/zaphfc/Makefile      2006-02-09 10:11:05.000000000 +0100
-+++ zaphfc_0.3.0-PRE-1o_florz-12/Makefile      2006-05-02 03:24:31.000000000 +0200
-@@ -1,15 +1,15 @@
--KINCLUDES = /usr/src/linux/include
-+KSRC=/usr/src/linux/
-+KINCLUDES = $(KSRC)include
- BRISTUFFBASE = $(shell dirname `pwd`)
- ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel")
--RTAI = $(shell [ -f /usr/realtime/include/rtai.h ] && echo "-DRTAITIMING -I/usr/realtime/include")
- HOSTCC=gcc
--CFLAGS+=-I. $(ZAP) $(RTAI) -O2 -g -Wall -DBUILDING_TONEZONE 
-+CFLAGS+=-I. $(ZAP) -O2 -g -Wall -DBUILDING_TONEZONE 
- CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
--KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) $(RTAI) -Wall
-+KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) -Wall
- KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h")
- KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char"; fi)
-@@ -105,8 +105,8 @@
- zaphfc.ko: zaphfc.c zaphfc.h
- linux26: 
--      @if ! [ -d /usr/src/linux-2.6 ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi
--      make -C /usr/src/linux-2.6 SUBDIRS=$(PWD) ZAP=$(ZAP) modules
-+      @if ! [ -d $(KSRC) ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi
-+      make -C $(KSRC) SUBDIRS=$(PWD) ZAP=$(ZAP) modules
- install:      install$(BUILDVER)
-diff -urN bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.c zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.c
---- bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.c      2006-04-25 15:38:47.000000000 +0200
-+++ zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.c      2006-05-02 03:24:31.000000000 +0200
-@@ -7,19 +7,21 @@
-  *
-  * Klaus-Peter Junghanns <kpj@junghanns.net>
-  *
-+ * Copyright (C) 2004, 2005, 2006  Florian Zumbiehl <florz@gmx.de>
-+ *  - support for slave mode of the HFC-S chip which allows it to
-+ *    sync its sample clock to an external source/another HFC chip
-+ *  - support for "interrupt bundling" (let only one card generate
-+ *    8 kHz timing interrupt no matter how many cards there are
-+ *    in the system)
-+ *  - interrupt loss tolerant b channel handling
-+ *
-  * This program is free software and may be modified and
-- * distributed under the terms of the GNU Public License.
-+ * distributed under the terms of the GNU General Public License.
-  *
-  */
- #include <linux/kernel.h>
- #include <linux/module.h>
--#ifdef RTAITIMING
--#include <asm/io.h>
--#include <rtai.h>
--#include <rtai_sched.h>
--#include <rtai_fifos.h>
--#endif
- #include <linux/pci.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
-@@ -27,6 +29,8 @@
- #include <zaptel.h>
- #include "zaphfc.h"
-+#define log2(n) ffz(~(n))
-+
- #if CONFIG_PCI
- #define CLKDEL_TE     0x0f    /* CLKDEL in TE mode */
-@@ -69,41 +73,30 @@
- static int hfc_dev_count = 0;
- static int modes = 0; // all TE
- static int debug = 0;
-+static int sync_slave = 0; // all master
-+static int timer_card = 0;
-+static int jitterbuffer = 1;
- static struct pci_dev *multi_hfc = NULL;
- static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
--void hfc_shutdownCard(struct hfc_card *hfctmp) {
--    unsigned long flags;
--
--    if (hfctmp == NULL) {
--      return;
--    }
--
--    if (hfctmp->pci_io == NULL) {
--      return;
--    }
--    
--    spin_lock_irqsave(&hfctmp->lock,flags);
--
-+void hfc_shutdownCard1(struct hfc_card *hfctmp) {
-     printk(KERN_INFO "zaphfc: shutting down card at %p.\n",hfctmp->pci_io);
-     /* Clear interrupt mask */
-     hfctmp->regs.int_m2 = 0;
-     hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
--    /* Reset pending interrupts */
--    hfc_inb(hfctmp, hfc_INT_S1);
-+    /* Remove interrupt handler */
-+    free_irq(hfctmp->irq,hfctmp);
-+}
-+
-+void hfc_shutdownCard2(struct hfc_card *hfctmp) {
-+    unsigned long flags;
--    /* Wait for interrupts that might still be pending */
--    spin_unlock_irqrestore(&hfctmp->lock, flags);
--    set_current_state(TASK_UNINTERRUPTIBLE);
--    schedule_timeout((30 * HZ) / 1000);       // wait 30 ms
-     spin_lock_irqsave(&hfctmp->lock,flags);
--    /* Remove interrupt handler */
--    if (hfctmp->irq) {
--      free_irq(hfctmp->irq, hfctmp);
--    }
-+    /* Reset pending interrupts */
-+    hfc_inb(hfctmp, hfc_INT_S1);
-     /* Soft-reset the card */
-     hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on
-@@ -117,8 +110,8 @@
-     pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0);    // disable memio and bustmaster
--    if (hfctmp->fifomem != NULL) {
--        kfree(hfctmp->fifomem);
-+    if (hfctmp->fifos != NULL) {
-+      free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES));
-     }
-     iounmap((void *) hfctmp->pci_io);
-     hfctmp->pci_io = NULL;
-@@ -128,11 +121,24 @@
-     spin_unlock_irqrestore(&hfctmp->lock,flags);
-     if (hfctmp->ztdev != NULL) {
-       zt_unregister(&hfctmp->ztdev->span);
--      kfree(hfctmp->ztdev);
-+      vfree(hfctmp->ztdev);
-       printk(KERN_INFO "unregistered from zaptel.\n");
-     }
- }
-+void hfc_shutdownCard(struct hfc_card *hfctmp) {
-+    if (hfctmp == NULL) {
-+      return;
-+    }
-+
-+    if (hfctmp->pci_io == NULL) {
-+      return;
-+    }
-+
-+    hfc_shutdownCard1(hfctmp);
-+    hfc_shutdownCard2(hfctmp);
-+}
-+
- void hfc_resetCard(struct hfc_card *hfctmp) {
-     unsigned long flags;
-@@ -176,14 +182,14 @@
-     hfctmp->regs.ctmt = hfc_CTMT_TRANSB1 | hfc_CTMT_TRANSB2; // all bchans are transparent , no freaking hdlc
-     hfc_outb(hfctmp, hfc_CTMT, hfctmp->regs.ctmt);
--    hfctmp->regs.int_m1 = 0;
-+    hfctmp->regs.int_m1=hfc_INTS_L1STATE;
-+    if(hfctmp->cardno==timer_card){
-+      hfctmp->regs.int_m2=hfc_M2_PROC_TRANS;
-+    }else{
-+      hfctmp->regs.int_m1|=hfc_INTS_DREC;
-+      hfctmp->regs.int_m2=0;
-+    }
-     hfc_outb(hfctmp, hfc_INT_M1, hfctmp->regs.int_m1);
--
--#ifdef RTAITIMING
--    hfctmp->regs.int_m2 = 0;
--#else
--    hfctmp->regs.int_m2 = hfc_M2_PROC_TRANS;
--#endif
-     hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
-     /* Clear already pending ints */
-@@ -195,8 +201,8 @@
-       hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_TE;        /* set tx_lo mode, error in datasheet ! */
-     }
--    hfctmp->regs.mst_mode = hfc_MST_MODE_MASTER;      /* HFC Master Mode */
-     hfc_outb(hfctmp, hfc_MST_MODE, hfctmp->regs.mst_mode);
-+    hfc_outb(hfctmp, hfc_MST_EMOD, hfctmp->regs.mst_emod);
-     hfc_outb(hfctmp, hfc_SCTRL, hfctmp->regs.sctrl);
-     hfctmp->regs.sctrl_r = 3;
-@@ -208,10 +214,8 @@
-     hfc_outb(hfctmp, hfc_CIRM, 0x80 | 0x40);  // bit order
-     /* Finally enable IRQ output */
--#ifndef RTAITIMING
-     hfctmp->regs.int_m2 |= hfc_M2_IRQ_ENABLE;
-     hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
--#endif
-     /* clear pending ints */
-     hfc_inb(hfctmp, hfc_INT_S1); 
-@@ -228,374 +232,219 @@
-     spin_unlock(&registerlock);
- }
--static void hfc_btrans(struct hfc_card *hfctmp, char whichB) {
--    // we are called with irqs disabled from the irq handler
--    int count, maxlen, total;
--    unsigned char *f1, *f2;
--    unsigned short *z1, *z2, newz1;
--    int freebytes;
--
--    if (whichB == 1) {
--      f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F1);
--        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F2);
--      z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z1 + (*f1 * 4));
--      z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z2 + (*f1 * 4));
--    } else {
--      f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F1);
--        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F2);
--      z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z1 + (*f1 * 4));
--      z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z2 + (*f1 * 4));
--    }
--
--    freebytes = *z2 - *z1;
--    if (freebytes <= 0) {
--      freebytes += hfc_B_FIFO_SIZE;
--    }
--    count = ZT_CHUNKSIZE;
--
--    total = count;
--    if (freebytes < count) {
--      hfctmp->clicks++;
--      /* only spit out this warning once per second to not make things worse! */
--      if (hfctmp->clicks > 100) {
--          printk(KERN_CRIT "zaphfc: bchan tx fifo full, dropping audio! (z1=%d, z2=%d)\n",*z1,*z2);
--          hfctmp->clicks = 0;
--      }
--      return;
--    }
--    
--    maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z1;
--    if (maxlen > count) {
--        maxlen = count;
--    }
--    newz1 = *z1 + total;
--    if (newz1 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { newz1 -= hfc_B_FIFO_SIZE; }
-+/*===========================================================================*/
--      if (whichB == 1) {
--          memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + *z1),hfctmp->ztdev->chans[0].writechunk, maxlen);
--      } else {
--          memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + *z1),hfctmp->ztdev->chans[1].writechunk, maxlen);
--      }
--      
--      count -= maxlen;
--      if (count > 0) {
--      // Buffer wrap
--          if (whichB == 1) {
--              memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[0].writechunk+maxlen, count);
--          } else {
--              memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[1].writechunk+maxlen, count);
--          }
--      }
-+#if hfc_B_FIFO_SIZE%ZT_CHUNKSIZE
-+#error hfc_B_FIFO_SIZE is not a multiple of ZT_CHUNKSIZE even though the code assumes this
-+#endif
-+    
-+static void hfc_dch_init(struct hfc_card *hfctmp){
-+    struct dch *chtmp=&hfctmp->dch;
--    *z1 = newz1;      /* send it now */
-+    chtmp->rx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DRX_F1);
-+    chtmp->rx.f2.v=0x1f;
-+    chtmp->rx.f2.z2.v=0x1ff;
--//    if (count > 0) printk(KERN_CRIT "zaphfc: bchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
--    return;    
-+    chtmp->tx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F1);
-+    chtmp->tx.f1.v=0x1f;
-+    chtmp->tx.f1.z1.v=0x1ff;
-+    chtmp->tx.f2.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F2);
- }
--static void hfc_brec(struct hfc_card *hfctmp, char whichB) {
--    // we are called with irqs disabled from the irq handler
--    int count, maxlen, drop;
--    volatile unsigned char *f1, *f2;
--    volatile unsigned short *z1, *z2, newz2;
--    int bytes = 0;
--
--    if (whichB == 1) {
--      f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F1);
--        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F2);
--      z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z1 + (*f1 * 4));
--      z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
--    } else {
--      f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F1);
--        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F2);
--      z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z1 + (*f1 * 4));
--      z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
--    }
-+static void hfc_bch_init(struct hfc_card *hfctmp){
-+    struct bch *chtmp=&hfctmp->bch;
--    bytes = *z1 - *z2;
--    if (bytes < 0) {
--      bytes += hfc_B_FIFO_SIZE;
--    }
--    count = ZT_CHUNKSIZE;
--    
--    if (bytes < ZT_CHUNKSIZE) {
--#ifndef RTAITIMING
--      printk(KERN_CRIT "zaphfc: bchan rx fifo not enough bytes to receive! (z1=%d, z2=%d, wanted %d got %d), probably a buffer overrun.\n",*z1,*z2,ZT_CHUNKSIZE,bytes);
--#endif
--      return;
--    }
-+    chtmp->checkcnt=0;
-+    chtmp->fill_fifo=0;
--    /* allowing the buffering of hfc_BCHAN_BUFFER bytes of audio data works around irq jitter */
--    if (bytes > hfc_BCHAN_BUFFER + ZT_CHUNKSIZE) {
--      /* if the system is too slow to handle it, we will have to drop it all (except 1 zaptel chunk) */
--      drop = bytes - ZT_CHUNKSIZE;
--      hfctmp->clicks++;
--      /* only spit out this warning once per second to not make things worse! */
--      if (hfctmp->clicks > 100) {
--          printk(KERN_CRIT "zaphfc: dropped audio (z1=%d, z2=%d, wanted %d got %d, dropped %d).\n",*z1,*z2,count,bytes,drop);
--          hfctmp->clicks = 0;
--      }
--      /* hm, we are processing the b chan data tooooo slowly... let's drop the lost audio */
--      newz2 = *z2 + drop;
--      if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
--          newz2 -= hfc_B_FIFO_SIZE; 
--      }
--      *z2 = newz2;
--    }
-+    chtmp->rx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1RX_Z1+0x1f*4);
-+    chtmp->rx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1RX_ZOFF);
-+    chtmp->rx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2RX_Z1+0x1f*4);
-+    chtmp->rx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2RX_ZOFF);
-+    chtmp->rx.z2=hfc_B_SUB_VAL;
-+    chtmp->rx.diff=0;
--    
--    maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z2;
--    if (maxlen > count) {
--        maxlen = count;
--    }
--    if (whichB == 1) {
--        memcpy(hfctmp->ztdev->chans[0].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + *z2), maxlen);
--    } else {
--        memcpy(hfctmp->ztdev->chans[1].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + *z2), maxlen);
--    }
--    newz2 = *z2 + count;
--    if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
--        newz2 -= hfc_B_FIFO_SIZE; 
-+    chtmp->tx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z1+0x1f*4);
-+    chtmp->tx.c[0].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z2+0x1f*4);
-+    chtmp->tx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1TX_ZOFF);
-+    chtmp->tx.c[0].filled=0;
-+    chtmp->tx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z1+0x1f*4);
-+    chtmp->tx.c[1].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z2+0x1f*4);
-+    chtmp->tx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2TX_ZOFF);
-+    chtmp->tx.c[1].filled=0;
-+    chtmp->tx.z1=hfc_B_SUB_VAL;
-+    chtmp->tx.diff=0;
-+
-+    hfc_dch_init(hfctmp);
-+
-+    chtmp->initialized=0;
-+}
-+
-+static int hfc_bch_check(struct hfc_card *hfctmp){
-+    struct bch *chtmp=&hfctmp->bch;
-+    int x,r;
-+
-+    for(x=0;x<2;x++){
-+      chtmp->tx.c[x].filled=(chtmp->tx.z1-*chtmp->tx.c[x].z2p+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE;
-+      chtmp->rx.c[x].filled=(*chtmp->rx.c[x].z1p-chtmp->rx.z2+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE;
-     }
--    *z2 = newz2;
--      
--    count -= maxlen;
--    if (count > 0) {
--    // Buffer wrap
--        if (whichB == 1) {
--          z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
--          memcpy(hfctmp->ztdev->chans[0].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + hfc_B_SUB_VAL), count);
--      } else {
--          z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
--          memcpy(hfctmp->ztdev->chans[1].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + hfc_B_SUB_VAL), count);
--      }
--      newz2 = *z2 + count;
--      if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
--          newz2 -= hfc_B_FIFO_SIZE; 
-+    if(chtmp->fill_fifo){
-+      chtmp->checkcnt++;
-+      chtmp->checkcnt%=ZT_CHUNKSIZE;
-+      r=!chtmp->checkcnt;
-+    }else{
-+      x=chtmp->tx.c[0].filled-chtmp->tx.c[1].filled;
-+      if(abs(x-chtmp->tx.diff)>1){
-+          printk(KERN_CRIT "zaphfc[%d]: tx sync changed: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled);
-+          chtmp->tx.diff=x;
-       }
-+      r=chtmp->tx.c[0].filled<=ZT_CHUNKSIZE*jitterbuffer&&chtmp->tx.c[1].filled<=ZT_CHUNKSIZE*jitterbuffer;
-     }
-+    return(r);
-+}
-+#define hfc_bch_inc_z(a,b) (a)=((a)-hfc_B_SUB_VAL+(b))%hfc_B_FIFO_SIZE+hfc_B_SUB_VAL
--    if (whichB == 1) {
--      zt_ec_chunk(&hfctmp->ztdev->chans[0], hfctmp->ztdev->chans[0].readchunk, hfctmp->ztdev->chans[0].writechunk);
--    } else {
--      zt_ec_chunk(&hfctmp->ztdev->chans[1], hfctmp->ztdev->chans[1].readchunk, hfctmp->ztdev->chans[1].writechunk);
-+static void hfc_bch_tx(struct hfc_card *hfctmp){
-+    struct bch *chtmp=&hfctmp->bch;
-+    int x;
-+
-+    for(x=0;x<2;x++)
-+      memcpy((void *)(chtmp->tx.c[x].fifo_base+chtmp->tx.z1),hfctmp->ztdev->chans[x].writechunk,ZT_CHUNKSIZE);
-+    hfc_bch_inc_z(chtmp->tx.z1,ZT_CHUNKSIZE);
-+    if(chtmp->fill_fifo){
-+      chtmp->fill_fifo--;
-+    }else if(chtmp->tx.c[0].filled<=1||chtmp->tx.c[1].filled<=1){
-+      chtmp->fill_fifo=jitterbuffer;
-+      if(chtmp->initialized)
-+          printk(KERN_CRIT "zaphfc[%d]: b channel buffer underrun: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled);
-     }
--    return;    
-+    if(!chtmp->fill_fifo)
-+      for(x=0;x<2;x++)*chtmp->tx.c[x].z1p=chtmp->tx.z1;
- }
--
--static void hfc_dtrans(struct hfc_card *hfctmp) {
--    // we are called with irqs disabled from the irq handler
-+static void hfc_bch_rx(struct hfc_card *hfctmp){
-+    struct bch *chtmp=&hfctmp->bch;
-     int x;
--    int count, maxlen, total;
--    unsigned char *f1, *f2, newf1;
--    unsigned short *z1, *z2, newz1;
--    int frames, freebytes;
--    if (hfctmp->ztdev->chans[2].bytes2transmit == 0) {
--      return;
-+    x=chtmp->rx.c[0].filled-chtmp->rx.c[1].filled;
-+    if(abs(x-chtmp->rx.diff)>1){
-+      printk(KERN_CRIT "zaphfc[%d]: rx sync changed: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled);
-+      chtmp->rx.diff=x;
-     }
--
--    f1 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F1);
--    f2 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F2);
--    z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
--    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z2 + (*f1 * 4));
--
--    frames = (*f1 - *f2) & hfc_FMASK;
--    if (frames < 0) {
--      frames += hfc_MAX_DFRAMES + 1;
-+    if(chtmp->rx.c[0].filled>=ZT_CHUNKSIZE&&chtmp->rx.c[1].filled>=ZT_CHUNKSIZE){
-+      if((chtmp->rx.c[0].filled>=ZT_CHUNKSIZE*(jitterbuffer+2)&&chtmp->rx.c[1].filled>=ZT_CHUNKSIZE*(jitterbuffer+2))||!chtmp->initialized){
-+          if(chtmp->initialized)
-+              printk(KERN_CRIT "zaphfc[%d]: b channel buffer overflow: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled);
-+          hfc_bch_inc_z(chtmp->rx.z2,chtmp->rx.c[0].filled-chtmp->rx.c[0].filled%ZT_CHUNKSIZE-ZT_CHUNKSIZE);
-+          chtmp->initialized=1;
-+      }
-+      for(x=0;x<2;x++){
-+          memcpy(hfctmp->ztdev->chans[x].readchunk,(void *)(chtmp->rx.c[x].fifo_base+chtmp->rx.z2),ZT_CHUNKSIZE);
-+          zt_ec_chunk(&hfctmp->ztdev->chans[x],hfctmp->ztdev->chans[x].readchunk,hfctmp->ztdev->chans[x].writechunk);
-+      }
-+      hfc_bch_inc_z(chtmp->rx.z2,ZT_CHUNKSIZE);
-     }
-+}
--    if (frames >= hfc_MAX_DFRAMES) {
--      printk(KERN_CRIT "zaphfc: dchan tx fifo total number of frames exceeded!\n");
--      return;
--    }
-+/*===========================================================================*/
--    freebytes = *z2 - *z1;
--    if (freebytes <= 0) {
--      freebytes += hfc_D_FIFO_SIZE;
--    }
--    count = hfctmp->ztdev->chans[2].bytes2transmit;
--
--    total = count;
--    if (freebytes < count) {
--      printk(KERN_CRIT "zaphfc: dchan tx fifo not enough free bytes! (z1=%d, z2=%d)\n",*z1,*z2);
--      return;
--    }
--    
--    newz1 = (*z1 + count) & hfc_ZMASK;
--    newf1 = ((*f1 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);    // next frame
--    
--    if (count > 0) {
--      if (debug) {
--          printk(KERN_CRIT "zaphfc: card %d TX [ ", hfctmp->cardno);
--          for (x=0; x<count; x++) {
-+static void hfc_dch_tx(struct hfc_card *hfctmp){
-+    struct dch *chtmp=&hfctmp->dch;
-+    u8 tx_f2_v;
-+    u16 x;
-+
-+    if(hfctmp->ztdev->chans[2].bytes2transmit){
-+      if(debug){
-+          printk(KERN_CRIT "zaphfc[%d]: card TX [ ",hfctmp->cardno);
-+          for(x=0;x<hfctmp->ztdev->chans[2].bytes2transmit;x++){
-               printk("%#2x ",hfctmp->dtransbuf[x]);
-           }
--          if (hfctmp->ztdev->chans[2].eoftx == 1) {
--              printk("] %d bytes\n", count);
--          } else {
--              printk("..] %d bytes\n", count);
--          }
--      }
--      maxlen = hfc_D_FIFO_SIZE - *z1;
--      if (maxlen > count) {
--          maxlen = count;
-+          printk("] %d bytes\n",hfctmp->ztdev->chans[2].bytes2transmit);
-       }
--      memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF + *z1),hfctmp->ztdev->chans[2].writechunk, maxlen);
--      count -= maxlen;
--      if (count > 0) {
--          memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF),(char *)(hfctmp->ztdev->chans[2].writechunk + maxlen), count);
-+      tx_f2_v=*chtmp->tx.f2.p;
-+      if(!(tx_f2_v-chtmp->tx.f1.v+hfc_MAX_DFRAMES+1-1)&(hfc_MAX_DFRAMES+1-1)){
-+          printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo total number of frames exceeded!\n",hfctmp->cardno);
-+      }else{
-+          if(((*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z2+tx_f2_v*4)-chtmp->tx.f1.z1.v+hfc_D_FIFO_SIZE-1)&(hfc_D_FIFO_SIZE-1))<hfctmp->ztdev->chans[2].bytes2transmit){
-+              printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo not enough space for frame!\n",hfctmp->cardno);
-+          }else{
-+              chtmp->tx.f1.v=((chtmp->tx.f1.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1);
-+              x=min(hfctmp->ztdev->chans[2].bytes2transmit,hfc_D_FIFO_SIZE-chtmp->tx.f1.z1.v);
-+              memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF+chtmp->tx.f1.z1.v,hfctmp->ztdev->chans[2].writechunk,x);
-+              memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF,hfctmp->ztdev->chans[2].writechunk+x,hfctmp->ztdev->chans[2].bytes2transmit-x);
-+              *(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z2+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v;
-+              chtmp->tx.f1.z1.v=(chtmp->tx.f1.z1.v+hfctmp->ztdev->chans[2].bytes2transmit+hfc_D_FIFO_SIZE)&(hfc_D_FIFO_SIZE-1);
-+              *(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z1+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v;
-+              *chtmp->tx.f1.p=chtmp->tx.f1.v;
-+          }
-       }
-     }
--
--    *z1 = newz1;
--
--    if (hfctmp->ztdev->chans[2].eoftx == 1) {
--      *f1 = newf1;
--      z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
--      *z1 = newz1;
--      hfctmp->ztdev->chans[2].eoftx = 0;
--    }
--//    printk(KERN_CRIT "zaphfc: dchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
--    return;    
- }
--/* receive a complete hdlc frame, skip broken or short frames */
--static void hfc_drec(struct hfc_card *hfctmp) {
--    int count=0, maxlen=0, framelen=0;
--    unsigned char *f1, *f2, *crcstat;
--    unsigned short *z1, *z2, oldz2, newz2;
-+static void hfc_dch_rx(struct hfc_card *hfctmp){
-+    struct dch *chtmp=&hfctmp->dch;
-+    u16 size;
-     hfctmp->ztdev->chans[2].bytes2receive=0;
--    hfctmp->ztdev->chans[2].eofrx = 0;
--
--    /* put the received data into the zaptel buffer
--       we'll call zt_receive() later when the timer fires. */
--    f1 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F1);
--    f2 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F2);
--
--    if (*f1 == *f2) return; /* nothing received, strange eh? */
--
--    z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z1 + (*f2 * 4));
--    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
--    
--    /* calculate length of frame, including 2 bytes CRC and 1 byte STAT */
--    count = *z1 - *z2;
--    
--    if (count < 0) { 
--      count += hfc_D_FIFO_SIZE; /* ring buffer wrapped */
--    }
--    count++;
--    framelen = count;
--
--    crcstat = (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z1);
--
--    if ((framelen < 4) || (*crcstat != 0x0)) {
--      /* the frame is too short for a valid HDLC frame or the CRC is borked */
--      printk(KERN_CRIT "zaphfc: empty HDLC frame or bad CRC received (framelen = %d, stat = %#x, card = %d).\n", framelen, *crcstat, hfctmp->cardno);
--      oldz2 = *z2;
--      *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);    /* NEXT!!! */
--        // recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!!
--      z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
--      *z2 = (oldz2 + framelen) & hfc_ZMASK;
--      hfctmp->drecinframe = 0;
--      hfctmp->regs.int_drec--;
--      /* skip short or broken frames */
--        hfctmp->ztdev->chans[2].bytes2receive = 0; 
--      return;
--    }
--
--    count -= 1;       /* strip STAT */
--    hfctmp->ztdev->chans[2].eofrx = 1;
--
--    if (count + *z2 <= hfc_D_FIFO_SIZE) {
--      maxlen = count;
--    } else {
--      maxlen = hfc_D_FIFO_SIZE - *z2;
-+    hfctmp->ztdev->chans[2].eofrx=0;
-+    if(*chtmp->rx.f1.p==chtmp->rx.f2.v){
-+      hfctmp->regs.int_drec=0;
-+    }else{
-+      size=((*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DRX_Z1+chtmp->rx.f2.v*4)-chtmp->rx.f2.z2.v+hfc_D_FIFO_SIZE)&(hfc_D_FIFO_SIZE-1))+1;
-+      if(size<4){
-+          printk(KERN_CRIT "zaphfc[%d]: empty HDLC frame received.\n",hfctmp->cardno);
-+      }else{
-+          u16 x=min(size,(u16)(hfc_D_FIFO_SIZE-chtmp->rx.f2.z2.v));
-+          memcpy(hfctmp->drecbuf,hfctmp->fifos+hfc_FIFO_DRX_ZOFF+chtmp->rx.f2.z2.v,x);
-+          memcpy(hfctmp->drecbuf+x,hfctmp->fifos+hfc_FIFO_DRX_ZOFF,size-x);
-+          if(hfctmp->drecbuf[size-1]){
-+              printk(KERN_CRIT "zaphfc[%d]: received d channel frame with bad CRC.\n",hfctmp->cardno);
-+          }else{
-+              hfctmp->ztdev->chans[2].bytes2receive=size-1;
-+              hfctmp->ztdev->chans[2].eofrx=1;
-+          }
-+      }
-+      chtmp->rx.f2.z2.v=(chtmp->rx.f2.z2.v+size)&(hfc_D_FIFO_SIZE-1);
-+      chtmp->rx.f2.v=((chtmp->rx.f2.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1);
-     }
--
--    /* copy first part */
--    memcpy(hfctmp->drecbuf, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z2), maxlen);
--    hfctmp->ztdev->chans[2].bytes2receive += maxlen; 
--    
--    count -= maxlen;
--    if (count > 0) {
--      /* ring buffer wrapped, copy rest from start of d fifo */
--      memcpy(hfctmp->drecbuf + maxlen, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF), count);
--      hfctmp->ztdev->chans[2].bytes2receive += count; 
--    }
--
--    /* frame read */
--    oldz2 = *z2;
--    newz2 = (oldz2 + framelen) & hfc_ZMASK;
--    *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);      /* NEXT!!! */
--    /* recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!! */
--    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
--    *z2 = newz2;
--    hfctmp->drecinframe = 0;
--    hfctmp->regs.int_drec--; 
- }
--#ifndef RTAITIMING
-+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-+
- #ifdef LINUX26
- static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
- #else
- static void hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
- #endif
-     struct hfc_card *hfctmp = dev_id;
--    unsigned long flags = 0;
--    unsigned char stat;
--#else
--static void hfc_service(struct hfc_card *hfctmp) {
--#endif
-+    struct hfc_card *hfctmp2;
-     struct zt_hfc *zthfc;
--    unsigned char s1, s2, l1state;
-+    unsigned char stat, s1, s2, l1state;
-+    unsigned long flags;
-+    unsigned long flags2=0;
-     int x;
-     if (!hfctmp) {
--#ifndef RTAITIMING
- #ifdef LINUX26
-               return IRQ_NONE;
- #else
-               return;
- #endif                
--#else
--      /* rtai */
--      return;
--#endif
-     }
-     if (!hfctmp->pci_io) {
-           printk(KERN_WARNING "%s: IO-mem disabled, cannot handle interrupt\n",
-                  __FUNCTION__);
--#ifndef RTAITIMING
- #ifdef LINUX26
-           return IRQ_NONE;
- #else
-           return;
- #endif                
--#else
--      /* rtai */
--      return;
--#endif
-     }
--    
--    /*        we assume a few things in this irq handler:
--      - the hfc-pci will only generate "timer" irqs (proc/non-proc)
--      - we need to use every 8th IRQ (to generate 1khz timing)
--      OR
--      - if we use rtai for timing the hfc-pci will not generate ANY irq,
--        instead rtai will call this "fake" irq with a 1khz realtime timer. :)
--      - rtai will directly service the card, not like it used to by triggering
--        the linux irq
--    */
--#ifndef RTAITIMING
-     spin_lock_irqsave(&hfctmp->lock, flags);
-     stat = hfc_inb(hfctmp, hfc_STATUS);
--
-     if ((stat & hfc_STATUS_ANYINT) == 0) {
-         // maybe we are sharing the irq
-       spin_unlock_irqrestore(&hfctmp->lock,flags);
-@@ -605,8 +454,6 @@
-       return;
- #endif                
-     }
--#endif
--
-     s1 = hfc_inb(hfctmp, hfc_INT_S1);
-     s2 = hfc_inb(hfctmp, hfc_INT_S2); 
-     if (s1 != 0) {
-@@ -625,18 +472,10 @@
-               }
-               switch (l1state) {
-                   case 3:
--#ifdef RTAITIMING
--                      sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
--#else
-                       sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d)", hfctmp->cardno, l1state);
--#endif
-                       break;
-                   default:
--#ifdef RTAITIMING
--                      sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
--#else
-                       sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d)", hfctmp->cardno, l1state);
--#endif
-               }
-               if (l1state == 2) {
-                   hfc_outb(hfctmp, hfc_STATES, hfc_STATES_ACTIVATE | hfc_STATES_DO_ACTION | hfc_STATES_NT_G2_G3);
-@@ -650,18 +489,10 @@
-               }
-               switch (l1state) {
-                   case 7:
--#ifdef RTAITIMING
--                      sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
--#else
-                       sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d)", hfctmp->cardno, l1state);
--#endif
-                       break;
-                   default:
--#ifdef RTAITIMING
--                      sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
--#else
-                       sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d)", hfctmp->cardno, l1state);
--#endif
-               }
-               if (l1state == 3) {
-                   hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
-@@ -671,7 +502,7 @@
-       }
-       if (s1 & hfc_INTS_DREC) {
-           // D chan RX (bit 5)
--          hfctmp->regs.int_drec++;
-+          hfctmp->regs.int_drec = 1;
-           // mr. zapata there is something for you!
-       //    printk(KERN_CRIT "d chan rx\n");              
-       }
-@@ -692,14 +523,10 @@
-           // B1 chan TX (bit 0)
-       }
-     }
--#ifdef RTAITIMING
--    /* fake an irq */
--    s2 |= hfc_M2_PROC_TRANS;
--#endif
-     if (s2 != 0) {
-       if (s2 & hfc_M2_PMESEL) {
-           // kaboom irq (bit 7)
--          printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n");
-+          // printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n");
-       }
-       if (s2 & hfc_M2_GCI_MON_REC) {
-           // RxR monitor channel (bit 2)
-@@ -707,32 +534,30 @@
-       if (s2 & hfc_M2_GCI_I_CHG) {
-           // GCI I-change  (bit 1)
-       }
--      if (s2 & hfc_M2_PROC_TRANS) {
-+      if((s2&hfc_M2_PROC_TRANS)&&(hfctmp->cardno==timer_card)){
-           // processing/non-processing transition  (bit 0)
--          hfctmp->ticks++;
--#ifndef RTAITIMING
--          if (hfctmp->ticks > 7) {
--              // welcome to zaptel timing :)
--#endif
--              hfctmp->ticks = 0;
--
-+      hfctmp2=hfctmp;
-+      hfctmp=hfc_dev_list;
-+      while(hfctmp){
-+          if(hfctmp->active){
-+          if(hfctmp!=hfctmp2)spin_lock_irqsave(&hfctmp->lock, flags2);
-+          if(hfc_bch_check(hfctmp)){
-               if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) {
-                   // clear dchan buffer
-+      //          memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf));
-+
-                   hfctmp->ztdev->chans[2].bytes2transmit = 0;
-                   hfctmp->ztdev->chans[2].maxbytes2transmit = hfc_D_FIFO_SIZE;
-                   zt_transmit(&(hfctmp->ztdev->span));
--                  hfc_btrans(hfctmp,1);
--                  hfc_btrans(hfctmp,2);
--                  hfc_dtrans(hfctmp);
-+                  hfc_bch_tx(hfctmp);
-+                  hfc_dch_tx(hfctmp);
-               }
--
--              hfc_brec(hfctmp,1);
--              hfc_brec(hfctmp,2);
--              if (hfctmp->regs.int_drec > 0) {
-+              hfc_bch_rx(hfctmp);
-+              if (hfctmp->regs.int_drec) {
-                   // dchan data to read
--                  hfc_drec(hfctmp);
-+                  hfc_dch_rx(hfctmp);
-                   if (hfctmp->ztdev->chans[2].bytes2receive > 0) {
-                           if (debug) {
-                               printk(KERN_CRIT "zaphfc: card %d RX [ ", hfctmp->cardno);
-@@ -757,19 +582,18 @@
-               if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) {
-                   zt_receive(&(hfctmp->ztdev->span));
-               }
--              
--#ifndef RTAITIMING
-           }
--#endif
-+          if(hfctmp!=hfctmp2)spin_unlock_irqrestore(&hfctmp->lock,flags2);
-+          }
-+          hfctmp=hfctmp->next;
-+      }
-+      hfctmp=hfctmp2;
-       }
--
-     }
--#ifndef RTAITIMING
-     spin_unlock_irqrestore(&hfctmp->lock,flags);
- #ifdef LINUX26
-       return IRQ_RETVAL(1);
- #endif                
--#endif
- }
-@@ -826,22 +650,21 @@
-     }
-     alreadyrunning = span->flags & ZT_FLAG_RUNNING;
-     
--    if (!alreadyrunning) {
--      span->chans[2].flags &= ~ZT_FLAG_HDLC;
--      span->chans[2].flags |= ZT_FLAG_BRIDCHAN;
--      
--      span->flags |= ZT_FLAG_RUNNING;
-+    if (alreadyrunning) return 0;
--      hfctmp->ticks = -2;
--      hfctmp->clicks = 0;
--      hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
--        hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
--    } else {
--      return 0;
--    }
-+    span->chans[2].flags &= ~ZT_FLAG_HDLC;
-+    span->chans[2].flags |= ZT_FLAG_BRIDCHAN;
-+    
-+    span->flags |= ZT_FLAG_RUNNING;
-+
-+    hfctmp->ticks = -2;       
-+    hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
-+    hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
-+    hfc_bch_init(hfctmp);
-     // drivers, start engines!
-     hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
-+    hfctmp->active=1;
-     return 0;
- }
-@@ -871,17 +694,9 @@
-     sprintf(zthfc->span.name, "ZTHFC%d", hfc_dev_count + 1);
-     if (hfctmp->regs.nt_mode == 1) {
--#ifdef RTAITIMING
--      sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] [realtime]", hfc_dev_count + 1);
--#else
-       sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT]", hfc_dev_count + 1);
--#endif
-     } else {
--#ifdef RTAITIMING
--      sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] [realtime]", hfc_dev_count + 1);
--#else
-       sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE]", hfc_dev_count + 1);
--#endif
-     }
-     zthfc->span.spanconfig = zthfc_spanconfig;
-@@ -918,32 +733,6 @@
-     return 0;
- }
--#ifdef RTAITIMING
--#define TICK_PERIOD  1000000
--#define TICK_PERIOD2 1000000000
--#define TASK_PRIORITY 1
--#define STACK_SIZE 10000
--
--static RT_TASK rt_task;
--static struct hfc_card *rtai_hfc_list[hfc_MAX_CARDS];
--static unsigned char rtai_hfc_counter = 0;
--
--static void rtai_register_hfc(struct hfc_card *hfctmp) {
--    rtai_hfc_list[rtai_hfc_counter++] = hfctmp;
--}
--
--static void rtai_loop(int t) {
--    int i=0;
--    for (;;) {
--      for (i=0; i < rtai_hfc_counter; i++) {
--          if (rtai_hfc_list[i] != NULL)
--              hfc_service(rtai_hfc_list[i]);
--      }
--        rt_task_wait_period();
--    }
--}
--#endif
--
- int hfc_findCards(int pcivendor, int pcidevice, char *vendor_name, char *card_name) {
-     struct pci_dev *tmp;
-     struct hfc_card *hfctmp = NULL;
-@@ -959,9 +748,9 @@
-       }
-       pci_set_master(tmp);
--      hfctmp = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
-+      hfctmp = vmalloc(sizeof(struct hfc_card));
-       if (!hfctmp) {
--          printk(KERN_WARNING "zaphfc: unable to kmalloc!\n");
-+          printk(KERN_WARNING "zaphfc: unable to vmalloc!\n");
-           pci_disable_device(tmp);
-           multi_hfc = NULL;
-           return -ENOMEM;
-@@ -969,6 +758,7 @@
-       memset(hfctmp, 0x0, sizeof(struct hfc_card));
-       spin_lock_init(&hfctmp->lock);
-       
-+      hfctmp->active=0;
-       hfctmp->pcidev = tmp;
-       hfctmp->pcibus = tmp->bus->number;
-       hfctmp->pcidevfn = tmp->devfn; 
-@@ -982,49 +772,39 @@
-       hfctmp->pci_io = (char *) tmp->resource[1].start;
-       if (!hfctmp->pci_io) {
-           printk(KERN_WARNING "zaphfc: no iomem!\n");
--          kfree(hfctmp);
-+          vfree(hfctmp);
-           pci_disable_device(tmp);
-           multi_hfc = NULL;
-           return -1;
-       }
--      
--      hfctmp->fifomem = kmalloc(65536, GFP_KERNEL);
--      if (!hfctmp->fifomem) {
--          printk(KERN_WARNING "zaphfc: unable to kmalloc fifomem!\n");
--          kfree(hfctmp);
-+
-+      hfctmp->fifos=(void *)__get_free_pages(GFP_KERNEL,log2(hfc_FIFO_MEM_SIZE_PAGES));
-+      if (!hfctmp->fifos) {
-+          printk(KERN_WARNING "zaphfc: unable to __get_free_pages fifomem!\n");
-+          vfree(hfctmp);
-           pci_disable_device(tmp);
-           multi_hfc = NULL;
-           return -ENOMEM;
-       } else {
--          memset(hfctmp->fifomem, 0x0, 65536);
--          hfctmp->fifos = (void *)(((ulong) hfctmp->fifomem) & ~0x7FFF) + 0x8000;
-           pci_write_config_dword(hfctmp->pcidev, 0x80, (u_int) virt_to_bus(hfctmp->fifos));
-           hfctmp->pci_io = ioremap((ulong) hfctmp->pci_io, 256);
-       }
--#ifdef RTAITIMING
--      /* we need no stinking irq */
--      hfctmp->irq = 0;
--#else
-       if (request_irq(hfctmp->irq, &hfc_interrupt, SA_INTERRUPT | SA_SHIRQ, "zaphfc", hfctmp)) {
-           printk(KERN_WARNING "zaphfc: unable to register irq\n");
--          kfree(hfctmp->fifomem);
--          kfree(hfctmp);
-+          free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES));
-+          vfree(hfctmp);
-           iounmap((void *) hfctmp->pci_io);
-           pci_disable_device(tmp);
-           multi_hfc = NULL;
-           return -EIO;
-       }
--#endif
--#ifdef RTAITIMING
--      rtai_register_hfc(hfctmp);
--#endif
-       printk(KERN_INFO
--                     "zaphfc: %s %s configured at mem %lx fifo %lx(%#x) IRQ %d HZ %d\n",
-+                     "zaphfc: %s %s configured at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n",
-                       vendor_name, card_name,
--                     (unsigned long) hfctmp->pci_io,
--                     (unsigned long) hfctmp->fifos,
-+                     (u_int) hfctmp->pci_io,
-+                     (u_int) hfctmp->fifos,
-                      (u_int) virt_to_bus(hfctmp->fifos),
-                      hfctmp->irq, HZ); 
-       pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY); // enable memio
-@@ -1041,11 +821,21 @@
-           hfctmp->regs.nt_mode = 0;
-       }
--      zthfc = kmalloc(sizeof(struct zt_hfc),GFP_KERNEL);
-+      if(sync_slave&(1<<hfc_dev_count)){
-+          printk(KERN_INFO "zaphfc: Card %d configured for slave mode\n",hfc_dev_count);
-+          hfctmp->regs.mst_mode=hfc_MST_MODE_SLAVE|hfc_MST_MODE_F0_LONG_DURATION;
-+          hfctmp->regs.mst_emod=hfc_MST_EMOD_SLOW_CLOCK_ADJ;
-+      }else{
-+          printk(KERN_INFO "zaphfc: Card %d configured for master mode\n",hfc_dev_count);
-+          hfctmp->regs.mst_mode=hfc_MST_MODE_MASTER|hfc_MST_MODE_F0_LONG_DURATION;
-+          hfctmp->regs.mst_emod=0;
-+      }
-+
-+      zthfc = vmalloc(sizeof(struct zt_hfc));
-       if (!zthfc) {
--          printk(KERN_CRIT "zaphfc: unable to kmalloc!\n");
-+          printk(KERN_CRIT "zaphfc: unable to vmalloc!\n");
-           hfc_shutdownCard(hfctmp);
--          kfree(hfctmp);
-+          vfree(hfctmp);
-           multi_hfc = NULL;
-           return -ENOMEM;
-       }
-@@ -1071,7 +861,6 @@
-       memset(hfctmp->btransbuf[1], 0x0, sizeof(hfctmp->btransbuf[1]));
-       hfctmp->ztdev->chans[1].writechunk = hfctmp->btransbuf[1];
--
-       hfc_registerCard(hfctmp);
-       hfc_resetCard(hfctmp);
-       tmp = pci_find_device(pcivendor, pcidevice, multi_hfc);
-@@ -1079,58 +868,42 @@
-     return 0;
- }
--
--
- int init_module(void) {
-     int i = 0;
--#ifdef RTAITIMING
--    RTIME tick_period;
--    for (i=0; i < hfc_MAX_CARDS; i++) {
--      rtai_hfc_list[i] = NULL;
-+    if(jitterbuffer<1){
-+      printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to minimum of 1\n",jitterbuffer);
-+      jitterbuffer=1;
-+    }else if(jitterbuffer>500){
-+      printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to maximum of 500\n",jitterbuffer);
-+      jitterbuffer=500;
-     }
--    rt_set_periodic_mode();
--#endif
--    i = 0;
-+    printk(KERN_INFO "zaphfc: jitterbuffer size: %d\n",jitterbuffer);
-     while (id_list[i].vendor_id) {
-       multi_hfc = NULL;
-       hfc_findCards(id_list[i].vendor_id, id_list[i].device_id, id_list[i].vendor_name, id_list[i].card_name);
-       i++;
-     }
--#ifdef RTAITIMING
--    for (i=0; i < hfc_MAX_CARDS; i++) {
--        if (rtai_hfc_list[i]) {
--          printk(KERN_INFO
--                     "zaphfc: configured %d at mem %#x fifo %#x(%#x) for realtime servicing\n",
--                      rtai_hfc_list[i]->cardno,
--                     (u_int) rtai_hfc_list[i]->pci_io,
--                     (u_int) rtai_hfc_list[i]->fifos,
--                     (u_int) virt_to_bus(rtai_hfc_list[i]->fifos));
--
--      }
--    }
--    rt_task_init(&rt_task, rtai_loop, 1, STACK_SIZE, TASK_PRIORITY, 0, 0);
--    tick_period = start_rt_timer(nano2count(TICK_PERIOD));
--    rt_task_make_periodic(&rt_task, rt_get_time() + tick_period, tick_period);
--#endif
-     printk(KERN_INFO "zaphfc: %d hfc-pci card(s) in this box.\n", hfc_dev_count);
-     return 0;
- }
- void cleanup_module(void) {
-     struct hfc_card *tmpcard;
--#ifdef RTAITIMING
--    stop_rt_timer();
--    rt_task_delete(&rt_task);
--#endif
-+
-     printk(KERN_INFO "zaphfc: stop\n");
- //    spin_lock(&registerlock);
-+    tmpcard=hfc_dev_list;
-+    while(tmpcard){
-+      hfc_shutdownCard1(tmpcard);
-+      tmpcard=tmpcard->next;
-+    }
-     while (hfc_dev_list != NULL) {
-       if (hfc_dev_list == NULL) break;
--      hfc_shutdownCard(hfc_dev_list);
-+      hfc_shutdownCard2(hfc_dev_list);
-       tmpcard = hfc_dev_list;
-       hfc_dev_list = hfc_dev_list->next;
-       if (tmpcard != NULL) {
--          kfree(tmpcard);
-+          vfree(tmpcard);
-           tmpcard = NULL;
-           printk(KERN_INFO "zaphfc: freed one card.\n");
-       }
-@@ -1141,11 +914,17 @@
- #ifdef LINUX26
--module_param(modes, int, 0600);
-+module_param(modes, int, 0400);
- module_param(debug, int, 0600);
-+module_param(sync_slave, int, 0400);
-+module_param(timer_card, int, 0400);
-+module_param(jitterbuffer, int, 0400);
- #else
- MODULE_PARM(modes,"i");
- MODULE_PARM(debug,"i");
-+MODULE_PARM(sync_slave,"i");
-+MODULE_PARM(timer_card,"i");
-+MODULE_PARM(jitterbuffer,"i");
- #endif
- MODULE_DESCRIPTION("HFC-S PCI A Zaptel Driver");
-@@ -1153,3 +932,6 @@
- #ifdef MODULE_LICENSE
- MODULE_LICENSE("GPL");
- #endif        
-+
-+/* vim:set sw=4: */
-+
-diff -urN bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.h zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.h
---- bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.h      2005-02-26 23:30:32.000000000 +0100
-+++ zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.h      2005-03-02 20:43:04.000000000 +0100
-@@ -135,8 +135,12 @@
- /* bits in HFCD_MST_MODE */
- #define hfc_MST_MODE_MASTER        0x01
- #define hfc_MST_MODE_SLAVE         0x00
-+#define hfc_MST_MODE_F0_LONG_DURATION         0x08
- /* remaining bits are for codecs control */
-+/* bits in HFCD_MST_EMOD */
-+#define hfc_MST_EMOD_SLOW_CLOCK_ADJ   0x01
-+
- /* bits in HFCD_SCTRL */
- #define hfc_SCTRL_B1_ENA           0x01
- #define hfc_SCTRL_B2_ENA           0x02
-@@ -236,6 +240,9 @@
- #define hfc_BTRANS_THRESHOLD 128
- #define hfc_BTRANS_THRESMASK 0x00
-+#define hfc_FIFO_MEM_SIZE_BYTES (32*1024)
-+#define hfc_FIFO_MEM_SIZE_PAGES ((hfc_FIFO_MEM_SIZE_BYTES+PAGE_SIZE-1)/PAGE_SIZE)
-+
- /* Structures */
- typedef struct hfc_regs {
-@@ -249,20 +256,67 @@
-     unsigned char connect;
-     unsigned char trm;
-     unsigned char mst_mode;
-+    unsigned char mst_emod;
-     unsigned char bswapped;
-     unsigned char nt_mode;
-     unsigned char int_drec;
- } hfc_regs;
-+struct bch {
-+    int fill_fifo,checkcnt,initialized;
-+    struct {
-+      u16 z2;
-+      struct {
-+          volatile u16 *z1p;
-+          volatile u8 *fifo_base;
-+          int filled;
-+      } c[2];
-+      int diff;
-+    } rx;
-+    struct {
-+      u16 z1;
-+      struct {
-+          volatile u16 *z1p,*z2p;
-+          volatile u8 *fifo_base;
-+          int filled;
-+      } c[2];
-+      int diff;
-+    } tx;
-+};
-+
-+struct dch {
-+    struct {
-+      struct {
-+          volatile u8 *p;
-+      } f1;
-+      struct {
-+          u8 v;
-+          struct {
-+              u16 v;
-+          } z2;
-+      } f2;
-+    } rx;
-+    struct {
-+      struct {
-+          u8 v;
-+          volatile u8 *p;
-+          struct {
-+              u16 v;
-+          } z1;
-+      } f1;
-+      struct {
-+          volatile u8 *p;
-+      } f2;
-+    } tx;
-+};
-+
- typedef struct hfc_card {
-     spinlock_t lock;
-     unsigned int irq;
-     unsigned int iomem;
-     int ticks;                
--    int clicks;               
-     unsigned char *pci_io;
--    void *fifomem;            // start of the shared mem
--    volatile void *fifos;     // 32k aligned mem for the fifos
-+    void *fifos;              // 32k aligned mem for the fifos
-     struct hfc_regs regs;
-     unsigned int pcibus;
-     unsigned int pcidevfn;
-@@ -274,6 +328,9 @@
-     unsigned char brecbuf[2][ZT_CHUNKSIZE];
-     unsigned char btransbuf[2][ZT_CHUNKSIZE];
-     unsigned char cardno;
-+    int active;
-+    struct bch bch;
-+    struct dch dch;
-     struct hfc_card *next;
- } hfc_card;
-@@ -284,6 +341,5 @@
-     struct hfc_card *card;
- } zt_hfc;
--/* tune this */
--#define hfc_BCHAN_BUFFER      8
--#define hfc_MAX_CARDS         8
-+/* vim:set sw=4: */
-+
diff --git a/src/patches/zaptel.patch b/src/patches/zaptel.patch
deleted file mode 100644 (file)
index 0804df0..0000000
+++ /dev/null
@@ -1,378 +0,0 @@
-diff -urN zaptel-1.2.6.orig/Makefile zaptel-1.2.6/Makefile
---- zaptel-1.2.6.orig/Makefile 2006-05-23 01:11:36.000000000 +0200
-+++ zaptel-1.2.6/Makefile      2006-06-06 14:54:33.000000000 +0200
-@@ -124,7 +124,7 @@
- ifneq (,$(wildcard /usr/include/newt.h))
- ZTTOOL:=zttool
- endif
--BINS=ztcfg torisatool makefw ztmonitor ztspeed $(ZTTOOL) zttest fxotune
-+BINS=ztcfg torisatool makefw ztmonitor ztspeed $(ZTTOOL) zttest fxotune ztpty
- all: $(BUILDVER) $(LIBTONEZONE_SO)
-@@ -209,6 +209,9 @@
- ztmonitor.o: ztmonitor.c zaptel.h
-+ztpty.o: ztpty.c
-+      $(CC) -o $@ -c $^
-+
- ztspeed.o: ztspeed.c
-       $(CC) -o $@ -c $^
-@@ -221,6 +224,9 @@
- ztspeed: ztspeed.o
-       $(CC) -o $@ $^
-+ztpty: ztpty.o
-+      $(CC) -o $@ $^
-+
- sethdlc-new: sethdlc-new.o
-       $(CC) -o $@ $^
-diff -urN zaptel-1.2.6.orig/zaptel.c zaptel-1.2.6/zaptel.c
---- zaptel-1.2.6.orig/zaptel.c 2005-12-17 03:04:05.000000000 +0100
-+++ zaptel-1.2.6/zaptel.c      2006-07-31 14:12:08.000000000 +0200
-@@ -139,6 +139,7 @@
- EXPORT_SYMBOL(zt_qevent_lock);
- EXPORT_SYMBOL(zt_hooksig);
- EXPORT_SYMBOL(zt_alarm_notify);
-+EXPORT_SYMBOL(zt_alarm_notify_no_master_change);
- EXPORT_SYMBOL(zt_set_dynamic_ioctl);
- EXPORT_SYMBOL(zt_ec_chunk);
- EXPORT_SYMBOL(zt_ec_span);
-@@ -2685,6 +2686,30 @@
-       }
- }
-+void zt_alarm_notify_no_master_change(struct zt_span *span)
-+{
-+      int j;
-+      int x;
-+
-+      span->alarms &= ~ZT_ALARM_LOOPBACK;
-+      /* Determine maint status */
-+      if (span->maintstat || span->mainttimer)
-+              span->alarms |= ZT_ALARM_LOOPBACK;
-+      /* DON'T CHANGE THIS AGAIN. THIS WAS DONE FOR A REASON.
-+         The expression (a != b) does *NOT* do the same thing
-+         as ((!a) != (!b)) */
-+      /* if change in general state */
-+      if ((!span->alarms) != (!span->lastalarms)) {
-+              if (span->alarms)
-+                      j = ZT_EVENT_ALARM;
-+              else
-+                      j = ZT_EVENT_NOALARM;
-+              span->lastalarms = span->alarms;
-+              for (x=0;x < span->channels;x++)
-+                      zt_qevent_lock(&span->chans[x], j);
-+      }
-+}
-+
- #define VALID_SPAN(j) do { \
-       if ((j >= ZT_MAX_SPANS) || (j < 1)) \
-               return -EINVAL; \
-@@ -4913,11 +4938,40 @@
-                                       *(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
-                               }
-                               bytes -= left;
-+#ifdef CONFIG_ZAPATA_BRI_DCHANS
-+                      } else if (ms->flags & ZT_FLAG_BRIDCHAN) {
-+                          /*
-+                           * Let's get this right, we want to transmit complete frames only.
-+                           * The card driver will do the dirty HDLC work for us.
-+                           * txb (transmit buffer) is supposed to be big enough to store one frame
-+                           * we will make this as big as the D fifo (1KB or 2KB)
-+                           */
-+
-+                          /* there are 'left' bytes in the user buffer left to transmit */
-+                          left = ms->writen[ms->outwritebuf] - ms->writeidx[ms->outwritebuf] - 2;
-+                          if (left > ms->maxbytes2transmit) {
-+                              memcpy(txb, buf + ms->writeidx[ms->outwritebuf], ms->maxbytes2transmit);
-+                              ms->writeidx[ms->outwritebuf] += ms->maxbytes2transmit;
-+                              txb += ms->maxbytes2transmit;
-+                              ms->bytes2transmit = ms->maxbytes2transmit;
-+                              ms->eoftx = 0;
-+                          } else {
-+                              memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
-+                              ms->writeidx[ms->outwritebuf] += left + 2;
-+                              txb += left;
-+                              ms->bytes2transmit = left;
-+                              ms->eoftx = 1;
-+                          }
-+                          bytes = 0;
-+#endif
-                       } else {
-                               memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
-                               ms->writeidx[ms->outwritebuf]+=left;
-                               txb += left;
-                               bytes -= left;
-+#if defined(CONFIG_ZAPATA_BRI_DCHANS) 
-+                              ms->bytes2transmit=ZT_CHUNKSIZE;
-+#endif
-                       }
-                       /* Check buffer status */
-                       if (ms->writeidx[ms->outwritebuf] >= ms->writen[ms->outwritebuf]) {
-@@ -4962,6 +5016,17 @@
-                               /* Transmit a flag if this is an HDLC channel */
-                               if (ms->flags & ZT_FLAG_HDLC)
-                                       fasthdlc_tx_frame_nocheck(&ms->txhdlc);
-+#if defined(CONFIG_ZAPATA_BRI_DCHANS) 
-+                              if(ms->flags & ZT_FLAG_BRIDCHAN) { 
-+                      //          if (ms->bytes2transmit > 0) {
-+                                      // txb += 2;
-+                                      // ms->bytes2transmit -= 2;
-+                                      bytes=0;
-+                                      ms->eoftx = 1;
-+//                                    printk(KERN_CRIT "zaptel EOF(%d) bytes2transmit %d\n",ms->eoftx,ms->bytes2transmit);
-+                      //          }
-+                              }
-+#endif
- #ifdef CONFIG_ZAPATA_NET
-                               if (ms->flags & ZT_FLAG_NETDEV)
-                                       netif_wake_queue(ztchan_to_dev(ms));
-@@ -4972,7 +5037,7 @@
-                                       tasklet_schedule(&ms->ppp_calls);
-                               }
- #endif
--                      }
-+                      } 
-               } else if (ms->curtone && !(ms->flags & ZT_FLAG_PSEUDO)) {
-                       left = ms->curtone->tonesamples - ms->tonep;
-                       if (left > bytes)
-@@ -5018,6 +5083,10 @@
-                               memset(txb, 0xFF, bytes);
-                       }
-                       bytes = 0;
-+#if defined(CONFIG_ZAPATA_BRI_DCHANS) 
-+              } else if(ms->flags & ZT_FLAG_BRIDCHAN) { 
-+                  bytes = 0;
-+#endif
-               } else {
-                       memset(txb, ZT_LIN2X(0, ms), bytes);    /* Lastly we use silence on telephony channels */
-                       bytes = 0;
-@@ -5743,6 +5812,13 @@
-       int left, x;
-       int bytes = ZT_CHUNKSIZE;
-+#if defined(CONFIG_ZAPATA_BRI_DCHANS) 
-+      if (ms->flags & ZT_FLAG_BRIDCHAN) {
-+          bytes = ms->bytes2receive;
-+          if (bytes < 1) return;
-+//        printk(KERN_CRIT "bytes2receive %d\n",ms->bytes2receive);
-+      }
-+#endif
-       while(bytes) {
- #if defined(CONFIG_ZAPATA_NET)  || defined(CONFIG_ZAPATA_PPP)
-@@ -5801,6 +5877,19 @@
-                                               }
-                                       }
-                               }
-+#ifdef CONFIG_ZAPATA_BRI_DCHANS
-+                      } else if (ms->flags & ZT_FLAG_BRIDCHAN) {
-+                          memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
-+                          rxb += left;
-+                          ms->readidx[ms->inreadbuf] += left;
-+                          bytes -= left;
-+                          if (ms->eofrx == 1) {
-+                              eof=1;
-+                          }
-+//                        printk(KERN_CRIT "receiving %d bytes\n",ms->bytes2receive);
-+                          ms->bytes2receive = 0;
-+                          ms->eofrx = 0;
-+#endif
-                       } else {
-                               /* Not HDLC */
-                               memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
-diff -urN zaptel-1.2.6.orig/zaptel.h zaptel-1.2.6/zaptel.h
---- zaptel-1.2.6.orig/zaptel.h 2005-12-17 03:04:05.000000000 +0100
-+++ zaptel-1.2.6/zaptel.h      2006-07-31 12:58:04.000000000 +0200
-@@ -994,6 +994,13 @@
-       int do_ppp_error;
-       struct sk_buff_head ppp_rq;
- #endif
-+#ifdef CONFIG_ZAPATA_BRI_DCHANS
-+      int bytes2receive;
-+      int maxbytes2transmit; /* size of the tx buffer in the card driver */
-+      int bytes2transmit;
-+      int eofrx;
-+      int eoftx;
-+#endif
-       spinlock_t lock;
-       char name[40];          /* Name */
-       /* Specified by zaptel */
-@@ -1068,7 +1075,7 @@
-       int             txbufpolicy;                    /* Buffer policy */
-       int             rxbufpolicy;                    /* Buffer policy */
-       int             txdisable;                              /* Disable transmitter */
--      int     rxdisable;                              /* Disable receiver */
-+      int             rxdisable;                              /* Disable receiver */
-       
-       
-       /* Tone zone stuff */
-@@ -1231,6 +1238,10 @@
- #define ZT_FLAG_T1PPP                 (1 << 15)
- #define ZT_FLAG_SIGFREEZE             (1 << 16)       /* Freeze signalling */
-+#if defined(CONFIG_ZAPATA_BRI_DCHANS) 
-+#define ZT_FLAG_BRIDCHAN              (1 << 17)
-+#endif
-+
- struct zt_span {
-       spinlock_t lock;
-       void *pvt;                      /* Private stuff */
-@@ -1404,6 +1415,9 @@
- /* Notify a change possible change in alarm status */
- extern void zt_alarm_notify(struct zt_span *span);
-+/* Notify a change possible change in alarm status, DONT change the zaptel master! */
-+extern void zt_alarm_notify_no_master_change(struct zt_span *span);
-+
- /* Initialize a tone state */
- extern void zt_init_tone_state(struct zt_tone_state *ts, struct zt_tone *zt);
-diff -urN zaptel-1.2.6.orig/zconfig.h zaptel-1.2.6/zconfig.h
---- zaptel-1.2.6.orig/zconfig.h        2005-11-29 19:42:08.000000000 +0100
-+++ zaptel-1.2.6/zconfig.h     2006-08-02 20:34:43.000000000 +0200
-@@ -49,11 +49,11 @@
- /* #define ECHO_CAN_MARK */
- /* #define ECHO_CAN_MARK2 */
- /* #define ECHO_CAN_MARK3 */
--#define ECHO_CAN_KB1
-+/* #define ECHO_CAN_KB1 */
- /* MG2 is a version of KB1 that has some changes to it that are
-  * supposed to improve how it performs.  If you have echo problems,
-  * try it out! */
--/* #define ECHO_CAN_MG2 */
-+#define ECHO_CAN_MG2
- /*
-  * Uncomment for aggressive residual echo supression under 
-@@ -152,4 +152,10 @@
-  */
- /* #define FXSFLASH */
-+/*
-+ * Uncomment the following for BRI D channels
-+ *
-+ */
-+#define CONFIG_ZAPATA_BRI_DCHANS
-+
- #endif
-diff -urN zaptel-1.2.6.orig/ztpty.c zaptel-1.2.6/ztpty.c
---- zaptel-1.2.6.orig/ztpty.c  1970-01-01 01:00:00.000000000 +0100
-+++ zaptel-1.2.6/ztpty.c       2006-06-06 14:54:33.000000000 +0200
-@@ -0,0 +1,112 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <fcntl.h>
-+#include <sys/time.h>
-+#include <sys/signal.h>
-+#include <sys/select.h>
-+#include <math.h>
-+#include "zaptel.h"
-+
-+#define SIZE 8000
-+
-+
-+
-+void doit(int fd, int stdinfd) {
-+    fd_set fds;
-+    char inbuffer[4096];
-+    char outbuffer[4096];
-+    int res = 0;
-+    int i = 0;
-+
-+//    fprintf(stderr, "fd %d stdin fd %d\n", fd, stdinfd);
-+
-+    for (;;) {
-+      FD_ZERO(&fds);
-+        FD_SET(fd, &fds);
-+      FD_SET(stdinfd, &fds);
-+        /* Wait for *some* sort of I/O */
-+        res = select(stdinfd + 1, &fds, NULL, NULL, NULL);
-+        if (res < 0) {
-+                fprintf(stderr, "Error in select: %s\n", strerror(errno));
-+                return;
-+        }
-+        if (FD_ISSET(stdinfd, &fds)) {
-+            res = read(stdinfd, inbuffer, sizeof(inbuffer));
-+          if (res > 0) {
-+//            fprintf(stderr, "read %d bytes from stdin\n", res);
-+              if (res > 0) {
-+                  for (i=0; i < res ; i++) {
-+                      if (inbuffer[i] == '\n') {
-+                          if ((i > 0) && (inbuffer[i-1] == ' ')) {
-+                              inbuffer[i-1] = 0x1a;
-+                          }
-+                          inbuffer[i] = 0xd;
-+                      }
-+                  }
-+              res = write(fd, inbuffer, res+2);
-+//            res = write(STDOUT_FILENO, inbuffer, res);
-+//            fprintf(stderr, "wrote %d bytes to stdout\n", res);
-+              }
-+          }
-+        }
-+        if (FD_ISSET(fd, &fds)) {
-+            res = read(fd, outbuffer, sizeof(outbuffer));
-+//        fprintf(stderr, "read %d bytes from fd\n", res);
-+          if (res > 0) {
-+              res = write(STDOUT_FILENO, outbuffer, res);
-+//            fprintf(stderr, "wrote %d bytes to stdout\n", res);
-+          }
-+        }
-+    }
-+
-+
-+}
-+
-+int main(int argc, char *argv[])
-+{
-+      int fd;
-+      int stdinfd;
-+      struct zt_params p;
-+      struct zt_bufferinfo bi;
-+      int blocksize=0;
-+      fd = open(argv[1], O_RDWR | O_NONBLOCK);
-+      if (fd < 0) {
-+              fprintf(stderr, "Unable to open zap interface: %s\n", strerror(errno));
-+              exit(1);
-+      }
-+      if (ioctl(fd, ZT_GET_PARAMS, &p)) {
-+              fprintf(stderr, "Unable to get parameters on '%s': %s\n", argv[1], strerror(errno));
-+              exit(1);
-+      }
-+      if ((p.sigtype != ZT_SIG_HDLCRAW) && (p.sigtype != ZT_SIG_HDLCFCS)) {
-+              fprintf(stderr, "%s is in %d signalling, not FCS HDLC or RAW HDLC mode\n", argv[1], p.sigtype);
-+              exit(1);
-+      }
-+
-+      if (ioctl(fd, ZT_GET_BLOCKSIZE, &blocksize)) {
-+              fprintf(stderr, "Unable to get blocksize on '%s': %s\n", argv[1], strerror(errno));
-+              exit(1);
-+      } else {
-+//            fprintf(stderr, "blocksize %d\n", blocksize);
-+      }
-+      
-+      bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
-+        bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
-+      bi.numbufs = 16;
-+      bi.bufsize = 1024;
-+      if (ioctl(fd, ZT_SET_BUFINFO, &bi)) {
-+              fprintf(stderr, "Unable to set buffer info on '%s': %s\n", argv[1], strerror(errno));
-+              exit(1);
-+      }
-+
-+      stdinfd = open("/dev/stdin", O_RDONLY | O_NONBLOCK);
-+
-+      
-+      doit(fd, stdinfd);
-+      close(stdinfd);
-+      close(fd);
-+      return 0;
-+}