[Pkg-voip-commits] r888 - in asterisk/trunk/debian: . patches
Mark Purcell
msp at costa.debian.org
Sun Oct 30 23:21:19 UTC 2005
Author: msp
Date: 2005-10-30 23:21:17 +0000 (Sun, 30 Oct 2005)
New Revision: 888
Removed:
asterisk/trunk/debian/patches/bristuff-0.2.0-RC8h.dpatch
asterisk/trunk/debian/patches/bristuff-0.2.0-RC8j.dpatch
Modified:
asterisk/trunk/debian/control
asterisk/trunk/debian/patches/00list
asterisk/trunk/debian/patches/30_ast-data-dir.dpatch
asterisk/trunk/debian/patches/98_fpm-sounds.dpatch
asterisk/trunk/debian/rules
Log:
Buildable 1.2.0-beta1
Modified: asterisk/trunk/debian/control
===================================================================
--- asterisk/trunk/debian/control 2005-10-30 21:14:37 UTC (rev 887)
+++ asterisk/trunk/debian/control 2005-10-30 23:21:17 UTC (rev 888)
@@ -48,19 +48,6 @@
depend on the many openh323 dependencies. For now asterisk-oh323 replaces this
version until chan_h323 does support the current OpenH323 version again.
-Package: asterisk-gtk-console
-Architecture: any
-Recommends: asterisk
-Replaces: asterisk (<= 1.0.2-1)
-Section: comm
-Depends: ${shlibs:Depends}
-Description: gtk based console for asterisk
- This package provides a limited GTK based console for the Asterisk Open Source
- PBX system.
- .
- It was separated out into its own package to avoid having the main package
- depend on xlibs and gtk-1.2
-
Package: asterisk-doc
Recommends: asterisk
Conflicts: asterisk (<=0.1.12-3)
Modified: asterisk/trunk/debian/patches/00list
===================================================================
--- asterisk/trunk/debian/patches/00list 2005-10-30 21:14:37 UTC (rev 887)
+++ asterisk/trunk/debian/patches/00list 2005-10-30 23:21:17 UTC (rev 888)
@@ -1,13 +1,13 @@
-defaults_debian
-Makefile_install_no1234
+#defaults_debian
+#Makefile_install_no1234
# Depends on defaults_debian:
-Makefile_datafiles
+#Makefile_datafiles
#bristuff-0.2.0-RC8j.dpatch
option_detach_12
#10_DPIC.dpatch
#20_Makefile.dpatch
#25_subdirs_Makefiles.dpatch
-#30_ast-data-dir.dpatch
+30_ast-data-dir.dpatch
40_initgroups.dpatch
system_libgsm
#50_debian-libgsm.dpatch
@@ -16,7 +16,7 @@
# app_sql_postgres seems "obsolete" and not used by default:
#70_debian-libpe-fe.dpatch
95_conf_sample.dpatch
-#98_fpm-sounds.dpatch
+98_fpm-sounds.dpatch
##08_debian-zaptel.dpatch
#chan-modem.dpatch
#app_queue.memleakfix.dpatch
Modified: asterisk/trunk/debian/patches/30_ast-data-dir.dpatch
===================================================================
--- asterisk/trunk/debian/patches/30_ast-data-dir.dpatch 2005-10-30 21:14:37 UTC (rev 887)
+++ asterisk/trunk/debian/patches/30_ast-data-dir.dpatch 2005-10-30 23:21:17 UTC (rev 888)
@@ -1,6 +1,5 @@
#! /bin/sh /usr/share/dpatch/dpatch-run
## ast_data_dir.dpatch by Mark Purcell <msp at debian.org>
-## data_dir.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Patch to make Asterisk conform with the Linux File System Hierarchy Standard (FHS)
@@ -8,74 +7,83 @@
## DP: not /var/lib/asterisk
@DPATCH@
-diff -urNad asterisk-1.0.8.dfsg.1/astconf.h /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/astconf.h
---- asterisk-1.0.8.dfsg.1/astconf.h 2003-01-30 17:03:20.000000000 +0200
-+++ /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/astconf.h 2005-06-25 16:04:49.000000000 +0300
-@@ -19,6 +19,7 @@
- extern char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH];
- extern char ast_config_AST_CONFIG_FILE[AST_CONFIG_MAX_PATH];
- extern char ast_config_AST_MODULE_DIR[AST_CONFIG_MAX_PATH];
-+extern char ast_config_AST_DATA_DIR[AST_CONFIG_MAX_PATH];
- extern char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH];
- extern char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH];
- extern char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH];
-diff -urNad asterisk-1.0.8.dfsg.1/asterisk.c /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/asterisk.c
---- asterisk-1.0.8.dfsg.1/asterisk.c 2005-05-16 06:04:58.000000000 +0300
-+++ /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/asterisk.c 2005-06-25 16:08:30.000000000 +0300
-@@ -119,6 +119,7 @@
+diff -urNad asterisk-1.2.0-beta1.dfsg~/asterisk.c asterisk-1.2.0-beta1.dfsg/asterisk.c
+--- asterisk-1.2.0-beta1.dfsg~/asterisk.c 2005-10-30 22:40:47.000000000 +0000
++++ asterisk-1.2.0-beta1.dfsg/asterisk.c 2005-10-30 22:40:48.000000000 +0000
+@@ -142,6 +142,7 @@
+ char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH];
+ char ast_config_AST_MONITOR_DIR[AST_CONFIG_MAX_PATH];
char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH];
++char ast_config_AST_DATA_DIR[AST_CONFIG_MAX_PATH];
char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH];
char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH];
-+char ast_config_AST_DATA_DIR[AST_CONFIG_MAX_PATH];
char ast_config_AST_DB[AST_CONFIG_MAX_PATH];
- char ast_config_AST_KEY_DIR[AST_CONFIG_MAX_PATH];
- char ast_config_AST_PID[AST_CONFIG_MAX_PATH];
-@@ -1506,6 +1507,7 @@
- strncpy((char *)ast_config_AST_VAR_DIR,AST_VAR_DIR,sizeof(ast_config_AST_VAR_DIR)-1);
- strncpy((char *)ast_config_AST_LOG_DIR,AST_LOG_DIR,sizeof(ast_config_AST_LOG_DIR)-1);
- strncpy((char *)ast_config_AST_AGI_DIR,AST_AGI_DIR,sizeof(ast_config_AST_AGI_DIR)-1);
-+ strncpy((char *)ast_config_AST_DATA_DIR,AST_DATA_DIR,sizeof(ast_config_AST_DATA_DIR)-1);
- strncpy((char *)ast_config_AST_DB,AST_DB,sizeof(ast_config_AST_DB)-1);
- strncpy((char *)ast_config_AST_KEY_DIR,AST_KEY_DIR,sizeof(ast_config_AST_KEY_DIR)-1);
- strncpy((char *)ast_config_AST_PID,AST_PID,sizeof(ast_config_AST_PID)-1);
-diff -urNad asterisk-1.0.8.dfsg.1/asterisk.h /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/asterisk.h
---- asterisk-1.0.8.dfsg.1/asterisk.h 2004-09-07 18:02:53.000000000 +0300
-+++ /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/asterisk.h 2005-06-25 16:03:15.000000000 +0300
-@@ -24,6 +24,7 @@
- #define AST_MODULE_DIR ASTMODDIR
- #define AST_SPOOL_DIR ASTSPOOLDIR
- #define AST_VAR_DIR ASTVARLIBDIR
-+#define AST_DATA_DIR ASTDATADIR
- #define AST_LOG_DIR ASTLOGDIR
- #define AST_AGI_DIR ASTAGIDIR
- #define AST_KEY_DIR ASTVARLIBDIR "/keys"
-@@ -32,8 +33,8 @@
+@@ -1698,6 +1699,7 @@
+ ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_VAR_DIR));
+ snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR);
+ ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR));
++ ast_copy_string(ast_config_AST_DATA_DIR, AST_DATA_DIR, sizeof(ast_config_AST_DATA_DIR));
+ ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR));
+ ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR));
+ ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB));
+@@ -1733,6 +1735,8 @@
+ } else if (!strcasecmp(v->name, "astvarlibdir")) {
+ ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR));
+ snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/%s", v->value, "astdb");
++ } else if (!strcasecmp(v->name, "astdatadir")) {
++ ast_copy_string(ast_config_AST_DATA_DIR, v->value, sizeof(ast_config_AST_DATA_DIR));
+ } else if (!strcasecmp(v->name, "astlogdir")) {
+ ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR));
+ } else if (!strcasecmp(v->name, "astagidir")) {
+diff -urNad asterisk-1.2.0-beta1.dfsg~/build_tools/make_defaults_h asterisk-1.2.0-beta1.dfsg/build_tools/make_defaults_h
+--- asterisk-1.2.0-beta1.dfsg~/build_tools/make_defaults_h 2005-06-20 18:26:07.000000000 +0100
++++ asterisk-1.2.0-beta1.dfsg/build_tools/make_defaults_h 2005-10-30 22:40:48.000000000 +0000
+@@ -11,6 +11,7 @@
+ #define AST_MODULE_DIR "${INSTALL_PATH}${MODULES_DIR}"
+ #define AST_SPOOL_DIR "${INSTALL_PATH}${ASTSPOOLDIR}"
+ #define AST_VAR_DIR "${INSTALL_PATH}${ASTVARLIBDIR}"
++#define AST_DATA_DIR "${INSTALL_PATH}${ASTDATADIR}"
+ #define AST_LOG_DIR "${INSTALL_PATH}${ASTLOGDIR}"
+ #define AST_AGI_DIR "${INSTALL_PATH}${AGI_DIR}"
+ #define AST_KEY_DIR "${INSTALL_PATH}${ASTVARLIBDIR}/keys"
+@@ -19,7 +20,7 @@
- #define AST_CONFIG_FILE ASTCONFPATH
+ #define AST_CONFIG_FILE "${INSTALL_PATH}${ASTCONFPATH}"
--#define AST_SOUNDS AST_VAR_DIR "/sounds"
--#define AST_IMAGES AST_VAR_DIR "/images"
-+#define AST_SOUNDS AST_DATA_DIR "/sounds"
-+#define AST_IMAGES AST_DATA_DIR "/images"
+-#define AST_SOUNDS "${INSTALL_PATH}${ASTVARLIBDIR}/sounds"
+-#define AST_IMAGES "${INSTALL_PATH}${ASTVARLIBDIR}/images"
++#define AST_SOUNDS "${INSTALL_PATH}${ASTDATADIR}/sounds"
++#define AST_IMAGES "${INSTALL_PATH}${ASTDATADIR}/images"
- /* Provided by module.c */
- extern int load_modules(void);
-diff -urNad asterisk-1.0.8.dfsg.1/file.c /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/file.c
---- asterisk-1.0.8.dfsg.1/file.c 2005-06-14 21:41:48.000000000 +0300
-+++ /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/file.c 2005-06-25 16:03:15.000000000 +0300
-@@ -284,7 +284,7 @@
- int fnsize = 0;
- char tmp[AST_CONFIG_MAX_PATH]="";
+ END
+diff -urNad asterisk-1.2.0-beta1.dfsg~/configs/musiconhold.conf.sample asterisk-1.2.0-beta1.dfsg/configs/musiconhold.conf.sample
+--- asterisk-1.2.0-beta1.dfsg~/configs/musiconhold.conf.sample 2005-08-25 17:11:46.000000000 +0100
++++ asterisk-1.2.0-beta1.dfsg/configs/musiconhold.conf.sample 2005-10-30 22:40:48.000000000 +0000
+@@ -4,7 +4,7 @@
-- snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_VAR_DIR, "sounds");
-+ snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_DATA_DIR, "sounds");
- fnsize = strlen(tmp) + strlen(filename) + strlen(ext) + 10;
- fn = malloc(fnsize);
- if (fn) {
-diff -urNad asterisk-1.0.8.dfsg.1/image.c /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/image.c
---- asterisk-1.0.8.dfsg.1/image.c 2004-06-22 21:48:59.000000000 +0300
-+++ /tmp/dpep.RIoflc/asterisk-1.0.8.dfsg.1/image.c 2005-06-25 16:03:15.000000000 +0300
-@@ -95,9 +95,9 @@
+ [default]
+ mode=quietmp3
+-directory=/var/lib/asterisk/mohmp3
++directory=/usr/share/asterisk/mohmp3
+
+ ; valid mode options:
+ ; quietmp3 -- default
+diff -urNad asterisk-1.2.0-beta1.dfsg~/file.c asterisk-1.2.0-beta1.dfsg/file.c
+--- asterisk-1.2.0-beta1.dfsg~/file.c 2005-08-23 16:43:47.000000000 +0100
++++ asterisk-1.2.0-beta1.dfsg/file.c 2005-10-30 22:40:48.000000000 +0000
+@@ -301,7 +301,7 @@
+ } else {
+ char tmp[AST_CONFIG_MAX_PATH] = "";
+
+- snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_VAR_DIR, "sounds");
++ snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_DATA_DIR, "sounds");
+ fnsize = strlen(tmp) + strlen(filename) + strlen(type) + 3;
+ fn = malloc(fnsize);
+ if (fn)
+diff -urNad asterisk-1.2.0-beta1.dfsg~/image.c asterisk-1.2.0-beta1.dfsg/image.c
+--- asterisk-1.2.0-beta1.dfsg~/image.c 2005-06-06 23:12:18.000000000 +0100
++++ asterisk-1.2.0-beta1.dfsg/image.c 2005-10-30 22:40:48.000000000 +0000
+@@ -97,9 +97,9 @@
snprintf(buf, len, "%s.%s", filename, ext);
} else {
if (preflang && strlen(preflang))
@@ -87,40 +95,51 @@
}
}
-diff -urNad --exclude=CVS --exclude=.svn ./Makefile /tmp/dpep-work.ozrhX4/asterisk-1.0.9.dfsg/Makefile
---- ./Makefile 2005-07-05 20:29:57.404767424 +0100
-+++ /tmp/dpep-work.ozrhX4/asterisk-1.0.9.dfsg/Makefile 2005-07-05 20:29:57.669727144 +0100
-@@ -84,11 +84,12 @@
+diff -urNad asterisk-1.2.0-beta1.dfsg~/include/asterisk.h asterisk-1.2.0-beta1.dfsg/include/asterisk.h
+--- asterisk-1.2.0-beta1.dfsg~/include/asterisk.h 2005-08-23 02:30:22.000000000 +0100
++++ asterisk-1.2.0-beta1.dfsg/include/asterisk.h 2005-10-30 22:41:27.000000000 +0000
+@@ -25,6 +25,7 @@
+ extern char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH];
+ extern char ast_config_AST_MONITOR_DIR[AST_CONFIG_MAX_PATH];
+ extern char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH];
++extern char ast_config_AST_DATA_DIR[AST_CONFIG_MAX_PATH];
+ extern char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH];
+ extern char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH];
+ extern char ast_config_AST_DB[AST_CONFIG_MAX_PATH];
+diff -urNad asterisk-1.2.0-beta1.dfsg~/Makefile asterisk-1.2.0-beta1.dfsg/Makefile
+--- asterisk-1.2.0-beta1.dfsg~/Makefile 2005-08-26 20:55:11.000000000 +0100
++++ asterisk-1.2.0-beta1.dfsg/Makefile 2005-10-30 22:40:48.000000000 +0000
+@@ -95,6 +95,7 @@
+ ifneq (${OSARCH},SunOS)
+ ASTLIBDIR=$(INSTALL_PREFIX)/usr/lib/asterisk
+ ASTVARLIBDIR=$(INSTALL_PREFIX)/var/lib/asterisk
++ASTDATADIR=$(INSTALL_PREFIX)/usr/share/asterisk
+ ASTETCDIR=$(INSTALL_PREFIX)/etc/asterisk
+ ASTSPOOLDIR=$(INSTALL_PREFIX)/var/spool/asterisk
+ ASTLOGDIR=$(INSTALL_PREFIX)/var/log/asterisk
+@@ -102,10 +103,10 @@
ASTCONFPATH=$(ASTETCDIR)/asterisk.conf
ASTBINDIR=$(INSTALL_PREFIX)/usr/bin
ASTSBINDIR=$(INSTALL_PREFIX)/usr/sbin
-ASTVARRUNDIR=$(INSTALL_PREFIX)/var/run
+ASTVARRUNDIR=$(INSTALL_PREFIX)/var/run/asterisk
-+ASTDATADIR=$(INSTALL_PREFIX)/usr/share/asterisk
ASTMANDIR=$(INSTALL_PREFIX)/usr/share/man
-
MODULES_DIR=$(ASTLIBDIR)/modules
-AGI_DIR=$(ASTVARLIBDIR)/agi-bin
+AGI_DIR=$(ASTDATADIR)/agi-bin
+ else
+ ASTLIBDIR=$(INSTALL_PREFIX)/opt/asterisk/lib
+ ASTVARLIBDIR=$(INSTALL_PREFIX)/var/opt/asterisk/lib
+@@ -443,38 +444,38 @@
- INCLUDE=-Iinclude -I../include
- CFLAGS=-pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations $(DEBUG) $(INCLUDE) -D_REENTRANT -D_GNU_SOURCE #-DMAKE_VALGRIND_HAPPY
-@@ -138,6 +139,7 @@
- CFLAGS+=-DASTVARLIBDIR=\"$(ASTVARLIBDIR)\"
- CFLAGS+=-DASTVARRUNDIR=\"$(ASTVARRUNDIR)\"
- CFLAGS+=-DASTSPOOLDIR=\"$(ASTSPOOLDIR)\"
-+CFLAGS+=-DASTDATADIR=\"$(ASTDATADIR)\"
- CFLAGS+=-DASTLOGDIR=\"$(ASTLOGDIR)\"
- CFLAGS+=-DASTCONFPATH=\"$(ASTCONFPATH)\"
- CFLAGS+=-DASTMODDIR=\"$(MODULES_DIR)\"
-@@ -279,28 +281,28 @@
- $(MAKE) -C stdtime clean
-
datafiles: all
+ sh mkpkgconfig $(DESTDIR)/usr/lib/pkgconfig
- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/digits
+- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/priv-callerintros
+ mkdir -p $(DESTDIR)$(ASTDATADIR)/sounds/digits
++ mkdir -p $(DESTDIR)$(ASTDATADIR)/sounds/priv-callerintros
for x in sounds/digits/*.gsm; do \
- if grep -q "^%`basename $$x`%" sounds.txt; then \
+ if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/digits ; \
+ install -m 644 $$x $(DESTDIR)$(ASTDATADIR)/sounds/digits ; \
else \
@@ -128,10 +147,21 @@
exit 1; \
fi; \
done
+- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/dictate
++ mkdir -p $(DESTDIR)$(ASTDATADIR)/sounds/dictate
+ for x in sounds/dictate/*.gsm; do \
+ if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
+- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/dictate ; \
++ install -m 644 $$x $(DESTDIR)$(ASTDATADIR)/sounds/dictate ; \
+ else \
+ echo "No description for $$x"; \
+ exit 1; \
+ fi; \
+ done
- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/letters
+ mkdir -p $(DESTDIR)$(ASTDATADIR)/sounds/letters
for x in sounds/letters/*.gsm; do \
- if grep -q "^%`basename $$x`%" sounds.txt; then \
+ if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/letters ; \
+ install -m 644 $$x $(DESTDIR)$(ASTDATADIR)/sounds/letters ; \
else \
@@ -142,16 +172,16 @@
- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/phonetic
+ mkdir -p $(DESTDIR)$(ASTDATADIR)/sounds/phonetic
for x in sounds/phonetic/*.gsm; do \
- if grep -q "^%`basename $$x`%" sounds.txt; then \
+ if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/phonetic ; \
+ install -m 644 $$x $(DESTDIR)$(ASTDATADIR)/sounds/phonetic ; \
else \
echo "No description for $$x"; \
exit 1; \
-@@ -308,16 +310,16 @@
+@@ -482,16 +483,16 @@
done
- for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-* sounds/agent-* sounds/invalid* sounds/tt-* sounds/auth-* sounds/privacy-* sounds/queue-*; do \
- if grep -q "^%`basename $$x`%" sounds.txt; then \
+ for x in sounds/demo-* sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-* sounds/agent-* sounds/invalid* sounds/tt-* sounds/auth-* sounds/privacy-* sounds/queue-*; do \
+ if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
+ install -m 644 $$x $(DESTDIR)$(ASTDATADIR)/sounds ; \
else \
@@ -159,7 +189,7 @@
exit 1; \
fi; \
done
-- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/mohmp3
+- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/mohmp3
- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/images
+ mkdir -p $(DESTDIR)$(ASTDATADIR)/mohmp3
+ mkdir -p $(DESTDIR)$(ASTDATADIR)/images
@@ -169,63 +199,48 @@
done
mkdir -p $(DESTDIR)$(AGI_DIR)
-@@ -337,6 +339,7 @@
+@@ -539,6 +540,7 @@
+ mkdir -p $(DESTDIR)$(ASTETCDIR)
mkdir -p $(DESTDIR)$(ASTBINDIR)
- mkdir -p $(DESTDIR)$(ASTSBINDIR)
mkdir -p $(DESTDIR)$(ASTVARRUNDIR)
+ mkdir -p $(DESTDIR)$(ASTDATADIR)
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail
- mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/tmp
- install -m 755 asterisk $(DESTDIR)$(ASTSBINDIR)/
-@@ -348,16 +351,16 @@
- for x in $(SUBDIRS); do $(MAKE) -C $$x install || exit 1 ; done
- install -d $(DESTDIR)$(ASTHEADERDIR)
- install -m 644 include/asterisk/*.h $(DESTDIR)$(ASTHEADERDIR)
-- rm -f $(DESTDIR)$(ASTVARLIBDIR)/sounds/vm
-- rm -f $(DESTDIR)$(ASTVARLIBDIR)/sounds/voicemail
-+ rm -f $(DESTDIR)$(ASTDATADIR)/sounds/vm
-+ rm -f $(DESTDIR)$(ASTDATADIR)/sounds/voicemail
- if [ ! -h $(DESTDIR)$(ASTSPOOLDIR)/vm ] && [ -d $(DESTDIR)$(ASTSPOOLDIR)/vm ]; then \
- mv $(DESTDIR)$(ASTSPOOLDIR)/vm $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default; \
- else \
- mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default; \
- rm -f $(DESTDIR)$(ASTSPOOLDIR)/vm; \
+ mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/dictate
+ mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/system
+@@ -556,8 +558,8 @@
+ if [ -n "$(OLDHEADERS)" ]; then \
+ rm -f $(addprefix $(DESTDIR)$(ASTHEADERDIR)/,$(OLDHEADERS)) ;\
fi
-- ln -s $(ASTSPOOLDIR)/voicemail/default $(DESTDIR)$(ASTSPOOLDIR)/vm
+- rm -f $(DESTDIR)$(ASTVARLIBDIR)/sounds/voicemail
- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds
-+ ln -s ../voicemail/default $(DESTDIR)$(ASTSPOOLDIR)/vm
++ rm -f $(DESTDIR)$(ASTDATADIR)/sounds/voicemail
+ mkdir -p $(DESTDIR)$(ASTDATADIR)/sounds
mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-csv
+ mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-custom
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/keys
- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/firmware
-@@ -371,8 +374,8 @@
+@@ -575,7 +577,7 @@
else \
echo "You need to do cvs update -d not just cvs update" ; \
fi
-- ( cd $(DESTDIR)$(ASTVARLIBDIR)/sounds ; ln -s $(ASTSPOOLDIR)/vm . )
- ( cd $(DESTDIR)$(ASTVARLIBDIR)/sounds ; ln -s $(ASTSPOOLDIR)/voicemail . )
-+ ( cd $(DESTDIR)$(ASTDATADIR)/sounds ; ln -s /var/spool/asterisk/vm . )
+ ( cd $(DESTDIR)$(ASTDATADIR)/sounds ; ln -s /var/spool/asterisk/voicemail . )
if [ -f mpg123-0.59r/mpg123 ]; then $(MAKE) -C mpg123-0.59r install; fi
@echo " +---- Asterisk Installation Complete -------+"
@echo " + +"
-@@ -441,24 +444,24 @@
- echo "uniquename = asterisk" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
+@@ -669,10 +671,10 @@
+ else \
+ echo "Skipping asterisk.conf creation"; \
+ fi
+- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
++ mkdir -p $(DESTDIR)$(ASTDATADIR)/sounds ; \
for x in sounds/demo-*; do \
- if grep -q "^%`basename $$x`%" sounds.txt; then \
+ if $(GREP) -q "^%`basename $$x`%" sounds.txt; then \
- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
+ install -m 644 $$x $(DESTDIR)$(ASTDATADIR)/sounds ; \
else \
echo "No description for $$x"; \
exit 1; \
- fi; \
- done
- for x in sounds/*.mp3; do \
-- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/mohmp3 ; \
-+ install -m 644 $$x $(DESTDIR)$(ASTDATADIR)/mohmp3 ; \
- done
-- rm -f $(DESTDIR)$(ASTVARLIBDIR)/mohmp3/sample-hold.mp3
-+ rm -f $(DESTDIR)$(ASTDATADIR)/mohmp3/sample-hold.mp3
+@@ -686,11 +688,11 @@
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/INBOX
:> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/unavail.gsm
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
@@ -239,27 +254,3 @@
done
webvmail:
-diff -urNad --exclude=CVS --exclude=.svn ./pbx/pbx_wilcalu.c /tmp/dpep-work.ozrhX4/asterisk-1.0.9.dfsg/pbx/pbx_wilcalu.c
---- ./pbx/pbx_wilcalu.c 2005-07-05 20:29:57.334778064 +0100
-+++ /tmp/dpep-work.ozrhX4/asterisk-1.0.9.dfsg/pbx/pbx_wilcalu.c 2005-07-05 20:29:57.669727144 +0100
-@@ -12,7 +12,7 @@
- * the GNU General Public License
-
- * Autodialer for Asterisk
-- * Redirect dialstring thru fifo "/var/run/autodial.ctl"
-+ * Redirect dialstring thru fifo "/var/run/asterisk/autodial.ctl"
- * Format of string is :
- * "tech/tele,filename&" ie. "tor1/23,file&"
- */
-diff -urNad asterisk-1.0.2/configs/musiconhold.conf.sample /tmp/dpep.lTPo9n/asterisk-1.0.2/configs/musiconhold.conf.sample
---- asterisk-1.0.2/configs/musiconhold.conf.sample 2004-08-01 16:19:04.000000000 +0200
-+++ /tmp/dpep.lTPo9n/asterisk-1.0.2/configs/musiconhold.conf.sample 2005-01-04 21:38:42.000000000 +0100
-@@ -2,7 +2,7 @@
- ; Music on hold class definitions
- ;
- [classes]
--default => quietmp3:/var/lib/asterisk/mohmp3
-+default => quietmp3:/usr/share/asterisk/mohmp3
- ;loud => mp3:/var/lib/asterisk/mohmp3
- ;random => quietmp3:/var/lib/asterisk/mohmp3,-z
- ;unbuffered => mp3nb:/var/lib/asterisk/mohmp3
Modified: asterisk/trunk/debian/patches/98_fpm-sounds.dpatch
===================================================================
--- asterisk/trunk/debian/patches/98_fpm-sounds.dpatch 2005-10-30 21:14:37 UTC (rev 887)
+++ asterisk/trunk/debian/patches/98_fpm-sounds.dpatch 2005-10-30 23:21:17 UTC (rev 888)
@@ -5,16 +5,18 @@
## DP: Don't try to install non-dfsg sounds from source
@DPATCH@
-diff -urNad asterisk-1.0.3/Makefile /tmp/dpep.r0xJTd/asterisk-1.0.3/Makefile
---- asterisk-1.0.3/Makefile 2005-01-15 11:02:32.000000000 +0100
-+++ /tmp/dpep.r0xJTd/asterisk-1.0.3/Makefile 2005-01-15 11:02:32.000000000 +0100
-@@ -433,9 +433,6 @@
+diff -urNad asterisk-1.2.0-beta1.dfsg~/Makefile asterisk-1.2.0-beta1.dfsg/Makefile
+--- asterisk-1.2.0-beta1.dfsg~/Makefile 2005-08-26 20:55:11.000000000 +0100
++++ asterisk-1.2.0-beta1.dfsg/Makefile 2005-10-25 20:57:34.000000000 +0100
+@@ -678,11 +678,6 @@
exit 1; \
fi; \
done
+- mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/mohmp3 ; \
- for x in sounds/*.mp3; do \
-- install -m 644 $$x $(DESTDIR)$(ASTDATADIR)/mohmp3 ; \
+- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/mohmp3 ; \
- done
- rm -f $(DESTDIR)$(ASTDATADIR)/mohmp3/sample-hold.mp3
+- rm -f $(DESTDIR)$(ASTVARLIBDIR)/mohmp3/sample-hold.mp3
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/INBOX
:> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/unavail.gsm
+ for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
Deleted: asterisk/trunk/debian/patches/bristuff-0.2.0-RC8h.dpatch
===================================================================
--- asterisk/trunk/debian/patches/bristuff-0.2.0-RC8h.dpatch 2005-10-30 21:14:37 UTC (rev 887)
+++ asterisk/trunk/debian/patches/bristuff-0.2.0-RC8h.dpatch 2005-10-30 23:21:17 UTC (rev 888)
@@ -1,5571 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## bristuff-0.2.0-RC8h.dpatch by <msp at debian.org>
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: From http://www.junghanns.net/asterisk/downloads/bristuff-0.2.0-RC8h.tar.gz
-
- at DPATCH@
-diff -urNad --exclude=CVS --exclude=.svn ./app_devstate.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/app_devstate.c
---- ./app_devstate.c 1970-01-01 01:00:00.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/app_devstate.c 2005-07-03 13:25:34.657107448 +0100
-@@ -0,0 +1,196 @@
-+/*
-+ * Devstate application
-+ *
-+ * Since we like the snom leds so much, a little app to
-+ * light the lights on the snom on demand ....
-+ *
-+ * Copyright (C) 2005, Druid Software
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include <asterisk/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 <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.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)
-+ return RESULT_SHOWUSAGE;
-+
-+ if (ast_db_put("DEVSTATES", argv[1], argv[2]))
-+ {
-+ ast_log(LOG_DEBUG, "ast_db_put failed\n");
-+ }
-+
-+ snprintf(devName, sizeof(devName), "DS/%s", argv[1]);
-+ ast_device_state_changed(devName);
-+ 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(devName);
-+
-+ 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 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 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;
-+ }
-+
-+ ast_mutex_lock(&s->lock);
-+
-+ if (!ast_db_put("DEVSTATES", devstate, value)) {
-+ snprintf(devName, sizeof(devName), "DS/%s", devstate);
-+ ast_device_state_changed(devName);
-+ 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");
-+ ast_mutex_unlock(&s->lock);
-+ return 0;
-+}
-+
-+int load_module(void)
-+{
-+ if (ast_channel_register_ex(type, tdesc, ((AST_FORMAT_MAX_AUDIO << 1) - 1), NULL, ds_devicestate)) {
-+ 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(type);
-+ return res;
-+}
-+
-+char *description(void)
-+{
-+ return tdesc;
-+}
-+
-+int usecount(void)
-+{
-+ int res;
-+ STANDARD_USECOUNT(res);
-+ return res;
-+}
-+
-+char *key()
-+{
-+ return ASTERISK_GPL_KEY;
-+}
-diff -urNad --exclude=CVS --exclude=.svn ./app_pickup.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/app_pickup.c
---- ./app_pickup.c 1970-01-01 01:00:00.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/app_pickup.c 2005-07-03 13:25:34.657107448 +0100
-@@ -0,0 +1,289 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * Pickup, channel independent call pickup
-+ *
-+ * Copyright (C) 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ * Copyright (C) 2004, Florian Overkamp <florian at obsimref.com>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include <asterisk/lock.h>
-+#include <asterisk/file.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/channel_pvt.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/module.h>
-+#include <asterisk/features.h>
-+#include <asterisk/options.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <signal.h>
-+
-+#include <pthread.h>
-+
-+
-+static char *tdesc = "PickUp/PickDown/Steal/PickupChan";
-+
-+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";
-+
-+
-+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';
-+ }
-+ /* 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;
-+}
-+
-+int unload_module(void)
-+{
-+ STANDARD_HANGUP_LOCALUSERS;
-+ ast_unregister_application(app4);
-+ ast_unregister_application(app3);
-+ ast_unregister_application(app2);
-+ return ast_unregister_application(app);
-+}
-+
-+int load_module(void)
-+{
-+ 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 -urNad --exclude=CVS --exclude=.svn ./apps/app_chanisavail.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_chanisavail.c
---- ./apps/app_chanisavail.c 2004-12-30 21:46:39.000000000 +0000
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_chanisavail.c 2005-07-03 13:25:34.658107296 +0100
-@@ -81,7 +81,7 @@
- }
- *number = '\0';
- number++;
-- if ((tempchan = ast_request(tech, chan->nativeformats, number))) {
-+ if ((tempchan = ast_request(tech, chan->nativeformats, number, NULL))) {
- pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
- /* Store the originally used channel too */
- snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_dial.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_dial.c
---- ./apps/app_dial.c 2005-05-12 02:43:36.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_dial.c 2005-07-03 13:25:34.660106992 +0100
-@@ -7,6 +7,10 @@
- *
- * Mark Spencer <markster at digium.com>
- *
-+ * Copyright (C) 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-@@ -56,6 +60,8 @@
- "n is the priority of the dialer instance), then it will be the next\n"
- "executed extension (this allows you to setup different behavior on busy from\n"
- "no-answer).\n"
-+"If an extension with priority +201 exists and there was no channel available\n"
-+"we will go there instead. So unregisterd VoIP phones will not be treaded as busy.\n"
- " This application returns -1 if the originating channel hangs up, or if the\n"
- "call is bridged and either of the parties in the bridge terminate the call.\n"
- "The option string may contain zero or more of the following characters:\n"
-@@ -66,6 +72,8 @@
- " don't allow callerids from other extensions then the ones\n"
- " that are assigned to you.\n"
- " 'r' -- indicate ringing to the calling party, pass no audio until answered.\n"
-+" 'R' -- indicate ringing to the calling party when the called party indicates\n"
-+" ringing, pass no audio until answered.\n"
- " 'm' -- provide hold music to the calling party until answered.\n"
- " 'M(x) -- Executes the macro (x) upon connect of the call\n"
- " 'h' -- allow callee to hang up by hitting *.\n"
-@@ -109,6 +117,7 @@
- int allowredirect_in;
- int allowredirect_out;
- int ringbackonly;
-+ int noinband;
- int musiconhold;
- int allowdisconnect_in;
- int allowdisconnect_out;
-@@ -151,7 +160,7 @@
- int single;
- struct ast_channel *winner;
-
-- single = (outgoing && !outgoing->next && !outgoing->musiconhold && !outgoing->ringbackonly);
-+ single = (outgoing && !outgoing->next && !outgoing->musiconhold && !outgoing->ringbackonly && !outgoing->noinband);
-
- if (single) {
- /* Turn off hold music, etc */
-@@ -180,12 +189,13 @@
- if (numlines == (numbusy + numcongestion + numnochan)) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time\n");
-- if (numbusy)
-+ if (numnochan) {
-+ strncpy(status, "CHANUNAVAIL", statussize - 1);
-+ } else if (numbusy) {
- strncpy(status, "BUSY", statussize - 1);
-- else if (numcongestion)
-+ } else if (numcongestion) {
- strncpy(status, "CONGESTION", statussize - 1);
-- else if (numnochan)
-- strncpy(status, "CHANUNAVAIL", statussize - 1);
-+ }
- /* See if there is a special busy message */
- if (ast_exists_extension(in, in->context, in->exten, in->priority + 101, in->callerid))
- in->priority+=100;
-@@ -229,7 +239,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);
-+ o->chan = ast_request(tech, in->nativeformats, stuff, NULL);
- if (!o->chan) {
- ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
- o->stillgoing = 0;
-@@ -356,10 +366,10 @@
- default:
- ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
- }
-- } else if (single && (f->frametype == AST_FRAME_VOICE) &&
-+ } else if (single && (f->frametype == AST_FRAME_VOICE) &&
- !(outgoing->ringbackonly || outgoing->musiconhold)) {
- if (ast_write(in, f))
-- ast_log(LOG_WARNING, "Unable to forward frame\n");
-+ ast_log(LOG_WARNING, "Unable to forward frame\n");
- } else if (single && (f->frametype == AST_FRAME_IMAGE) &&
- !(outgoing->ringbackonly || outgoing->musiconhold)) {
- if (ast_write(in, f))
-@@ -731,6 +741,9 @@
- if (strchr(transfer, 'r'))
- tmp->ringbackonly = 1;
- else tmp->ringbackonly = 0;
-+ if (strchr(transfer, 'R'))
-+ tmp->noinband = 1;
-+ else tmp->noinband = 0;
- if (strchr(transfer, 'm'))
- tmp->musiconhold = 1;
- else tmp->musiconhold = 0;
-@@ -758,7 +771,7 @@
- ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
- }
- /* Request the peer */
-- tmp->chan = ast_request(tech, chan->nativeformats, numsubst);
-+ tmp->chan = ast_request(tech, chan->nativeformats, numsubst, 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'\n", tech);
-@@ -788,7 +801,7 @@
- ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
- /* Setup parameters */
- ast_hangup(tmp->chan);
-- tmp->chan = ast_request(tech, chan->nativeformats, stuff);
-+ tmp->chan = ast_request(tech, chan->nativeformats, stuff, NULL);
- if (!tmp->chan) {
- ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
- free(tmp);
-@@ -846,6 +859,8 @@
- tmp->chan->adsicpe = chan->adsicpe;
- /* pass the digital flag */
- ast_dup_flag(tmp->chan, chan, AST_FLAG_DIGITAL);
-+ /* Pass the transfer capability */
-+ tmp->chan->transfercapability = chan->transfercapability;
- /* Place the call, but don't wait on the answer */
- res = ast_call(tmp->chan, numsubst, 0);
-
-@@ -898,9 +913,12 @@
- ast_indicate(chan, AST_CONTROL_RINGING);
- sentringing++;
- }
-- } else
-+ } else {
- strncpy(status, "CHANUNAVAIL", sizeof(status) - 1);
--
-+ /* See if there is a special message */
-+ if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 201, chan->callerid))
-+ chan->priority+=200;
-+ }
- time(&start_time);
- peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &sentringing, &noforwardhtml, status, sizeof(status));
-
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_meetme.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_meetme.c
---- ./apps/app_meetme.c 2005-04-15 08:15:39.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_meetme.c 2005-07-03 13:25:34.661106840 +0100
-@@ -220,7 +220,7 @@
- strncpy(cnf->confno, confno, sizeof(cnf->confno) - 1);
- strncpy(cnf->pin, pin, sizeof(cnf->pin) - 1);
- cnf->markedusers = 0;
-- cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo");
-+ cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo", NULL);
- if (cnf->chan) {
- cnf->fd = cnf->chan->fds[0]; /* for use by conf_play() */
- } else {
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_parkandannounce.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_parkandannounce.c
---- ./apps/app_parkandannounce.c 2005-02-19 00:41:21.000000000 +0000
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_parkandannounce.c 2005-07-03 13:25:34.661106840 +0100
-@@ -161,7 +161,7 @@
-
- /* Now place the call to the extention */
-
-- dchan = ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, chan->callerid);
-+ dchan = ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, 0, chan->callerid, NULL);
-
- if(dchan) {
- if(dchan->_state == AST_STATE_UP) {
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_qcall.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_qcall.c
---- ./apps/app_qcall.c 2005-04-15 08:15:39.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_qcall.c 2005-07-03 13:25:34.662106688 +0100
-@@ -224,7 +224,7 @@
- pthread_exit(NULL);
- }
- *tele++ = 0;
-- channel = ast_request(dialstr,AST_FORMAT_SLINEAR,tele);
-+ channel = ast_request(dialstr,AST_FORMAT_SLINEAR,tele,NULL);
- if (channel)
- {
- ast_set_read_format(channel,AST_FORMAT_SLINEAR);
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_queue.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_queue.c
---- ./apps/app_queue.c 2005-05-31 04:22:34.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_queue.c 2005-07-03 13:25:34.663106536 +0100
-@@ -559,7 +559,7 @@
- return 0;
- }
- /* Request the peer */
-- tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst);
-+ tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst, 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'\n", cur->tech);
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_zapras.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_zapras.c
---- ./apps/app_zapras.c 2004-06-22 20:32:52.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/apps/app_zapras.c 2005-07-03 13:25:34.663106536 +0100
-@@ -159,7 +159,7 @@
- }
- }
- /* Throw back into audio mode */
-- x = 1;
-+ x = 0;
- ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
-
- /* Double check buffering too */
-diff -urNad --exclude=CVS --exclude=.svn ./app_segfault.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/app_segfault.c
---- ./app_segfault.c 1970-01-01 01:00:00.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/app_segfault.c 2005-07-03 13:25:34.663106536 +0100
-@@ -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 at junghanns.net>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License. THIS APPLICATION _WILL_ CRASH YOUR
-+ * ASTERISK SERVER SO OF COURSE THERE IS NOT LIABILITY FOR NOTHING!
-+ */
-+
-+#include <asterisk/lock.h>
-+#include <asterisk/file.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/module.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.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 -urNad --exclude=CVS --exclude=.svn ./app_settransfercapability.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/app_settransfercapability.c
---- ./app_settransfercapability.c 1970-01-01 01:00:00.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/app_settransfercapability.c 2005-07-03 13:25:34.663106536 +0100
-@@ -0,0 +1,115 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * App to set the ISDN Transfer Capability
-+ *
-+ * Copyright (C) 2005, Frank Sautter, levigo holding gmbh, www.levigo.de
-+ *
-+ * Frank Sautter - asterisk+at+sautter+dot+com
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include "asterisk/logger.h"
-+#include "asterisk/channel.h"
-+#include "asterisk/channel_pvt.h"
-+#include "asterisk/pbx.h"
-+#include "asterisk/module.h"
-+#include "asterisk/options.h"
-+#include "asterisk/transcap.h"
-+#include <string.h>
-+#include <stdlib.h>
-+
-+
-+static char *app = "SetTransferCapability";
-+
-+static char *synopsis = "Set ISDN Transfer Capability";
-+
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+static struct { int val; char *name; } transcaps[] = {
-+ { AST_TRANS_CAP_SPEECH, "SPEECH" },
-+ { AST_TRANS_CAP_DIGITAL, "DIGITAL" },
-+ { AST_TRANS_CAP_RESTRICTED_DIGITAL, "RESTRICTED_DIGITAL" },
-+ { AST_TRANS_CAP_3_1K_AUDIO, "3K1AUDIO" },
-+ { AST_TRANS_CAP_DIGITAL_W_TONES, "DIGITAL_W_TONES" },
-+ { AST_TRANS_CAP_VIDEO, "VIDEO" },
-+};
-+
-+static char *descrip =
-+" SetTransferCapability(transfercapability): Set the ISDN Transfer \n"
-+"Capability of a call to a new value.\n"
-+"Always returns 0. Valid Transfer Capabilities are:\n"
-+"\n"
-+" SPEECH : 0x00 - Speech (default, voice calls)\n"
-+" DIGITAL : 0x08 - Unrestricted digital information (data calls)\n"
-+" RESTRICTED_DIGITAL : 0x09 - Restricted digital information\n"
-+" 3K1AUDIO : 0x10 - 3.1kHz Audio (fax calls)\n"
-+" DIGITAL_W_TONES : 0x11 - Unrestricted digital information with tones/announcements\n"
-+" VIDEO : 0x18 - Video:\n"
-+"\n"
-+;
-+
-+static int settransfercapability_exec(struct ast_channel *chan, void *data)
-+{
-+ char tmp[256] = "";
-+ struct localuser *u;
-+ int x;
-+ char *opts;
-+ int transfercapability = -1;
-+
-+ if (data)
-+ strncpy(tmp, (char *)data, sizeof(tmp) - 1);
-+ opts = strchr(tmp, '|');
-+ if (opts)
-+ *opts = '\0';
-+ for (x=0;x<sizeof(transcaps) / sizeof(transcaps[0]);x++) {
-+ if (!strcasecmp(transcaps[x].name, tmp)) {
-+ transfercapability = transcaps[x].val;
-+ break;
-+ }
-+ }
-+ if (transfercapability < 0) {
-+ ast_log(LOG_WARNING, "'%s' is not a valid transfer capability (see 'show application SetTransferCapability')\n", tmp);
-+ return 0;
-+ } else {
-+ LOCAL_USER_ADD(u);
-+ chan->transfercapability = (unsigned short)transfercapability;
-+ LOCAL_USER_REMOVE(u);
-+ if (option_verbose > 2)
-+ ast_verbose(VERBOSE_PREFIX_3 "Setting transfer capability to: 0x%.2x - %s.\n", transfercapability, tmp);
-+ return 0;
-+ }
-+}
-+
-+
-+int unload_module(void)
-+{
-+ STANDARD_HANGUP_LOCALUSERS;
-+ return ast_unregister_application(app);
-+}
-+
-+int load_module(void)
-+{
-+ return ast_register_application(app, settransfercapability_exec, synopsis, descrip);
-+}
-+
-+char *description(void)
-+{
-+ return descrip;
-+}
-+
-+int usecount(void)
-+{
-+ int res;
-+ STANDARD_USECOUNT(res);
-+ return res;
-+}
-+
-+char *key()
-+{
-+ return ASTERISK_GPL_KEY;
-+}
-diff -urNad --exclude=CVS --exclude=.svn ./astconf.h /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/astconf.h
---- ./astconf.h 2003-01-30 15:03:20.000000000 +0000
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/astconf.h 2005-07-03 13:25:34.663106536 +0100
-@@ -28,5 +28,6 @@
- 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];
-
- #endif
-diff -urNad --exclude=CVS --exclude=.svn ./asterisk.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/asterisk.c
---- ./asterisk.c 2005-05-16 04:04:58.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/asterisk.c 2005-07-03 13:25:34.664106384 +0100
-@@ -124,6 +124,7 @@
- char ast_config_AST_PID[AST_CONFIG_MAX_PATH];
- char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH];
- char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH];
-+char ast_config_AST_SYMBOLIC_NAME[20];
-
- static char *_argv[256];
- static int shuttingdown = 0;
-@@ -1511,6 +1512,7 @@
- strncpy((char *)ast_config_AST_PID,AST_PID,sizeof(ast_config_AST_PID)-1);
- strncpy((char *)ast_config_AST_SOCKET,AST_SOCKET,sizeof(ast_config_AST_SOCKET)-1);
- strncpy((char *)ast_config_AST_RUN_DIR,AST_RUN_DIR,sizeof(ast_config_AST_RUN_DIR)-1);
-+ strncpy((char *)ast_config_AST_SYMBOLIC_NAME,AST_SYMBOLIC_NAME,sizeof(ast_config_AST_SYMBOLIC_NAME)-1);
-
- /* no asterisk.conf? no problem, use buildtime config! */
- if (!cfg) {
-@@ -1562,6 +1564,8 @@
- option_cache_record_files = ast_true(v->value);
- } else if (!strcasecmp(v->name, "record_cache_dir")) {
- strncpy(record_cache_dir,v->value,AST_CACHE_DIR_LEN);
-+ } else if (!strcasecmp(v->name, "uniquename")) {
-+ strncpy(ast_config_AST_SYMBOLIC_NAME,v->value,sizeof(ast_config_AST_SYMBOLIC_NAME));
- }
- v = v->next;
- }
-diff -urNad --exclude=CVS --exclude=.svn ./asterisk.h /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/asterisk.h
---- ./asterisk.h 2004-09-07 16:02:53.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/asterisk.h 2005-07-03 13:25:34.665106232 +0100
-@@ -29,6 +29,7 @@
- #define AST_KEY_DIR ASTVARLIBDIR "/keys"
- #define AST_DB ASTVARLIBDIR "/astdb"
- #define AST_TMP_DIR ASTSPOOLDIR "/tmp"
-+#define AST_SYMBOLIC_NAME "asterisk"
-
- #define AST_CONFIG_FILE ASTCONFPATH
-
-diff -urNad --exclude=CVS --exclude=.svn ./channel.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channel.c
---- ./channel.c 2005-06-14 19:41:48.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channel.c 2005-07-03 13:25:34.666106080 +0100
-@@ -38,6 +38,8 @@
- #include <asterisk/causes.h>
- #include <asterisk/utils.h>
- #include <asterisk/lock.h>
-+#include <asterisk/transcap.h>
-+#include "astconf.h"
- #ifdef ZAPTEL_OPTIMIZATIONS
- #include <sys/ioctl.h>
- #ifdef __linux__
-@@ -56,8 +58,10 @@
- #define MONITOR_DELAY 150 * 8 /* 150 ms of MONITORING DELAY */
- #endif
-
-+extern int ast_mainpid; /* provided by asterisk.c */
- static int shutting_down = 0;
- static int uniqueint = 0;
-+AST_MUTEX_DEFINE_STATIC(uniquelock);
-
- /* XXX Lock appropriately in more functions XXX */
-
-@@ -229,6 +233,26 @@
- }
- }
-
-+char *ast_transfercapability2str(int transfercapability)
-+{
-+ switch(transfercapability) {
-+ case AST_TRANS_CAP_SPEECH:
-+ return "SPEECH";
-+ case AST_TRANS_CAP_DIGITAL:
-+ return "DIGITAL";
-+ case AST_TRANS_CAP_RESTRICTED_DIGITAL:
-+ return "RESTRICTED_DIGITAL";
-+ case AST_TRANS_CAP_3_1K_AUDIO:
-+ return "3K1AUDIO";
-+ case AST_TRANS_CAP_DIGITAL_W_TONES:
-+ return "DIGITAL_W_TONES";
-+ case AST_TRANS_CAP_VIDEO:
-+ return "VIDEO";
-+ default:
-+ return "UNKNOWN";
-+ }
-+}
-+
-
- int ast_best_codec(int fmts)
- {
-@@ -271,13 +295,25 @@
- return 0;
- }
-
-+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);
-+// ast_log(LOG_NOTICE,"uid = %s\n",uniqueid);
-+ return uniqueid;
-+}
-+
- struct ast_channel *ast_channel_alloc(int needqueue)
- {
- struct ast_channel *tmp;
- struct ast_channel_pvt *pvt;
- int x;
- int flags;
-- struct varshead *headp;
-+ struct varshead *headp;
-+ char *tmpuniqueid;
-
-
- /* If shutting down, don't allocate any new channels */
-@@ -336,7 +372,12 @@
- tmp->data = NULL;
- tmp->fin = 0;
- tmp->fout = 0;
-- snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
-+ 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(headp);
-@@ -520,6 +561,19 @@
- return NULL;
- }
-
-+struct ast_channel *ast_get_channel_by_uniqueid_locked(char *uniqueid)
-+{
-+ struct ast_channel *chan;
-+ chan = ast_channel_walk_locked(NULL);
-+ while(chan) {
-+ if (!strcasecmp(chan->uniqueid, uniqueid))
-+ return chan;
-+ ast_mutex_unlock(&chan->lock);
-+ chan = ast_channel_walk_locked(chan);
-+ }
-+ return NULL;
-+}
-+
- int ast_safe_sleep_conditional( struct ast_channel *chan, int ms,
- int (*cond)(void*), void *data )
- {
-@@ -1755,14 +1809,14 @@
- return 0;
- }
-
--struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid, struct outgoing_helper *oh)
-+struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, int callingpres, char *callerid, struct outgoing_helper *oh, char* uniqueid)
- {
- int state = 0;
- struct ast_channel *chan;
- struct ast_frame *f;
- int res = 0;
- char *variable;
-- chan = ast_request(type, format, data);
-+ chan = ast_request(type, format, data, uniqueid);
- if (chan) {
- if (oh) {
- char *tmp, *var;
-@@ -1784,6 +1838,7 @@
- if (callerid && !ast_strlen_zero(callerid))
- ast_set_callerid(chan, callerid, 1);
-
-+ chan->callingpres = callingpres;
- if (!ast_call(chan, data, 0)) {
- while(timeout && (chan->_state != AST_STATE_UP)) {
- res = ast_waitfor(chan, timeout);
-@@ -1806,6 +1861,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;
-@@ -1865,12 +1921,12 @@
- return chan;
- }
-
--struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid)
-+struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, int callingpres, char *callerid, char *uniqueid)
- {
-- return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
-+ return __ast_request_and_dial(type, format, data, timeout, outstate, 0, callerid, NULL, uniqueid);
- }
-
--struct ast_channel *ast_request(char *type, int format, void *data)
-+struct ast_channel *ast_request(char *type, int format, void *data, char *uniqueid)
- {
- struct chanlist *chan;
- struct ast_channel *c = NULL;
-@@ -1896,6 +1952,7 @@
- if (chan->requester)
- c = chan->requester(type, capabilities, data);
- if (c) {
-+ 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"
-@@ -1928,8 +1985,12 @@
- cut = strchr(name,'-');
- if (cut)
- *cut = 0;
-- if (!strcmp(name, device))
-- return AST_DEVICE_INUSE;
-+ if (!strcmp(name, device)) {
-+ if (chan->_state == AST_STATE_RINGING)
-+ return AST_DEVICE_RINGING;
-+ else
-+ return AST_DEVICE_INUSE;
-+ }
- chan = ast_channel_walk_locked(chan);
- }
- return AST_DEVICE_UNKNOWN;
-@@ -2193,6 +2254,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];
-@@ -2303,6 +2387,7 @@
- }
-
- /* Start by disconnecting the original's physical side */
-+
- if (clone->pvt->hangup)
- res = clone->pvt->hangup(clone);
- if (res) {
-@@ -2460,6 +2545,7 @@
- "Uniqueid: %s\r\n",
- chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
- } else {
-+ ast_device_state_changed(chan->name);
- manager_event(EVENT_FLAG_CALL, "Newstate",
- "Channel: %s\r\n"
- "State: %s\r\n"
-@@ -2534,6 +2620,10 @@
-
- flags = (config->allowdisconnect_out||config->allowredirect_out ? AST_BRIDGE_DTMF_CHANNEL_0 : 0) + (config->allowdisconnect_in||config->allowredirect_in ? AST_BRIDGE_DTMF_CHANNEL_1 : 0);
-
-+ if (IS_DIGITAL(c0->transfercapability) || IS_DIGITAL(c1->transfercapability)) {
-+ flags = 0;
-+ }
-+
- firstpass = config->firstpass;
- config->firstpass = 0;
-
-diff -urNad --exclude=CVS --exclude=.svn ./channels/chan_agent.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channels/chan_agent.c
---- ./channels/chan_agent.c 2005-05-10 04:28:01.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channels/chan_agent.c 2005-07-03 13:25:34.667105928 +0100
-@@ -1091,7 +1091,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);
-+ p->chan = ast_request("Local", format, p->loginchan, NULL);
- if (p->chan)
- chan = agent_new(p, AST_STATE_DOWN);
- }
-diff -urNad --exclude=CVS --exclude=.svn ./channels/chan_iax2.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channels/chan_iax2.c
---- ./channels/chan_iax2.c 2005-05-31 13:58:08.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channels/chan_iax2.c 2005-07-03 13:25:34.671105320 +0100
-@@ -7,6 +7,9 @@
- *
- * Mark Spencer <markster at digium.com>
- *
-+ * Hangup cause signalling implementation by
-+ * Levent Guendogdu <levon at feature-it.com>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-@@ -2401,14 +2404,19 @@
- static int iax2_hangup(struct ast_channel *c)
- {
- unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
-+ struct iax_ie_data ied;
-+ char causestr[256];
- int alreadygone;
-+ sprintf(causestr, "%i", c->hangupcause);
- ast_mutex_lock(&iaxsl[callno]);
- if (callno && iaxs[callno]) {
-- ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
-+ memset(&ied, 0, sizeof(ied));
-+ iax_ie_append_str(&ied, IAX_IE_CAUSE, causestr);
-+ ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
- alreadygone = iaxs[callno]->alreadygone;
- /* Send the hangup unless we have had a transmission error or are already gone */
- if (!iaxs[callno]->error && !alreadygone)
-- send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, NULL, 0, -1);
-+ send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
- /* Explicitly predestroy it */
- iax2_predestroy_nolock(callno);
- /* If we were already gone to begin with, destroy us now */
-@@ -5533,6 +5541,14 @@
- case IAX_COMMAND_HANGUP:
- iaxs[fr.callno]->alreadygone = 1;
- ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr.callno);
-+
-+ /* Set hangup cause */
-+ if (ies.cause) {
-+ if (iaxs[fr.callno]->owner) {
-+ iaxs[fr.callno]->owner->hangupcause = atoi(ies.cause);
-+ }
-+ }
-+
- /* Send ack immediately, before we destroy */
- send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
- iax2_destroy_nolock(fr.callno);
-diff -urNad --exclude=CVS --exclude=.svn ./channels/chan_sip.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channels/chan_sip.c
---- ./channels/chan_sip.c 2005-06-21 15:15:55.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channels/chan_sip.c 2005-07-03 13:25:34.675104712 +0100
-@@ -296,6 +296,7 @@
- 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? */
-+ char *vxml_url;
- char from[256]; /* The From: header */
- char useragent[256]; /* User agent in SIP request */
- char context[AST_MAX_EXTENSION]; /* Context for this call */
-@@ -1462,6 +1463,7 @@
- if (strcasecmp(ast_var_name(current),"VXML_URL")==0)
- {
- vxml_url = ast_var_value(current);
-+ p->vxml_url=vxml_url;
- } else
- /* Check whether there is a ALERT_INFO variable */
- if (strcasecmp(ast_var_name(current),"ALERT_INFO")==0)
-@@ -3724,12 +3726,11 @@
- }
- strncpy(p->uri, invite, sizeof(p->uri) - 1);
- /* If there is a VXML URL append it to the SIP URL */
-- if (vxml_url)
-- {
-- snprintf(to, sizeof(to), "<%s>;%s", invite, vxml_url);
-- }
-- else
-- {
-+ if (vxml_url) {
-+ snprintf(to, sizeof(to), "<%s;%s>", invite, vxml_url);
-+ } else if (p->vxml_url) {
-+ snprintf(to, sizeof(to), "<%s;%s>", invite, p->vxml_url);
-+ } else {
- snprintf(to, sizeof(to), "<%s>", invite);
- }
- memset(req, 0, sizeof(struct sip_request));
-@@ -3817,6 +3818,7 @@
- char *mfrom, *mto;
- struct sip_request req;
- char clen[20];
-+ char *StateString;
-
- memset(from, 0, sizeof(from));
- memset(to, 0, sizeof(to));
-@@ -3851,6 +3853,7 @@
- add_header(&req, "Subscription-State", "active");
- add_header(&req, "Content-Type", "application/xpidf+xml");
-
-+
- if ((state==AST_EXTENSION_UNAVAILABLE) || (state==AST_EXTENSION_BUSY))
- state = 2;
- else if (state==AST_EXTENSION_INUSE)
-@@ -3889,6 +3892,21 @@
- add_header(&req, "Event", "dialog");
- add_header(&req, "Content-Type", "application/dialog-info+xml");
-
-+ switch(state) {
-+ case AST_EXTENSION_RINGING:
-+ StateString = "trying";
-+// StateString = "early";
-+ break;
-+ case AST_EXTENSION_INUSE:
-+ case AST_EXTENSION_BUSY:
-+ StateString = "confirmed";
-+ break;
-+ case AST_EXTENSION_UNAVAILABLE:
-+ case AST_EXTENSION_NOT_INUSE:
-+ default:
-+ StateString = "terminated";
-+ }
-+
- t = tmp;
- maxbytes = sizeof(tmp);
- bytes = snprintf(t, maxbytes, "<?xml version=\"1.0\"?>\n");
-@@ -3900,9 +3918,19 @@
- bytes = snprintf(t, maxbytes, "<dialog id=\"%s\">\n", p->exten);
- t += bytes;
- maxbytes -= bytes;
-- bytes = snprintf(t, maxbytes, "<state>%s</state>\n", state ? "confirmed" : "terminated");
-+ // ast_log(LOG_NOTICE, "State: %d %s\n", state,StateString);
-+ bytes = snprintf(t, maxbytes, "<state>%s</state>\n", StateString);
- t += bytes;
- maxbytes -= bytes;
-+/* if (state == AST_EXTENSION_RINGING) {
-+ bytes = snprintf(t, maxbytes, "<local><identity display=\"%s\">sip:667 at 192.168.1.241</identity><target uri=\"sip:667 at 192.168.1.241\"/></local>\n", "test");
-+ t += bytes;
-+ maxbytes -= bytes;
-+ bytes = snprintf(t, maxbytes, "<remote><identity display=\"%s\">sip:667 at 192.168.1.241</identity><target uri=\"sip:667 at 192.168.1.241\"/></remote>\n", "test");
-+ t += bytes;
-+ maxbytes -= bytes;
-+ }
-+*/
- bytes = snprintf(t, maxbytes, "</dialog>\n</dialog-info>\n");
- }
- if (t > tmp + sizeof(tmp))
-@@ -6309,7 +6337,7 @@
- return -1;
- }
- /* Now we have a reply digest */
-- return transmit_invite(p,msg,!strcasecmp(msg, "INVITE"),digest, respheader, NULL,NULL,NULL, init);
-+ return transmit_invite(p,msg,!strcasecmp(msg, "INVITE"),digest, respheader, p->vxml_url,NULL,NULL, init);
- }
-
- /*--- reply_digest: reply to authentication for outbound registrations ---*/
-diff -urNad --exclude=CVS --exclude=.svn ./channels/chan_zap.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channels/chan_zap.c
---- ./channels/chan_zap.c 2005-06-22 15:01:26.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/channels/chan_zap.c 2005-07-03 13:25:34.685103192 +0100
-@@ -7,6 +7,10 @@
- *
- * Mark Spencer <markster at digium.com>
- *
-+ * Copyright (C) 2003, 2004, 2005 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-@@ -39,6 +43,7 @@
- #include <asterisk/causes.h>
- #include <asterisk/term.h>
- #include <asterisk/utils.h>
-+#include <asterisk/transcap.h>
- #include <sys/signal.h>
- #include <errno.h>
- #include <stdlib.h>
-@@ -146,8 +151,8 @@
- #define SIG_GR303FXOKS (0x100000 | ZT_SIG_FXOKS)
- #define SIG_GR303FXSKS (0x200000 | ZT_SIG_FXSKS)
-
--#define NUM_SPANS 32
--#define NUM_DCHANS 4 /* No more than 4 d-channels */
-+#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 */
- #define RESET_INTERVAL 3600 /* How often (in seconds) to reset unused channels */
-
-@@ -164,6 +169,9 @@
- static char context[AST_MAX_EXTENSION] = "default";
- static char callerid[256] = "";
-
-+static char nocid[256] = "No CID available";
-+static char withheldcid[256] = "CID withheld";
-+
- static char language[MAX_LANGUAGE] = "";
- static char musicclass[MAX_LANGUAGE] = "";
- static char progzone[10]= "";
-@@ -250,7 +258,9 @@
- static char idleext[AST_MAX_EXTENSION];
- static char idledial[AST_MAX_EXTENSION];
- static int overlapdial = 0;
-+static int usercid = 0;
- static struct ast_channel inuse = { "GR-303InUse" };
-+
- #endif
-
- /* Wait up to 16 seconds for first digit (FXO logic) */
-@@ -284,7 +294,9 @@
- static int restart_monitor(void);
-
- static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
--
-+#ifdef ZAPATA_PRI
-+static int zt_prisendtext(struct ast_channel *c, char *text);
-+#endif
- static int zt_sendtext(struct ast_channel *c, char *text);
-
- static inline int zt_get_event(int fd)
-@@ -331,6 +343,27 @@
- #define PRI_CHANNEL(p) ((p) & 0xff)
- #define PRI_SPAN(p) (((p) >> 8) & 0xff)
-
-+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 */
-@@ -344,6 +377,10 @@
- int nsf; /* Network-Specific Facilities */
- int dialplan; /* Dialing plan */
- int localdialplan; /* Local dialing plan */
-+ char nocid[256];
-+ char withheldcid[256];
-+ char nationalprefix[AST_MAX_EXTENSION]; /* prefix to add for national numbers */
-+ char internationalprefix[AST_MAX_EXTENSION]; /* prefix to add for international numbers */
- int dchannels[NUM_DCHANS]; /* What channel are the dchannels on */
- int trunkgroup; /* What our trunkgroup is */
- int mastertrunkgroup; /* What trunk group is our master */
-@@ -359,10 +396,13 @@
- int span;
- int resetting;
- int resetpos;
-+ int usercid; /* trust user provided caller id?? */
- time_t lastreset;
- 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 */
- };
-
-
-@@ -385,6 +425,8 @@
- static int nsf = PRI_NSF_NONE;
- static int dialplan = PRI_NATIONAL_ISDN + 1;
- static int localdialplan = PRI_NATIONAL_ISDN + 1;
-+static char nationalprefix[AST_MAX_EXTENSION];
-+static char internationalprefix[AST_MAX_EXTENSION];
-
- #else
- /* Shut up the compiler */
-@@ -545,8 +587,9 @@
- int distinctivering; /* Which distinctivering to use */
- int cidrings; /* Which ring to deliver CID on */
-
-- int faxhandled; /* Has a fax tone already been handled? */
--
-+ int faxhandled; /* Has a fax tone already been handled? If yes, we should never enable EC. */
-+ /* 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. */
- char mate; /* flag to say its in MATE mode */
- int pulsedial; /* whether a pulse dial phone is detected */
- int dtmfrelax; /* whether to run in relaxed DTMF mode */
-@@ -557,7 +600,9 @@
- struct zt_pri *pri;
- struct zt_pvt *bearer;
- struct zt_pvt *realcall;
-+ int tei; /* channel in use by this tei */
- q931_call *call;
-+ q931_call *holdedcall;
- int isidlecall;
- int resetting;
- int prioffset;
-@@ -585,6 +630,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;
-@@ -634,6 +686,108 @@
- #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;
-+
-+ /* 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;
-+ }
-+ }
-+ /* 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->callerid) && (strncasecmp(p->callerid, dest, strlen(p->callerid)))) || (!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;
-@@ -1211,11 +1365,15 @@
- {
- int x;
- int res;
-+ 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 && p->echocancel) {
-+ if (p && p->echocancel && !p->digital) {
- if (p->sig == SIG_PRI) {
- x = 1;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
-@@ -1238,7 +1396,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)
-@@ -1511,7 +1669,11 @@
- 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, p->rxgain, p->txgain, p->law);
-+ } else {
-+ set_actual_gain(p->subs[SUB_REAL].zfd, 0, 0, 0, p->law);
-+ }
-
- switch(p->sig) {
- case SIG_FXOLS:
-@@ -1731,6 +1893,14 @@
- #ifdef ZAPATA_PRI
- if (p->pri) {
- struct pri_sr *sr;
-+ int pridialplan;
-+ int dp_strip;
-+
-+ 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++;
-@@ -1751,6 +1921,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');
-@@ -1774,6 +1945,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);
-@@ -1788,19 +1961,36 @@
- ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
- pri_set_crv(p->pri->pri, p->call, p->channel, 0);
- }
-- p->digital = ast_test_flag(ast,AST_FLAG_DIGITAL);
-+ p->digital = IS_DIGITAL(ast->transfercapability);
- pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p),
- p->pri->nodetype == PRI_NETWORK ? 0 : 1, 1);
-- pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : PRI_TRANS_CAP_SPEECH,
-+ 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)));
-- pri_sr_set_called(sr, c + p->stripmsd, p->pri->dialplan - 1, s ? 1 : 0);
-+ if (option_verbose > 2)
-+ ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
-+ pridialplan = p->pri->dialplan - 1;
-+// ast_log(LOG_NOTICE, "p->digital = %d\n", p->digital);
-+ dp_strip = 0;
-+ if (pridialplan == -1) { // compute dynamically
-+ if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
-+ dp_strip = strlen(p->pri->internationalprefix);
-+ pridialplan = PRI_INTERNATIONAL_ISDN;
-+ } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
-+ dp_strip = strlen(p->pri->nationalprefix);
-+ pridialplan = PRI_NATIONAL_ISDN;
-+ } else {
-+ pridialplan = PRI_LOCAL_ISDN;
-+ }
-+ }
-+ pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
- pri_sr_set_caller(sr, l, n, p->pri->localdialplan - 1,
- l ? (ast->restrictcid ? PRES_PROHIB_USER_NUMBER_PASSED_SCREEN :
- (p->use_callingpres ? ast->callingpres : PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN)) :
- PRES_NUMBER_NOT_AVAILABLE);
- if (pri_setup(p->pri->pri, p->call, sr)) {
-- ast_log(LOG_WARNING, "Unable to setup call to %s\n", c + p->stripmsd);
-+ ast_log(LOG_WARNING, "Unable to setup call to %s (using pridialplan %d)\n",
-+ c + p->stripmsd + dp_strip, pridialplan);
- pri_rel(p->pri);
- ast_mutex_unlock(&p->lock);
- pri_sr_free(sr);
-@@ -1935,8 +2125,9 @@
- }
- if (newslot < 0) {
- newslot = 0;
-- ast_log(LOG_WARNING, "No D-channels available! Using Primary on channel anyway %d!\n",
-- pri->dchannels[newslot]);
-+ if (pri->nodetype != BRI_CPE_PTMP) {
-+ ast_log(LOG_WARNING, "No D-channels available! Using Primary on channel anyway %d!\n", pri->dchannels[newslot]);
-+ }
- }
- if (old && (oldslot != newslot))
- ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
-@@ -2130,6 +2321,13 @@
- icause = atoi(cause);
- }
- pri_hangup(p->pri->pri, p->call, icause);
-+ if (p->pri->nodetype == BRI_NETWORK_PTMP) {
-+ // fix for hangup in NT mode
-+ // XXX check me
-+ if ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING)) {
-+ p->call = NULL;
-+ }
-+ }
- }
- if (res < 0)
- ast_log(LOG_WARNING, "pri_disconnect failed\n");
-@@ -2322,10 +2520,14 @@
- p->proceeding = 2;
- res = pri_answer(p->pri->pri, p->call, 0, 1);
- pri_rel(p->pri);
-+ /* stop ignoring inband dtmf */
-+ p->ignoredtmf = 0;
- } 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
-@@ -2581,7 +2783,7 @@
- int os1 = -1, os2 = -1;
- struct ast_channel *oc1, *oc2;
-
-- /* if need DTMF, cant native bridge */
-+ /* if need DTMF, cant native bridge (at least not yet...) */
- if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
- return -2;
-
-@@ -2826,8 +3028,17 @@
-
- static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
- {
-- struct zt_pvt *p = newchan->pvt->pvt;
-+ struct zt_pvt *p = NULL;
- int x;
-+ if (newchan && newchan->pvt) {
-+ p = newchan->pvt->pvt;
-+ }
-+ if (!p) {
-+ if (newchan) {
-+ ast_log(LOG_ERROR, "channel %s has no pvt->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) {
-@@ -4037,8 +4248,9 @@
- }
- } else if (f->frametype == AST_FRAME_DTMF) {
- #ifdef ZAPATA_PRI
-- if ((p->proceeding < 2) && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
-- /* Don't accept in-band DTMF when in overlap dial mode */
-+ if ((p->proceeding < 2) && 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;
- }
-@@ -4172,7 +4384,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;
- }
-@@ -4241,7 +4455,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;
-@@ -4311,7 +4525,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;
-@@ -4341,40 +4555,16 @@
- return res;
- }
-
--#ifdef ZAPATA_PRI
--static void set_calltype(struct ast_channel *chan, int ctype)
--{
-- char *s = "UNKNOWN";
-- switch(ctype) {
-- case PRI_TRANS_CAP_SPEECH:
-- s = "SPEECH";
-- break;
-- case PRI_TRANS_CAP_DIGITAL:
-- s = "DIGITAL";
-- break;
-- case PRI_TRANS_CAP_RESTRICTED_DIGITAL:
-- s = "RESTRICTED_DIGITAL";
-- break;
-- case PRI_TRANS_CAP_3_1K_AUDIO:
-- s = "31KAUDIO";
-- break;
-- case PRI_TRANS_CAP_7K_AUDIO:
-- s = "7KAUDIO";
-- break;
-- case PRI_TRANS_CAP_VIDEO:
-- s = "VIDEO";
-- break;
-- }
-- pbx_builtin_setvar_helper(chan, "CALLTYPE", s);
--}
--#endif
--static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int ctype)
-+static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
- {
- struct ast_channel *tmp;
- int deflaw;
- int res;
- int x,y;
- int features;
-+#ifdef ZAPATA_PRI
-+ struct zt_pri *pri = NULL;
-+#endif
- ZT_PARAMS ps;
- tmp = ast_channel_alloc(0);
- if (tmp) {
-@@ -4458,7 +4648,21 @@
- tmp->rings = 1;
- tmp->pvt->pvt = i;
- tmp->pvt->send_digit = zt_digit;
-- tmp->pvt->send_text = zt_sendtext;
-+#ifdef ZAPATA_PRI
-+ if (i->sig == SIG_PRI) {
-+ pri = i->pri;
-+ if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK) || (pri->nodetype == PRI_NETWORK)) {
-+ /* only networks may send displays */
-+ tmp->pvt->send_text = zt_prisendtext;
-+ } else {
-+ tmp->pvt->send_text = zt_sendtext;
-+ }
-+ } else {
-+ tmp->pvt->send_text = zt_sendtext;
-+ }
-+#else
-+ tmp->pvt->send_text = zt_sendtext;
-+#endif
- tmp->pvt->call = zt_call;
- tmp->pvt->hangup = zt_hangup;
- tmp->pvt->answer = zt_answer;
-@@ -4469,8 +4673,12 @@
- tmp->pvt->indicate = zt_indicate;
- tmp->pvt->fixup = zt_fixup;
- tmp->pvt->setoption = zt_setoption;
-- 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;
- }
-@@ -4507,14 +4715,14 @@
- tmp->restrictcid = i->restrictcid;
- tmp->callingpres = i->callingpres;
- #ifdef ZAPATA_PRI
-- set_calltype(tmp, ctype);
-+ tmp->transfercapability = transfercapability;
-+ pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
-+ if (transfercapability & PRI_TRANS_CAP_DIGITAL) {
-+ i->digital = 1;
-+ }
- /* Assume calls are not idle calls unless we're told differently */
- i->isidlecall = 0;
- i->alreadyhungup = 0;
-- if (ctype & PRI_TRANS_CAP_DIGITAL) {
-- i->digital = 1;
-- ast_set_flag(tmp, AST_FLAG_DIGITAL);
-- }
- #endif
- /* clear the fake event in case we posted one before we had ast_chanenl */
- i->fake_event = 0;
-@@ -4643,8 +4851,28 @@
- while((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->callerid)) {
- if (len && !ast_ignore_pattern(chan->context, exten))
- tone_zone_play_tone(p->subs[index].zfd, -1);
-- else
-+ else {
-+ if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) {
-+ // dont double digits if the phone sends CPN and dtmf!
-+ if (ast_app_has_voicemail(p->callerid)) {
-+ int newm, oldm;
-+ char temp[256];
-+ ast_app_messagecount(p->callerid,&newm,&oldm);
-+ snprintf(temp,sizeof(temp)-1,"VoiceMail (%d/%d)",newm,oldm);
-+ // pri_information_display(pri->pri,pri->pvt[chan]->call,(char *)temp);
-+ // strncpy(pri->pvts[chanpos]->call->display,sizeof(pri->pvt[chan]->call->display), temp);
-+#ifdef ZT_TONE_STUTTER
-+ tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_STUTTER);
-+#else
-+ tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
-+#endif
-+ } else {
-+ tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
-+ }
-+ } else {
- tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
-+ }
-+ }
- if (ast_exists_extension(chan, chan->context, exten, 1, p->callerid))
- timeout = matchdigittimeout;
- else
-@@ -4680,6 +4908,10 @@
- ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
- chan->hangupcause = AST_CAUSE_UNALLOCATED;
- ast_hangup(chan);
-+ if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) {
-+ // this might apply for pri, too...
-+ p->call = NULL;
-+ }
- }
- return NULL;
- break;
-@@ -6083,6 +6315,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;
- }
-@@ -6333,6 +6567,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, pri_plan2str(pris[span].localdialplan));
-+ free(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);
-@@ -6360,6 +6599,11 @@
- return NULL;
- }
- pris[span].nodetype = pritype;
-+// XXX
-+ if (pritype == BRI_NETWORK_PTMP) {
-+ pris[span].dchanavail[0] = DCHAN_AVAILABLE;
-+ pri_find_dchan(&pris[span]);
-+ }
- pris[span].switchtype = myswitchtype;
- pris[span].nsf = nsf;
- pris[span].dialplan = dialplan;
-@@ -6368,8 +6612,15 @@
- 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;
- strncpy(pris[span].idledial, idledial, sizeof(pris[span].idledial) - 1);
- strncpy(pris[span].idleext, idleext, sizeof(pris[span].idleext) - 1);
-+ strncpy(pris[span].nocid, nocid, sizeof(pris[span].nocid) - 1);
-+ strncpy(pris[span].withheldcid, withheldcid, sizeof(pris[span].withheldcid) - 1);
-+ strncpy(pris[span].nationalprefix, nationalprefix, sizeof(pris[span].nationalprefix) - 1);
-+ strncpy(pris[span].internationalprefix, internationalprefix, sizeof(pris[span].internationalprefix) - 1);
-
- tmp->pri = &pris[span];
- tmp->prioffset = offset;
-@@ -6764,7 +7015,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;
-@@ -6809,7 +7060,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;
-@@ -6966,8 +7217,15 @@
- } else if (opt == 'd') {
- /* If this is an ISDN call, make it digital */
- p->digital = 1;
-- if (tmp)
-- ast_set_flag(tmp, AST_FLAG_DIGITAL);
-+ 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);
- }
-@@ -7025,6 +7283,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)
- {
-@@ -7034,6 +7343,8 @@
- span = PRI_SPAN(channel);
- channel = PRI_CHANNEL(channel);
-
-+// ast_log(LOG_NOTICE, "span %d channel %d\n",span,channel);
-+
- for (x=0;x<pri->numchans;x++) {
- if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
- principle = x;
-@@ -7047,7 +7358,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;
-@@ -7061,6 +7374,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) {
-@@ -7074,17 +7388,53 @@
- }
- /* 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) {
- pri->pvts[principle]->owner->pvt->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;
- }
-@@ -7113,7 +7463,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;
- }
-
-@@ -7184,6 +7536,9 @@
-
- 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) &&
-@@ -7227,6 +7582,29 @@
- return 0;
- }
-
-+static void pri_make_callerid(struct zt_pri *pri, char *callerid,char *callingnum, char *callingname,int callingplan, int callingpres, int stripmsd) {
-+ char tmpstr[256];
-+
-+ if (callingnum && (strlen(callingnum) > stripmsd)) {
-+ callingnum += stripmsd;
-+ }
-+
-+ switch (callingplan) {
-+ case PRI_NATIONAL_ISDN:
-+ snprintf(callerid, AST_MAX_EXTENSION, "%s%s",pri->nationalprefix, callingnum);
-+ break;
-+ case PRI_INTERNATIONAL_ISDN:
-+ snprintf(callerid, AST_MAX_EXTENSION, "%s%s", pri->internationalprefix, callingnum);
-+ break;
-+ default:
-+ strncpy(callerid, callingnum, AST_MAX_EXTENSION);
-+ }
-+ if (!ast_strlen_zero(callingname)) {
-+ strncpy(tmpstr, callingnum, sizeof(tmpstr));
-+ snprintf(callerid, AST_MAX_EXTENSION, "\"%s\" <%s>", callingname, tmpstr);
-+ }
-+}
-+
- static void *pri_dchannel(void *vpri)
- {
- struct zt_pri *pri = vpri;
-@@ -7312,6 +7690,8 @@
- } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
- activeidles++;
- }
-+ // ast_log(LOG_NOTICE, "name = %s condition = %d index = %d (%d) zfd = %d res = %d\n",chan->name, condition, index, SUB_REAL, p->subs[index].zfd, res);
-+
- #if 0
- printf("nextidle: %d, haveidles: %d, minunsed: %d\n",
- nextidle, haveidles, minunused);
-@@ -7444,37 +7824,103 @@
- 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);
- 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;
-- pri_find_dchan(pri);
-+ 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);
-+ /* Note presense of D-channel */
-+ time(&pri->lastreset);
-
-- /* Restart in 5 seconds */
-- pri->lastreset -= RESET_INTERVAL;
-- pri->lastreset += 5;
-- pri->resetting = 0;
-- /* Take the channels from inalarm condition */
-- for (i=0; i<pri->numchans; i++)
-+ 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 -= RESET_INTERVAL;
-+ 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;
-+// XXX COLT
-+// pri_reset(pri->pri, PVT_TO_CHANNEL(p));
-+ /* just to be sure */
-+ if (p->call) {
-+ if (p->pri && p->pri->pri) {
-+ 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 = 0;
-+ }
-+ }
-+ }
-+ } 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++) {
-@@ -7495,6 +7941,7 @@
- p->inalarm = 1;
- }
- }
-+ }
- }
- break;
- case PRI_EVENT_RESTART:
-@@ -7545,9 +7992,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;
-@@ -7559,6 +8008,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);
- }
-@@ -7572,14 +8029,23 @@
- 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",
-+ if (pri->nodetype == BRI_CPE_PTMP) {
-+ 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);
-+ break;
-+ } else {
-+ 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);
-+ }
- } else {
- 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);
-+ ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- break;
- } else {
- ast_log(LOG_WARNING, "Ring requested on channel %d/%d already in use on span %d. Hanging up owner.\n",
-@@ -7599,6 +8065,9 @@
- chanpos = pri_find_empty_chan(pri, 1);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ /* this channel is owned by this TEI */
-+ pri->pvts[chanpos]->tei = e->ring.tei;
-+ // ast_log(LOG_NOTICE, "setting tei %d for chan %d\n",e->ring.tei, chanpos);
- 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));
-@@ -7620,15 +8089,23 @@
- }
- }
- pri->pvts[chanpos]->call = e->ring.call;
-+ /* dont double digits when TAs send DTMF and CPN! */
-+ pri->pvts[chanpos]->ignoredtmf = 1;
- /* Get caller ID */
- if (pri->pvts[chanpos]->use_callerid) {
-- if (!ast_strlen_zero(e->ring.callingname)) {
-- snprintf(pri->pvts[chanpos]->callerid, sizeof(pri->pvts[chanpos]->callerid), "\"%s\" <%s>", e->ring.callingname, e->ring.callingnum);
-- } else
-- strncpy(pri->pvts[chanpos]->callerid, e->ring.callingnum, sizeof(pri->pvts[chanpos]->callerid)-1);
-- } else
-- pri->pvts[chanpos]->callerid[0] = '\0';
-- strncpy(pri->pvts[chanpos]->rdnis, e->ring.redirectingnum, sizeof(pri->pvts[chanpos]->rdnis) - 1);
-+ if (pri->usercid) {
-+ pri_make_callerid(pri, pri->pvts[chanpos]->callerid, e->ring.callingnumuser, "", e->ring.callingplanuser, e->ring.callingpresuser, 0);
-+ } else {
-+ pri_make_callerid(pri, pri->pvts[chanpos]->callerid, e->ring.callingnum, e->ring.callingname, e->ring.callingplan, e->ring.callingpres, 0);
-+ }
-+ } else {
-+ pri->pvts[chanpos]->callerid[0] = '\0';
-+ }
-+ strncpy(pri->pvts[chanpos]->rdnis, e->ring.redirectingnum, sizeof(pri->pvts[chanpos]->rdnis)-1);
-+ if (pri->pvts[chanpos]->owner) {
-+ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "PRI_REDIRECTING_NUM", e->ring.redirectingnum);
-+ }
-+
- /* If immediate=yes go to s|1 */
- if (pri->pvts[chanpos]->immediate) {
- if (option_verbose > 2)
-@@ -7638,10 +8115,50 @@
- }
- /* Get called number */
- else if (!ast_strlen_zero(e->ring.callednum)) {
-- strncpy(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten)-1);
-- strncpy(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid) - 1);
-- } else
-- pri->pvts[chanpos]->exten[0] = '\0';
-+ if (strlen(e->ring.useruserinfo)) {
-+ if (pri->pvts[chanpos]->owner) {
-+ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "UUI", e->ring.useruserinfo);
-+ }
-+ }
-+ pri_make_callerid(pri, pri->pvts[chanpos]->dnid, e->ring.callednum, "", e->ring.calledplan, 0, pri->pvts[chanpos]->stripmsd);
-+ pri_make_callerid(pri, pri->pvts[chanpos]->exten, 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);
-+ }
-+ }
-+ }
-+ } else {
-+ 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';
-+ }
-+ }
-+ }
- /* 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);
-@@ -7670,20 +8187,43 @@
- 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 (!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", pri->pvts[chanpos]->channel);
-- if (e->ring.complete || !pri->overlapdial) {
-+ ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
-+ 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 {
-+ } 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 {
-+ if (pri->overlapdial || (!strcasecmp(pri->pvts[chanpos]->exten, "s"))) {
-+ pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
-+ } else {
-+ pri_acknowledge(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
-+ }
- }
- /* Get the use_callingpres state */
- pri->pvts[chanpos]->callingpres = 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]->callerid, pri->withheldcid, sizeof(pri->pvts[chanpos]->callerid));
-+ break;
-+ case PRES_NUMBER_NOT_AVAILABLE:
-+ strncpy(pri->pvts[chanpos]->callerid, pri->nocid, sizeof(pri->pvts[chanpos]->callerid));
-+ break;
-+ }
- /* Start PBX */
- if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->callerid)) {
- /* Release the PRI lock while we create the channel */
-@@ -7696,15 +8236,29 @@
- 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);
-+ zt_enable_ec(pri->pvts[chanpos]);
-+ }
-+ if (!ast_strlen_zero(e->ring.useruserinfo)) {
-+ pbx_builtin_setvar_helper(c, "UUI", e->ring.useruserinfo);
- }
- 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, e->ring.callingnum, e->ring.callingname, e->ring.callingplan, e->ring.callingpres, 0);
-+ pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
-+ }
-+ if (!ast_strlen_zero(e->ring.callingnumuser)) {
-+ char tmpstr[256];
-+ pri_make_callerid(pri, tmpstr, e->ring.callingnumuser, "", e->ring.callingplanuser, e->ring.callingpresuser, 0);
-+ pbx_builtin_setvar_helper(c, "PRI_USER_CID", e->ring.callednum);
-+ }
- 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",
-- e->ring.callingnum, !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", e->ring.callingnum, !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",
-@@ -7723,10 +8277,26 @@
- ast_mutex_lock(&pri->lock);
- if (c) {
- if (option_verbose > 2)
-- ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
-- e->ring.callingnum, 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]);
-+ zt_enable_ec(pri->pvts[chanpos]);
-+ if (e->ring.useruserinfo) {
-+ pbx_builtin_setvar_helper(c, "UUI", e->ring.useruserinfo);
-+ }
-+ 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, e->ring.callingnum, e->ring.callingname, e->ring.callingplan, e->ring.callingpres, 0);
-+ pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
-+ }
-+ if (!ast_strlen_zero(e->ring.callingnumuser)) {
-+ char tmpstr[256];
-+ pri_make_callerid(pri, tmpstr, e->ring.callingnumuser, "", e->ring.callingplanuser, e->ring.callingpresuser, 0);
-+ pbx_builtin_setvar_helper(c, "PRI_USER_CID", e->ring.callednum);
-+ }
- } 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);
-@@ -7764,7 +8334,7 @@
- } else {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
-- zt_enable_ec(pri->pvts[chanpos]);
-+ // zt_enable_ec(pri->pvts[chanpos]);
- pri->pvts[chanpos]->subs[SUB_REAL].needringing =1;
- pri->pvts[chanpos]->proceeding=2;
- } else
-@@ -7777,7 +8347,13 @@
- /* Get chan value if e->e is not PRI_EVNT_RINGING */
- chanpos = pri_find_principle(pri, e->proceeding.channel);
- if (chanpos > -1) {
-- if (pri->overlapdial && !pri->pvts[chanpos]->proceeding) {
-+ if ((e->proceeding.cause == PRI_CAUSE_USER_BUSY) && (pri->pvts[chanpos]->priindication_oob != 2)) {
-+ /* received PROGRESS with cause BUSY, no inband callprogress wanted => hang up! */
-+ if (pri->pvts[chanpos]->owner) {
-+ pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-+ }
-+ } else {
-+ if (pri->overlapdial && !pri->pvts[chanpos]->proceeding) {
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-@@ -7785,13 +8361,21 @@
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ }
- }
- }
- break;
- case PRI_EVENT_PROCEEDING:
- chanpos = pri_find_principle(pri, e->proceeding.channel);
- if (chanpos > -1) {
-- if (pri->overlapdial && !pri->pvts[chanpos]->proceeding) {
-+ 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 {
-+// pri->pvts[chanpos]->ignoredtmf = 0;
-+ if (pri->overlapdial && !pri->pvts[chanpos]->proceeding) {
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-@@ -7802,6 +8386,7 @@
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
- pri->pvts[chanpos]->proceeding=2;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ }
- }
- }
- break;
-@@ -7827,7 +8412,296 @@
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
-- break;
-+ 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 (pri->pvts[chanpos]->owner->bridge) {
-+ 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]->callerid, sizeof(zpc->msn));
-+ strncpy(zpc->callid, e->suspend_req.callid, sizeof(zpc->callid));
-+ ast_masq_park_call(pri->pvts[chanpos]->owner->bridge, 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 (p->owner->bridge) {
-+ 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]->callerid, sizeof(zhc->msn));
-+ strncpy(zhc->uniqueid, p->owner->bridge->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 = p->owner->bridge;
-+ zhc->next = pri->holded_calls;
-+ pri->holded_calls = zhc;
-+
-+ /* put channel on hold */
-+ ast_masq_hold_call(p->owner->bridge, 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) {
-@@ -7843,6 +8717,8 @@
- chanpos = -1;
- } else {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ pri->pvts[chanpos]->tei = e->answer.tei;
-+ // ast_log(LOG_NOTICE, "TEI %d answered\n", e->answer.tei);
- if (pri->pvts[chanpos]->master && (pri->pvts[chanpos]->master->sig == SIG_FXSKS)) {
- ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
- x = ZT_START;
-@@ -7865,9 +8741,13 @@
- } else if (pri->pvts[chanpos]->confirmanswer) {
- ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
- } 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
-+ pri->pvts[chanpos]->ignoredtmf = 0;
- }
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
-@@ -7890,6 +8770,9 @@
- if (pri->pvts[chanpos]->master)
- pri_hangup_all(pri->pvts[chanpos]->master, 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);
- /* Queue a BUSY instead of a hangup if our cause is appropriate */
- pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
- switch(e->hangup.cause) {
-@@ -7914,18 +8797,33 @@
- } else {
- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
- 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;
-+ }
- }
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- } else {
-- ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n",
-+ 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);
-+ 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;
-@@ -7935,17 +8833,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",
-+ if (pri->nodetype == BRI_NETWORK_PTMP) {
-+ pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
-+ } 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 hangup if we want to hear inband 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]->master)
- pri_hangup_all(pri->pvts[chanpos]->master, 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:
-@@ -7964,20 +8870,81 @@
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-+ 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;
-+
-+ onhold = pri_get_callonhold(pri, -1, e->hangup.tei);
-+
-+ if (onhold) {
-+
-+ 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!!! */
-+ transferee->zombie = 1;
-+ pri->pvts[chanpos]->owner = NULL;
-+ pri->pvts[chanpos]->tei = -1;
-+ }
-+ }
-+ } else {
-+ ast_retrieve_call_to_death(onhold->uniqueid);
-+ }
-+ onhold->alreadyhungup = 1;
-+ pri_hangup(pri->pri, onhold->call, e->hangup.cause);
-+ onhold = NULL;
-+ ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ break;
-+ }
-+ }
-+ }
- } else {
- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
- pri->pvts[chanpos]->call = NULL;
-+ pri->pvts[chanpos]->tei = -1;
- }
- if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
-- if (option_verbose > 2)
-+ if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) {
-+ if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n",
- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-- pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
-- pri->pvts[chanpos]->resetting = 1;
-+ pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
-+ pri->pvts[chanpos]->resetting = 1;
-+ }
- }
- 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);
-+ 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);
-+ }
-+ }
- }
- }
- break;
-@@ -7992,6 +8959,7 @@
- chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ pri->pvts[chanpos]->tei = -1;
- pri->pvts[chanpos]->call = NULL;
- pri->pvts[chanpos]->resetting = 0;
- if (pri->pvts[chanpos]->owner) {
-@@ -8066,17 +9034,98 @@
- ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
- } else {
-- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-- pri->pvts[chanpos]->setup_ack = 1;
-- /* Send any queued digits */
-- for (x=0;x<strlen(pri->pvts[chanpos]->dialdest);x++) {
-+ chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
-+ if (chanpos < 0) {
-+ ast_log(LOG_WARNING, "Received SETUP_ACK on channel %d/%d not in use on span %d\n",
-+ PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
-+ chanpos = -1;
-+ } else {
-+ ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ pri->pvts[chanpos]->setup_ack = 1;
-+ if (pri->pvts[chanpos]->owner) {
-+ // ast_log(LOG_NOTICE, "SETUP_ACK for '%s'\n", pri->pvts[chanpos]->owner->name);
-+ }
-+ /* Send any queued digits */
-+ for (x=0;x<strlen(pri->pvts[chanpos]->dialdest);x++) {
- ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
- pri_information(pri->pri, pri->pvts[chanpos]->call,
- pri->pvts[chanpos]->dialdest[x]);
-+ }
-+ ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
-- 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);
-+ 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);
-+ 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 !!! */
-+ chan->zombie = 1;
-+ }
-+ }
-+ ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ }
-+ /* disconnect */
-+ pri_hangup(pri->pri, e->facility.call, 16);
-+ } else if (e->facility.operation == 0x0D) {
-+ ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum);
-+ /* mmmmmkay */
-+
-+ /* lock the channel */
-+
-+ /* async goto */
-+
-+ /* disconnect isdn layer */
-+ } 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);
- }
-@@ -8225,6 +9274,7 @@
-
-
-
-+
- static int handle_pri_no_debug(int fd, int argc, char *argv[])
- {
- int span;
-@@ -8345,6 +9395,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 pri_debug = {
- { "pri", "debug", "span", NULL }, handle_pri_debug, "Enables PRI debugging on a span", pri_debug_help, complete_span_4 };
-
-@@ -8357,8 +9419,53 @@
- static struct ast_cli_entry pri_show_span = {
- { "pri", "show", "span", NULL }, handle_pri_show_span, "Displays PRI Information", pri_show_span_help, complete_span_4 };
-
-+static struct ast_cli_entry bri_debug = {
-+ { "bri", "debug", "span", NULL }, handle_pri_debug, "Enables BRI debugging on a span", bri_debug_help, complete_span_4 };
-+
-+static struct ast_cli_entry bri_no_debug = {
-+ { "bri", "no", "debug", "span", NULL }, handle_pri_no_debug, "Disables BRI debugging on a span", bri_no_debug_help, complete_span_5 };
-+
-+static struct ast_cli_entry bri_really_debug = {
-+ { "bri", "intense", "debug", "span", NULL }, handle_pri_really_debug, "Enables REALLY INTENSE BRI debugging", bri_really_debug_help, complete_span_5 };
-+
- #endif /* ZAPATA_PRI */
-
-+static int app_zapEC(struct ast_channel *chan, void *data)
-+{
-+ int res=-1;
-+ struct zt_pvt *p = NULL;
-+
-+ if (!data) {
-+ ast_log(LOG_WARNING, "zapEC requires one argument (on | off)\n");
-+ }
-+ if (chan && !strcasecmp("ZAP",chan->type)) {
-+ p = chan->pvt->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");
-+ }
-+
-+ 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[])
-@@ -8920,6 +10027,10 @@
- ast_cli_unregister(&pri_no_debug);
- ast_cli_unregister(&pri_really_debug);
- ast_cli_unregister(&pri_show_span);
-+
-+ ast_cli_unregister(&bri_debug);
-+ ast_cli_unregister(&bri_no_debug);
-+ ast_cli_unregister(&bri_really_debug);
- #endif
- #ifdef ZAPATA_R2
- ast_cli_unregister(&r2_debug);
-@@ -8936,6 +10047,7 @@
- ast_manager_unregister( "ZapDNDon" );
- ast_manager_unregister("ZapShowChannels");
- ast_unregister_application(app_callingpres);
-+ ast_unregister_application(zapEC_app);
- ast_channel_unregister(typecompat);
- ast_channel_unregister(type);
- if (!ast_mutex_lock(&iflock)) {
-@@ -9283,7 +10395,7 @@
- }
- } else if (!strcasecmp(v->name, "echotraining")) {
- if (sscanf(v->value, "%i", &y) == 1) {
-- if ((y < 10) || (y > 4000)) {
-+ if ((y < 10) || (y > 2000)) {
- ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 2000 ms at line %d\n", v->lineno);
- } else {
- echotraining = y;
-@@ -9462,6 +10574,22 @@
- 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")) {
-@@ -9490,6 +10618,8 @@
- dialplan = PRI_INTERNATIONAL_ISDN + 1;
- } else if (!strcasecmp(v->value, "local")) {
- dialplan = PRI_LOCAL_ISDN + 1;
-+ } else if (!strcasecmp(v->value, "dynamic")) {
-+ dialplan = 0;
- } else {
- ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
- }
-@@ -9505,8 +10635,16 @@
- } else if (!strcasecmp(v->value, "local")) {
- localdialplan = PRI_LOCAL_ISDN + 1;
- } else {
-- ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
-+ ast_log(LOG_WARNING, "Unknown PRI local dialplan '%s' at line %d.\n", v->value, v->lineno);
- }
-+ } else if (!strcasecmp(v->name, "nocid")) {
-+ strncpy(nocid, v->value, sizeof(nocid) - 1);
-+ } else if (!strcasecmp(v->name, "withheldcid")) {
-+ strncpy(withheldcid, v->value, sizeof(withheldcid) - 1);
-+ } else if (!strcasecmp(v->name, "nationalprefix")) {
-+ strncpy(nationalprefix, v->value, sizeof(nationalprefix) - 1);
-+ } else if (!strcasecmp(v->name, "internationalprefix")) {
-+ strncpy(internationalprefix, v->value, sizeof(internationalprefix) - 1);
- } else if (!strcasecmp(v->name, "switchtype")) {
- if (!strcasecmp(v->value, "national"))
- switchtype = PRI_SWITCH_NI2;
-@@ -9544,15 +10682,18 @@
- 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' or 'outofband' at line %d\n",
-- v->value, v->lineno);
-+ 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, "minunused")) {
- minunused = atoi(v->value);
- } else if (!strcasecmp(v->name, "idleext")) {
- strncpy(idleext, v->value, sizeof(idleext) - 1);
- } else if (!strcasecmp(v->name, "idledial")) {
- strncpy(idledial, v->value, sizeof(idledial) - 1);
-+ } else if (!strcasecmp(v->name, "pritrustusercid")) {
-+ usercid = ast_true(v->value);
- } else if (!strcasecmp(v->name, "overlapdial")) {
- overlapdial = ast_true(v->value);
- #endif
-@@ -9708,12 +10849,12 @@
- if(res) {
- return -1;
- }
-- if (ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, zt_request)) {
-+ if (ast_channel_register_ex(type, tdesc, AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW, zt_request, zt_devicestate)) {
- ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
- __unload_module();
- return -1;
- }
-- if (ast_channel_register(typecompat, tdesc, AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, zt_request)) {
-+ if (ast_channel_register_ex(typecompat, tdesc, AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW, zt_request, zt_devicestate)) {
- ast_log(LOG_ERROR, "Unable to register channel class %s\n", typecompat);
- __unload_module();
- return -1;
-@@ -9723,6 +10864,10 @@
- ast_cli_register(&pri_no_debug);
- ast_cli_register(&pri_really_debug);
- ast_cli_register(&pri_show_span);
-+
-+ ast_cli_register(&bri_debug);
-+ ast_cli_register(&bri_no_debug);
-+ ast_cli_register(&bri_really_debug);
- #endif
- #ifdef ZAPATA_R2
- ast_cli_register(&r2_debug);
-@@ -9734,6 +10879,7 @@
- ast_cli_register(&zap_show_cadences_cli);
-
- ast_register_application(app_callingpres, change_callingpres, synopsis_callingpres, descrip_callingpres);
-+ ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc);
- memset(round_robin, 0, sizeof(round_robin));
- ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
- ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
-@@ -10007,6 +11153,22 @@
- } else if (!strcasecmp(v->value, "pri_cpe")) {
- cur_signalling = SIG_PRI;
- 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
- } else {
- ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
-@@ -10081,6 +11243,26 @@
- }
- #endif
-
-+#ifdef ZAPATA_PRI
-+static int zt_prisendtext(struct ast_channel *c, char *text)
-+{
-+ struct zt_pvt *p = (struct zt_pvt *)c->pvt->pvt;
-+ ast_log(LOG_NOTICE, "text\n");
-+ 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,text);
-+ pri_rel(p->pri);
-+ } else ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
-+ }
-+ }
-+ return 0;
-+}
-+#endif
-+
- static int zt_sendtext(struct ast_channel *c, char *text)
- {
- #define END_SILENCE_LEN 400
-diff -urNad --exclude=CVS --exclude=.svn ./codecs/codec_ilbc.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/codecs/codec_ilbc.c
---- ./codecs/codec_ilbc.c 2004-06-22 19:49:00.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/codecs/codec_ilbc.c 2005-07-03 13:25:34.685103192 +0100
-@@ -32,7 +32,7 @@
- #include "slin_ilbc_ex.h"
- #include "ilbc_slin_ex.h"
-
--#define USE_ILBC_ENHANCER 0
-+#define USE_ILBC_ENHANCER 1
-
- AST_MUTEX_DEFINE_STATIC(localuser_lock);
- static int localusecnt=0;
-diff -urNad --exclude=CVS --exclude=.svn ./HARDWARE /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/HARDWARE
---- ./HARDWARE 2004-08-03 07:31:20.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/HARDWARE 2005-07-03 13:25:34.686103040 +0100
-@@ -37,6 +37,13 @@
- * Wildcard TE410P - Quad T1/E1 switchable interface. Supports PRI and
- RBS signalling, as well as PPP, FR, and HDLC data modes.
-
-+-- Junghanns.NET
-+ 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
-+
- Non-zaptel compatible hardware
- ==============================
-
-diff -urNad --exclude=CVS --exclude=.svn ./include/asterisk/channel.h /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/include/asterisk/channel.h
---- ./include/asterisk/channel.h 2005-06-14 19:41:48.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/include/asterisk/channel.h 2005-07-03 13:25:34.686103040 +0100
-@@ -34,6 +34,9 @@
- //! Max length of an extension
- #define AST_MAX_EXTENSION 80
-
-+//! Max length of the uniqueid
-+#define AST_MAX_UNIQUEID 64
-+
- #include <asterisk/cdr.h>
- #include <asterisk/monitor.h>
-
-@@ -52,6 +55,8 @@
- int (*generate)(struct ast_channel *chan, void *data, int len, int samples);
- };
-
-+extern ast_mutex_t uniquelock;
-+
- //! Main Channel structure associated with a channel.
- /*!
- * This is the side of it mostly used by the pbx and call management.
-@@ -186,6 +191,8 @@
- /*! Private channel implementation details */
- struct ast_channel_pvt *pvt;
-
-+ /* isdn transfer capability */
-+ unsigned short transfercapability;
-
- /*! Jump buffer used for returning from applications */
- jmp_buf jmp[AST_CHANNEL_MAX_STACK];
-@@ -217,7 +224,7 @@
- unsigned int fout;
-
- /* Unique Channel Identifier */
-- char uniqueid[32];
-+ char uniqueid[AST_MAX_UNIQUEID];
-
- /* Why is the channel hanged up */
- int hangupcause;
-@@ -361,6 +368,8 @@
- #define AST_DEVICE_INVALID 4
- /*! Device is unavailable */
- #define AST_DEVICE_UNAVAILABLE 5
-+/*! Device is ringing */
-+#define AST_DEVICE_RINGING 6
-
- //! Requests a channel
- /*!
-@@ -371,7 +380,7 @@
- * by the low level module
- * Returns an ast_channel on success, NULL on failure.
- */
--struct ast_channel *ast_request(char *type, int format, void *data);
-+struct ast_channel *ast_request(char *type, int format, void *data, char *uniqueid);
-
- //! Search the Channels by Name
- /*!
-@@ -405,9 +414,9 @@
- * 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(char *type, int format, void *data, int timeout, int *reason, char *callerid);
-+struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *reason, int callingpres, char *callerid, char *uniqueid);
-
--struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *reason, char *callerid, struct outgoing_helper *oh);
-+struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *reason, int callingpres, char *callerid, struct outgoing_helper *oh, char *uniqueid);
-
- //! Registers a channel
- /*!
-@@ -638,6 +647,9 @@
- //! Get channel by name (locks channel)
- struct ast_channel *ast_get_channel_by_name_locked(char *channame);
-
-+//! Get channel by uniqueid (locks channel)
-+struct ast_channel *ast_get_channel_by_uniqueid_locked(char *uniqueid);
-+
- //! Waits for a digit
- /*!
- * \param c channel to wait for a digit on
-@@ -709,6 +721,11 @@
- 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 state
- /*!
- * \param state state to get the name of
-@@ -718,6 +735,15 @@
- */
- char *ast_state2str(int state);
-
-+/*! Gives the string form of a given transfer capability */
-+/*!
-+ * \param transercapability transfercapabilty to get the name of
-+ * Give a name to a transfercapbility
-+ * See above
-+ * Returns the text form of the binary transfer capbility
-+ */
-+char *ast_transfercapability2str(int transfercapability);
-+
- /* Options: Some low-level drivers may implement "options" allowing fine tuning of the
- low level channel. See frame.h for options. Note that many channel drivers may support
- none or a subset of those features, and you should not count on this if you want your
-diff -urNad --exclude=CVS --exclude=.svn ./include/asterisk/features.h /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/include/asterisk/features.h
---- ./include/asterisk/features.h 2004-07-18 00:56:12.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/include/asterisk/features.h 2005-07-03 13:25:34.686103040 +0100
-@@ -38,10 +38,17 @@
- */
- 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);
-+
- //! 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);
- extern char *ast_pickup_ext(void);
-
- //! Bridge a call, optionally allowing redirection
-@@ -50,5 +57,7 @@
-
- extern int ast_pickup_call(struct ast_channel *chan);
-
-+extern int ast_autoanswer_login(struct ast_channel *chan, void *data);
-+extern int ast_masq_autoanswer_login(struct ast_channel *rchan, void *data);
-
- #endif /* _AST_FEATURES_H */
-diff -urNad --exclude=CVS --exclude=.svn ./include/asterisk/pbx.h /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/include/asterisk/pbx.h
---- ./include/asterisk/pbx.h 2004-08-21 19:55:39.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/include/asterisk/pbx.h 2005-07-03 13:25:34.687102888 +0100
-@@ -42,6 +42,8 @@
- #define AST_EXTENSION_BUSY 2
- //! All devices UNAVAILABLE/UNREGISTERED
- #define AST_EXTENSION_UNAVAILABLE 3
-+//! One ore more devices RINGING
-+#define AST_EXTENSION_RINGING 4
-
- struct ast_context;
- struct ast_exten;
-@@ -103,6 +105,8 @@
- */
- extern struct ast_app *pbx_findapp(char *app);
-
-+void *ast_pbx_run_app(void *data);
-+
- //! executes an application
- /*!
- * \param c channel to execute on
-@@ -487,11 +491,11 @@
-
- /* Synchronously or asynchronously make an outbound call and send it to a
- particular extension */
--int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, char *callerid, char *variable, char *account );
-+int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, int callingpres, char *callerid, char *variable, char *account, char *uniqueid);
-
- /* Synchronously or asynchronously make an outbound call and send it to a
- particular application with given extension */
--int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid, char *variable, char *account);
-+int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid, char *variable, char *account, char *uniqueid);
-
- /* Functions for returning values from structures */
- char *ast_get_context_name(struct ast_context *con);
-diff -urNad --exclude=CVS --exclude=.svn ./include/asterisk/transcap.h /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/include/asterisk/transcap.h
---- ./include/asterisk/transcap.h 1970-01-01 01:00:00.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/include/asterisk/transcap.h 2005-07-03 13:25:34.687102888 +0100
-@@ -0,0 +1,33 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * General Asterisk channel definitions.
-+ *
-+ * Copyright (C) 1999 - 2005, Digium, Inc.
-+ *
-+ * Matthew Fredrickson <creslin at digium.com>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#ifndef _ASTERISK_TRANSCAP_H
-+#define _ASTERISK_TRANSCAP_H
-+
-+/* These definitions are taken directly out of libpri.h and used here.
-+ * DO NOT change them as it will cause unexpected behavior in channels
-+ * that utilize these fields.
-+ */
-+
-+#define AST_TRANS_CAP_SPEECH 0x0
-+#define AST_TRANS_CAP_DIGITAL 0x08
-+#define AST_TRANS_CAP_RESTRICTED_DIGITAL 0x09
-+#define AST_TRANS_CAP_3_1K_AUDIO 0x10
-+#define AST_TRANS_CAP_7K_AUDIO 0x11 /* Depriciated ITU Q.931 (05/1998)*/
-+#define AST_TRANS_CAP_DIGITAL_W_TONES 0x11
-+#define AST_TRANS_CAP_VIDEO 0x18
-+
-+#define IS_DIGITAL(cap)\
-+ (cap) & AST_TRANS_CAP_DIGITAL ? 1 : 0
-+
-+#endif /* _ASTERISK_TRANSCAP_H */
-diff -urNad --exclude=CVS --exclude=.svn ./Makefile /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/Makefile
---- ./Makefile 2005-04-26 15:30:23.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/Makefile 2005-07-03 13:25:34.687102888 +0100
-@@ -473,6 +473,8 @@
- echo "astspooldir => $(ASTSPOOLDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
- echo "astrundir => $(ASTVARRUNDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
- echo "astlogdir => $(ASTLOGDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
-+ echo "[options]" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
-+ echo "uniquename = asterisk" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
- for x in sounds/demo-*; do \
- if grep -q "^%`basename $$x`%" sounds.txt; then \
- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
-diff -urNad --exclude=CVS --exclude=.svn ./manager.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/manager.c
---- ./manager.c 2005-04-15 08:15:39.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/manager.c 2005-07-03 13:25:34.689102584 +0100
-@@ -9,6 +9,9 @@
- *
- * Mark Spencer <markster at digium.com>
- *
-+ * Copyright (C) 2003-2004, Junghanns.NET Gmbh
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-@@ -40,6 +43,7 @@
- #include <asterisk/md5.h>
- #include <asterisk/acl.h>
- #include <asterisk/utils.h>
-+#include <asterisk/astdb.h>
-
- struct fast_originate_helper
- {
-@@ -55,6 +59,8 @@
- char exten[256];
- char idtext[256];
- int priority;
-+ int callingpres;
-+ char uniqueid[64];
- };
-
- static int enabled = 0;
-@@ -553,18 +559,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_channel_walk_locked(NULL);
-- while(c) {
-- if (!strcasecmp(c->name, name)) {
-- break;
-- }
-- ast_mutex_unlock(&c->lock);
-- c = ast_channel_walk_locked(c);
-- }
-+ 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;
-@@ -669,6 +674,120 @@
- return 0;
- }
-
-+static char mandescr_dbget[] =
-+"Description: Get a value from astdb\n"
-+"Variables: \n"
-+" Family: ...\n"
-+" Key: ...\n";
-+
-+static int action_dbget(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");
-+ char dbresult[256];
-+
-+ 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;
-+ }
-+
-+ ast_mutex_lock(&s->lock);
-+ if (ast_db_get(family, key, dbresult, sizeof(dbresult) - 1)) {
-+ ast_cli(s->fd, "Response: Failed\r\n");
-+ } else {
-+ ast_cli(s->fd, "Response: Success\r\n"
-+ "Value: %s\r\n" ,dbresult);
-+ }
-+ if (id && !ast_strlen_zero(id))
-+ ast_cli(s->fd, "ActionID: %s\r\n",id);
-+ ast_cli(s->fd, "\r\n");
-+ ast_mutex_unlock(&s->lock);
-+
-+ return 0;
-+}
-+
-+static char mandescr_dbput[] =
-+"Description: Put a value into astdb\n"
-+"Variables: \n"
-+" Family: ...\n"
-+" Key: ...\n"
-+" Value: ...\n";
-+
-+static int action_dbput(struct mansession *s, struct message *m)
-+{
-+ char *family = astman_get_header(m, "Family");
-+ char *key = astman_get_header(m, "Key");
-+ char *value = astman_get_header(m, "Value");
-+ 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 (!strlen(value)) {
-+ astman_send_error(s, m, "No value specified");
-+ return 0;
-+ }
-+
-+ ast_mutex_lock(&s->lock);
-+ if (ast_db_put(family, key, value)) {
-+ 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");
-+ ast_mutex_unlock(&s->lock);
-+
-+ return 0;
-+}
-+
-+
-+static char mandescr_dbdel[] =
-+"Description: remove value from astdb\n"
-+"Variables: \n"
-+" Family: ...\n"
-+" Key: ...\n";
-+
-+static int action_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;
-+ }
-+
-+ ast_mutex_lock(&s->lock);
-+ 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");
-+ ast_mutex_unlock(&s->lock);
-+
-+ return 0;
-+}
-+
-
- static int action_status(struct mansession *s, struct message *m)
- {
-@@ -761,32 +880,50 @@
- {
- char *name = astman_get_header(m, "Channel");
- char *name2 = astman_get_header(m, "ExtraChannel");
-+ char *uniqueid = astman_get_header(m, "Uniqueid");
-+ char *uniqueid2 = astman_get_header(m, "ExtraUniqueid");
- char *exten = astman_get_header(m, "Exten");
- char *context = astman_get_header(m, "Context");
- char *priority = astman_get_header(m, "Priority");
-+ 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 (!name || 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) {
-- astman_send_error(s, m, "Channel not existent");
-+ astman_send_error(s, m, "Channel not existant");
- return 0;
- }
-+ if (!ast_strlen_zero(uniqueid2)) {
-+ chan2 = ast_get_channel_by_uniqueid_locked(uniqueid2);
-+ if (!ast_strlen_zero(priority2) && (sscanf(priority, "%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)
-@@ -834,26 +971,28 @@
- int res;
- int reason = 0;
- 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, !ast_strlen_zero(in->callerid) ? in->callerid : NULL, in->variable, in->account);
-+ res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, !ast_strlen_zero(in->callerid) ? in->callerid : NULL, in->variable, in->account, 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, !ast_strlen_zero(in->callerid) ? in->callerid : NULL, in->variable, in->account);
-+ 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->callerid) ? in->callerid : NULL, in->variable, in->account, in->uniqueid);
- }
- if (!res)
- manager_event(EVENT_FLAG_CALL,
- "OriginateSuccess",
- "%s"
-+ "Uniqueid: %s\r\n"
- "Channel: %s/%s\r\n"
- "Context: %s\r\n"
- "Exten: %s\r\n",
-- in->idtext, in->tech, in->data, in->context, in->exten);
-+ in->idtext, in->uniqueid, in->tech, in->data, in->context, in->exten);
- else
- manager_event(EVENT_FLAG_CALL,
- "OriginateFailure",
- "%s"
-+ "Uniqueid: %s\r\n"
- "Channel: %s/%s\r\n"
- "Context: %s\r\n"
- "Exten: %s\r\n",
-- in->idtext, in->tech, in->data, in->context, in->exten);
-+ in->idtext, in->uniqueid, in->tech, in->data, in->context, in->exten);
-
- free(in);
- return NULL;
-@@ -871,6 +1010,7 @@
- " Data: Data to use (requires 'Application')\n"
- " Timeout: How long to wait for call to be answered (in ms)\n"
- " CallerID: Caller ID to be set on the outgoing channel\n"
-+" CallingPres: Caller ID presentation to be set on the outgoing channel\n"
- " Variable: Channel variable to set (VAR1=value1|VAR2=value2)\n"
- " Account: Account code\n"
- " Async: Set to 'true' for fast origination\n";
-@@ -883,6 +1023,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 *variable = astman_get_header(m, "Variable");
- char *account = astman_get_header(m, "Account");
- char *app = astman_get_header(m, "Application");
-@@ -890,11 +1031,14 @@
- char *async = astman_get_header(m, "Async");
- char *id = astman_get_header(m, "ActionID");
- char *tech, *data;
-+ char *uniqueid;
- int pi = 0;
-+ int cpresi = 0;
- int res;
- int to = 30000;
- int reason = 0;
- char tmp[256];
-+ char idText[256] = "";
- pthread_t th;
- pthread_attr_t attr;
- if (!name) {
-@@ -909,6 +1053,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;
-+ }
- strncpy(tmp, name, sizeof(tmp) - 1);
- tech = tmp;
- data = strchr(tmp, '/');
-@@ -918,6 +1066,7 @@
- }
- *data = '\0';
- data++;
-+ uniqueid = ast_alloc_uniqueid();
- if (ast_true(async)) {
- struct fast_originate_helper *fast = malloc(sizeof(struct fast_originate_helper));
- if (!fast) {
-@@ -935,8 +1084,10 @@
- strncpy(fast->account, account, sizeof(fast->account) - 1);
- strncpy(fast->context, context, sizeof(fast->context) - 1);
- strncpy(fast->exten, exten, sizeof(fast->exten) - 1);
-+ strncpy(fast->uniqueid, uniqueid, sizeof(fast->uniqueid) - 1);
- 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)) {
-@@ -946,19 +1097,30 @@
- }
- }
- } else if (!ast_strlen_zero(app)) {
-- res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, !ast_strlen_zero(callerid) ? callerid : NULL, variable, account);
-+ res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 0, !ast_strlen_zero(callerid) ? callerid : NULL, variable, account, uniqueid);
- } else {
- if (exten && context && pi)
-- res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, !ast_strlen_zero(callerid) ? callerid : NULL, variable, account);
-+ res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 0, cpresi, !ast_strlen_zero(callerid) ? callerid : NULL, variable, account, 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
-- astman_send_error(s, m, "Originate failed");
-+ if (!res) {
-+ if (id && !ast_strlen_zero(id)) {
-+ snprintf(idText,256,"ActionID: %s\r\n",id);
-+ }
-+ ast_mutex_lock(&s->lock);
-+ ast_cli(s->fd, "Response: Success\r\n"
-+ "%s"
-+ "Message: Originate successfully queued\r\n"
-+ "Uniqueid: %s\r\n"
-+ "\r\n",
-+ idText, uniqueid);
-+ ast_mutex_unlock(&s->lock);
-+ } else {
-+ astman_send_error(s, m, "Originate failed");
-+ }
- return 0;
- }
-
-@@ -1464,6 +1626,9 @@
- ast_manager_register2( "AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout );
- ast_manager_register2( "MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus );
- ast_manager_register2( "MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount );
-+ ast_manager_register2( "DBget", EVENT_FLAG_CALL, action_dbget, "Retrieve a value from astdb", mandescr_dbget );
-+ ast_manager_register2( "DBput", EVENT_FLAG_CALL, action_dbput, "Store a value in astdb", mandescr_dbput );
-+ ast_manager_register2( "DBdel", EVENT_FLAG_CALL, action_dbdel, "Delete a key from astdb", mandescr_dbdel );
- ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands);
-
- ast_cli_register(&show_mancmd_cli);
-diff -urNad --exclude=CVS --exclude=.svn ./pbx/pbx_spool.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/pbx/pbx_spool.c
---- ./pbx/pbx_spool.c 2005-04-02 18:41:19.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/pbx/pbx_spool.c 2005-07-03 13:25:34.689102584 +0100
-@@ -219,11 +219,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->callerid, o->variable, o->account);
-+ 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->callerid, o->variable, o->account, 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->callerid, o->variable, o->account);
-+ 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->callerid, o->variable, o->account, NULL);
- }
- if (res) {
- ast_log(LOG_NOTICE, "Call failed to go through, reason %d\n", reason);
-diff -urNad --exclude=CVS --exclude=.svn ./pbx/pbx_wilcalu.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/pbx/pbx_wilcalu.c
---- ./pbx/pbx_wilcalu.c 2004-08-08 18:15:02.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/pbx/pbx_wilcalu.c 2005-07-03 13:25:34.689102584 +0100
-@@ -192,7 +192,7 @@
- }
- ast_log(LOG_DEBUG, "Autodial Tech %s(%d) Tele %s(%d) Filename %s(%d)\n",tech, (int)strlen(tech), tele, (int)strlen(tele), filename, (int)strlen(filename));
-
-- channel=ast_request(tech,AST_FORMAT_SLINEAR,tele);
-+ channel=ast_request(tech,AST_FORMAT_SLINEAR,tele,NULL);
- if(channel!=NULL){
- ast_call(channel,tele,10000);
- } else {
-diff -urNad --exclude=CVS --exclude=.svn ./pbx.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/pbx.c
---- ./pbx.c 2005-06-14 19:41:48.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/pbx.c 2005-07-03 13:25:34.692102128 +0100
-@@ -267,7 +267,8 @@
-
- { "Hangup", pbx_builtin_hangup,
- "Unconditional hangup",
-- " Hangup(): Unconditionally hangs up a given channel by returning -1 always.\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,
-@@ -1388,12 +1389,15 @@
-
- res = ast_device_state(cur);
- switch (res) {
-+ case AST_DEVICE_RINGING:
-+ return AST_EXTENSION_RINGING;
- case AST_DEVICE_NOT_INUSE:
- allunavailable = 0;
- allbusy = 0;
- break;
- case AST_DEVICE_INUSE:
-- return AST_EXTENSION_INUSE;
-+ allbusy = 0;
-+ // return AST_EXTENSION_INUSE;
- case AST_DEVICE_BUSY:
- allunavailable = 0;
- allfree = 0;
-@@ -4063,7 +4067,7 @@
- return NULL;
- }
-
--int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, char *callerid, char *variable, char *account)
-+int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, int callingpres, char *callerid, char *variable, char *account, char *uniqueid)
- {
- struct ast_channel *chan;
- struct async_stat *as;
-@@ -4074,7 +4078,7 @@
-
- if (sync) {
- LOAD_OH(oh);
-- chan = __ast_request_and_dial(type, format, data, timeout, reason, callerid, &oh);
-+ chan = __ast_request_and_dial(type, format, data, timeout, reason, callingpres, callerid, &oh, uniqueid);
- if (chan) {
- pbx_builtin_setaccount(chan, account);
- if (chan->_state == AST_STATE_UP) {
-@@ -4129,7 +4133,7 @@
- if (!as)
- return -1;
- memset(as, 0, sizeof(struct async_stat));
-- chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
-+ chan = ast_request_and_dial(type, format, data, timeout, reason, callingpres, callerid, uniqueid);
- if (!chan) {
- free(as);
- return -1;
-@@ -4165,7 +4169,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;
-@@ -4181,7 +4185,7 @@
- return NULL;
- }
-
--int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid, char *variable, char *account)
-+int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid, char *variable, char *account, char *uniqueid)
- {
- struct ast_channel *chan;
- struct async_stat *as;
-@@ -4193,7 +4197,7 @@
- if (!app || ast_strlen_zero(app))
- return -1;
- if (sync) {
-- chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
-+ chan = ast_request_and_dial(type, format, data, timeout, reason, 0, callerid, uniqueid);
- if (chan) {
- pbx_builtin_setaccount(chan, account);
- if (variable) {
-@@ -4239,7 +4243,7 @@
- if (!as)
- return -1;
- memset(as, 0, sizeof(struct async_stat));
-- chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
-+ chan = ast_request_and_dial(type, format, data, timeout, reason, 0, callerid, uniqueid);
- if (!chan) {
- free(as);
- return -1;
-@@ -4453,6 +4457,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 */
- return -1;
- }
-@@ -4854,6 +4861,9 @@
- return -1;
- }
- }
-+ if (chan->_state != AST_STATE_UP) {
-+ ast_answer(chan);
-+ }
- return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options);
- }
-
-@@ -4861,8 +4871,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;
- }
-
-@@ -4870,8 +4884,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;
- }
-
-@@ -4879,8 +4897,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 -urNad --exclude=CVS --exclude=.svn ./README /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/README
---- ./README 2005-05-11 04:44:07.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/README 2005-07-03 13:25:34.692102128 +0100
-@@ -1,6 +1,7 @@
- The Asterisk Open Source PBX
- by Mark Spencer <markster at digium.com>
--Copyright (C) 2001-2004 Digium
-+Copyright (C) 2001-2004 Digium and others....
-+Copyright (C) 2002-2004 Junghanns.NET GmbH and others....
- ================================================================
- * SECURITY
- It is imperative that you read and fully understand the contents of
-@@ -23,14 +24,6 @@
- Asterisk is distributed under GNU General Public License. The GPL also
- must apply to all loadable modules as well, except as defined below.
-
-- Digium, Inc. (formerly Linux Support Services) retains copyright to all
--of the core Asterisk system, and therefore can grant, at its sole discretion,
--the ability for companies, individuals, or organizations to create proprietary
--or Open Source (but non-GPL'd) modules which may be dynamically linked at
--runtime with the portions of Asterisk which fall under our copyright
--umbrella, or are distributed under more flexible licenses than GPL.
--
--
- If you wish to use our code in other GPL programs, don't worry -- there
- is no requirement that you provide the same exemption in your GPL'd
- products (although if you've written a module for Asterisk we would
-@@ -39,12 +32,6 @@
- Specific permission is also granted to OpenSSL and OpenH323 to link to
- Asterisk.
-
-- If you have any questions, whatsoever, regarding our licensing policy,
--please contact us.
--
-- Modules that are GPL-licensed and not available under Digium's
--licensing scheme are added to the Asterisk-addons CVS module.
--
- * REQUIRED COMPONENTS
-
- == Linux ==
-diff -urNad --exclude=CVS --exclude=.svn ./res/Makefile /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/res/Makefile
---- ./res/Makefile 2004-07-17 21:58:01.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/res/Makefile 2005-07-03 13:25:34.692102128 +0100
-@@ -12,7 +12,7 @@
- #
-
- MODS=res_adsi.so res_features.so res_crypto.so res_musiconhold.so res_indications.so res_monitor.so \
-- res_agi.so
-+ res_agi.so res_watchdog.so
- MODS+=$(shell if [ -f "/usr/include/odbcinst.h" ]; then echo "res_odbc.so res_config_odbc.so"; fi)
- MODS+=$(shell if [ -f "/usr/local/include/odbcinst.h" ]; then echo "res_odbc.so res_config_odbc.so"; fi)
- MODS+=$(shell if [ -f "/usr/include/osp/osp.h" ]; then echo "res_osp.so"; fi)
-diff -urNad --exclude=CVS --exclude=.svn ./res/res_features.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/res/res_features.c
---- ./res/res_features.c 2005-05-15 16:55:31.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/res/res_features.c 2005-07-03 13:25:34.694101824 +0100
-@@ -7,6 +7,10 @@
- *
- * Mark Spencer <markster at digium.com>
- *
-+ * Copyright (C) 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-@@ -28,6 +32,7 @@
- #include <asterisk/manager.h>
- #include <asterisk/utils.h>
- #include <asterisk/adsi.h>
-+#include <asterisk/indications.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <unistd.h>
-@@ -51,6 +56,7 @@
- #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
-
- 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;
-@@ -102,6 +108,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;
-
-@@ -120,12 +140,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;
-@@ -135,6 +194,12 @@
- return parking_ext;
- }
-
-+char *ast_parking_con(void)
-+{
-+ return parking_con;
-+}
-+
-+
- char *ast_pickup_ext(void)
- {
- return pickup_ext;
-@@ -227,9 +292,10 @@
- "From: %s\r\n"
- "Timeout: %ld\r\n"
- "CallerID: %s\r\n"
-+ "Uniqueid: %s\r\n"
- ,pu->parkingnum, pu->chan->name, peer->name
- ,(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL)
-- ,(pu->chan->callerid ? pu->chan->callerid : "")
-+ ,(pu->chan->callerid ? pu->chan->callerid : ""), pu->chan->uniqueid
- );
-
- if (peer) {
-@@ -290,6 +356,8 @@
- strncpy(chan->context, rchan->context, sizeof(chan->context) - 1);
- strncpy(chan->exten, rchan->exten, sizeof(chan->exten) - 1);
- chan->priority = rchan->priority;
-+ /* might be dirty but we want trackable channels */
-+ strncpy(chan->uniqueid, rchan->uniqueid, sizeof(chan->uniqueid) - 1);
- /* Make the masq execute */
- f = ast_read(chan);
- if (f)
-@@ -306,7 +374,7 @@
- {
- /* Copy voice back and forth between the two channels. Give the peer
- the ability to transfer calls with '#<extension' syntax. */
-- int len;
-+ struct tone_zone_sound *ts;
- struct ast_frame *f;
- struct ast_channel *who;
- char newext[256], *ptr;
-@@ -447,29 +515,23 @@
- memset(newext, 0, sizeof(newext));
- ptr = newext;
-
-- /* Transfer */
-- if ((res=ast_streamfile(transferer, "pbx-transfer", transferer->language))) {
-- ast_moh_stop(transferee);
-- ast_autoservice_stop(transferee);
-- break;
-- }
-- if ((res=ast_waitstream(transferer, AST_DIGIT_ANY)) < 0) {
-- ast_moh_stop(transferee);
-- ast_autoservice_stop(transferee);
-- break;
-- }
-- ast_stopstream(transferer);
-- if (res > 0) {
-- /* If they've typed a digit already, handle it */
-- newext[0] = res;
-- ptr++;
-- len --;
-+ ts = ast_get_indication_tone(transferer->zone, "dial");
-+ if (ts && ts->data[0])
-+ res = ast_playtones_start(transferer, 0, ts->data, 0);
-+ else
-+ res = ast_playtones_start(transferer, 0, "400", 0);
-+
-+ if (res) {
-+ ast_moh_stop(transferee);
-+ ast_autoservice_stop(transferee);
-+ break;
- }
- res = 0;
- while (strlen(newext) < sizeof(newext) - 1) {
- res = ast_waitfordigit(transferer, transferdigittimeout);
- if (res < 1)
- break;
-+ ast_playtones_stop(transferer);
- if (res == '#')
- break;
- *(ptr++) = res;
-@@ -514,7 +576,7 @@
- ast_verbose(VERBOSE_PREFIX_3 "Transferring %s to '%s' (context %s) priority 1\n"
- ,transferee->name, newext, transferer_real_context);
- if (ast_async_goto(transferee, transferer_real_context, newext, 1))
-- ast_log(LOG_WARNING, "Async goto fialed :(\n");
-+ ast_log(LOG_WARNING, "Async goto failed :(\n");
- res = -1;
- } else {
- /* Set the channel's new extension, since it exists, using transferer context */
-@@ -743,6 +805,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));
-+ config.allowredirect_in = 1;
-+ config.allowredirect_out = 1;
-+ config.allowdisconnect_out = 0;
-+ config.allowdisconnect_in = 0;
-+ 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 to retrieve.\n", uniqueid);
-+ return NULL;
-+ }
-+ } else {
-+ ast_log(LOG_WARNING, "Could not find 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))
-+ pu->chan->exception = 1;
-+ 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;
-@@ -898,11 +1236,12 @@
- "Channel: %s\r\n"
- "Timeout: %ld\r\n"
- "CallerID: %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->callerid ? cur->chan->callerid : "")
-+ ,(cur->chan->callerid ? cur->chan->callerid : ""), cur->chan->uniqueid
- ,idText);
- ast_mutex_unlock(&s->lock);
-
-@@ -920,6 +1259,388 @@
- }
-
-
-+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, 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 *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))
-+ pu->chan->exception = 1;
-+ 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));
-+ config.allowredirect_in = 1;
-+ config.allowredirect_out = 0;
-+ config.allowdisconnect_in = 1;
-+ config.allowdisconnect_out = 0;
-+ 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 load_module(void)
- {
-@@ -930,6 +1651,7 @@
- struct ast_variable *var;
-
- ast_cli_register(&showparked);
-+ ast_cli_register(&showautoanswer);
-
- cfg = ast_load("features.conf");
- if (!cfg) {
-@@ -984,12 +1706,19 @@
- }
- ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, parkcall, strdup(""), FREE, registrar);
- 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;
- }
-
-@@ -1032,7 +1761,10 @@
- STANDARD_HANGUP_LOCALUSERS;
-
- ast_manager_unregister( "ParkedCalls" );
-+ ast_cli_unregister(&showautoanswer);
- ast_cli_unregister(&showparked);
-+ ast_unregister_application(autoanswer);
-+ ast_unregister_application(autoanswerlogin);
- ast_unregister_application(parkcall);
- return ast_unregister_application(parkedcall);
- }
-diff -urNad --exclude=CVS --exclude=.svn ./res/res_watchdog.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/res/res_watchdog.c
---- ./res/res_watchdog.c 1970-01-01 01:00:00.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/res/res_watchdog.c 2005-07-03 13:25:34.695101672 +0100
-@@ -0,0 +1,151 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * Resource to make watchdogs happy
-+ *
-+ * Copyright (C) 2005, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#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/channel_pvt.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>
-+#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>
-+
-+/* Registrar for operations */
-+
-+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", 5);
-+ }
-+ 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_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_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);
-+ 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 -urNad --exclude=CVS --exclude=.svn ./rtp.c /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/rtp.c
---- ./rtp.c 2005-05-31 13:55:43.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/rtp.c 2005-07-03 13:25:34.695101672 +0100
-@@ -417,6 +417,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 -urNad --exclude=CVS --exclude=.svn ./watchdog.conf.sample /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/watchdog.conf.sample
---- ./watchdog.conf.sample 1970-01-01 01:00:00.000000000 +0100
-+++ /tmp/dpep-work.FwunSi/asterisk-1.0.9.dfsg/watchdog.conf.sample 2005-07-03 13:25:34.698101216 +0100
-@@ -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
-+
Deleted: asterisk/trunk/debian/patches/bristuff-0.2.0-RC8j.dpatch
===================================================================
--- asterisk/trunk/debian/patches/bristuff-0.2.0-RC8j.dpatch 2005-10-30 21:14:37 UTC (rev 887)
+++ asterisk/trunk/debian/patches/bristuff-0.2.0-RC8j.dpatch 2005-10-30 23:21:17 UTC (rev 888)
@@ -1,5522 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## bristuff-0.2.0-RC8j.dpatch by <msp at debian.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: From http://www.junghanns.net/asterisk/downloads/
-
- at DPATCH@
-diff -urNad --exclude=CVS --exclude=.svn ./app_devstate.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/app_devstate.c
---- ./app_devstate.c 1970-01-01 10:00:00.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/app_devstate.c 2005-07-22 10:11:12.610332864 +1000
-@@ -0,0 +1,196 @@
-+/*
-+ * Devstate application
-+ *
-+ * Since we like the snom leds so much, a little app to
-+ * light the lights on the snom on demand ....
-+ *
-+ * Copyright (C) 2005, Druid Software
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include <asterisk/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 <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.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)
-+ return RESULT_SHOWUSAGE;
-+
-+ if (ast_db_put("DEVSTATES", argv[1], argv[2]))
-+ {
-+ ast_log(LOG_DEBUG, "ast_db_put failed\n");
-+ }
-+
-+ snprintf(devName, sizeof(devName), "DS/%s", argv[1]);
-+ ast_device_state_changed(devName);
-+ 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(devName);
-+
-+ 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 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 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;
-+ }
-+
-+ ast_mutex_lock(&s->lock);
-+
-+ if (!ast_db_put("DEVSTATES", devstate, value)) {
-+ snprintf(devName, sizeof(devName), "DS/%s", devstate);
-+ ast_device_state_changed(devName);
-+ 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");
-+ ast_mutex_unlock(&s->lock);
-+ return 0;
-+}
-+
-+int load_module(void)
-+{
-+ if (ast_channel_register_ex(type, tdesc, ((AST_FORMAT_MAX_AUDIO << 1) - 1), NULL, ds_devicestate)) {
-+ 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(type);
-+ return res;
-+}
-+
-+char *description(void)
-+{
-+ return tdesc;
-+}
-+
-+int usecount(void)
-+{
-+ int res;
-+ STANDARD_USECOUNT(res);
-+ return res;
-+}
-+
-+char *key()
-+{
-+ return ASTERISK_GPL_KEY;
-+}
-diff -urNad --exclude=CVS --exclude=.svn ./app_pickup.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/app_pickup.c
---- ./app_pickup.c 1970-01-01 10:00:00.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/app_pickup.c 2005-07-22 10:11:12.610332864 +1000
-@@ -0,0 +1,289 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * Pickup, channel independent call pickup
-+ *
-+ * Copyright (C) 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ * Copyright (C) 2004, Florian Overkamp <florian at obsimref.com>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include <asterisk/lock.h>
-+#include <asterisk/file.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/channel_pvt.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/module.h>
-+#include <asterisk/features.h>
-+#include <asterisk/options.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <signal.h>
-+
-+#include <pthread.h>
-+
-+
-+static char *tdesc = "PickUp/PickDown/Steal/PickupChan";
-+
-+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";
-+
-+
-+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';
-+ }
-+ /* 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;
-+}
-+
-+int unload_module(void)
-+{
-+ STANDARD_HANGUP_LOCALUSERS;
-+ ast_unregister_application(app4);
-+ ast_unregister_application(app3);
-+ ast_unregister_application(app2);
-+ return ast_unregister_application(app);
-+}
-+
-+int load_module(void)
-+{
-+ 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 -urNad --exclude=CVS --exclude=.svn ./apps/app_chanisavail.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_chanisavail.c
---- ./apps/app_chanisavail.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_chanisavail.c 2005-07-22 10:11:12.610332864 +1000
-@@ -81,7 +81,7 @@
- }
- *number = '\0';
- number++;
-- if ((tempchan = ast_request(tech, chan->nativeformats, number))) {
-+ if ((tempchan = ast_request(tech, chan->nativeformats, number, NULL))) {
- pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
- /* Store the originally used channel too */
- snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_dial.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_dial.c
---- ./apps/app_dial.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_dial.c 2005-07-22 10:11:12.611332712 +1000
-@@ -7,6 +7,10 @@
- *
- * Mark Spencer <markster at digium.com>
- *
-+ * Copyright (C) 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-@@ -56,6 +60,8 @@
- "n is the priority of the dialer instance), then it will be the next\n"
- "executed extension (this allows you to setup different behavior on busy from\n"
- "no-answer).\n"
-+"If an extension with priority +201 exists and there was no channel available\n"
-+"we will go there instead. So unregisterd VoIP phones will not be treaded as busy.\n"
- " This application returns -1 if the originating channel hangs up, or if the\n"
- "call is bridged and either of the parties in the bridge terminate the call.\n"
- "The option string may contain zero or more of the following characters:\n"
-@@ -66,6 +72,8 @@
- " don't allow callerids from other extensions then the ones\n"
- " that are assigned to you.\n"
- " 'r' -- indicate ringing to the calling party, pass no audio until answered.\n"
-+" 'R' -- indicate ringing to the calling party when the called party indicates\n"
-+" ringing, pass no audio until answered.\n"
- " 'm' -- provide hold music to the calling party until answered.\n"
- " 'M(x) -- Executes the macro (x) upon connect of the call\n"
- " 'h' -- allow callee to hang up by hitting *.\n"
-@@ -109,6 +117,7 @@
- int allowredirect_in;
- int allowredirect_out;
- int ringbackonly;
-+ int noinband;
- int musiconhold;
- int allowdisconnect_in;
- int allowdisconnect_out;
-@@ -151,7 +160,7 @@
- int single;
- struct ast_channel *winner;
-
-- single = (outgoing && !outgoing->next && !outgoing->musiconhold && !outgoing->ringbackonly);
-+ single = (outgoing && !outgoing->next && !outgoing->musiconhold && !outgoing->ringbackonly && !outgoing->noinband);
-
- if (single) {
- /* Turn off hold music, etc */
-@@ -180,12 +189,13 @@
- if (numlines == (numbusy + numcongestion + numnochan)) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time\n");
-- if (numbusy)
-+ if (numnochan) {
-+ strncpy(status, "CHANUNAVAIL", statussize - 1);
-+ } else if (numbusy) {
- strncpy(status, "BUSY", statussize - 1);
-- else if (numcongestion)
-+ } else if (numcongestion) {
- strncpy(status, "CONGESTION", statussize - 1);
-- else if (numnochan)
-- strncpy(status, "CHANUNAVAIL", statussize - 1);
-+ }
- /* See if there is a special busy message */
- if (ast_exists_extension(in, in->context, in->exten, in->priority + 101, in->callerid))
- in->priority+=100;
-@@ -229,7 +239,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);
-+ o->chan = ast_request(tech, in->nativeformats, stuff, NULL);
- if (!o->chan) {
- ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
- o->stillgoing = 0;
-@@ -356,10 +366,10 @@
- default:
- ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
- }
-- } else if (single && (f->frametype == AST_FRAME_VOICE) &&
-+ } else if (single && (f->frametype == AST_FRAME_VOICE) &&
- !(outgoing->ringbackonly || outgoing->musiconhold)) {
- if (ast_write(in, f))
-- ast_log(LOG_WARNING, "Unable to forward frame\n");
-+ ast_log(LOG_WARNING, "Unable to forward frame\n");
- } else if (single && (f->frametype == AST_FRAME_IMAGE) &&
- !(outgoing->ringbackonly || outgoing->musiconhold)) {
- if (ast_write(in, f))
-@@ -731,6 +741,9 @@
- if (strchr(transfer, 'r'))
- tmp->ringbackonly = 1;
- else tmp->ringbackonly = 0;
-+ if (strchr(transfer, 'R'))
-+ tmp->noinband = 1;
-+ else tmp->noinband = 0;
- if (strchr(transfer, 'm'))
- tmp->musiconhold = 1;
- else tmp->musiconhold = 0;
-@@ -758,7 +771,7 @@
- ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
- }
- /* Request the peer */
-- tmp->chan = ast_request(tech, chan->nativeformats, numsubst);
-+ tmp->chan = ast_request(tech, chan->nativeformats, numsubst, 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'\n", tech);
-@@ -788,7 +801,7 @@
- ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
- /* Setup parameters */
- ast_hangup(tmp->chan);
-- tmp->chan = ast_request(tech, chan->nativeformats, stuff);
-+ tmp->chan = ast_request(tech, chan->nativeformats, stuff, NULL);
- if (!tmp->chan) {
- ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
- free(tmp);
-@@ -846,6 +859,8 @@
- tmp->chan->adsicpe = chan->adsicpe;
- /* pass the digital flag */
- ast_dup_flag(tmp->chan, chan, AST_FLAG_DIGITAL);
-+ /* Pass the transfer capability */
-+ tmp->chan->transfercapability = chan->transfercapability;
- /* Place the call, but don't wait on the answer */
- res = ast_call(tmp->chan, numsubst, 0);
-
-@@ -898,9 +913,12 @@
- ast_indicate(chan, AST_CONTROL_RINGING);
- sentringing++;
- }
-- } else
-+ } else {
- strncpy(status, "CHANUNAVAIL", sizeof(status) - 1);
--
-+ /* See if there is a special message */
-+ if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 201, chan->callerid))
-+ chan->priority+=200;
-+ }
- time(&start_time);
- peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &sentringing, &noforwardhtml, status, sizeof(status));
-
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_meetme.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_meetme.c
---- ./apps/app_meetme.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_meetme.c 2005-07-22 10:11:12.612332560 +1000
-@@ -220,7 +220,7 @@
- strncpy(cnf->confno, confno, sizeof(cnf->confno) - 1);
- strncpy(cnf->pin, pin, sizeof(cnf->pin) - 1);
- cnf->markedusers = 0;
-- cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo");
-+ cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo", NULL);
- if (cnf->chan) {
- cnf->fd = cnf->chan->fds[0]; /* for use by conf_play() */
- } else {
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_parkandannounce.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_parkandannounce.c
---- ./apps/app_parkandannounce.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_parkandannounce.c 2005-07-22 10:11:12.612332560 +1000
-@@ -161,7 +161,7 @@
-
- /* Now place the call to the extention */
-
-- dchan = ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, chan->callerid);
-+ dchan = ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, 0, chan->callerid, NULL);
-
- if(dchan) {
- if(dchan->_state == AST_STATE_UP) {
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_qcall.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_qcall.c
---- ./apps/app_qcall.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_qcall.c 2005-07-22 10:11:12.614332256 +1000
-@@ -224,7 +224,7 @@
- pthread_exit(NULL);
- }
- *tele++ = 0;
-- channel = ast_request(dialstr,AST_FORMAT_SLINEAR,tele);
-+ channel = ast_request(dialstr,AST_FORMAT_SLINEAR,tele,NULL);
- if (channel)
- {
- ast_set_read_format(channel,AST_FORMAT_SLINEAR);
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_queue.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_queue.c
---- ./apps/app_queue.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_queue.c 2005-07-22 10:11:12.616331952 +1000
-@@ -559,7 +559,7 @@
- return 0;
- }
- /* Request the peer */
-- tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst);
-+ tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst, 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'\n", cur->tech);
-diff -urNad --exclude=CVS --exclude=.svn ./apps/app_zapras.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_zapras.c
---- ./apps/app_zapras.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/apps/app_zapras.c 2005-07-22 10:11:12.616331952 +1000
-@@ -159,7 +159,7 @@
- }
- }
- /* Throw back into audio mode */
-- x = 1;
-+ x = 0;
- ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
-
- /* Double check buffering too */
-diff -urNad --exclude=CVS --exclude=.svn ./app_segfault.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/app_segfault.c
---- ./app_segfault.c 1970-01-01 10:00:00.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/app_segfault.c 2005-07-22 10:11:12.616331952 +1000
-@@ -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 at junghanns.net>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License. THIS APPLICATION _WILL_ CRASH YOUR
-+ * ASTERISK SERVER SO OF COURSE THERE IS NOT LIABILITY FOR NOTHING!
-+ */
-+
-+#include <asterisk/lock.h>
-+#include <asterisk/file.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/module.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.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 -urNad --exclude=CVS --exclude=.svn ./app_settransfercapability.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/app_settransfercapability.c
---- ./app_settransfercapability.c 1970-01-01 10:00:00.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/app_settransfercapability.c 2005-07-22 10:11:12.616331952 +1000
-@@ -0,0 +1,115 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * App to set the ISDN Transfer Capability
-+ *
-+ * Copyright (C) 2005, Frank Sautter, levigo holding gmbh, www.levigo.de
-+ *
-+ * Frank Sautter - asterisk+at+sautter+dot+com
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include "asterisk/logger.h"
-+#include "asterisk/channel.h"
-+#include "asterisk/channel_pvt.h"
-+#include "asterisk/pbx.h"
-+#include "asterisk/module.h"
-+#include "asterisk/options.h"
-+#include "asterisk/transcap.h"
-+#include <string.h>
-+#include <stdlib.h>
-+
-+
-+static char *app = "SetTransferCapability";
-+
-+static char *synopsis = "Set ISDN Transfer Capability";
-+
-+STANDARD_LOCAL_USER;
-+
-+LOCAL_USER_DECL;
-+
-+static struct { int val; char *name; } transcaps[] = {
-+ { AST_TRANS_CAP_SPEECH, "SPEECH" },
-+ { AST_TRANS_CAP_DIGITAL, "DIGITAL" },
-+ { AST_TRANS_CAP_RESTRICTED_DIGITAL, "RESTRICTED_DIGITAL" },
-+ { AST_TRANS_CAP_3_1K_AUDIO, "3K1AUDIO" },
-+ { AST_TRANS_CAP_DIGITAL_W_TONES, "DIGITAL_W_TONES" },
-+ { AST_TRANS_CAP_VIDEO, "VIDEO" },
-+};
-+
-+static char *descrip =
-+" SetTransferCapability(transfercapability): Set the ISDN Transfer \n"
-+"Capability of a call to a new value.\n"
-+"Always returns 0. Valid Transfer Capabilities are:\n"
-+"\n"
-+" SPEECH : 0x00 - Speech (default, voice calls)\n"
-+" DIGITAL : 0x08 - Unrestricted digital information (data calls)\n"
-+" RESTRICTED_DIGITAL : 0x09 - Restricted digital information\n"
-+" 3K1AUDIO : 0x10 - 3.1kHz Audio (fax calls)\n"
-+" DIGITAL_W_TONES : 0x11 - Unrestricted digital information with tones/announcements\n"
-+" VIDEO : 0x18 - Video:\n"
-+"\n"
-+;
-+
-+static int settransfercapability_exec(struct ast_channel *chan, void *data)
-+{
-+ char tmp[256] = "";
-+ struct localuser *u;
-+ int x;
-+ char *opts;
-+ int transfercapability = -1;
-+
-+ if (data)
-+ strncpy(tmp, (char *)data, sizeof(tmp) - 1);
-+ opts = strchr(tmp, '|');
-+ if (opts)
-+ *opts = '\0';
-+ for (x=0;x<sizeof(transcaps) / sizeof(transcaps[0]);x++) {
-+ if (!strcasecmp(transcaps[x].name, tmp)) {
-+ transfercapability = transcaps[x].val;
-+ break;
-+ }
-+ }
-+ if (transfercapability < 0) {
-+ ast_log(LOG_WARNING, "'%s' is not a valid transfer capability (see 'show application SetTransferCapability')\n", tmp);
-+ return 0;
-+ } else {
-+ LOCAL_USER_ADD(u);
-+ chan->transfercapability = (unsigned short)transfercapability;
-+ LOCAL_USER_REMOVE(u);
-+ if (option_verbose > 2)
-+ ast_verbose(VERBOSE_PREFIX_3 "Setting transfer capability to: 0x%.2x - %s.\n", transfercapability, tmp);
-+ return 0;
-+ }
-+}
-+
-+
-+int unload_module(void)
-+{
-+ STANDARD_HANGUP_LOCALUSERS;
-+ return ast_unregister_application(app);
-+}
-+
-+int load_module(void)
-+{
-+ return ast_register_application(app, settransfercapability_exec, synopsis, descrip);
-+}
-+
-+char *description(void)
-+{
-+ return descrip;
-+}
-+
-+int usecount(void)
-+{
-+ int res;
-+ STANDARD_USECOUNT(res);
-+ return res;
-+}
-+
-+char *key()
-+{
-+ return ASTERISK_GPL_KEY;
-+}
-diff -urNad --exclude=CVS --exclude=.svn ./astconf.h /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/astconf.h
---- ./astconf.h 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/astconf.h 2005-07-22 10:11:12.616331952 +1000
-@@ -28,5 +28,6 @@
- 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];
-
- #endif
-diff -urNad --exclude=CVS --exclude=.svn ./asterisk.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/asterisk.c
---- ./asterisk.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/asterisk.c 2005-07-22 10:11:12.617331800 +1000
-@@ -124,6 +124,7 @@
- char ast_config_AST_PID[AST_CONFIG_MAX_PATH];
- char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH];
- char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH];
-+char ast_config_AST_SYMBOLIC_NAME[20];
-
- static char *_argv[256];
- static int shuttingdown = 0;
-@@ -1511,6 +1512,7 @@
- strncpy((char *)ast_config_AST_PID,AST_PID,sizeof(ast_config_AST_PID)-1);
- strncpy((char *)ast_config_AST_SOCKET,AST_SOCKET,sizeof(ast_config_AST_SOCKET)-1);
- strncpy((char *)ast_config_AST_RUN_DIR,AST_RUN_DIR,sizeof(ast_config_AST_RUN_DIR)-1);
-+ strncpy((char *)ast_config_AST_SYMBOLIC_NAME,AST_SYMBOLIC_NAME,sizeof(ast_config_AST_SYMBOLIC_NAME)-1);
-
- /* no asterisk.conf? no problem, use buildtime config! */
- if (!cfg) {
-@@ -1562,6 +1564,8 @@
- option_cache_record_files = ast_true(v->value);
- } else if (!strcasecmp(v->name, "record_cache_dir")) {
- strncpy(record_cache_dir,v->value,AST_CACHE_DIR_LEN);
-+ } else if (!strcasecmp(v->name, "uniquename")) {
-+ strncpy(ast_config_AST_SYMBOLIC_NAME,v->value,sizeof(ast_config_AST_SYMBOLIC_NAME));
- }
- v = v->next;
- }
-diff -urNad --exclude=CVS --exclude=.svn ./asterisk.h /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/asterisk.h
---- ./asterisk.h 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/asterisk.h 2005-07-22 10:11:12.617331800 +1000
-@@ -29,6 +29,7 @@
- #define AST_KEY_DIR ASTVARLIBDIR "/keys"
- #define AST_DB ASTVARLIBDIR "/astdb"
- #define AST_TMP_DIR ASTSPOOLDIR "/tmp"
-+#define AST_SYMBOLIC_NAME "asterisk"
-
- #define AST_CONFIG_FILE ASTCONFPATH
-
-diff -urNad --exclude=CVS --exclude=.svn ./channel.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/channel.c
---- ./channel.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/channel.c 2005-07-22 10:11:12.619331496 +1000
-@@ -38,6 +38,8 @@
- #include <asterisk/causes.h>
- #include <asterisk/utils.h>
- #include <asterisk/lock.h>
-+#include <asterisk/transcap.h>
-+#include "astconf.h"
- #ifdef ZAPTEL_OPTIMIZATIONS
- #include <sys/ioctl.h>
- #ifdef __linux__
-@@ -56,8 +58,10 @@
- #define MONITOR_DELAY 150 * 8 /* 150 ms of MONITORING DELAY */
- #endif
-
-+extern int ast_mainpid; /* provided by asterisk.c */
- static int shutting_down = 0;
- static int uniqueint = 0;
-+AST_MUTEX_DEFINE_STATIC(uniquelock);
-
- /* XXX Lock appropriately in more functions XXX */
-
-@@ -229,6 +233,26 @@
- }
- }
-
-+char *ast_transfercapability2str(int transfercapability)
-+{
-+ switch(transfercapability) {
-+ case AST_TRANS_CAP_SPEECH:
-+ return "SPEECH";
-+ case AST_TRANS_CAP_DIGITAL:
-+ return "DIGITAL";
-+ case AST_TRANS_CAP_RESTRICTED_DIGITAL:
-+ return "RESTRICTED_DIGITAL";
-+ case AST_TRANS_CAP_3_1K_AUDIO:
-+ return "3K1AUDIO";
-+ case AST_TRANS_CAP_DIGITAL_W_TONES:
-+ return "DIGITAL_W_TONES";
-+ case AST_TRANS_CAP_VIDEO:
-+ return "VIDEO";
-+ default:
-+ return "UNKNOWN";
-+ }
-+}
-+
-
- int ast_best_codec(int fmts)
- {
-@@ -271,13 +295,25 @@
- return 0;
- }
-
-+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);
-+// ast_log(LOG_NOTICE,"uid = %s\n",uniqueid);
-+ return uniqueid;
-+}
-+
- struct ast_channel *ast_channel_alloc(int needqueue)
- {
- struct ast_channel *tmp;
- struct ast_channel_pvt *pvt;
- int x;
- int flags;
-- struct varshead *headp;
-+ struct varshead *headp;
-+ char *tmpuniqueid;
-
-
- /* If shutting down, don't allocate any new channels */
-@@ -336,7 +372,12 @@
- tmp->data = NULL;
- tmp->fin = 0;
- tmp->fout = 0;
-- snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
-+ 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(headp);
-@@ -520,6 +561,19 @@
- return NULL;
- }
-
-+struct ast_channel *ast_get_channel_by_uniqueid_locked(char *uniqueid)
-+{
-+ struct ast_channel *chan;
-+ chan = ast_channel_walk_locked(NULL);
-+ while(chan) {
-+ if (!strcasecmp(chan->uniqueid, uniqueid))
-+ return chan;
-+ ast_mutex_unlock(&chan->lock);
-+ chan = ast_channel_walk_locked(chan);
-+ }
-+ return NULL;
-+}
-+
- int ast_safe_sleep_conditional( struct ast_channel *chan, int ms,
- int (*cond)(void*), void *data )
- {
-@@ -1755,14 +1809,14 @@
- return 0;
- }
-
--struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid, struct outgoing_helper *oh)
-+struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, int callingpres, char *callerid, struct outgoing_helper *oh, char* uniqueid)
- {
- int state = 0;
- struct ast_channel *chan;
- struct ast_frame *f;
- int res = 0;
- char *variable;
-- chan = ast_request(type, format, data);
-+ chan = ast_request(type, format, data, uniqueid);
- if (chan) {
- if (oh) {
- char *tmp, *var;
-@@ -1784,6 +1838,7 @@
- if (callerid && !ast_strlen_zero(callerid))
- ast_set_callerid(chan, callerid, 1);
-
-+ chan->callingpres = callingpres;
- if (!ast_call(chan, data, 0)) {
- while(timeout && (chan->_state != AST_STATE_UP)) {
- res = ast_waitfor(chan, timeout);
-@@ -1806,6 +1861,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;
-@@ -1865,12 +1921,12 @@
- return chan;
- }
-
--struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid)
-+struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, int callingpres, char *callerid, char *uniqueid)
- {
-- return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
-+ return __ast_request_and_dial(type, format, data, timeout, outstate, 0, callerid, NULL, uniqueid);
- }
-
--struct ast_channel *ast_request(char *type, int format, void *data)
-+struct ast_channel *ast_request(char *type, int format, void *data, char *uniqueid)
- {
- struct chanlist *chan;
- struct ast_channel *c = NULL;
-@@ -1896,6 +1952,7 @@
- if (chan->requester)
- c = chan->requester(type, capabilities, data);
- if (c) {
-+ 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"
-@@ -1928,8 +1985,12 @@
- cut = strchr(name,'-');
- if (cut)
- *cut = 0;
-- if (!strcmp(name, device))
-- return AST_DEVICE_INUSE;
-+ if (!strcmp(name, device)) {
-+ if (chan->_state == AST_STATE_RINGING)
-+ return AST_DEVICE_RINGING;
-+ else
-+ return AST_DEVICE_INUSE;
-+ }
- chan = ast_channel_walk_locked(chan);
- }
- return AST_DEVICE_UNKNOWN;
-@@ -2193,6 +2254,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];
-@@ -2303,6 +2387,7 @@
- }
-
- /* Start by disconnecting the original's physical side */
-+
- if (clone->pvt->hangup)
- res = clone->pvt->hangup(clone);
- if (res) {
-@@ -2460,6 +2545,7 @@
- "Uniqueid: %s\r\n",
- chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
- } else {
-+ ast_device_state_changed(chan->name);
- manager_event(EVENT_FLAG_CALL, "Newstate",
- "Channel: %s\r\n"
- "State: %s\r\n"
-@@ -2534,6 +2620,10 @@
-
- flags = (config->allowdisconnect_out||config->allowredirect_out ? AST_BRIDGE_DTMF_CHANNEL_0 : 0) + (config->allowdisconnect_in||config->allowredirect_in ? AST_BRIDGE_DTMF_CHANNEL_1 : 0);
-
-+ if (IS_DIGITAL(c0->transfercapability) || IS_DIGITAL(c1->transfercapability)) {
-+ flags = 0;
-+ }
-+
- firstpass = config->firstpass;
- config->firstpass = 0;
-
-diff -urNad --exclude=CVS --exclude=.svn ./channels/chan_agent.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/channels/chan_agent.c
---- ./channels/chan_agent.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/channels/chan_agent.c 2005-07-22 10:11:12.620331344 +1000
-@@ -1091,7 +1091,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);
-+ p->chan = ast_request("Local", format, p->loginchan, NULL);
- if (p->chan)
- chan = agent_new(p, AST_STATE_DOWN);
- }
-diff -urNad --exclude=CVS --exclude=.svn ./channels/chan_sip.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/channels/chan_sip.c
---- ./channels/chan_sip.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/channels/chan_sip.c 2005-07-22 10:11:12.625330584 +1000
-@@ -296,6 +296,7 @@
- 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? */
-+ char *vxml_url;
- char from[256]; /* The From: header */
- char useragent[256]; /* User agent in SIP request */
- char context[AST_MAX_EXTENSION]; /* Context for this call */
-@@ -1462,6 +1463,7 @@
- if (strcasecmp(ast_var_name(current),"VXML_URL")==0)
- {
- vxml_url = ast_var_value(current);
-+ p->vxml_url=vxml_url;
- } else
- /* Check whether there is a ALERT_INFO variable */
- if (strcasecmp(ast_var_name(current),"ALERT_INFO")==0)
-@@ -3724,12 +3726,11 @@
- }
- strncpy(p->uri, invite, sizeof(p->uri) - 1);
- /* If there is a VXML URL append it to the SIP URL */
-- if (vxml_url)
-- {
-- snprintf(to, sizeof(to), "<%s>;%s", invite, vxml_url);
-- }
-- else
-- {
-+ if (vxml_url) {
-+ snprintf(to, sizeof(to), "<%s;%s>", invite, vxml_url);
-+ } else if (p->vxml_url) {
-+ snprintf(to, sizeof(to), "<%s;%s>", invite, p->vxml_url);
-+ } else {
- snprintf(to, sizeof(to), "<%s>", invite);
- }
- memset(req, 0, sizeof(struct sip_request));
-@@ -3817,6 +3818,7 @@
- char *mfrom, *mto;
- struct sip_request req;
- char clen[20];
-+ char *StateString;
-
- memset(from, 0, sizeof(from));
- memset(to, 0, sizeof(to));
-@@ -3851,6 +3853,7 @@
- add_header(&req, "Subscription-State", "active");
- add_header(&req, "Content-Type", "application/xpidf+xml");
-
-+
- if ((state==AST_EXTENSION_UNAVAILABLE) || (state==AST_EXTENSION_BUSY))
- state = 2;
- else if (state==AST_EXTENSION_INUSE)
-@@ -3889,6 +3892,21 @@
- add_header(&req, "Event", "dialog");
- add_header(&req, "Content-Type", "application/dialog-info+xml");
-
-+ switch(state) {
-+ case AST_EXTENSION_RINGING:
-+ StateString = "trying";
-+// StateString = "early";
-+ break;
-+ case AST_EXTENSION_INUSE:
-+ case AST_EXTENSION_BUSY:
-+ StateString = "confirmed";
-+ break;
-+ case AST_EXTENSION_UNAVAILABLE:
-+ case AST_EXTENSION_NOT_INUSE:
-+ default:
-+ StateString = "terminated";
-+ }
-+
- t = tmp;
- maxbytes = sizeof(tmp);
- bytes = snprintf(t, maxbytes, "<?xml version=\"1.0\"?>\n");
-@@ -3900,9 +3918,19 @@
- bytes = snprintf(t, maxbytes, "<dialog id=\"%s\">\n", p->exten);
- t += bytes;
- maxbytes -= bytes;
-- bytes = snprintf(t, maxbytes, "<state>%s</state>\n", state ? "confirmed" : "terminated");
-+ // ast_log(LOG_NOTICE, "State: %d %s\n", state,StateString);
-+ bytes = snprintf(t, maxbytes, "<state>%s</state>\n", StateString);
- t += bytes;
- maxbytes -= bytes;
-+/* if (state == AST_EXTENSION_RINGING) {
-+ bytes = snprintf(t, maxbytes, "<local><identity display=\"%s\">sip:667 at 192.168.1.241</identity><target uri=\"sip:667 at 192.168.1.241\"/></local>\n", "test");
-+ t += bytes;
-+ maxbytes -= bytes;
-+ bytes = snprintf(t, maxbytes, "<remote><identity display=\"%s\">sip:667 at 192.168.1.241</identity><target uri=\"sip:667 at 192.168.1.241\"/></remote>\n", "test");
-+ t += bytes;
-+ maxbytes -= bytes;
-+ }
-+*/
- bytes = snprintf(t, maxbytes, "</dialog>\n</dialog-info>\n");
- }
- if (t > tmp + sizeof(tmp))
-@@ -6309,7 +6337,7 @@
- return -1;
- }
- /* Now we have a reply digest */
-- return transmit_invite(p,msg,!strcasecmp(msg, "INVITE"),digest, respheader, NULL,NULL,NULL, init);
-+ return transmit_invite(p,msg,!strcasecmp(msg, "INVITE"),digest, respheader, p->vxml_url,NULL,NULL, init);
- }
-
- /*--- reply_digest: reply to authentication for outbound registrations ---*/
-diff -urNad --exclude=CVS --exclude=.svn ./channels/chan_zap.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/channels/chan_zap.c
---- ./channels/chan_zap.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/channels/chan_zap.c 2005-07-22 10:11:12.634329216 +1000
-@@ -7,6 +7,10 @@
- *
- * Mark Spencer <markster at digium.com>
- *
-+ * Copyright (C) 2003, 2004, 2005 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-@@ -39,6 +43,7 @@
- #include <asterisk/causes.h>
- #include <asterisk/term.h>
- #include <asterisk/utils.h>
-+#include <asterisk/transcap.h>
- #include <sys/signal.h>
- #include <errno.h>
- #include <stdlib.h>
-@@ -146,8 +151,8 @@
- #define SIG_GR303FXOKS (0x100000 | ZT_SIG_FXOKS)
- #define SIG_GR303FXSKS (0x200000 | ZT_SIG_FXSKS)
-
--#define NUM_SPANS 32
--#define NUM_DCHANS 4 /* No more than 4 d-channels */
-+#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 */
- #define RESET_INTERVAL 3600 /* How often (in seconds) to reset unused channels */
-
-@@ -164,6 +169,9 @@
- static char context[AST_MAX_EXTENSION] = "default";
- static char callerid[256] = "";
-
-+static char nocid[256] = "No CID available";
-+static char withheldcid[256] = "CID withheld";
-+
- static char language[MAX_LANGUAGE] = "";
- static char musicclass[MAX_LANGUAGE] = "";
- static char progzone[10]= "";
-@@ -250,7 +258,9 @@
- static char idleext[AST_MAX_EXTENSION];
- static char idledial[AST_MAX_EXTENSION];
- static int overlapdial = 0;
-+static int usercid = 0;
- static struct ast_channel inuse = { "GR-303InUse" };
-+
- #endif
-
- /* Wait up to 16 seconds for first digit (FXO logic) */
-@@ -284,7 +294,9 @@
- static int restart_monitor(void);
-
- static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
--
-+#ifdef ZAPATA_PRI
-+static int zt_prisendtext(struct ast_channel *c, char *text);
-+#endif
- static int zt_sendtext(struct ast_channel *c, char *text);
-
- static inline int zt_get_event(int fd)
-@@ -331,6 +343,27 @@
- #define PRI_CHANNEL(p) ((p) & 0xff)
- #define PRI_SPAN(p) (((p) >> 8) & 0xff)
-
-+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 */
-@@ -344,6 +377,10 @@
- int nsf; /* Network-Specific Facilities */
- int dialplan; /* Dialing plan */
- int localdialplan; /* Local dialing plan */
-+ char nocid[256];
-+ char withheldcid[256];
-+ char nationalprefix[AST_MAX_EXTENSION]; /* prefix to add for national numbers */
-+ char internationalprefix[AST_MAX_EXTENSION]; /* prefix to add for international numbers */
- int dchannels[NUM_DCHANS]; /* What channel are the dchannels on */
- int trunkgroup; /* What our trunkgroup is */
- int mastertrunkgroup; /* What trunk group is our master */
-@@ -359,10 +396,13 @@
- int span;
- int resetting;
- int resetpos;
-+ int usercid; /* trust user provided caller id?? */
- time_t lastreset;
- 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 */
- };
-
-
-@@ -385,6 +425,8 @@
- static int nsf = PRI_NSF_NONE;
- static int dialplan = PRI_NATIONAL_ISDN + 1;
- static int localdialplan = PRI_NATIONAL_ISDN + 1;
-+static char nationalprefix[AST_MAX_EXTENSION];
-+static char internationalprefix[AST_MAX_EXTENSION];
-
- #else
- /* Shut up the compiler */
-@@ -545,8 +587,9 @@
- int distinctivering; /* Which distinctivering to use */
- int cidrings; /* Which ring to deliver CID on */
-
-- int faxhandled; /* Has a fax tone already been handled? */
--
-+ int faxhandled; /* Has a fax tone already been handled? If yes, we should never enable EC. */
-+ /* 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. */
- char mate; /* flag to say its in MATE mode */
- int pulsedial; /* whether a pulse dial phone is detected */
- int dtmfrelax; /* whether to run in relaxed DTMF mode */
-@@ -557,7 +600,9 @@
- struct zt_pri *pri;
- struct zt_pvt *bearer;
- struct zt_pvt *realcall;
-+ int tei; /* channel in use by this tei */
- q931_call *call;
-+ q931_call *holdedcall;
- int isidlecall;
- int resetting;
- int prioffset;
-@@ -585,6 +630,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;
-@@ -634,6 +686,108 @@
- #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;
-+
-+ /* 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;
-+ }
-+ }
-+ /* 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->callerid) && (strncasecmp(p->callerid, dest, strlen(p->callerid)))) || (!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;
-@@ -1211,11 +1365,15 @@
- {
- int x;
- int res;
-+ 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 && p->echocancel) {
-+ if (p && p->echocancel && !p->digital) {
- if (p->sig == SIG_PRI) {
- x = 1;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
-@@ -1238,7 +1396,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)
-@@ -1511,7 +1669,11 @@
- 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, p->rxgain, p->txgain, p->law);
-+ } else {
-+ set_actual_gain(p->subs[SUB_REAL].zfd, 0, 0, 0, p->law);
-+ }
-
- switch(p->sig) {
- case SIG_FXOLS:
-@@ -1731,6 +1893,14 @@
- #ifdef ZAPATA_PRI
- if (p->pri) {
- struct pri_sr *sr;
-+ int pridialplan;
-+ int dp_strip;
-+
-+ 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++;
-@@ -1751,6 +1921,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');
-@@ -1774,6 +1945,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);
-@@ -1788,19 +1961,36 @@
- ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
- pri_set_crv(p->pri->pri, p->call, p->channel, 0);
- }
-- p->digital = ast_test_flag(ast,AST_FLAG_DIGITAL);
-+ p->digital = IS_DIGITAL(ast->transfercapability);
- pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p),
- p->pri->nodetype == PRI_NETWORK ? 0 : 1, 1);
-- pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : PRI_TRANS_CAP_SPEECH,
-+ 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)));
-- pri_sr_set_called(sr, c + p->stripmsd, p->pri->dialplan - 1, s ? 1 : 0);
-+ if (option_verbose > 2)
-+ ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
-+ pridialplan = p->pri->dialplan - 1;
-+// ast_log(LOG_NOTICE, "p->digital = %d\n", p->digital);
-+ dp_strip = 0;
-+ if (pridialplan == -1) { // compute dynamically
-+ if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
-+ dp_strip = strlen(p->pri->internationalprefix);
-+ pridialplan = PRI_INTERNATIONAL_ISDN;
-+ } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
-+ dp_strip = strlen(p->pri->nationalprefix);
-+ pridialplan = PRI_NATIONAL_ISDN;
-+ } else {
-+ pridialplan = PRI_LOCAL_ISDN;
-+ }
-+ }
-+ pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
- pri_sr_set_caller(sr, l, n, p->pri->localdialplan - 1,
- l ? (ast->restrictcid ? PRES_PROHIB_USER_NUMBER_PASSED_SCREEN :
- (p->use_callingpres ? ast->callingpres : PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN)) :
- PRES_NUMBER_NOT_AVAILABLE);
- if (pri_setup(p->pri->pri, p->call, sr)) {
-- ast_log(LOG_WARNING, "Unable to setup call to %s\n", c + p->stripmsd);
-+ ast_log(LOG_WARNING, "Unable to setup call to %s (using pridialplan %d)\n",
-+ c + p->stripmsd + dp_strip, pridialplan);
- pri_rel(p->pri);
- ast_mutex_unlock(&p->lock);
- pri_sr_free(sr);
-@@ -1935,8 +2125,9 @@
- }
- if (newslot < 0) {
- newslot = 0;
-- ast_log(LOG_WARNING, "No D-channels available! Using Primary on channel anyway %d!\n",
-- pri->dchannels[newslot]);
-+ if (pri->nodetype != BRI_CPE_PTMP) {
-+ ast_log(LOG_WARNING, "No D-channels available! Using Primary on channel anyway %d!\n", pri->dchannels[newslot]);
-+ }
- }
- if (old && (oldslot != newslot))
- ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
-@@ -2130,6 +2321,13 @@
- icause = atoi(cause);
- }
- pri_hangup(p->pri->pri, p->call, icause);
-+ if (p->pri->nodetype == BRI_NETWORK_PTMP) {
-+ // fix for hangup in NT mode
-+ // XXX check me
-+ if ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING)) {
-+ p->call = NULL;
-+ }
-+ }
- }
- if (res < 0)
- ast_log(LOG_WARNING, "pri_disconnect failed\n");
-@@ -2322,10 +2520,14 @@
- p->proceeding = 2;
- res = pri_answer(p->pri->pri, p->call, 0, 1);
- pri_rel(p->pri);
-+ /* stop ignoring inband dtmf */
-+ p->ignoredtmf = 0;
- } 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
-@@ -2581,7 +2783,7 @@
- int os1 = -1, os2 = -1;
- struct ast_channel *oc1, *oc2;
-
-- /* if need DTMF, cant native bridge */
-+ /* if need DTMF, cant native bridge (at least not yet...) */
- if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
- return -2;
-
-@@ -2826,8 +3028,17 @@
-
- static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
- {
-- struct zt_pvt *p = newchan->pvt->pvt;
-+ struct zt_pvt *p = NULL;
- int x;
-+ if (newchan && newchan->pvt) {
-+ p = newchan->pvt->pvt;
-+ }
-+ if (!p) {
-+ if (newchan) {
-+ ast_log(LOG_ERROR, "channel %s has no pvt->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) {
-@@ -4037,8 +4248,9 @@
- }
- } else if (f->frametype == AST_FRAME_DTMF) {
- #ifdef ZAPATA_PRI
-- if ((p->proceeding < 2) && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
-- /* Don't accept in-band DTMF when in overlap dial mode */
-+ if ((p->proceeding < 2) && 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;
- }
-@@ -4172,7 +4384,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;
- }
-@@ -4241,7 +4455,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;
-@@ -4311,7 +4525,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;
-@@ -4341,40 +4555,16 @@
- return res;
- }
-
--#ifdef ZAPATA_PRI
--static void set_calltype(struct ast_channel *chan, int ctype)
--{
-- char *s = "UNKNOWN";
-- switch(ctype) {
-- case PRI_TRANS_CAP_SPEECH:
-- s = "SPEECH";
-- break;
-- case PRI_TRANS_CAP_DIGITAL:
-- s = "DIGITAL";
-- break;
-- case PRI_TRANS_CAP_RESTRICTED_DIGITAL:
-- s = "RESTRICTED_DIGITAL";
-- break;
-- case PRI_TRANS_CAP_3_1K_AUDIO:
-- s = "31KAUDIO";
-- break;
-- case PRI_TRANS_CAP_7K_AUDIO:
-- s = "7KAUDIO";
-- break;
-- case PRI_TRANS_CAP_VIDEO:
-- s = "VIDEO";
-- break;
-- }
-- pbx_builtin_setvar_helper(chan, "CALLTYPE", s);
--}
--#endif
--static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int ctype)
-+static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
- {
- struct ast_channel *tmp;
- int deflaw;
- int res;
- int x,y;
- int features;
-+#ifdef ZAPATA_PRI
-+ struct zt_pri *pri = NULL;
-+#endif
- ZT_PARAMS ps;
- tmp = ast_channel_alloc(0);
- if (tmp) {
-@@ -4458,7 +4648,21 @@
- tmp->rings = 1;
- tmp->pvt->pvt = i;
- tmp->pvt->send_digit = zt_digit;
-- tmp->pvt->send_text = zt_sendtext;
-+#ifdef ZAPATA_PRI
-+ if (i->sig == SIG_PRI) {
-+ pri = i->pri;
-+ if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK) || (pri->nodetype == PRI_NETWORK)) {
-+ /* only networks may send displays */
-+ tmp->pvt->send_text = zt_prisendtext;
-+ } else {
-+ tmp->pvt->send_text = zt_sendtext;
-+ }
-+ } else {
-+ tmp->pvt->send_text = zt_sendtext;
-+ }
-+#else
-+ tmp->pvt->send_text = zt_sendtext;
-+#endif
- tmp->pvt->call = zt_call;
- tmp->pvt->hangup = zt_hangup;
- tmp->pvt->answer = zt_answer;
-@@ -4469,8 +4673,12 @@
- tmp->pvt->indicate = zt_indicate;
- tmp->pvt->fixup = zt_fixup;
- tmp->pvt->setoption = zt_setoption;
-- 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;
- }
-@@ -4507,14 +4715,14 @@
- tmp->restrictcid = i->restrictcid;
- tmp->callingpres = i->callingpres;
- #ifdef ZAPATA_PRI
-- set_calltype(tmp, ctype);
-+ tmp->transfercapability = transfercapability;
-+ pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
-+ if (transfercapability & PRI_TRANS_CAP_DIGITAL) {
-+ i->digital = 1;
-+ }
- /* Assume calls are not idle calls unless we're told differently */
- i->isidlecall = 0;
- i->alreadyhungup = 0;
-- if (ctype & PRI_TRANS_CAP_DIGITAL) {
-- i->digital = 1;
-- ast_set_flag(tmp, AST_FLAG_DIGITAL);
-- }
- #endif
- /* clear the fake event in case we posted one before we had ast_chanenl */
- i->fake_event = 0;
-@@ -4643,8 +4851,28 @@
- while((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->callerid)) {
- if (len && !ast_ignore_pattern(chan->context, exten))
- tone_zone_play_tone(p->subs[index].zfd, -1);
-- else
-+ else {
-+ if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) {
-+ // dont double digits if the phone sends CPN and dtmf!
-+ if (ast_app_has_voicemail(p->callerid)) {
-+ int newm, oldm;
-+ char temp[256];
-+ ast_app_messagecount(p->callerid,&newm,&oldm);
-+ snprintf(temp,sizeof(temp)-1,"VoiceMail (%d/%d)",newm,oldm);
-+ // pri_information_display(pri->pri,pri->pvt[chan]->call,(char *)temp);
-+ // strncpy(pri->pvts[chanpos]->call->display,sizeof(pri->pvt[chan]->call->display), temp);
-+#ifdef ZT_TONE_STUTTER
-+ tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_STUTTER);
-+#else
-+ tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
-+#endif
-+ } else {
-+ tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
-+ }
-+ } else {
- tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
-+ }
-+ }
- if (ast_exists_extension(chan, chan->context, exten, 1, p->callerid))
- timeout = matchdigittimeout;
- else
-@@ -4680,6 +4908,10 @@
- ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
- chan->hangupcause = AST_CAUSE_UNALLOCATED;
- ast_hangup(chan);
-+ if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) {
-+ // this might apply for pri, too...
-+ p->call = NULL;
-+ }
- }
- return NULL;
- break;
-@@ -6083,6 +6315,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;
- }
-@@ -6333,6 +6567,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, pri_plan2str(pris[span].localdialplan));
-+ free(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);
-@@ -6360,6 +6599,11 @@
- return NULL;
- }
- pris[span].nodetype = pritype;
-+// XXX
-+ if (pritype == BRI_NETWORK_PTMP) {
-+ pris[span].dchanavail[0] = DCHAN_AVAILABLE;
-+ pri_find_dchan(&pris[span]);
-+ }
- pris[span].switchtype = myswitchtype;
- pris[span].nsf = nsf;
- pris[span].dialplan = dialplan;
-@@ -6368,8 +6612,15 @@
- 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;
- strncpy(pris[span].idledial, idledial, sizeof(pris[span].idledial) - 1);
- strncpy(pris[span].idleext, idleext, sizeof(pris[span].idleext) - 1);
-+ strncpy(pris[span].nocid, nocid, sizeof(pris[span].nocid) - 1);
-+ strncpy(pris[span].withheldcid, withheldcid, sizeof(pris[span].withheldcid) - 1);
-+ strncpy(pris[span].nationalprefix, nationalprefix, sizeof(pris[span].nationalprefix) - 1);
-+ strncpy(pris[span].internationalprefix, internationalprefix, sizeof(pris[span].internationalprefix) - 1);
-
- tmp->pri = &pris[span];
- tmp->prioffset = offset;
-@@ -6764,7 +7015,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;
-@@ -6809,7 +7060,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;
-@@ -6966,8 +7217,15 @@
- } else if (opt == 'd') {
- /* If this is an ISDN call, make it digital */
- p->digital = 1;
-- if (tmp)
-- ast_set_flag(tmp, AST_FLAG_DIGITAL);
-+ 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);
- }
-@@ -7025,6 +7283,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)
- {
-@@ -7034,6 +7343,8 @@
- span = PRI_SPAN(channel);
- channel = PRI_CHANNEL(channel);
-
-+// ast_log(LOG_NOTICE, "span %d channel %d\n",span,channel);
-+
- for (x=0;x<pri->numchans;x++) {
- if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
- principle = x;
-@@ -7047,7 +7358,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;
-@@ -7061,6 +7374,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) {
-@@ -7074,17 +7388,53 @@
- }
- /* 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) {
- pri->pvts[principle]->owner->pvt->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;
- }
-@@ -7113,7 +7463,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;
- }
-
-@@ -7184,6 +7536,9 @@
-
- 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) &&
-@@ -7227,6 +7582,29 @@
- return 0;
- }
-
-+static void pri_make_callerid(struct zt_pri *pri, char *callerid,char *callingnum, char *callingname,int callingplan, int callingpres, int stripmsd) {
-+ char tmpstr[256];
-+
-+ if (callingnum && (strlen(callingnum) > stripmsd)) {
-+ callingnum += stripmsd;
-+ }
-+
-+ switch (callingplan) {
-+ case PRI_NATIONAL_ISDN:
-+ snprintf(callerid, AST_MAX_EXTENSION, "%s%s",pri->nationalprefix, callingnum);
-+ break;
-+ case PRI_INTERNATIONAL_ISDN:
-+ snprintf(callerid, AST_MAX_EXTENSION, "%s%s", pri->internationalprefix, callingnum);
-+ break;
-+ default:
-+ strncpy(callerid, callingnum, AST_MAX_EXTENSION);
-+ }
-+ if (!ast_strlen_zero(callingname)) {
-+ strncpy(tmpstr, callingnum, sizeof(tmpstr));
-+ snprintf(callerid, AST_MAX_EXTENSION, "\"%s\" <%s>", callingname, tmpstr);
-+ }
-+}
-+
- static void *pri_dchannel(void *vpri)
- {
- struct zt_pri *pri = vpri;
-@@ -7312,6 +7690,8 @@
- } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
- activeidles++;
- }
-+ // ast_log(LOG_NOTICE, "name = %s condition = %d index = %d (%d) zfd = %d res = %d\n",chan->name, condition, index, SUB_REAL, p->subs[index].zfd, res);
-+
- #if 0
- printf("nextidle: %d, haveidles: %d, minunsed: %d\n",
- nextidle, haveidles, minunused);
-@@ -7444,37 +7824,103 @@
- 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);
- 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;
-- pri_find_dchan(pri);
-+ 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);
-+ /* Note presense of D-channel */
-+ time(&pri->lastreset);
-
-- /* Restart in 5 seconds */
-- pri->lastreset -= RESET_INTERVAL;
-- pri->lastreset += 5;
-- pri->resetting = 0;
-- /* Take the channels from inalarm condition */
-- for (i=0; i<pri->numchans; i++)
-+ 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 -= RESET_INTERVAL;
-+ 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;
-+// XXX COLT
-+// pri_reset(pri->pri, PVT_TO_CHANNEL(p));
-+ /* just to be sure */
-+ if (p->call) {
-+ if (p->pri && p->pri->pri) {
-+ 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 = 0;
-+ }
-+ }
-+ }
-+ } 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++) {
-@@ -7495,6 +7941,7 @@
- p->inalarm = 1;
- }
- }
-+ }
- }
- break;
- case PRI_EVENT_RESTART:
-@@ -7545,9 +7992,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;
-@@ -7559,6 +8008,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);
- }
-@@ -7572,14 +8029,23 @@
- 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",
-+ if (pri->nodetype == BRI_CPE_PTMP) {
-+ 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);
-+ break;
-+ } else {
-+ 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);
-+ }
- } else {
- 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);
-+ ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- break;
- } else {
- ast_log(LOG_WARNING, "Ring requested on channel %d/%d already in use on span %d. Hanging up owner.\n",
-@@ -7599,6 +8065,9 @@
- chanpos = pri_find_empty_chan(pri, 1);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ /* this channel is owned by this TEI */
-+ pri->pvts[chanpos]->tei = e->ring.tei;
-+ // ast_log(LOG_NOTICE, "setting tei %d for chan %d\n",e->ring.tei, chanpos);
- 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));
-@@ -7620,15 +8089,23 @@
- }
- }
- pri->pvts[chanpos]->call = e->ring.call;
-+ /* dont double digits when TAs send DTMF and CPN! */
-+ pri->pvts[chanpos]->ignoredtmf = 1;
- /* Get caller ID */
- if (pri->pvts[chanpos]->use_callerid) {
-- if (!ast_strlen_zero(e->ring.callingname)) {
-- snprintf(pri->pvts[chanpos]->callerid, sizeof(pri->pvts[chanpos]->callerid), "\"%s\" <%s>", e->ring.callingname, e->ring.callingnum);
-- } else
-- strncpy(pri->pvts[chanpos]->callerid, e->ring.callingnum, sizeof(pri->pvts[chanpos]->callerid)-1);
-- } else
-- pri->pvts[chanpos]->callerid[0] = '\0';
-- strncpy(pri->pvts[chanpos]->rdnis, e->ring.redirectingnum, sizeof(pri->pvts[chanpos]->rdnis) - 1);
-+ if (pri->usercid) {
-+ pri_make_callerid(pri, pri->pvts[chanpos]->callerid, e->ring.callingnumuser, "", e->ring.callingplanuser, e->ring.callingpresuser, 0);
-+ } else {
-+ pri_make_callerid(pri, pri->pvts[chanpos]->callerid, e->ring.callingnum, e->ring.callingname, e->ring.callingplan, e->ring.callingpres, 0);
-+ }
-+ } else {
-+ pri->pvts[chanpos]->callerid[0] = '\0';
-+ }
-+ strncpy(pri->pvts[chanpos]->rdnis, e->ring.redirectingnum, sizeof(pri->pvts[chanpos]->rdnis)-1);
-+ if (pri->pvts[chanpos]->owner) {
-+ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "PRI_REDIRECTING_NUM", e->ring.redirectingnum);
-+ }
-+
- /* If immediate=yes go to s|1 */
- if (pri->pvts[chanpos]->immediate) {
- if (option_verbose > 2)
-@@ -7638,10 +8115,50 @@
- }
- /* Get called number */
- else if (!ast_strlen_zero(e->ring.callednum)) {
-- strncpy(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten)-1);
-- strncpy(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid) - 1);
-- } else
-- pri->pvts[chanpos]->exten[0] = '\0';
-+ if (strlen(e->ring.useruserinfo)) {
-+ if (pri->pvts[chanpos]->owner) {
-+ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "UUI", e->ring.useruserinfo);
-+ }
-+ }
-+ pri_make_callerid(pri, pri->pvts[chanpos]->dnid, e->ring.callednum, "", e->ring.calledplan, 0, pri->pvts[chanpos]->stripmsd);
-+ pri_make_callerid(pri, pri->pvts[chanpos]->exten, 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);
-+ }
-+ }
-+ }
-+ } else {
-+ 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';
-+ }
-+ }
-+ }
- /* 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);
-@@ -7670,20 +8187,43 @@
- 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 (!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", pri->pvts[chanpos]->channel);
-- if (e->ring.complete || !pri->overlapdial) {
-+ ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
-+ 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 {
-+ } 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 {
-+ if (pri->overlapdial || (!strcasecmp(pri->pvts[chanpos]->exten, "s"))) {
-+ pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
-+ } else {
-+ pri_acknowledge(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
-+ }
- }
- /* Get the use_callingpres state */
- pri->pvts[chanpos]->callingpres = 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]->callerid, pri->withheldcid, sizeof(pri->pvts[chanpos]->callerid));
-+ break;
-+ case PRES_NUMBER_NOT_AVAILABLE:
-+ strncpy(pri->pvts[chanpos]->callerid, pri->nocid, sizeof(pri->pvts[chanpos]->callerid));
-+ break;
-+ }
- /* Start PBX */
- if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->callerid)) {
- /* Release the PRI lock while we create the channel */
-@@ -7696,15 +8236,29 @@
- 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);
-+ zt_enable_ec(pri->pvts[chanpos]);
-+ }
-+ if (!ast_strlen_zero(e->ring.useruserinfo)) {
-+ pbx_builtin_setvar_helper(c, "UUI", e->ring.useruserinfo);
- }
- 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, e->ring.callingnum, e->ring.callingname, e->ring.callingplan, e->ring.callingpres, 0);
-+ pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
-+ }
-+ if (!ast_strlen_zero(e->ring.callingnumuser)) {
-+ char tmpstr[256];
-+ pri_make_callerid(pri, tmpstr, e->ring.callingnumuser, "", e->ring.callingplanuser, e->ring.callingpresuser, 0);
-+ pbx_builtin_setvar_helper(c, "PRI_USER_CID", e->ring.callednum);
-+ }
- 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",
-- e->ring.callingnum, !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", e->ring.callingnum, !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",
-@@ -7723,10 +8277,26 @@
- ast_mutex_lock(&pri->lock);
- if (c) {
- if (option_verbose > 2)
-- ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
-- e->ring.callingnum, 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]);
-+ zt_enable_ec(pri->pvts[chanpos]);
-+ if (e->ring.useruserinfo) {
-+ pbx_builtin_setvar_helper(c, "UUI", e->ring.useruserinfo);
-+ }
-+ 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, e->ring.callingnum, e->ring.callingname, e->ring.callingplan, e->ring.callingpres, 0);
-+ pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
-+ }
-+ if (!ast_strlen_zero(e->ring.callingnumuser)) {
-+ char tmpstr[256];
-+ pri_make_callerid(pri, tmpstr, e->ring.callingnumuser, "", e->ring.callingplanuser, e->ring.callingpresuser, 0);
-+ pbx_builtin_setvar_helper(c, "PRI_USER_CID", e->ring.callednum);
-+ }
- } 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);
-@@ -7764,7 +8334,7 @@
- } else {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
- if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
-- zt_enable_ec(pri->pvts[chanpos]);
-+ // zt_enable_ec(pri->pvts[chanpos]);
- pri->pvts[chanpos]->subs[SUB_REAL].needringing =1;
- pri->pvts[chanpos]->proceeding=2;
- } else
-@@ -7777,7 +8347,13 @@
- /* Get chan value if e->e is not PRI_EVNT_RINGING */
- chanpos = pri_find_principle(pri, e->proceeding.channel);
- if (chanpos > -1) {
-- if (pri->overlapdial && !pri->pvts[chanpos]->proceeding) {
-+ if ((e->proceeding.cause == PRI_CAUSE_USER_BUSY) && (pri->pvts[chanpos]->priindication_oob != 2)) {
-+ /* received PROGRESS with cause BUSY, no inband callprogress wanted => hang up! */
-+ if (pri->pvts[chanpos]->owner) {
-+ pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-+ }
-+ } else {
-+ if (pri->overlapdial && !pri->pvts[chanpos]->proceeding) {
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-@@ -7785,13 +8361,21 @@
- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ }
- }
- }
- break;
- case PRI_EVENT_PROCEEDING:
- chanpos = pri_find_principle(pri, e->proceeding.channel);
- if (chanpos > -1) {
-- if (pri->overlapdial && !pri->pvts[chanpos]->proceeding) {
-+ 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 {
-+// pri->pvts[chanpos]->ignoredtmf = 0;
-+ if (pri->overlapdial && !pri->pvts[chanpos]->proceeding) {
- struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
-
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-@@ -7802,6 +8386,7 @@
- zap_queue_frame(pri->pvts[chanpos], &f, pri);
- pri->pvts[chanpos]->proceeding=2;
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ }
- }
- }
- break;
-@@ -7827,7 +8412,296 @@
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
- }
-- break;
-+ 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 (pri->pvts[chanpos]->owner->bridge) {
-+ 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]->callerid, sizeof(zpc->msn));
-+ strncpy(zpc->callid, e->suspend_req.callid, sizeof(zpc->callid));
-+ ast_masq_park_call(pri->pvts[chanpos]->owner->bridge, 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 (p->owner->bridge) {
-+ 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]->callerid, sizeof(zhc->msn));
-+ strncpy(zhc->uniqueid, p->owner->bridge->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 = p->owner->bridge;
-+ zhc->next = pri->holded_calls;
-+ pri->holded_calls = zhc;
-+
-+ /* put channel on hold */
-+ ast_masq_hold_call(p->owner->bridge, 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) {
-@@ -7843,6 +8717,8 @@
- chanpos = -1;
- } else {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ pri->pvts[chanpos]->tei = e->answer.tei;
-+ // ast_log(LOG_NOTICE, "TEI %d answered\n", e->answer.tei);
- if (pri->pvts[chanpos]->master && (pri->pvts[chanpos]->master->sig == SIG_FXSKS)) {
- ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
- x = ZT_START;
-@@ -7865,9 +8741,13 @@
- } else if (pri->pvts[chanpos]->confirmanswer) {
- ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
- } 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
-+ pri->pvts[chanpos]->ignoredtmf = 0;
- }
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
-@@ -7890,6 +8770,9 @@
- if (pri->pvts[chanpos]->master)
- pri_hangup_all(pri->pvts[chanpos]->master, 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);
- /* Queue a BUSY instead of a hangup if our cause is appropriate */
- pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
- switch(e->hangup.cause) {
-@@ -7914,18 +8797,33 @@
- } else {
- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
- 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;
-+ }
- }
- ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- } else {
-- ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n",
-+ 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);
-+ 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;
-@@ -7935,17 +8833,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",
-+ if (pri->nodetype == BRI_NETWORK_PTMP) {
-+ pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
-+ } 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 hangup if we want to hear inband 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]->master)
- pri_hangup_all(pri->pvts[chanpos]->master, 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:
-@@ -7964,20 +8870,81 @@
- }
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-+ 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;
-+
-+ onhold = pri_get_callonhold(pri, -1, e->hangup.tei);
-+
-+ if (onhold) {
-+
-+ 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!!! */
-+ transferee->zombie = 1;
-+ pri->pvts[chanpos]->owner = NULL;
-+ pri->pvts[chanpos]->tei = -1;
-+ }
-+ }
-+ } else {
-+ ast_retrieve_call_to_death(onhold->uniqueid);
-+ }
-+ onhold->alreadyhungup = 1;
-+ pri_hangup(pri->pri, onhold->call, e->hangup.cause);
-+ onhold = NULL;
-+ ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ break;
-+ }
-+ }
-+ }
- } else {
- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
- pri->pvts[chanpos]->call = NULL;
-+ pri->pvts[chanpos]->tei = -1;
- }
- if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
-- if (option_verbose > 2)
-+ if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) {
-+ if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n",
- PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-- pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
-- pri->pvts[chanpos]->resetting = 1;
-+ pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
-+ pri->pvts[chanpos]->resetting = 1;
-+ }
- }
- 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);
-+ 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);
-+ }
-+ }
- }
- }
- break;
-@@ -7992,6 +8959,7 @@
- chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
- if (chanpos > -1) {
- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ pri->pvts[chanpos]->tei = -1;
- pri->pvts[chanpos]->call = NULL;
- pri->pvts[chanpos]->resetting = 0;
- if (pri->pvts[chanpos]->owner) {
-@@ -8066,17 +9034,98 @@
- ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n",
- PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
- } else {
-- ast_mutex_lock(&pri->pvts[chanpos]->lock);
-- pri->pvts[chanpos]->setup_ack = 1;
-- /* Send any queued digits */
-- for (x=0;x<strlen(pri->pvts[chanpos]->dialdest);x++) {
-+ chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
-+ if (chanpos < 0) {
-+ ast_log(LOG_WARNING, "Received SETUP_ACK on channel %d/%d not in use on span %d\n",
-+ PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
-+ chanpos = -1;
-+ } else {
-+ ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ pri->pvts[chanpos]->setup_ack = 1;
-+ if (pri->pvts[chanpos]->owner) {
-+ // ast_log(LOG_NOTICE, "SETUP_ACK for '%s'\n", pri->pvts[chanpos]->owner->name);
-+ }
-+ /* Send any queued digits */
-+ for (x=0;x<strlen(pri->pvts[chanpos]->dialdest);x++) {
- ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
- pri_information(pri->pri, pri->pvts[chanpos]->call,
- pri->pvts[chanpos]->dialdest[x]);
-+ }
-+ ast_mutex_unlock(&pri->pvts[chanpos]->lock);
- }
-- 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);
-+ 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);
-+ 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 !!! */
-+ chan->zombie = 1;
-+ }
-+ }
-+ ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ }
-+ /* disconnect */
-+ pri_hangup(pri->pri, e->facility.call, 16);
-+ } else if (e->facility.operation == 0x0D) {
-+ ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum);
-+ /* mmmmmkay */
-+
-+ /* lock the channel */
-+
-+ /* async goto */
-+
-+ /* disconnect isdn layer */
-+ } 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);
- }
-@@ -8225,6 +9274,7 @@
-
-
-
-+
- static int handle_pri_no_debug(int fd, int argc, char *argv[])
- {
- int span;
-@@ -8345,6 +9395,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 pri_debug = {
- { "pri", "debug", "span", NULL }, handle_pri_debug, "Enables PRI debugging on a span", pri_debug_help, complete_span_4 };
-
-@@ -8357,8 +9419,53 @@
- static struct ast_cli_entry pri_show_span = {
- { "pri", "show", "span", NULL }, handle_pri_show_span, "Displays PRI Information", pri_show_span_help, complete_span_4 };
-
-+static struct ast_cli_entry bri_debug = {
-+ { "bri", "debug", "span", NULL }, handle_pri_debug, "Enables BRI debugging on a span", bri_debug_help, complete_span_4 };
-+
-+static struct ast_cli_entry bri_no_debug = {
-+ { "bri", "no", "debug", "span", NULL }, handle_pri_no_debug, "Disables BRI debugging on a span", bri_no_debug_help, complete_span_5 };
-+
-+static struct ast_cli_entry bri_really_debug = {
-+ { "bri", "intense", "debug", "span", NULL }, handle_pri_really_debug, "Enables REALLY INTENSE BRI debugging", bri_really_debug_help, complete_span_5 };
-+
- #endif /* ZAPATA_PRI */
-
-+static int app_zapEC(struct ast_channel *chan, void *data)
-+{
-+ int res=-1;
-+ struct zt_pvt *p = NULL;
-+
-+ if (!data) {
-+ ast_log(LOG_WARNING, "zapEC requires one argument (on | off)\n");
-+ }
-+ if (chan && !strcasecmp("ZAP",chan->type)) {
-+ p = chan->pvt->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");
-+ }
-+
-+ 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[])
-@@ -8920,6 +10027,10 @@
- ast_cli_unregister(&pri_no_debug);
- ast_cli_unregister(&pri_really_debug);
- ast_cli_unregister(&pri_show_span);
-+
-+ ast_cli_unregister(&bri_debug);
-+ ast_cli_unregister(&bri_no_debug);
-+ ast_cli_unregister(&bri_really_debug);
- #endif
- #ifdef ZAPATA_R2
- ast_cli_unregister(&r2_debug);
-@@ -8936,6 +10047,7 @@
- ast_manager_unregister( "ZapDNDon" );
- ast_manager_unregister("ZapShowChannels");
- ast_unregister_application(app_callingpres);
-+ ast_unregister_application(zapEC_app);
- ast_channel_unregister(typecompat);
- ast_channel_unregister(type);
- if (!ast_mutex_lock(&iflock)) {
-@@ -9283,7 +10395,7 @@
- }
- } else if (!strcasecmp(v->name, "echotraining")) {
- if (sscanf(v->value, "%i", &y) == 1) {
-- if ((y < 10) || (y > 4000)) {
-+ if ((y < 10) || (y > 2000)) {
- ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 2000 ms at line %d\n", v->lineno);
- } else {
- echotraining = y;
-@@ -9462,6 +10574,22 @@
- 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")) {
-@@ -9490,6 +10618,8 @@
- dialplan = PRI_INTERNATIONAL_ISDN + 1;
- } else if (!strcasecmp(v->value, "local")) {
- dialplan = PRI_LOCAL_ISDN + 1;
-+ } else if (!strcasecmp(v->value, "dynamic")) {
-+ dialplan = 0;
- } else {
- ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
- }
-@@ -9505,8 +10635,16 @@
- } else if (!strcasecmp(v->value, "local")) {
- localdialplan = PRI_LOCAL_ISDN + 1;
- } else {
-- ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
-+ ast_log(LOG_WARNING, "Unknown PRI local dialplan '%s' at line %d.\n", v->value, v->lineno);
- }
-+ } else if (!strcasecmp(v->name, "nocid")) {
-+ strncpy(nocid, v->value, sizeof(nocid) - 1);
-+ } else if (!strcasecmp(v->name, "withheldcid")) {
-+ strncpy(withheldcid, v->value, sizeof(withheldcid) - 1);
-+ } else if (!strcasecmp(v->name, "nationalprefix")) {
-+ strncpy(nationalprefix, v->value, sizeof(nationalprefix) - 1);
-+ } else if (!strcasecmp(v->name, "internationalprefix")) {
-+ strncpy(internationalprefix, v->value, sizeof(internationalprefix) - 1);
- } else if (!strcasecmp(v->name, "switchtype")) {
- if (!strcasecmp(v->value, "national"))
- switchtype = PRI_SWITCH_NI2;
-@@ -9544,15 +10682,18 @@
- 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' or 'outofband' at line %d\n",
-- v->value, v->lineno);
-+ 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, "minunused")) {
- minunused = atoi(v->value);
- } else if (!strcasecmp(v->name, "idleext")) {
- strncpy(idleext, v->value, sizeof(idleext) - 1);
- } else if (!strcasecmp(v->name, "idledial")) {
- strncpy(idledial, v->value, sizeof(idledial) - 1);
-+ } else if (!strcasecmp(v->name, "pritrustusercid")) {
-+ usercid = ast_true(v->value);
- } else if (!strcasecmp(v->name, "overlapdial")) {
- overlapdial = ast_true(v->value);
- #endif
-@@ -9708,12 +10849,12 @@
- if(res) {
- return -1;
- }
-- if (ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, zt_request)) {
-+ if (ast_channel_register_ex(type, tdesc, AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW, zt_request, zt_devicestate)) {
- ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
- __unload_module();
- return -1;
- }
-- if (ast_channel_register(typecompat, tdesc, AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, zt_request)) {
-+ if (ast_channel_register_ex(typecompat, tdesc, AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW, zt_request, zt_devicestate)) {
- ast_log(LOG_ERROR, "Unable to register channel class %s\n", typecompat);
- __unload_module();
- return -1;
-@@ -9723,6 +10864,10 @@
- ast_cli_register(&pri_no_debug);
- ast_cli_register(&pri_really_debug);
- ast_cli_register(&pri_show_span);
-+
-+ ast_cli_register(&bri_debug);
-+ ast_cli_register(&bri_no_debug);
-+ ast_cli_register(&bri_really_debug);
- #endif
- #ifdef ZAPATA_R2
- ast_cli_register(&r2_debug);
-@@ -9734,6 +10879,7 @@
- ast_cli_register(&zap_show_cadences_cli);
-
- ast_register_application(app_callingpres, change_callingpres, synopsis_callingpres, descrip_callingpres);
-+ ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc);
- memset(round_robin, 0, sizeof(round_robin));
- ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
- ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
-@@ -10007,6 +11153,22 @@
- } else if (!strcasecmp(v->value, "pri_cpe")) {
- cur_signalling = SIG_PRI;
- 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
- } else {
- ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
-@@ -10081,6 +11243,26 @@
- }
- #endif
-
-+#ifdef ZAPATA_PRI
-+static int zt_prisendtext(struct ast_channel *c, char *text)
-+{
-+ struct zt_pvt *p = (struct zt_pvt *)c->pvt->pvt;
-+ ast_log(LOG_NOTICE, "text\n");
-+ 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,text);
-+ pri_rel(p->pri);
-+ } else ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
-+ }
-+ }
-+ return 0;
-+}
-+#endif
-+
- static int zt_sendtext(struct ast_channel *c, char *text)
- {
- #define END_SILENCE_LEN 400
-diff -urNad --exclude=CVS --exclude=.svn ./codecs/codec_ilbc.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/codecs/codec_ilbc.c
---- ./codecs/codec_ilbc.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/codecs/codec_ilbc.c 2005-07-22 10:11:12.635329064 +1000
-@@ -32,7 +32,7 @@
- #include "slin_ilbc_ex.h"
- #include "ilbc_slin_ex.h"
-
--#define USE_ILBC_ENHANCER 0
-+#define USE_ILBC_ENHANCER 1
-
- AST_MUTEX_DEFINE_STATIC(localuser_lock);
- static int localusecnt=0;
-diff -urNad --exclude=CVS --exclude=.svn ./HARDWARE /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/HARDWARE
---- ./HARDWARE 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/HARDWARE 2005-07-22 10:11:12.635329064 +1000
-@@ -37,6 +37,13 @@
- * Wildcard TE410P - Quad T1/E1 switchable interface. Supports PRI and
- RBS signalling, as well as PPP, FR, and HDLC data modes.
-
-+-- Junghanns.NET
-+ 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
-+
- Non-zaptel compatible hardware
- ==============================
-
-diff -urNad --exclude=CVS --exclude=.svn ./include/asterisk/channel.h /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/include/asterisk/channel.h
---- ./include/asterisk/channel.h 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/include/asterisk/channel.h 2005-07-22 10:11:30.025685328 +1000
-@@ -34,6 +34,9 @@
- //! Max length of an extension
- #define AST_MAX_EXTENSION 80
-
-+//! Max length of the uniqueid
-+#define AST_MAX_UNIQUEID 64
-+
- #include <asterisk/cdr.h>
- #include <asterisk/monitor.h>
-
-@@ -186,6 +189,8 @@
- /*! Private channel implementation details */
- struct ast_channel_pvt *pvt;
-
-+ /* isdn transfer capability */
-+ unsigned short transfercapability;
-
- /*! Jump buffer used for returning from applications */
- jmp_buf jmp[AST_CHANNEL_MAX_STACK];
-@@ -217,7 +222,7 @@
- unsigned int fout;
-
- /* Unique Channel Identifier */
-- char uniqueid[32];
-+ char uniqueid[AST_MAX_UNIQUEID];
-
- /* Why is the channel hanged up */
- int hangupcause;
-@@ -361,6 +366,8 @@
- #define AST_DEVICE_INVALID 4
- /*! Device is unavailable */
- #define AST_DEVICE_UNAVAILABLE 5
-+/*! Device is ringing */
-+#define AST_DEVICE_RINGING 6
-
- //! Requests a channel
- /*!
-@@ -371,7 +378,7 @@
- * by the low level module
- * Returns an ast_channel on success, NULL on failure.
- */
--struct ast_channel *ast_request(char *type, int format, void *data);
-+struct ast_channel *ast_request(char *type, int format, void *data, char *uniqueid);
-
- //! Search the Channels by Name
- /*!
-@@ -405,9 +412,9 @@
- * 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(char *type, int format, void *data, int timeout, int *reason, char *callerid);
-+struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *reason, int callingpres, char *callerid, char *uniqueid);
-
--struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *reason, char *callerid, struct outgoing_helper *oh);
-+struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *reason, int callingpres, char *callerid, struct outgoing_helper *oh, char *uniqueid);
-
- //! Registers a channel
- /*!
-@@ -638,6 +645,9 @@
- //! Get channel by name (locks channel)
- struct ast_channel *ast_get_channel_by_name_locked(char *channame);
-
-+//! Get channel by uniqueid (locks channel)
-+struct ast_channel *ast_get_channel_by_uniqueid_locked(char *uniqueid);
-+
- //! Waits for a digit
- /*!
- * \param c channel to wait for a digit on
-@@ -709,6 +719,11 @@
- 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 state
- /*!
- * \param state state to get the name of
-@@ -718,6 +733,15 @@
- */
- char *ast_state2str(int state);
-
-+/*! Gives the string form of a given transfer capability */
-+/*!
-+ * \param transercapability transfercapabilty to get the name of
-+ * Give a name to a transfercapbility
-+ * See above
-+ * Returns the text form of the binary transfer capbility
-+ */
-+char *ast_transfercapability2str(int transfercapability);
-+
- /* Options: Some low-level drivers may implement "options" allowing fine tuning of the
- low level channel. See frame.h for options. Note that many channel drivers may support
- none or a subset of those features, and you should not count on this if you want your
-diff -urNad --exclude=CVS --exclude=.svn ./include/asterisk/features.h /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/include/asterisk/features.h
---- ./include/asterisk/features.h 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/include/asterisk/features.h 2005-07-22 10:11:12.636328912 +1000
-@@ -38,10 +38,17 @@
- */
- 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);
-+
- //! 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);
- extern char *ast_pickup_ext(void);
-
- //! Bridge a call, optionally allowing redirection
-@@ -50,5 +57,7 @@
-
- extern int ast_pickup_call(struct ast_channel *chan);
-
-+extern int ast_autoanswer_login(struct ast_channel *chan, void *data);
-+extern int ast_masq_autoanswer_login(struct ast_channel *rchan, void *data);
-
- #endif /* _AST_FEATURES_H */
-diff -urNad --exclude=CVS --exclude=.svn ./include/asterisk/pbx.h /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/include/asterisk/pbx.h
---- ./include/asterisk/pbx.h 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/include/asterisk/pbx.h 2005-07-22 10:11:12.636328912 +1000
-@@ -42,6 +42,8 @@
- #define AST_EXTENSION_BUSY 2
- //! All devices UNAVAILABLE/UNREGISTERED
- #define AST_EXTENSION_UNAVAILABLE 3
-+//! One ore more devices RINGING
-+#define AST_EXTENSION_RINGING 4
-
- struct ast_context;
- struct ast_exten;
-@@ -103,6 +105,8 @@
- */
- extern struct ast_app *pbx_findapp(char *app);
-
-+void *ast_pbx_run_app(void *data);
-+
- //! executes an application
- /*!
- * \param c channel to execute on
-@@ -487,11 +491,11 @@
-
- /* Synchronously or asynchronously make an outbound call and send it to a
- particular extension */
--int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, char *callerid, char *variable, char *account );
-+int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, int callingpres, char *callerid, char *variable, char *account, char *uniqueid);
-
- /* Synchronously or asynchronously make an outbound call and send it to a
- particular application with given extension */
--int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid, char *variable, char *account);
-+int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid, char *variable, char *account, char *uniqueid);
-
- /* Functions for returning values from structures */
- char *ast_get_context_name(struct ast_context *con);
-diff -urNad --exclude=CVS --exclude=.svn ./include/asterisk/transcap.h /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/include/asterisk/transcap.h
---- ./include/asterisk/transcap.h 1970-01-01 10:00:00.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/include/asterisk/transcap.h 2005-07-22 10:11:12.636328912 +1000
-@@ -0,0 +1,33 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * General Asterisk channel definitions.
-+ *
-+ * Copyright (C) 1999 - 2005, Digium, Inc.
-+ *
-+ * Matthew Fredrickson <creslin at digium.com>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#ifndef _ASTERISK_TRANSCAP_H
-+#define _ASTERISK_TRANSCAP_H
-+
-+/* These definitions are taken directly out of libpri.h and used here.
-+ * DO NOT change them as it will cause unexpected behavior in channels
-+ * that utilize these fields.
-+ */
-+
-+#define AST_TRANS_CAP_SPEECH 0x0
-+#define AST_TRANS_CAP_DIGITAL 0x08
-+#define AST_TRANS_CAP_RESTRICTED_DIGITAL 0x09
-+#define AST_TRANS_CAP_3_1K_AUDIO 0x10
-+#define AST_TRANS_CAP_7K_AUDIO 0x11 /* Depriciated ITU Q.931 (05/1998)*/
-+#define AST_TRANS_CAP_DIGITAL_W_TONES 0x11
-+#define AST_TRANS_CAP_VIDEO 0x18
-+
-+#define IS_DIGITAL(cap)\
-+ (cap) & AST_TRANS_CAP_DIGITAL ? 1 : 0
-+
-+#endif /* _ASTERISK_TRANSCAP_H */
-diff -urNad --exclude=CVS --exclude=.svn ./Makefile /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/Makefile
---- ./Makefile 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/Makefile 2005-07-22 10:11:12.638328608 +1000
-@@ -473,6 +473,8 @@
- echo "astspooldir => $(ASTSPOOLDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
- echo "astrundir => $(ASTVARRUNDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
- echo "astlogdir => $(ASTLOGDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
-+ echo "[options]" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
-+ echo "uniquename = asterisk" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
- for x in sounds/demo-*; do \
- if grep -q "^%`basename $$x`%" sounds.txt; then \
- install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
-diff -urNad --exclude=CVS --exclude=.svn ./Makefile.rej /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/Makefile.rej
---- ./Makefile.rej 1970-01-01 10:00:00.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/Makefile.rej 2005-07-22 10:11:12.638328608 +1000
-@@ -0,0 +1,17 @@
-+***************
-+*** 12,18 ****
-+ #
-+
-+ MODS=res_adsi.so res_features.so res_crypto.so res_musiconhold.so res_indications.so res_monitor.so \
-+- res_agi.so
-+ MODS+=$(shell if [ -f "/usr/include/odbcinst.h" ]; then echo "res_odbc.so res_config_odbc.so"; fi)
-+ MODS+=$(shell if [ -f "/usr/local/include/odbcinst.h" ]; then echo "res_odbc.so res_config_odbc.so"; fi)
-+ MODS+=$(shell if [ -f "/usr/include/osp/osp.h" ]; then echo "res_osp.so"; fi)
-+--- 12,18 ----
-+ #
-+
-+ MODS=res_adsi.so res_features.so res_crypto.so res_musiconhold.so res_indications.so res_monitor.so \
-++ res_agi.so res_watchdog.so
-+ MODS+=$(shell if [ -f "/usr/include/odbcinst.h" ]; then echo "res_odbc.so res_config_odbc.so"; fi)
-+ MODS+=$(shell if [ -f "/usr/local/include/odbcinst.h" ]; then echo "res_odbc.so res_config_odbc.so"; fi)
-+ MODS+=$(shell if [ -f "/usr/include/osp/osp.h" ]; then echo "res_osp.so"; fi)
-diff -urNad --exclude=CVS --exclude=.svn ./manager.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/manager.c
---- ./manager.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/manager.c 2005-07-22 10:11:12.639328456 +1000
-@@ -9,6 +9,9 @@
- *
- * Mark Spencer <markster at digium.com>
- *
-+ * Copyright (C) 2003-2004, Junghanns.NET Gmbh
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-@@ -40,6 +43,7 @@
- #include <asterisk/md5.h>
- #include <asterisk/acl.h>
- #include <asterisk/utils.h>
-+#include <asterisk/astdb.h>
-
- struct fast_originate_helper
- {
-@@ -55,6 +59,8 @@
- char exten[256];
- char idtext[256];
- int priority;
-+ int callingpres;
-+ char uniqueid[64];
- };
-
- static int enabled = 0;
-@@ -553,18 +559,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_channel_walk_locked(NULL);
-- while(c) {
-- if (!strcasecmp(c->name, name)) {
-- break;
-- }
-- ast_mutex_unlock(&c->lock);
-- c = ast_channel_walk_locked(c);
-- }
-+ 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;
-@@ -669,6 +674,120 @@
- return 0;
- }
-
-+static char mandescr_dbget[] =
-+"Description: Get a value from astdb\n"
-+"Variables: \n"
-+" Family: ...\n"
-+" Key: ...\n";
-+
-+static int action_dbget(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");
-+ char dbresult[256];
-+
-+ 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;
-+ }
-+
-+ ast_mutex_lock(&s->lock);
-+ if (ast_db_get(family, key, dbresult, sizeof(dbresult) - 1)) {
-+ ast_cli(s->fd, "Response: Failed\r\n");
-+ } else {
-+ ast_cli(s->fd, "Response: Success\r\n"
-+ "Value: %s\r\n" ,dbresult);
-+ }
-+ if (id && !ast_strlen_zero(id))
-+ ast_cli(s->fd, "ActionID: %s\r\n",id);
-+ ast_cli(s->fd, "\r\n");
-+ ast_mutex_unlock(&s->lock);
-+
-+ return 0;
-+}
-+
-+static char mandescr_dbput[] =
-+"Description: Put a value into astdb\n"
-+"Variables: \n"
-+" Family: ...\n"
-+" Key: ...\n"
-+" Value: ...\n";
-+
-+static int action_dbput(struct mansession *s, struct message *m)
-+{
-+ char *family = astman_get_header(m, "Family");
-+ char *key = astman_get_header(m, "Key");
-+ char *value = astman_get_header(m, "Value");
-+ 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 (!strlen(value)) {
-+ astman_send_error(s, m, "No value specified");
-+ return 0;
-+ }
-+
-+ ast_mutex_lock(&s->lock);
-+ if (ast_db_put(family, key, value)) {
-+ 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");
-+ ast_mutex_unlock(&s->lock);
-+
-+ return 0;
-+}
-+
-+
-+static char mandescr_dbdel[] =
-+"Description: remove value from astdb\n"
-+"Variables: \n"
-+" Family: ...\n"
-+" Key: ...\n";
-+
-+static int action_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;
-+ }
-+
-+ ast_mutex_lock(&s->lock);
-+ 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");
-+ ast_mutex_unlock(&s->lock);
-+
-+ return 0;
-+}
-+
-
- static int action_status(struct mansession *s, struct message *m)
- {
-@@ -761,32 +880,50 @@
- {
- char *name = astman_get_header(m, "Channel");
- char *name2 = astman_get_header(m, "ExtraChannel");
-+ char *uniqueid = astman_get_header(m, "Uniqueid");
-+ char *uniqueid2 = astman_get_header(m, "ExtraUniqueid");
- char *exten = astman_get_header(m, "Exten");
- char *context = astman_get_header(m, "Context");
- char *priority = astman_get_header(m, "Priority");
-+ 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 (!name || 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) {
-- astman_send_error(s, m, "Channel not existent");
-+ astman_send_error(s, m, "Channel not existant");
- return 0;
- }
-+ if (!ast_strlen_zero(uniqueid2)) {
-+ chan2 = ast_get_channel_by_uniqueid_locked(uniqueid2);
-+ if (!ast_strlen_zero(priority2) && (sscanf(priority, "%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)
-@@ -834,26 +971,28 @@
- int res;
- int reason = 0;
- 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, !ast_strlen_zero(in->callerid) ? in->callerid : NULL, in->variable, in->account);
-+ res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, !ast_strlen_zero(in->callerid) ? in->callerid : NULL, in->variable, in->account, 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, !ast_strlen_zero(in->callerid) ? in->callerid : NULL, in->variable, in->account);
-+ 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->callerid) ? in->callerid : NULL, in->variable, in->account, in->uniqueid);
- }
- if (!res)
- manager_event(EVENT_FLAG_CALL,
- "OriginateSuccess",
- "%s"
-+ "Uniqueid: %s\r\n"
- "Channel: %s/%s\r\n"
- "Context: %s\r\n"
- "Exten: %s\r\n",
-- in->idtext, in->tech, in->data, in->context, in->exten);
-+ in->idtext, in->uniqueid, in->tech, in->data, in->context, in->exten);
- else
- manager_event(EVENT_FLAG_CALL,
- "OriginateFailure",
- "%s"
-+ "Uniqueid: %s\r\n"
- "Channel: %s/%s\r\n"
- "Context: %s\r\n"
- "Exten: %s\r\n",
-- in->idtext, in->tech, in->data, in->context, in->exten);
-+ in->idtext, in->uniqueid, in->tech, in->data, in->context, in->exten);
-
- free(in);
- return NULL;
-@@ -871,6 +1010,7 @@
- " Data: Data to use (requires 'Application')\n"
- " Timeout: How long to wait for call to be answered (in ms)\n"
- " CallerID: Caller ID to be set on the outgoing channel\n"
-+" CallingPres: Caller ID presentation to be set on the outgoing channel\n"
- " Variable: Channel variable to set (VAR1=value1|VAR2=value2)\n"
- " Account: Account code\n"
- " Async: Set to 'true' for fast origination\n";
-@@ -883,6 +1023,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 *variable = astman_get_header(m, "Variable");
- char *account = astman_get_header(m, "Account");
- char *app = astman_get_header(m, "Application");
-@@ -890,11 +1031,14 @@
- char *async = astman_get_header(m, "Async");
- char *id = astman_get_header(m, "ActionID");
- char *tech, *data;
-+ char *uniqueid;
- int pi = 0;
-+ int cpresi = 0;
- int res;
- int to = 30000;
- int reason = 0;
- char tmp[256];
-+ char idText[256] = "";
- pthread_t th;
- pthread_attr_t attr;
- if (!name) {
-@@ -909,6 +1053,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;
-+ }
- strncpy(tmp, name, sizeof(tmp) - 1);
- tech = tmp;
- data = strchr(tmp, '/');
-@@ -918,6 +1066,7 @@
- }
- *data = '\0';
- data++;
-+ uniqueid = ast_alloc_uniqueid();
- if (ast_true(async)) {
- struct fast_originate_helper *fast = malloc(sizeof(struct fast_originate_helper));
- if (!fast) {
-@@ -935,8 +1084,10 @@
- strncpy(fast->account, account, sizeof(fast->account) - 1);
- strncpy(fast->context, context, sizeof(fast->context) - 1);
- strncpy(fast->exten, exten, sizeof(fast->exten) - 1);
-+ strncpy(fast->uniqueid, uniqueid, sizeof(fast->uniqueid) - 1);
- 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)) {
-@@ -946,19 +1097,30 @@
- }
- }
- } else if (!ast_strlen_zero(app)) {
-- res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, !ast_strlen_zero(callerid) ? callerid : NULL, variable, account);
-+ res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 0, !ast_strlen_zero(callerid) ? callerid : NULL, variable, account, uniqueid);
- } else {
- if (exten && context && pi)
-- res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, !ast_strlen_zero(callerid) ? callerid : NULL, variable, account);
-+ res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 0, cpresi, !ast_strlen_zero(callerid) ? callerid : NULL, variable, account, 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
-- astman_send_error(s, m, "Originate failed");
-+ if (!res) {
-+ if (id && !ast_strlen_zero(id)) {
-+ snprintf(idText,256,"ActionID: %s\r\n",id);
-+ }
-+ ast_mutex_lock(&s->lock);
-+ ast_cli(s->fd, "Response: Success\r\n"
-+ "%s"
-+ "Message: Originate successfully queued\r\n"
-+ "Uniqueid: %s\r\n"
-+ "\r\n",
-+ idText, uniqueid);
-+ ast_mutex_unlock(&s->lock);
-+ } else {
-+ astman_send_error(s, m, "Originate failed");
-+ }
- return 0;
- }
-
-@@ -1464,6 +1626,9 @@
- ast_manager_register2( "AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout );
- ast_manager_register2( "MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus );
- ast_manager_register2( "MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount );
-+ ast_manager_register2( "DBget", EVENT_FLAG_CALL, action_dbget, "Retrieve a value from astdb", mandescr_dbget );
-+ ast_manager_register2( "DBput", EVENT_FLAG_CALL, action_dbput, "Store a value in astdb", mandescr_dbput );
-+ ast_manager_register2( "DBdel", EVENT_FLAG_CALL, action_dbdel, "Delete a key from astdb", mandescr_dbdel );
- ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands);
-
- ast_cli_register(&show_mancmd_cli);
-diff -urNad --exclude=CVS --exclude=.svn ./pbx/pbx_spool.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/pbx/pbx_spool.c
---- ./pbx/pbx_spool.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/pbx/pbx_spool.c 2005-07-22 10:11:12.640328304 +1000
-@@ -219,11 +219,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->callerid, o->variable, o->account);
-+ 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->callerid, o->variable, o->account, 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->callerid, o->variable, o->account);
-+ 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->callerid, o->variable, o->account, NULL);
- }
- if (res) {
- ast_log(LOG_NOTICE, "Call failed to go through, reason %d\n", reason);
-diff -urNad --exclude=CVS --exclude=.svn ./pbx/pbx_wilcalu.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/pbx/pbx_wilcalu.c
---- ./pbx/pbx_wilcalu.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/pbx/pbx_wilcalu.c 2005-07-22 10:11:12.640328304 +1000
-@@ -192,7 +192,7 @@
- }
- ast_log(LOG_DEBUG, "Autodial Tech %s(%d) Tele %s(%d) Filename %s(%d)\n",tech, (int)strlen(tech), tele, (int)strlen(tele), filename, (int)strlen(filename));
-
-- channel=ast_request(tech,AST_FORMAT_SLINEAR,tele);
-+ channel=ast_request(tech,AST_FORMAT_SLINEAR,tele,NULL);
- if(channel!=NULL){
- ast_call(channel,tele,10000);
- } else {
-diff -urNad --exclude=CVS --exclude=.svn ./pbx.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/pbx.c
---- ./pbx.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/pbx.c 2005-07-22 10:11:12.642328000 +1000
-@@ -267,7 +267,8 @@
-
- { "Hangup", pbx_builtin_hangup,
- "Unconditional hangup",
-- " Hangup(): Unconditionally hangs up a given channel by returning -1 always.\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,
-@@ -1388,12 +1389,15 @@
-
- res = ast_device_state(cur);
- switch (res) {
-+ case AST_DEVICE_RINGING:
-+ return AST_EXTENSION_RINGING;
- case AST_DEVICE_NOT_INUSE:
- allunavailable = 0;
- allbusy = 0;
- break;
- case AST_DEVICE_INUSE:
-- return AST_EXTENSION_INUSE;
-+ allbusy = 0;
-+ // return AST_EXTENSION_INUSE;
- case AST_DEVICE_BUSY:
- allunavailable = 0;
- allfree = 0;
-@@ -4063,7 +4067,7 @@
- return NULL;
- }
-
--int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, char *callerid, char *variable, char *account)
-+int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, int callingpres, char *callerid, char *variable, char *account, char *uniqueid)
- {
- struct ast_channel *chan;
- struct async_stat *as;
-@@ -4074,7 +4078,7 @@
-
- if (sync) {
- LOAD_OH(oh);
-- chan = __ast_request_and_dial(type, format, data, timeout, reason, callerid, &oh);
-+ chan = __ast_request_and_dial(type, format, data, timeout, reason, callingpres, callerid, &oh, uniqueid);
- if (chan) {
- pbx_builtin_setaccount(chan, account);
- if (chan->_state == AST_STATE_UP) {
-@@ -4129,7 +4133,7 @@
- if (!as)
- return -1;
- memset(as, 0, sizeof(struct async_stat));
-- chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
-+ chan = ast_request_and_dial(type, format, data, timeout, reason, callingpres, callerid, uniqueid);
- if (!chan) {
- free(as);
- return -1;
-@@ -4165,7 +4169,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;
-@@ -4181,7 +4185,7 @@
- return NULL;
- }
-
--int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid, char *variable, char *account)
-+int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid, char *variable, char *account, char *uniqueid)
- {
- struct ast_channel *chan;
- struct async_stat *as;
-@@ -4193,7 +4197,7 @@
- if (!app || ast_strlen_zero(app))
- return -1;
- if (sync) {
-- chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
-+ chan = ast_request_and_dial(type, format, data, timeout, reason, 0, callerid, uniqueid);
- if (chan) {
- pbx_builtin_setaccount(chan, account);
- if (variable) {
-@@ -4239,7 +4243,7 @@
- if (!as)
- return -1;
- memset(as, 0, sizeof(struct async_stat));
-- chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
-+ chan = ast_request_and_dial(type, format, data, timeout, reason, 0, callerid, uniqueid);
- if (!chan) {
- free(as);
- return -1;
-@@ -4453,6 +4457,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 */
- return -1;
- }
-@@ -4854,6 +4861,9 @@
- return -1;
- }
- }
-+ if (chan->_state != AST_STATE_UP) {
-+ ast_answer(chan);
-+ }
- return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options);
- }
-
-@@ -4861,8 +4871,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;
- }
-
-@@ -4870,8 +4884,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;
- }
-
-@@ -4879,8 +4897,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 -urNad --exclude=CVS --exclude=.svn ./README /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/README
---- ./README 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/README 2005-07-22 10:11:12.643327848 +1000
-@@ -1,6 +1,7 @@
- The Asterisk Open Source PBX
- by Mark Spencer <markster at digium.com>
--Copyright (C) 2001-2004 Digium
-+Copyright (C) 2001-2004 Digium and others....
-+Copyright (C) 2002-2004 Junghanns.NET GmbH and others....
- ================================================================
- * SECURITY
- It is imperative that you read and fully understand the contents of
-@@ -23,14 +24,6 @@
- Asterisk is distributed under GNU General Public License. The GPL also
- must apply to all loadable modules as well, except as defined below.
-
-- Digium, Inc. (formerly Linux Support Services) retains copyright to all
--of the core Asterisk system, and therefore can grant, at its sole discretion,
--the ability for companies, individuals, or organizations to create proprietary
--or Open Source (but non-GPL'd) modules which may be dynamically linked at
--runtime with the portions of Asterisk which fall under our copyright
--umbrella, or are distributed under more flexible licenses than GPL.
--
--
- If you wish to use our code in other GPL programs, don't worry -- there
- is no requirement that you provide the same exemption in your GPL'd
- products (although if you've written a module for Asterisk we would
-@@ -39,12 +32,6 @@
- Specific permission is also granted to OpenSSL and OpenH323 to link to
- Asterisk.
-
-- If you have any questions, whatsoever, regarding our licensing policy,
--please contact us.
--
-- Modules that are GPL-licensed and not available under Digium's
--licensing scheme are added to the Asterisk-addons CVS module.
--
- * REQUIRED COMPONENTS
-
- == Linux ==
-diff -urNad --exclude=CVS --exclude=.svn ./res/res_features.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/res/res_features.c
---- ./res/res_features.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/res/res_features.c 2005-07-22 10:11:12.645327544 +1000
-@@ -7,6 +7,10 @@
- *
- * Mark Spencer <markster at digium.com>
- *
-+ * Copyright (C) 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-@@ -28,6 +32,7 @@
- #include <asterisk/manager.h>
- #include <asterisk/utils.h>
- #include <asterisk/adsi.h>
-+#include <asterisk/indications.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <unistd.h>
-@@ -51,6 +56,7 @@
- #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
-
- 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;
-@@ -102,6 +108,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;
-
-@@ -120,12 +140,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;
-@@ -135,6 +194,12 @@
- return parking_ext;
- }
-
-+char *ast_parking_con(void)
-+{
-+ return parking_con;
-+}
-+
-+
- char *ast_pickup_ext(void)
- {
- return pickup_ext;
-@@ -227,9 +292,10 @@
- "From: %s\r\n"
- "Timeout: %ld\r\n"
- "CallerID: %s\r\n"
-+ "Uniqueid: %s\r\n"
- ,pu->parkingnum, pu->chan->name, peer->name
- ,(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL)
-- ,(pu->chan->callerid ? pu->chan->callerid : "")
-+ ,(pu->chan->callerid ? pu->chan->callerid : ""), pu->chan->uniqueid
- );
-
- if (peer) {
-@@ -290,6 +356,8 @@
- strncpy(chan->context, rchan->context, sizeof(chan->context) - 1);
- strncpy(chan->exten, rchan->exten, sizeof(chan->exten) - 1);
- chan->priority = rchan->priority;
-+ /* might be dirty but we want trackable channels */
-+ strncpy(chan->uniqueid, rchan->uniqueid, sizeof(chan->uniqueid) - 1);
- /* Make the masq execute */
- f = ast_read(chan);
- if (f)
-@@ -306,7 +374,7 @@
- {
- /* Copy voice back and forth between the two channels. Give the peer
- the ability to transfer calls with '#<extension' syntax. */
-- int len;
-+ struct tone_zone_sound *ts;
- struct ast_frame *f;
- struct ast_channel *who;
- char newext[256], *ptr;
-@@ -447,29 +515,23 @@
- memset(newext, 0, sizeof(newext));
- ptr = newext;
-
-- /* Transfer */
-- if ((res=ast_streamfile(transferer, "pbx-transfer", transferer->language))) {
-- ast_moh_stop(transferee);
-- ast_autoservice_stop(transferee);
-- break;
-- }
-- if ((res=ast_waitstream(transferer, AST_DIGIT_ANY)) < 0) {
-- ast_moh_stop(transferee);
-- ast_autoservice_stop(transferee);
-- break;
-- }
-- ast_stopstream(transferer);
-- if (res > 0) {
-- /* If they've typed a digit already, handle it */
-- newext[0] = res;
-- ptr++;
-- len --;
-+ ts = ast_get_indication_tone(transferer->zone, "dial");
-+ if (ts && ts->data[0])
-+ res = ast_playtones_start(transferer, 0, ts->data, 0);
-+ else
-+ res = ast_playtones_start(transferer, 0, "400", 0);
-+
-+ if (res) {
-+ ast_moh_stop(transferee);
-+ ast_autoservice_stop(transferee);
-+ break;
- }
- res = 0;
- while (strlen(newext) < sizeof(newext) - 1) {
- res = ast_waitfordigit(transferer, transferdigittimeout);
- if (res < 1)
- break;
-+ ast_playtones_stop(transferer);
- if (res == '#')
- break;
- *(ptr++) = res;
-@@ -514,7 +576,7 @@
- ast_verbose(VERBOSE_PREFIX_3 "Transferring %s to '%s' (context %s) priority 1\n"
- ,transferee->name, newext, transferer_real_context);
- if (ast_async_goto(transferee, transferer_real_context, newext, 1))
-- ast_log(LOG_WARNING, "Async goto fialed :(\n");
-+ ast_log(LOG_WARNING, "Async goto failed :(\n");
- res = -1;
- } else {
- /* Set the channel's new extension, since it exists, using transferer context */
-@@ -743,6 +805,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));
-+ config.allowredirect_in = 1;
-+ config.allowredirect_out = 1;
-+ config.allowdisconnect_out = 0;
-+ config.allowdisconnect_in = 0;
-+ 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 to retrieve.\n", uniqueid);
-+ return NULL;
-+ }
-+ } else {
-+ ast_log(LOG_WARNING, "Could not find 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))
-+ pu->chan->exception = 1;
-+ 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;
-@@ -898,11 +1236,12 @@
- "Channel: %s\r\n"
- "Timeout: %ld\r\n"
- "CallerID: %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->callerid ? cur->chan->callerid : "")
-+ ,(cur->chan->callerid ? cur->chan->callerid : ""), cur->chan->uniqueid
- ,idText);
- ast_mutex_unlock(&s->lock);
-
-@@ -920,6 +1259,388 @@
- }
-
-
-+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, 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 *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))
-+ pu->chan->exception = 1;
-+ 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));
-+ config.allowredirect_in = 1;
-+ config.allowredirect_out = 0;
-+ config.allowdisconnect_in = 1;
-+ config.allowdisconnect_out = 0;
-+ 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 load_module(void)
- {
-@@ -930,6 +1651,7 @@
- struct ast_variable *var;
-
- ast_cli_register(&showparked);
-+ ast_cli_register(&showautoanswer);
-
- cfg = ast_load("features.conf");
- if (!cfg) {
-@@ -984,12 +1706,19 @@
- }
- ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, parkcall, strdup(""), FREE, registrar);
- 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;
- }
-
-@@ -1032,7 +1761,10 @@
- STANDARD_HANGUP_LOCALUSERS;
-
- ast_manager_unregister( "ParkedCalls" );
-+ ast_cli_unregister(&showautoanswer);
- ast_cli_unregister(&showparked);
-+ ast_unregister_application(autoanswer);
-+ ast_unregister_application(autoanswerlogin);
- ast_unregister_application(parkcall);
- return ast_unregister_application(parkedcall);
- }
-diff -urNad --exclude=CVS --exclude=.svn ./res_watchdog.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/res_watchdog.c
---- ./res_watchdog.c 1970-01-01 10:00:00.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/res_watchdog.c 2005-07-22 10:11:12.645327544 +1000
-@@ -0,0 +1,151 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * Resource to make watchdogs happy
-+ *
-+ * Copyright (C) 2005, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#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/channel_pvt.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>
-+#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>
-+
-+/* Registrar for operations */
-+
-+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", 5);
-+ }
-+ 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_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_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);
-+ 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 -urNad --exclude=CVS --exclude=.svn ./rtp.c /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/rtp.c
---- ./rtp.c 2005-07-22 10:10:35.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/rtp.c 2005-07-22 10:11:12.646327392 +1000
-@@ -417,6 +417,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 -urNad --exclude=CVS --exclude=.svn ./watchdog.conf.sample /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/watchdog.conf.sample
---- ./watchdog.conf.sample 1970-01-01 10:00:00.000000000 +1000
-+++ /tmp/dpep-work.6cUjRV/asterisk-1.0.9.dfsg/watchdog.conf.sample 2005-07-22 10:11:12.646327392 +1000
-@@ -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
-+
Modified: asterisk/trunk/debian/rules
===================================================================
--- asterisk/trunk/debian/rules 2005-10-30 21:14:37 UTC (rev 887)
+++ asterisk/trunk/debian/rules 2005-10-30 23:21:17 UTC (rev 888)
@@ -123,7 +123,7 @@
dh_installdirs var/run/asterisk
# Add here commands to install the package into debian/<packagename>
- $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+ $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install samples
cp debian/asterisk.conf $(CURDIR)/debian/tmp/etc/asterisk/asterisk.conf
#cp channels/h323/h323.conf.sample $(CURDIR)/debian/tmp/etc/asterisk/h323.conf
mkdir -p $(CURDIR)/debian/tmp/etc/default/
More information about the Pkg-voip-commits
mailing list