From 5f89267744bc0c4bafed04e8ea7f7353e4bad356 Mon Sep 17 00:00:00 2001 From: ms Date: Wed, 17 May 2006 11:25:29 +0000 Subject: [PATCH] =?utf8?q?Ge=C3=A4ndert:=20=20=20*=20Asterisk=20jetzt=20in?= =?utf8?q?=20der=20Version=201.2.7.1=20mit=20Bristuff=200.3.0-PRE-1o=20und?= =?utf8?q?=20Florz-Patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@119 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8 --- doc/ChangeLog | 10 + doc/packages-list.txt | 2 +- lfs/asterisk | 70 +- ...isk-1.2.4-iax2-bristuff-0.3.0-PRE-1l.patch | 1828 ---------------- ...tuff-0.3.0-PRE-1l.patch => asterisk.patch} | 1925 ++++++++++++----- ...istuff-0.3.0-PRE-1l.patch => libpri.patch} | 970 +++++---- src/patches/zaphfc_0.3.0-PRE-1o_florz-12.diff | 1293 +++++++++++ ...istuff-0.3.0-PRE-1l.patch => zaptel.patch} | 20 +- 8 files changed, 3351 insertions(+), 2767 deletions(-) delete mode 100644 src/patches/asterisk-1.2.4-iax2-bristuff-0.3.0-PRE-1l.patch rename src/patches/{asterisk-1.2.4-ipfire-bristuff-0.3.0-PRE-1l.patch => asterisk.patch} (89%) rename src/patches/{asterisk-1.2.4-libpri-bristuff-0.3.0-PRE-1l.patch => libpri.patch} (90%) create mode 100644 src/patches/zaphfc_0.3.0-PRE-1o_florz-12.diff rename src/patches/{asterisk-1.2.4-zaptel-bristuff-0.3.0-PRE-1l.patch => zaptel.patch} (88%) diff --git a/doc/ChangeLog b/doc/ChangeLog index d6eccd7672..aabc83408f 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,13 @@ +------------------------------------------------------------------------ +r118 | ms | 2006-05-16 13:12:49 +0200 (Di, 16 Mai 2006) | 7 lines + +Hinzugefügt: + * NFS + * Portmap - braucht man für NFS +Geändert: + * IP_CONNTRACK-Patch erstellt damit die Verbindungsanzeige im Webinterface ohne Workaround funktioniert. (Noch nicht vollständig getestet!) + * ./make.sh commit optimiert + ------------------------------------------------------------------------ r117 | ms | 2006-05-16 13:01:06 +0200 (Di, 16 Mai 2006) | 3 lines diff --git a/doc/packages-list.txt b/doc/packages-list.txt index 0c70162c4c..0563a1859f 100644 --- a/doc/packages-list.txt +++ b/doc/packages-list.txt @@ -19,7 +19,7 @@ * apache_1.3.34 * arping-2.05 * as86-0.16.17 - * asterisk-1.2.4 + * asterisk-1.2.7.1 * autoconf-2.59 * automake-1.8.4 * bash-2.05b diff --git a/lfs/asterisk b/lfs/asterisk index 7045408b88..d22bd12a0a 100644 --- a/lfs/asterisk +++ b/lfs/asterisk @@ -26,17 +26,17 @@ include Config -VER = 1.2.4 +VER = 1.2.7.1 THISAPP = asterisk-$(VER) DL_FILE = $(THISAPP).tar.gz -DL_FROM = http://www.asterisk-support.de/mirror/asterisk-1.2.4 +DL_FROM = http://www.asterisk-support.de/mirror/asterisk-1.2.7.1 DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) ASTERISK = $(THISAPP) -ZAPTEL = zaptel-1.2.3 -BRISTUFF = bristuff-0.3.0-PRE-1l +ZAPTEL = zaptel-1.2.5 +BRISTUFF = bristuff-0.3.0-PRE-1o LIBPRI = libpri-1.2.2 SPANDSP = spandsp-0.0.2pre25 OH323 = asterisk-oh323-0.7.3 @@ -63,9 +63,9 @@ app_txfax.c = http://soft-switch.org/downloads/spandsp/$(SPANDSP)/asterisk-1.2.x apps_Makefile.patch = http://soft-switch.org/downloads/spandsp/$(SPANDSP)/asterisk-1.2.x/apps_Makefile.patch $(OH323).tar.gz = http://www.inaccessnetworks.com/projects/asterisk-oh323/download/$(OH323).tar.gz -$(DL_FILE)_MD5 = 14721abdc85fc3381db275b61dffce2d -$(ZAPTEL).tar.gz_MD5 = 9bcb705458f9b20a9644310298a9cd4d -$(BRISTUFF).tar.gz_MD5 = 81941539b03b6ac8f193b33451e0a740 +$(DL_FILE)_MD5 = 5c4b473eee2fbc2cb9e346f0564ef970 +$(ZAPTEL).tar.gz_MD5 = 8c8561259d29a314aa5a076050124697 +$(BRISTUFF).tar.gz_MD5 = 93bb8a5661aaf3022cf4a102ea061f83 $(LIBPRI).tar.gz_MD5 = efce9c3699110588df5e4cf09eae01d9 app_rxfax.c_MD5 = ab6983b51c412883545b36993d704999 app_txfax.c_MD5 = 8c8fcb263b76897022b4c28052a7b439 @@ -111,40 +111,78 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) tar xfz $(DIR_DL)/$(LIBPRI).tar.gz && \ tar xfz $(DIR_DL)/$(ASTERISK).tar.gz && \ tar xfz $(DIR_DL)/$(OH323).tar.gz + # Build Zaptel cd $(DIR_SRC)/$(BRISTUFF)/$(ZAPTEL) && \ - patch -Np1 < $(DIR_SRC)/src/patches/asterisk-1.2.4-zaptel-$(BRISTUFF).patch && \ - make clean all KVERS=$(KVER) && \ + patch -Np1 < $(DIR_SRC)/src/patches/zaptel.patch && \ + make clean && \ + make all KVERS=$(KVER)-smp && \ + make install KVERS=$(KVER)-smp && \ + make clean && \ + make all KVERS=$(KVER) && \ make install KVERS=$(KVER) + cd $(DIR_SRC)/$(BRISTUFF)/$(ZAPTEL) && install -D -m 644 zaptel.h /usr/include/linux/zaptel.h + cd $(DIR_SRC)/$(BRISTUFF)/$(ZAPTEL) && install -D -m 644 zconfig.h /usr/include/linux/zconfig.h + cd $(DIR_SRC)/$(BRISTUFF)/$(ZAPTEL) && install -D -m 644 ecdis.h /usr/include/linux/ecdis.h + cd $(DIR_SRC)/$(BRISTUFF)/$(ZAPTEL) && install -D -m 644 fasthdlc.h /usr/include/linux/fasthdlc.h + cd $(DIR_SRC)/$(BRISTUFF)/$(ZAPTEL) && install -D -m 644 kb1ec.h /usr/include/linux/kb1ec.h + cd $(DIR_SRC)/$(BRISTUFF)/$(ZAPTEL) && install -D -m 644 kb1ec_const.h /usr/include/linux/kb1ec_const.h + cd $(DIR_SRC)/$(BRISTUFF)/$(ZAPTEL) && install -D -m 644 biquad.h /usr/include/linux/biquad.h + cd $(DIR_SRC)/$(BRISTUFF)/$(ZAPTEL) && install -D -m 644 arith.h /usr/include/linux/arith.h + ln -nf -v /usr/include/linux/zaptel.h /usr/include/zaptel.h + ln -nf -v /usr/include/linux/zconfig.h /usr/include/zconfig.h + ln -nf -v /usr/include/linux/ecdis.h /usr/include/ecdis.h + ln -nf -v /usr/include/linux/fasthdlc.h /usr/include/fasthdlc.h + ln -nf -v /usr/include/linux/kb1ec.h /usr/include/kb1ec.h + ln -nf -v /usr/include/linux/kb1ec_const.h /usr/include/kb1ec_const.h + ln -nf -v /usr/include/linux/biquad.h /usr/include/biquad.h + ln -nf -v /usr/include/linux/arith.h /usr/include/arith.h + # Build Libpri cd $(DIR_SRC)/$(BRISTUFF)/$(LIBPRI) && \ - patch -Np1 < $(DIR_SRC)/src/patches/asterisk-1.2.4-libpri-$(BRISTUFF).patch && \ + patch -Np1 < $(DIR_SRC)/src/patches/libpri.patch && \ make clean all KVERS=$(KVER) && \ make install KVERS=$(KVER) + + # Build libgsmat + cd $(DIR_SRC)/$(BRISTUFF)/libgsmat-0.0.1 && \ + make clean all && \ + make install + + # Build uno/duo/quad GSM PCI driver + cd $(DIR_SRC)/$(BRISTUFF)/ztgsm && \ + make clean linux24 && \ + install -D -m 644 ztgsm.o /lib/modules/$(KVER)/misc/ztgsm.o + # Build qozap cd $(DIR_SRC)/$(BRISTUFF)/qozap && \ make clean linux24 && \ install -D -m 644 qozap.o /lib/modules/$(KVER)/misc/qozap.o + # Build cwain cd $(DIR_SRC)/$(BRISTUFF)/cwain && \ make clean linux24 && \ install -D -m 644 cwain.o /lib/modules/$(KVER)/misc/cwain.o + # Build zaphfc cd $(DIR_SRC)/$(BRISTUFF)/zaphfc && \ - make clean linux24 && \ + patch -Np1 < $(DIR_SRC)/src/patches/zaphfc_0.3.0-PRE-1o_florz-12.diff && \ + cd $(DIR_SRC)/$(BRISTUFF)/zaphfc && make clean linux24 && \ install -D -m 644 zaphfc.o /lib/modules/$(KVER)/misc/zaphfc.o + # Build Asterisk cd $(DIR_SRC)/$(BRISTUFF)/$(ASTERISK) && \ - patch -Np1 < $(DIR_SRC)/src/patches/$(THISAPP)-ipfire-$(BRISTUFF).patch && \ - patch -Np1 < $(DIR_SRC)/src/patches/$(THISAPP)-iax2-$(BRISTUFF).patch && \ - cp -fv $(DIR_DL)/app_{r,t}xfax.c $(DIR_SRC)/$(BRISTUFF)/$(ASTERISK)/apps && \ - cd $(DIR_SRC)/$(BRISTUFF)/$(ASTERISK)/apps && \ - patch < $(DIR_DL)/apps_Makefile.patch && \ + patch -Np1 < $(DIR_SRC)/src/patches/asterisk.patch # && \ + ### FAX geht noch nicht mit Asterisk 1.2.7.1 + # cp -fv $(DIR_DL)/app_{r,t}xfax.c $(DIR_SRC)/$(BRISTUFF)/$(ASTERISK)/apps && \ + # cd $(DIR_SRC)/$(BRISTUFF)/$(ASTERISK)/apps && \ + # patch < $(DIR_DL)/apps_Makefile.patch && \ cd $(DIR_SRC)/$(BRISTUFF)/$(ASTERISK) && \ make clean && \ make all && \ make install && \ make samples + # Build OH323 cd $(DIR_SRC)/$(BRISTUFF)/$(OH323) && \ make ASTERISKINCDIR=$(DIR_SRC)/$(BRISTUFF)/$(ASTERISK)/include OH323WRAPLIBDIR=/usr/lib && \ diff --git a/src/patches/asterisk-1.2.4-iax2-bristuff-0.3.0-PRE-1l.patch b/src/patches/asterisk-1.2.4-iax2-bristuff-0.3.0-PRE-1l.patch deleted file mode 100644 index 5cbd642641..0000000000 --- a/src/patches/asterisk-1.2.4-iax2-bristuff-0.3.0-PRE-1l.patch +++ /dev/null @@ -1,1828 +0,0 @@ -diff -urN asterisk-1.2.4/channels/chan_iax2.c asterisk-1.2.4.carrier/channels/chan_iax2.c ---- asterisk-1.2.4/channels/chan_iax2.c 2006-01-31 09:41:43.000000000 +0100 -+++ asterisk-1.2.4.carrier/channels/chan_iax2.c 2006-02-08 09:49:45.000000000 +0100 -@@ -179,6 +179,8 @@ - static struct ast_netsock_list *netsock; - static int defaultsockfd = -1; - -+static char servername[80]; -+ - static int usecnt; - AST_MUTEX_DEFINE_STATIC(usecnt_lock); - -@@ -232,6 +234,10 @@ - - static pthread_t netthreadid = AST_PTHREADT_NULL; - -+static pthread_t regthreadid = AST_PTHREADT_NULL; -+ -+static pthread_t auththreadid = AST_PTHREADT_NULL; -+ - enum { - IAX_STATE_STARTED = (1 << 0), - IAX_STATE_AUTHENTICATED = (1 << 1), -@@ -606,6 +612,25 @@ - ast_mutex_t lock; - } iaxq; - -+typedef struct iax_auth_frame { -+ struct iax_auth_frame *prev; -+ struct iax_auth_frame *next; -+ struct iax_frame *frame; -+ struct sockaddr_in sin; -+ int fd; -+ int subclass; -+ struct iax_ies ies; -+ unsigned char iebuf[4096]; -+} iax_auth_frame; -+ -+static struct ast_iax2_auth_queue { -+ struct iax_auth_frame *head; -+ struct iax_auth_frame *tail; -+ int count; -+ ast_cond_t cond; -+ ast_mutex_t lock; -+} callq, regq; -+ - static struct ast_user_list { - struct iax2_user *users; - ast_mutex_t lock; -@@ -712,6 +737,8 @@ - static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS]; - static ast_mutex_t iaxsl[IAX_MAX_CALLS]; - static struct timeval lastused[IAX_MAX_CALLS]; -+/* some packets have been queued for asynchronous processing */ -+static int iaxs_queued[IAX_MAX_CALLS]; - - - static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int); -@@ -798,11 +825,12 @@ - static int send_lagrq(void *data) - { - int callno = (long)data; -- /* Ping only if it's real not if it's bridged */ -+ /* Ping only if it's real not if it's bridged (and not if it's queued!)*/ - if (iaxs[callno]) { - #ifdef BRIDGE_OPTIMIZATION - if (!iaxs[callno]->bridgecallno) - #endif -+ if (!iaxs_queued[callno]) - send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); - return 1; - } else -@@ -1070,8 +1098,9 @@ - } - } - if ((res < 1) && (new >= NEW_ALLOW)) { -- if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer)) -- snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); -+ /* We are NOT calling iax2_getpeernme() here, because it WILL BLOCK when using realtime. -+ Instead we will overwrite the host filed in the iax_pvt for each new call or registration. */ -+ snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); - gettimeofday(&now, NULL); - for (x=1;xcallno) return 1; -+ -+ fr = malloc(sizeof(struct iax_auth_frame)); -+ if (!fr) { -+ ast_log(LOG_ERROR, "Unable to malloc!\n"); -+ return 1; -+ } -+ memset(fr,0,sizeof(fr)); -+ fr->next = NULL; -+ fr->prev = NULL; -+ fr->frame = ifr; -+ fr->subclass = subclass; -+ fr->fd = fd; -+ memcpy(fr->iebuf, iebuf, iebuflen); -+ if (iebuflen) -+ iax_parse_ies(&fr->ies, fr->iebuf, iebuflen); -+ memcpy(&fr->sin, sin, sizeof(struct sockaddr_in)); -+ ast_mutex_lock(&authq->lock); -+ if (maydrop && (authq->count > 5000)) { -+ ast_mutex_unlock(&authq->lock); -+ ast_mutex_unlock(&iaxsl[ifr->callno]); -+ free(fr); -+ if (option_verbose > 5) -+ ast_log(LOG_WARNING, "Queue too long, not queueing frame.\n"); -+ return -1; -+ } -+ if (!authq->head) { -+ /* Empty queue */ -+ authq->head = fr; -+ authq->tail = fr; -+ } else { -+ /* Double link */ -+ authq->tail->next = fr; -+ fr->prev = authq->tail; -+ authq->tail = fr; -+ } -+ iaxs_queued[ifr->callno]++; -+ authq->count++; -+ ast_mutex_unlock(&iaxsl[ifr->callno]); -+ ast_cond_signal(&authq->cond); -+ ast_mutex_unlock(&authq->lock); -+ return 0; -+} -+ - static void destroy_firmware(struct iax_firmware *cur) - { - /* Close firmware */ -@@ -1713,8 +1794,10 @@ - /* Transfer timeout */ - send_command(iaxs[f->callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); - } else if (f->final) { -- if (f->final) -+ if (!iaxs_queued[f->callno]) { -+ if (f->final) - iax2_destroy_nolock(f->callno); -+ } - } else { - if (iaxs[f->callno]->owner) - ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno); -@@ -1729,12 +1812,14 @@ - if (iaxs[f->callno]->owner) - iaxs[f->callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; - } else { -- if (iaxs[f->callno]->reg) { -+ if (!iaxs_queued[f->callno]) { -+ if (iaxs[f->callno]->reg) { - memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us)); - iaxs[f->callno]->reg->regstate = REG_STATE_TIMEOUT; - iaxs[f->callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; -+ } -+ iax2_destroy_nolock(f->callno); - } -- iax2_destroy_nolock(f->callno); - } - } - -@@ -2706,6 +2791,8 @@ - snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); - ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); - snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); -+// the following line is commented out for compatibility -+// ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "servername", servername, NULL); - ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL); - } - -@@ -5034,16 +5121,17 @@ - } - /* We release the lock for the call to prevent a deadlock, but it's okay because - only the current thread could possibly make it go away or make changes */ -- ast_mutex_unlock(&iaxsl[callno]); -+// ast_mutex_unlock(&iaxsl[callno]); - /* SLD: first call to lookup peer during registration */ - p = find_peer(peer, 1); -- ast_mutex_lock(&iaxsl[callno]); -- -+// ast_mutex_lock(&iaxsl[callno]); - if (!p) { - if (authdebug) - ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); - return -1; - } -+ /* set the host name here. instead of doing it in find_callno() */ -+ ast_copy_string(iaxs[callno]->host, p->name, sizeof(iaxs[callno]->host)); - - if (!ast_test_flag(p, IAX_DYNAMIC)) { - if (authdebug) -@@ -5677,11 +5765,13 @@ - if (!refresh) - refresh = min_reg_expire; - if (refresh > max_reg_expire) { -- ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", -+ if (option_verbose > 5) -+ ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", - p->name, max_reg_expire, refresh); - p->expiry = max_reg_expire; - } else if (refresh < min_reg_expire) { -- ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", -+ if (option_verbose > 5) -+ ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", - p->name, min_reg_expire, refresh); - p->expiry = min_reg_expire; - } else { -@@ -5720,6 +5810,7 @@ - iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); - if (ast_test_flag(p, IAX_TEMPONLY)) - destroy_peer(p); -+ ast_mutex_lock(&iaxsl[callno]); - return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); - } - -@@ -6279,6 +6370,8 @@ - struct timeval rxtrunktime; - struct iax_ies ies; - struct iax_ie_data ied0, ied1; -+ unsigned char iebuf[4096]; -+ int iebuflen = 0; - int format; - int exists; - int minivid = 0; -@@ -6609,9 +6702,11 @@ - cur->retries = -1; - /* Destroy call if this is the end */ - if (cur->final) { -- if (iaxdebug && option_debug) -+ if (!iaxs_queued[fr.callno]) { -+ if (iaxdebug && option_debug) - ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr.callno); -- iax2_destroy_nolock(fr.callno); -+ iax2_destroy_nolock(fr.callno); -+ } - } - } - } -@@ -6639,6 +6734,8 @@ - - if (f.datalen) { - if (f.frametype == AST_FRAME_IAX) { -+ memcpy(iebuf, buf + sizeof(struct ast_iax2_full_hdr), f.datalen); -+ iebuflen = f.datalen; - if (iax_parse_ies(&ies, buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { - ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); - ast_mutex_unlock(&iaxsl[fr.callno]); -@@ -6772,166 +6869,11 @@ - break; - if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) - check_provisioning(&sin, fd, ies.serviceident, ies.provver); -- /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ -- if (ast_test_flag(iaxs[fr.callno], IAX_TRUNK)) { -- fr.callno = make_trunk(fr.callno, 1); -- } - /* For security, always ack immediately */ - if (delayreject) - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); -- if (check_access(fr.callno, &sin, &ies)) { -- /* They're not allowed on */ -- auth_fail(fr.callno, IAX_COMMAND_REJECT); -- if (authdebug) -- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); -- break; -- } -- /* This might re-enter the IAX code and need the lock */ -- if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { -- ast_mutex_unlock(&iaxsl[fr.callno]); -- exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num); -- ast_mutex_lock(&iaxsl[fr.callno]); -- } else -- exists = 0; -- if (ast_strlen_zero(iaxs[fr.callno]->secret) && ast_strlen_zero(iaxs[fr.callno]->inkeys)) { -- if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { -- memset(&ied0, 0, sizeof(ied0)); -- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); -- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); -- send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -- if (authdebug) -- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); -- } else { -- /* Select an appropriate format */ -- -- if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { -- if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { -- using_prefs = "reqonly"; -- } else { -- using_prefs = "disabled"; -- } -- format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability; -- memset(&pref, 0, sizeof(pref)); -- strcpy(caller_pref_buf, "disabled"); -- strcpy(host_pref_buf, "disabled"); -- } else { -- using_prefs = "mine"; -- if(ies.codec_prefs) { -- ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0); -- /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ -- if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { -- pref = rpref; -- using_prefs = "caller"; -- } else { -- pref = iaxs[fr.callno]->prefs; -- } -- } else -- pref = iaxs[fr.callno]->prefs; -- -- format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0); -- ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1); -- ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); -- } -- if (!format) { -- if(!ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) -- format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability; -- if (!format) { -- memset(&ied0, 0, sizeof(ied0)); -- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); -- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); -- send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -- if (authdebug) { -- if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) -- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); -- else -- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); -- } -- } else { -- /* Pick one... */ -- if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { -- if(!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) -- format = 0; -- } else { -- if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { -- using_prefs = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; -- memset(&pref, 0, sizeof(pref)); -- format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); -- strcpy(caller_pref_buf,"disabled"); -- strcpy(host_pref_buf,"disabled"); -- } else { -- using_prefs = "mine"; -- if(ies.codec_prefs) { -- /* Do the opposite of what we tried above. */ -- if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { -- pref = iaxs[fr.callno]->prefs; -- } else { -- pref = rpref; -- using_prefs = "caller"; -- } -- format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1); -- -- } else /* if no codec_prefs IE do it the old way */ -- format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); -- } -- } -- -- if (!format) { -- memset(&ied0, 0, sizeof(ied0)); -- iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); -- iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); -- ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); -- send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -- if (authdebug) -- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); -- ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); -- break; -- } -- } -- } -- if (format) { -- /* No authentication required, let them in */ -- memset(&ied1, 0, sizeof(ied1)); -- iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); -- send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); -- if (strcmp(iaxs[fr.callno]->exten, "TBD")) { -- ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); -- if (option_verbose > 2) -- ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" -- "%srequested format = %s,\n" -- "%srequested prefs = %s,\n" -- "%sactual format = %s,\n" -- "%shost prefs = %s,\n" -- "%spriority = %s\n", -- ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), -- VERBOSE_PREFIX_4, -- ast_getformatname(iaxs[fr.callno]->peerformat), -- VERBOSE_PREFIX_4, -- caller_pref_buf, -- VERBOSE_PREFIX_4, -- ast_getformatname(format), -- VERBOSE_PREFIX_4, -- host_pref_buf, -- VERBOSE_PREFIX_4, -- using_prefs); -- -- if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format))) -- iax2_destroy_nolock(fr.callno); -- } else { -- ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); -- /* If this is a TBD call, we're ready but now what... */ -- if (option_verbose > 2) -- ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); -- } -- } -- } -- break; -- } -- if (iaxs[fr.callno]->authmethods & IAX_AUTH_MD5) -- merge_encryption(iaxs[fr.callno],ies.encmethods); -- else -- iaxs[fr.callno]->encmethods = 0; -- authenticate_request(iaxs[fr.callno]); -- ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_AUTHENTICATED); -+ fr.af.datalen = 0; -+ iax2_queue_auth_frame(&callq, f.subclass, iaxfrdup2(&fr), buf, iebuf, iebuflen, &sin, fd, 0); - break; - case IAX_COMMAND_DPREQ: - /* Request status in the dialplan */ -@@ -6947,14 +6889,22 @@ - } - break; - case IAX_COMMAND_HANGUP: -- ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); -- ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr.callno); -- /* Set hangup cause according to remote */ -- if (ies.causecode && iaxs[fr.callno]->owner) -- iaxs[fr.callno]->owner->hangupcause = ies.causecode; -- /* 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); -+ if (iaxs_queued[fr.callno]) { -+ /* there is something queued, maybe the call has not been authorized yet. */ -+ /* Send ack immediately, before we destroy */ -+ send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); -+ fr.af.datalen = 0; -+ iax2_queue_auth_frame(&callq, f.subclass, iaxfrdup2(&fr), buf, iebuf, iebuflen, &sin, fd, 0); -+ } else { -+ ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); -+ ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr.callno); -+ /* Set hangup cause according to remote */ -+ if (ies.causecode && iaxs[fr.callno]->owner) -+ iaxs[fr.callno]->owner->hangupcause = ies.causecode; -+ /* 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); -+ } - break; - case IAX_COMMAND_REJECT: - memset(&f, 0, sizeof(f)); -@@ -7183,31 +7133,36 @@ - /* For security, always ack immediately */ - if (delayreject) - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); -- /* Ignore once we've started */ -- if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { -+ if (iaxs_queued[fr.callno]) { -+ /* there is something queued, take the same path */ -+ fr.af.datalen = 0; -+ iax2_queue_auth_frame(&callq, f.subclass, iaxfrdup2(&fr), buf, iebuf, iebuflen, &sin, fd, 0); -+ } else { -+ /* Ignore once we've started */ -+ if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { - ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : ""); - break; -- } -- if (authenticate_verify(iaxs[fr.callno], &ies)) { -+ } -+ if (authenticate_verify(iaxs[fr.callno], &ies)) { - if (authdebug) - ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->username); - memset(&ied0, 0, sizeof(ied0)); - auth_fail(fr.callno, IAX_COMMAND_REJECT); - break; -- } -- if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { -+ } -+ if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { - /* This might re-enter the IAX code and need the lock */ - exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num); -- } else -+ } else - exists = 0; -- if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { -+ if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { - if (authdebug) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); - memset(&ied0, 0, sizeof(ied0)); - iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); - iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -- } else { -+ } else { - /* Select an appropriate format */ - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { -@@ -7332,6 +7287,7 @@ - ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); - } - } -+ } - } - break; - case IAX_COMMAND_DIAL: -@@ -7357,11 +7313,16 @@ - } - break; - case IAX_COMMAND_INVAL: -- iaxs[fr.callno]->error = ENOTCONN; -- ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr.callno); -- iax2_destroy_nolock(fr.callno); -- if (option_debug) -+ if (iaxs_queued[fr.callno]) { -+ fr.af.datalen = 0; -+ iax2_queue_auth_frame(&callq, f.subclass, iaxfrdup2(&fr), buf, iebuf, iebuflen, &sin, fd, 0); -+ } else { -+ iaxs[fr.callno]->error = ENOTCONN; -+ ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr.callno); -+ iax2_destroy_nolock(fr.callno); -+ if (option_debug) - ast_log(LOG_DEBUG, "Destroying call %d\n", fr.callno); -+ } - break; - case IAX_COMMAND_VNAK: - ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); -@@ -7373,21 +7334,11 @@ - /* For security, always ack immediately */ - if (delayreject) - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); -- if (register_verify(fr.callno, &sin, &ies)) { -- /* Send delayed failure */ -- auth_fail(fr.callno, IAX_COMMAND_REGREJ); -- break; -- } -- if ((ast_strlen_zero(iaxs[fr.callno]->secret) && ast_strlen_zero(iaxs[fr.callno]->inkeys)) || ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_AUTHENTICATED)) { -- if (f.subclass == IAX_COMMAND_REGREL) -- memset(&sin, 0, sizeof(sin)); -- if (update_registry(iaxs[fr.callno]->peer, &sin, fr.callno, ies.devicetype, fd, ies.refresh)) -- ast_log(LOG_WARNING, "Registry error\n"); -- if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) -- check_provisioning(&sin, fd, ies.serviceident, ies.provver); -- break; -+ fr.af.datalen = 0; -+ if (iax2_queue_auth_frame(®q, f.subclass, iaxfrdup2(&fr), buf, iebuf, iebuflen, &sin, fd, 1)) { -+ /* queueing failed due to a full queue */ -+ iax2_destroy_nolock(fr.callno); - } -- registry_authrequest(iaxs[fr.callno]->peer, fr.callno); - break; - case IAX_COMMAND_REGACK: - if (iax2_ack_registry(&ies, &sin, fr.callno)) -@@ -7989,6 +7940,478 @@ - return ast_pthread_create(&netthreadid, NULL, network_thread, NULL); - } - -+struct iax_auth_frame *iax2_get_next_auth_frame(struct ast_iax2_auth_queue *authq) { -+ struct iax_auth_frame *frame = NULL; -+ -+ /* sleep until the network_thread queues us a frame, then grab it and release the lock A.S.A.P. */ -+ ast_mutex_lock(&authq->lock); -+ if (authq->count == 0) -+ ast_cond_wait(&authq->cond, &authq->lock); -+ frame = authq->head; -+ if (frame) { -+ if (frame->next) { -+// frame->next->prev = NULL; -+ authq->head = frame->next; -+ } else { -+ authq->head = NULL; -+ authq->tail = NULL; -+ } -+ authq->count--; -+ } else { -+ ast_log(LOG_ERROR, "I SHOULD NEVER HAPPEN! EXPECT SOME MAJOR KABOOM! DUCK AND COVER!\n"); -+ } -+ ast_mutex_unlock(&authq->lock); -+ return frame; -+} -+ -+ -+void *auth_thread(void *data) -+{ -+ /* -+ The network_thread queues iax_frames into our queue and wakes us up. -+ We will authenticate IAX_COMMAND_NEWs and IAX_COMMAND_REGREQs. -+ -+ We also have to process IAX_COMMAND_HANGUP when somebody hangs up a call -+ before it has been authorized! -+ -+ If ever possible we shall not lock any iaxsl[...]. -+ */ -+ struct ast_iax2_auth_queue *authq = (struct ast_iax2_auth_queue *)data; -+ struct iax_frame *ifr; -+ struct iax_auth_frame *fr; -+ struct iax_ies *ies; -+ struct iax_ie_data ied0, ied1; -+ struct ast_channel *c; -+ char iabuf[INET_ADDRSTRLEN]; -+ int exists; -+ int format; -+ int dequeued = 0; -+ char host_pref_buf[128]; -+ char caller_pref_buf[128]; -+ struct ast_codec_pref pref,rpref; -+ char *using_prefs = "mine"; -+ -+ if (!authq) { -+ ast_log(LOG_ERROR, "no queue!\n"); -+ return NULL; -+ } -+ -+ for(;;) { -+ fr = iax2_get_next_auth_frame(authq); -+ ifr = fr->frame; -+ ies = &fr->ies; -+ if (ifr) { -+ if (ifr->callno > 0) { -+ /* we will not lock iaxsl[ifr->callno], instead we will haveset a flag in iaxs_queued[ifr->callno]. -+ if this flag is set the socket_read thread may not touch iaxs[ifr->callno]. instead of -+ processing the incoming packets there it has to queue them to us! -+ This should only happen with IAX_COMMAND_HANGUP when hanging up a not-yet-established call. -+ -+ However we will try to deliver audio frames in socket_read. If we get audio data for call -+ whos signalling frames have been queued we should be safe to just drop them. -+ -+ When we really want to destroy something we will aquire the lock first. -+ */ -+ switch(fr->subclass) { -+ case IAX_COMMAND_NEW: -+ iax2_getpeername(fr->sin, iaxs[ifr->callno]->host, sizeof(iaxs[ifr->callno]->host), 1); -+ if (check_access(ifr->callno, &fr->sin, ies)) { -+ /* They're not allowed on */ -+ if (authdebug) -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->exten, iaxs[ifr->callno]->context); -+ auth_fail(ifr->callno, IAX_COMMAND_REJECT); -+ break; -+ } -+ /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ -+ if (ast_test_flag(iaxs[ifr->callno], IAX_TRUNK)) { -+ ifr->callno = make_trunk(ifr->callno, 1); -+ } -+ /* This might re-enter the IAX code and need the lock */ -+ if (strcasecmp(iaxs[ifr->callno]->exten, "TBD")) { -+ // ast_mutex_unlock(&iaxsl[ifr->callno]); -+ exists = ast_exists_extension(NULL, iaxs[ifr->callno]->context, iaxs[ifr->callno]->exten, 1, iaxs[ifr->callno]->cid_num); -+ // ast_mutex_lock(&iaxsl[ifr->callno]); -+ } else -+ exists = 0; -+ if (ast_strlen_zero(iaxs[ifr->callno]->secret) && ast_strlen_zero(iaxs[ifr->callno]->inkeys)) { -+ if (strcmp(iaxs[ifr->callno]->exten, "TBD") && !exists) { -+ memset(&ied0, 0, sizeof(ied0)); -+ iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); -+ iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); -+ send_command_final(iaxs[ifr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -+ if (authdebug) -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->exten, iaxs[ifr->callno]->context); -+ } else { -+ /* Select an appropriate format */ -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOPREFS)) { -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP)) { -+ using_prefs = "reqonly"; -+ } else { -+ using_prefs = "disabled"; -+ } -+ format = iaxs[ifr->callno]->peerformat & iaxs[ifr->callno]->capability; -+ memset(&pref, 0, sizeof(pref)); -+ strcpy(caller_pref_buf, "disabled"); -+ strcpy(host_pref_buf, "disabled"); -+ } else { -+ using_prefs = "mine"; -+ if(ies->codec_prefs) { -+ ast_codec_pref_convert(&rpref, ies->codec_prefs, 32, 0); -+ /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ -+ if (ast_test_flag(iaxs[ifr->callno], IAX_CODEC_USER_FIRST)) { -+ pref = rpref; -+ using_prefs = "caller"; -+ } else { -+ pref = iaxs[ifr->callno]->prefs; -+ } -+ } else -+ pref = iaxs[ifr->callno]->prefs; -+ -+ format = ast_codec_choose(&pref, iaxs[ifr->callno]->capability & iaxs[ifr->callno]->peercapability, 0); -+ ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1); -+ ast_codec_pref_string(&iaxs[ifr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); -+ } -+ if (!format) { -+ if(!ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP)) -+ format = iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability; -+ if (!format) { -+ memset(&ied0, 0, sizeof(ied0)); -+ iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); -+ iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); -+ send_command_final(iaxs[ifr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -+ if (authdebug) { -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP)) -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->peerformat, iaxs[ifr->callno]->capability); -+ else -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->peerformat, iaxs[ifr->callno]->peercapability, iaxs[ifr->callno]->capability); -+ } -+ } else { -+ /* Pick one... */ -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP)) { -+ if(!(iaxs[ifr->callno]->peerformat & iaxs[ifr->callno]->capability)) -+ format = 0; -+ } else { -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOPREFS)) { -+ using_prefs = ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; -+ memset(&pref, 0, sizeof(pref)); -+ format = ast_best_codec(iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability); -+ strcpy(caller_pref_buf,"disabled"); -+ strcpy(host_pref_buf,"disabled"); -+ } else { -+ using_prefs = "mine"; -+ if(ies->codec_prefs) { -+ /* Do the opposite of what we tried above. */ -+ if (ast_test_flag(iaxs[ifr->callno], IAX_CODEC_USER_FIRST)) { -+ pref = iaxs[ifr->callno]->prefs; -+ } else { -+ pref = rpref; -+ using_prefs = "caller"; -+ } -+ format = ast_codec_choose(&pref, iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability, 1); -+ -+ } else /* if no codec_prefs IE do it the old way */ -+ format = ast_best_codec(iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability); -+ } -+ } -+ -+ if (!format) { -+ memset(&ied0, 0, sizeof(ied0)); -+ iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); -+ iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); -+ ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability); -+ send_command_final(iaxs[ifr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -+ if (authdebug) -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->peerformat, iaxs[ifr->callno]->peercapability, iaxs[ifr->callno]->capability); -+ ast_set_flag(iaxs[ifr->callno], IAX_ALREADYGONE); -+ break; -+ } -+ } -+ } -+ if (format) { -+ /* No authentication required, let them in */ -+ memset(&ied1, 0, sizeof(ied1)); -+ iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); -+ send_command(iaxs[ifr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); -+ if (strcmp(iaxs[ifr->callno]->exten, "TBD")) { -+ ast_set_flag(&iaxs[ifr->callno]->state, IAX_STATE_STARTED); -+ if (option_verbose > 2) -+ ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" -+ "%srequested format = %s,\n" -+ "%srequested prefs = %s,\n" -+ "%sactual format = %s,\n" -+ "%shost prefs = %s,\n" -+ "%spriority = %s\n", -+ ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), -+ VERBOSE_PREFIX_4, -+ ast_getformatname(iaxs[ifr->callno]->peerformat), -+ VERBOSE_PREFIX_4, -+ caller_pref_buf, -+ VERBOSE_PREFIX_4, -+ ast_getformatname(format), -+ VERBOSE_PREFIX_4, -+ host_pref_buf, -+ VERBOSE_PREFIX_4, -+ using_prefs); -+ -+ if(!(c = ast_iax2_new(ifr->callno, AST_STATE_RING, format))) { -+ ast_mutex_lock(&iaxsl[ifr->callno]); -+ iax2_destroy_nolock(ifr->callno); -+ ast_mutex_unlock(&iaxsl[ifr->callno]); -+ } -+ } else { -+ ast_set_flag(&iaxs[ifr->callno]->state, IAX_STATE_TBD); -+ /* If this is a TBD call, we're ready but now what... */ -+ if (option_verbose > 2) -+ ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr)); -+ } -+ } -+ } -+ break; -+ } -+ if (iaxs[ifr->callno]->authmethods & IAX_AUTH_MD5) -+ merge_encryption(iaxs[ifr->callno],ies->encmethods); -+ else -+ iaxs[ifr->callno]->encmethods = 0; -+ authenticate_request(iaxs[ifr->callno]); -+ ast_set_flag(&iaxs[ifr->callno]->state, IAX_STATE_AUTHENTICATED); -+ break; -+ case IAX_COMMAND_REGREQ: -+ case IAX_COMMAND_REGREL: -+ // usleep(1000000); -+ if (register_verify(ifr->callno, &fr->sin, ies)) { -+ /* Send delayed failure */ -+ auth_fail(ifr->callno, IAX_COMMAND_REGREJ); -+ break; -+ } -+ if ((ast_strlen_zero(iaxs[ifr->callno]->secret) && ast_strlen_zero(iaxs[ifr->callno]->inkeys)) || ast_test_flag(&iaxs[ifr->callno]->state, IAX_STATE_AUTHENTICATED)) { -+ if (fr->subclass == IAX_COMMAND_REGREL) -+ memset(&fr->sin, 0, sizeof(struct sockaddr_in)); -+ if (update_registry(iaxs[ifr->callno]->peer, &fr->sin, ifr->callno, ies->devicetype, fr->fd, ies->refresh)) -+ ast_log(LOG_WARNING, "Registry error\n"); -+ if (ies->provverpres && ies->serviceident && fr->sin.sin_addr.s_addr) -+ check_provisioning(&fr->sin, fr->fd, ies->serviceident, ies->provver); -+ /* update registry leaves us locked, so we have to unlock to not deadlock */ -+ iaxs_queued[ifr->callno]--; -+ if (iaxs_queued[ifr->callno] < 0) iaxs_queued[ifr->callno] = 0; -+ ast_mutex_unlock(&iaxsl[ifr->callno]); -+ break; -+ } -+ registry_authrequest(iaxs[ifr->callno]->peer, ifr->callno); -+ break; -+ case IAX_COMMAND_HANGUP: -+ /* Here we really have to lock */ -+ ast_mutex_lock(&iaxsl[ifr->callno]); -+ if (iaxs[ifr->callno]) { -+ ast_set_flag(iaxs[ifr->callno], IAX_ALREADYGONE); -+ ast_log(LOG_DEBUG, "Asynchronously destroying %d, having received hangup\n", ifr->callno); -+ /* Set hangup cause according to remote */ -+ if (ies->causecode && iaxs[ifr->callno]->owner) -+ iaxs[ifr->callno]->owner->hangupcause = ies->causecode; -+ iax2_destroy_nolock(ifr->callno); -+ } -+ iaxs_queued[ifr->callno]--; -+ if (iaxs_queued[ifr->callno] < 0) iaxs_queued[ifr->callno] = 0; -+ dequeued = 1; -+ ast_mutex_unlock(&iaxsl[ifr->callno]); -+ break; -+ case IAX_COMMAND_INVAL: -+ /* Here we really have to lock */ -+ ast_mutex_lock(&iaxsl[ifr->callno]); -+ if (iaxs[ifr->callno]) { -+ iaxs[ifr->callno]->error = ENOTCONN; -+ ast_log(LOG_DEBUG, "Asynchronously destroying %d, having received INVAL\n", ifr->callno); -+ iax2_destroy_nolock(ifr->callno); -+ if (option_debug) -+ ast_log(LOG_DEBUG, "Destroying call %d\n", ifr->callno); -+ } -+ iaxs_queued[ifr->callno]--; -+ if (iaxs_queued[ifr->callno] < 0) iaxs_queued[ifr->callno] = 0; -+ dequeued = 1; -+ ast_mutex_unlock(&iaxsl[ifr->callno]); -+ break; -+ case IAX_COMMAND_AUTHREP: -+ /* Ignore once we've started */ -+ if (ast_test_flag(&iaxs[ifr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { -+ ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[ifr->callno]->owner ? iaxs[ifr->callno]->owner->name : ""); -+ break; -+ } -+ if (authenticate_verify(iaxs[ifr->callno], ies)) { -+ if (authdebug) -+ ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[ifr->callno]->addr.sin_addr), iaxs[ifr->callno]->username); -+ memset(&ied0, 0, sizeof(ied0)); -+ auth_fail(ifr->callno, IAX_COMMAND_REJECT); -+ break; -+ } -+ ast_mutex_lock(&iaxsl[ifr->callno]); -+ if (strcasecmp(iaxs[ifr->callno]->exten, "TBD")) { -+ /* This might re-enter the IAX code and need the lock */ -+ exists = ast_exists_extension(NULL, iaxs[ifr->callno]->context, iaxs[ifr->callno]->exten, 1, iaxs[ifr->callno]->cid_num); -+ } else -+ exists = 0; -+ if (strcmp(iaxs[ifr->callno]->exten, "TBD") && !exists) { -+ if (authdebug) -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->exten, iaxs[ifr->callno]->context); -+ memset(&ied0, 0, sizeof(ied0)); -+ iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); -+ iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); -+ send_command_final(iaxs[ifr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -+ } else { -+ /* Select an appropriate format */ -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOPREFS)) { -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP)) { -+ using_prefs = "reqonly"; -+ } else { -+ using_prefs = "disabled"; -+ } -+ format = iaxs[ifr->callno]->peerformat & iaxs[ifr->callno]->capability; -+ memset(&pref, 0, sizeof(pref)); -+ strcpy(caller_pref_buf, "disabled"); -+ strcpy(host_pref_buf, "disabled"); -+ } else { -+ using_prefs = "mine"; -+ if(ies->codec_prefs) { -+ /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ -+ ast_codec_pref_convert(&rpref, ies->codec_prefs, 32, 0); -+ if (ast_test_flag(iaxs[ifr->callno], IAX_CODEC_USER_FIRST)) { -+ ast_codec_pref_convert(&pref, ies->codec_prefs, 32, 0); -+ using_prefs = "caller"; -+ } else { -+ pref = iaxs[ifr->callno]->prefs; -+ } -+ } else /* if no codec_prefs IE do it the old way */ -+ pref = iaxs[ifr->callno]->prefs; -+ -+ format = ast_codec_choose(&pref, iaxs[ifr->callno]->capability & iaxs[ifr->callno]->peercapability, 0); -+ ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1); -+ ast_codec_pref_string(&iaxs[ifr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); -+ } -+ if (!format) { -+ if(!ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP)) { -+ ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[ifr->callno]->peerformat), iaxs[ifr->callno]->peercapability); -+ format = iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability; -+ } -+ if (!format) { -+ if (authdebug) { -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP)) -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->peerformat, iaxs[ifr->callno]->capability); -+ else -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->peerformat, iaxs[ifr->callno]->peercapability, iaxs[ifr->callno]->capability); -+ } -+ memset(&ied0, 0, sizeof(ied0)); -+ iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); -+ iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); -+ send_command_final(iaxs[ifr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -+ } else { -+ /* Pick one... */ -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP)) { -+ if(!(iaxs[ifr->callno]->peerformat & iaxs[ifr->callno]->capability)) -+ format = 0; -+ } else { -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOPREFS)) { -+ using_prefs = ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; -+ memset(&pref, 0, sizeof(pref)); -+ format = ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP) ? -+ iaxs[ifr->callno]->peerformat : ast_best_codec(iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability); -+ strcpy(caller_pref_buf,"disabled"); -+ strcpy(host_pref_buf,"disabled"); -+ } else { -+ using_prefs = "mine"; -+ if(ies->codec_prefs) { -+ /* Do the opposite of what we tried above. */ -+ if (ast_test_flag(iaxs[ifr->callno], IAX_CODEC_USER_FIRST)) { -+ pref = iaxs[ifr->callno]->prefs; -+ } else { -+ pref = rpref; -+ using_prefs = "caller"; -+ } -+ format = ast_codec_choose(&pref, iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability, 1); -+ } else /* if no codec_prefs IE do it the old way */ -+ format = ast_best_codec(iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability); -+ } -+ } -+ if (!format) { -+ ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[ifr->callno]->peercapability & iaxs[ifr->callno]->capability); -+ if (authdebug) { -+ if(ast_test_flag(iaxs[ifr->callno], IAX_CODEC_NOCAP)) -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->peerformat, iaxs[ifr->callno]->capability); -+ else -+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), iaxs[ifr->callno]->peerformat, iaxs[ifr->callno]->peercapability, iaxs[ifr->callno]->capability); -+ } -+ memset(&ied0, 0, sizeof(ied0)); -+ iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); -+ iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); -+ send_command_final(iaxs[ifr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); -+ } -+ } -+ } -+ if (format) { -+ /* Authentication received */ -+ memset(&ied1, 0, sizeof(ied1)); -+ iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); -+ send_command(iaxs[ifr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); -+ if (strcmp(iaxs[ifr->callno]->exten, "TBD")) { -+ ast_set_flag(&iaxs[ifr->callno]->state, IAX_STATE_STARTED); -+ if (option_verbose > 2) -+ ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" -+ "%srequested format = %s,\n" -+ "%srequested prefs = %s,\n" -+ "%sactual format = %s,\n" -+ "%shost prefs = %s,\n" -+ "%spriority = %s\n", -+ ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr), -+ VERBOSE_PREFIX_4, -+ ast_getformatname(iaxs[ifr->callno]->peerformat), -+ VERBOSE_PREFIX_4, -+ caller_pref_buf, -+ VERBOSE_PREFIX_4, -+ ast_getformatname(format), -+ VERBOSE_PREFIX_4, -+ host_pref_buf, -+ VERBOSE_PREFIX_4, -+ using_prefs); -+ -+ ast_set_flag(&iaxs[ifr->callno]->state, IAX_STATE_STARTED); -+ if(!(c = ast_iax2_new(ifr->callno, AST_STATE_RING, format))) -+ iax2_destroy_nolock(ifr->callno); -+ } else { -+ ast_set_flag(&iaxs[ifr->callno]->state, IAX_STATE_TBD); -+ /* If this is a TBD call, we're ready but now what... */ -+ if (option_verbose > 2) -+ ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), fr->sin.sin_addr)); -+ } -+ } -+ } -+ iaxs_queued[ifr->callno]--; -+ if (iaxs_queued[ifr->callno] < 0) iaxs_queued[ifr->callno] = 0; -+ ast_mutex_unlock(&iaxsl[ifr->callno]); -+ } -+ if (!dequeued) { -+ ast_mutex_lock(&iaxsl[ifr->callno]); -+ iaxs_queued[ifr->callno]--; -+ if (iaxs_queued[ifr->callno] < 0) iaxs_queued[ifr->callno] = 0; -+ ast_mutex_unlock(&iaxsl[ifr->callno]); -+ } -+ } -+ iax_frame_free(ifr); -+ free(fr); -+ fr = NULL; -+ } -+ -+ } -+ return NULL; -+} -+ -+ -+static int start_auth_thread(void) -+{ -+ return ast_pthread_create(&auththreadid, NULL, auth_thread, &callq); -+} -+ -+static int start_reg_thread(void) -+{ -+ return ast_pthread_create(®threadid, NULL, auth_thread, ®q); -+} -+ - static struct iax2_context *build_context(char *context) - { - struct iax2_context *con = malloc(sizeof(struct iax2_context)); -@@ -8882,6 +9305,7 @@ - tmpstr = ast_strdupa(data); - parse_dial_string(tmpstr, &pds); - -+ast_log(LOG_NOTICE, "calling create_addr here\n"); - /* Populate our address from the given */ - if (create_addr(pds.peer, &sin, &cai)) - return -1; -@@ -9492,6 +9916,11 @@ - static int __unload_module(void) - { - int x; -+ /* Cancel the authentication thread */ -+ if (auththreadid != AST_PTHREADT_NULL) { -+ pthread_cancel(auththreadid); -+ pthread_join(auththreadid, NULL); -+ } - /* Cancel the network thread, close the net socket */ - if (netthreadid != AST_PTHREADT_NULL) { - pthread_cancel(netthreadid); -@@ -9514,6 +9943,8 @@ - - int unload_module() - { -+ ast_mutex_destroy(®q.lock); -+ ast_mutex_destroy(&callq.lock); - ast_mutex_destroy(&iaxq.lock); - ast_mutex_destroy(&userl.lock); - ast_mutex_destroy(&peerl.lock); -@@ -9535,6 +9966,9 @@ - struct ast_netsock *ns; - struct sockaddr_in sin; - -+ /* you never can tell */ -+ memset(iaxs_queued, 0, sizeof(iaxs_queued)); -+ - ast_custom_function_register(&iaxpeer_function); - - iax_set_output(iax_debug_output); -@@ -9577,7 +10011,14 @@ - } - ast_netsock_init(netsock); - -+ gethostname(servername, sizeof(servername) - 1); -+ ast_log(LOG_NOTICE, "servername = %s\n", servername); -+ - ast_mutex_init(&iaxq.lock); -+ ast_mutex_init(®q.lock); -+ ast_cond_init(®q.cond, NULL); -+ ast_mutex_init(&callq.lock); -+ ast_cond_init(&callq.cond, NULL); - ast_mutex_init(&userl.lock); - ast_mutex_init(&peerl.lock); - ast_mutex_init(&waresl.lock); -@@ -9621,6 +10062,16 @@ - ast_netsock_release(netsock); - } - -+ res = start_reg_thread(); -+ if (res) { -+ ast_log(LOG_ERROR, "Unable to start registration thread\n"); -+ } -+ -+ res = start_auth_thread(); -+ if (res) { -+ ast_log(LOG_ERROR, "Unable to start authentication thread\n"); -+ } -+ - for (reg = registrations; reg; reg = reg->next) - iax2_do_register(reg); - ast_mutex_lock(&peerl.lock); -diff -urN asterisk-1.2.4/res/Makefile asterisk-1.2.4.carrier/res/Makefile ---- asterisk-1.2.4/res/Makefile 2006-01-31 09:41:43.000000000 +0100 -+++ asterisk-1.2.4.carrier/res/Makefile 2006-01-31 15:04:30.000000000 +0100 -@@ -13,6 +13,21 @@ - - MODS=res_indications.so res_monitor.so res_adsi.so res_agi.so res_features.so res_watchdog.so - -+# -+# MySQL stuff... Autoconf anyone?? -+# -+MODS+=$(shell if [ -d /usr/local/mysql/include ] || [ -d /usr/include/mysql ] || [ -d /usr/local/include/mysql ] || [ -d /opt/mysql/include ]; then echo "res_config_mysql.so"; fi) -+CFLAGS+=$(shell if [ -d /usr/local/mysql/include ]; then echo "-I/usr/local/mysql/include"; fi) -+CFLAGS+=$(shell if [ -d /usr/include/mysql ]; then echo "-I/usr/include/mysql"; fi) -+CFLAGS+=$(shell if [ -d /usr/local/include/mysql ]; then echo "-I/usr/local/include/mysql"; fi) -+CFLAGS+=$(shell if [ -d /opt/mysql/include/mysql ]; then echo "-I/opt/mysql/include/mysql"; fi) -+MLFLAGS= -+MLFLAGS+=$(shell if [ -d /usr/lib/mysql ]; then echo "-L/usr/lib/mysql"; fi) -+MLFLAGS+=$(shell if [ -d /usr/lib64/mysql ]; then echo "-L/usr/lib64/mysql"; fi) -+MLFLAGS+=$(shell if [ -d /usr/local/mysql/lib ]; then echo "-L/usr/local/mysql/lib"; fi) -+MLFLAGS+=$(shell if [ -d /usr/local/lib/mysql ]; then echo "-L/usr/local/lib/mysql"; fi) -+MLFLAGS+=$(shell if [ -d /opt/mysql/lib/mysql ]; then echo "-L/opt/mysql/lib/mysql"; fi) -+ - ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/odbcinst.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/odbcinst.h),) - ifneq (${OSARCH},FreeBSD) - MODS+=res_config_odbc.so -@@ -109,6 +124,9 @@ - res_config_odbc.so: res_config_odbc.o - $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} ${CYG_RES_CONFIG_ODBC_LIB} - -+res_config_mysql.so: res_config_mysql.o -+ $(CC) $(SOLINK) -o $@ $< -lmysqlclient -lz $(MLFLAGS) -+ - ifneq ($(wildcard .depend),) - include .depend - endif -diff -urN asterisk-1.2.4/res/res_config_mysql.c asterisk-1.2.4.carrier/res/res_config_mysql.c ---- asterisk-1.2.4/res/res_config_mysql.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4.carrier/res/res_config_mysql.c 2006-01-31 14:54:49.000000000 +0100 -@@ -0,0 +1,680 @@ -+/* -+ * Asterisk -- A telephony toolkit for Linux. -+ * -+ * Copyright (C) 1999-2005, Digium, Inc. -+ * -+ * Mark Spencer - Asterisk Author -+ * Matthew Boehm - MySQL RealTime Driver Author -+ * -+ * res_config_mysql.c -+ * -+ * v2.0 - (10-07-05) - mutex_lock fixes (bug #4973, comment #0034602) -+ * -+ * v1.9 - (08-19-05) - Added support to correctly honor the family database specified -+ * in extconfig.conf (bug #4973) -+ * -+ * v1.8 - (04-21-05) - Modified return values of update_mysql to better indicate -+ * what really happened. -+ * -+ * v1.7 - (01-28-05) - Fixed non-initialization of ast_category struct -+ * in realtime_multi_mysql function which caused segfault. -+ * -+ * v1.6 - (00-00-00) - Skipped to bring comments into sync with version number in CVS. -+ * -+ * v1.5.1 - (01-26-05) - Added better(?) locking stuff -+ * -+ * v1.5 - (01-26-05) - Brought up to date with new config.h changes (bug #3406) -+ * - Added in extra locking provided by georg (bug #3248) -+ * -+ * v1.4 - (12-02-04) - Added realtime_multi_mysql function -+ * This function will return an ast_config with categories, -+ * unlike standard realtime_mysql which only returns -+ * a linked list of ast_variables -+ * -+ * v1.3 - (12-01-04) - Added support other operators -+ * Ex: =, !=, LIKE, NOT LIKE, RLIKE, etc... -+ * -+ * v1.2 - (11-DD-04) - Added reload. Updated load and unload. -+ * Code beautification (doc/CODING-GUIDELINES) -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static char *res_config_mysql_desc = "MySQL RealTime Configuration Driver"; -+ -+AST_MUTEX_DEFINE_STATIC(mysql_lock); -+#define RES_CONFIG_MYSQL_CONF "res_mysql.conf" -+MYSQL mysql; -+static char dbhost[50]; -+static char dbuser[50]; -+static char dbpass[50]; -+static char dbname[50]; -+static char dbsock[50]; -+static int dbport; -+static int connected; -+static time_t connect_time; -+ -+static int parse_config(void); -+static int mysql_reconnect(const char *database); -+static int realtime_mysql_status(int fd, int argc, char **argv); -+ -+STANDARD_LOCAL_USER; -+ -+LOCAL_USER_DECL; -+ -+static char cli_realtime_mysql_status_usage[] = -+"Usage: realtime mysql status\n" -+" Shows connection information for the MySQL RealTime driver\n"; -+ -+static struct ast_cli_entry cli_realtime_mysql_status = { -+ { "realtime", "mysql", "status", NULL }, realtime_mysql_status, -+ "Shows connection information for the MySQL RealTime driver", cli_realtime_mysql_status_usage, NULL }; -+ -+static struct ast_variable *realtime_mysql(const char *database, const char *table, va_list ap) -+{ -+ MYSQL_RES *result; -+ MYSQL_ROW row; -+ MYSQL_FIELD *fields; -+ int numFields, i; -+ char sql[256]; -+ char *stringp; -+ char *chunk; -+ char *op; -+ const char *newparam, *newval; -+ struct ast_variable *var=NULL, *prev=NULL; -+ -+ if(!table) { -+ ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n"); -+ return NULL; -+ } -+ -+ /* Get the first parameter and first value in our list of passed paramater/value pairs */ -+ newparam = va_arg(ap, const char *); -+ newval = va_arg(ap, const char *); -+ if(!newparam || !newval) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n"); -+ mysql_close(&mysql); -+ return NULL; -+ } -+ -+ /* Create the first part of the query using the first parameter/value pairs we just extracted -+ If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ -+ -+ if(!strchr(newparam, ' ')) op = " ="; else op = ""; -+ -+ snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, newval); -+ while((newparam = va_arg(ap, const char *))) { -+ newval = va_arg(ap, const char *); -+ if(!strchr(newparam, ' ')) op = " ="; else op = ""; -+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, newval); -+ } -+ va_end(ap); -+ -+ ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql); -+ -+ /* We now have our complete statement; Lets connect to the server and execute it. */ -+ ast_mutex_lock(&mysql_lock); -+ if(!mysql_reconnect(database)) { -+ ast_mutex_unlock(&mysql_lock); -+ return NULL; -+ } -+ -+// ast_log(LOG_NOTICE, "SQL: %s\m", sql); -+ -+ if(mysql_real_query(&mysql, sql, strlen(sql))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n"); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql)); -+ ast_mutex_unlock(&mysql_lock); -+ return NULL; -+ } -+ -+ if((result = mysql_store_result(&mysql))) { -+ numFields = mysql_num_fields(result); -+ fields = mysql_fetch_fields(result); -+ -+ while((row = mysql_fetch_row(result))) { -+ for(i = 0; i < numFields; i++) { -+ stringp = row[i]; -+ while(stringp) { -+ chunk = strsep(&stringp, ";"); -+ if(chunk && !ast_strlen_zero(ast_strip(chunk))) { -+ if(prev) { -+ prev->next = ast_variable_new(fields[i].name, chunk); -+ if (prev->next) { -+ prev = prev->next; -+ } -+ } else { -+ prev = var = ast_variable_new(fields[i].name, chunk); -+ } -+ } -+ } -+ } -+ } -+ } else { -+ ast_log(LOG_WARNING, "MySQL RealTime: Could not find any rows in table %s.\n", table); -+ } -+ -+ mysql_free_result(result); -+ ast_mutex_unlock(&mysql_lock); -+ -+ return var; -+} -+ -+static struct ast_config *realtime_multi_mysql(const char *database, const char *table, va_list ap) -+{ -+ MYSQL_RES *result; -+ MYSQL_ROW row; -+ MYSQL_FIELD *fields; -+ int numFields, i; -+ char sql[256]; -+ const char *initfield = NULL; -+ char *stringp; -+ char *chunk; -+ char *op; -+ const char *newparam, *newval; -+ struct ast_realloca ra; -+ struct ast_variable *var=NULL; -+ struct ast_config *cfg = NULL; -+ struct ast_category *cat = NULL; -+ -+ if(!table) { -+ ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n"); -+ return NULL; -+ } -+ -+ memset(&ra, 0, sizeof(ra)); -+ -+ cfg = ast_config_new(); -+ if (!cfg) { -+ /* If I can't alloc memory at this point, why bother doing anything else? */ -+ ast_log(LOG_WARNING, "Out of memory!\n"); -+ return NULL; -+ } -+ -+ /* Get the first parameter and first value in our list of passed paramater/value pairs */ -+ newparam = va_arg(ap, const char *); -+ newval = va_arg(ap, const char *); -+ if(!newparam || !newval) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n"); -+ mysql_close(&mysql); -+ return NULL; -+ } -+ -+ initfield = ast_strdupa(newparam); -+ if(initfield && (op = strchr(initfield, ' '))) { -+ *op = '\0'; -+ } -+ -+ /* Create the first part of the query using the first parameter/value pairs we just extracted -+ If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ -+ -+ if(!strchr(newparam, ' ')) op = " ="; else op = ""; -+ -+ snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, newval); -+ while((newparam = va_arg(ap, const char *))) { -+ newval = va_arg(ap, const char *); -+ if(!strchr(newparam, ' ')) op = " ="; else op = ""; -+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, newval); -+ } -+ -+ if(initfield) { -+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield); -+ } -+ -+ va_end(ap); -+ -+ ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql); -+ -+ /* We now have our complete statement; Lets connect to the server and execute it. */ -+ ast_mutex_lock(&mysql_lock); -+ if(!mysql_reconnect(database)) { -+ ast_mutex_unlock(&mysql_lock); -+ return NULL; -+ } -+ -+ if(mysql_real_query(&mysql, sql, strlen(sql))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n"); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql)); -+ ast_mutex_unlock(&mysql_lock); -+ return NULL; -+ } -+ -+ if((result = mysql_store_result(&mysql))) { -+ numFields = mysql_num_fields(result); -+ fields = mysql_fetch_fields(result); -+ -+ while((row = mysql_fetch_row(result))) { -+ var = NULL; -+ cat = ast_category_new(""); -+ if(!cat) { -+ ast_log(LOG_WARNING, "Out of memory!\n"); -+ continue; -+ } -+ for(i = 0; i < numFields; i++) { -+ stringp = row[i]; -+ while(stringp) { -+ chunk = strsep(&stringp, ";"); -+ if(chunk && !ast_strlen_zero(ast_strip(chunk))) { -+ if(initfield && !strcmp(initfield, fields[i].name)) { -+ ast_category_rename(cat, chunk); -+ } -+ var = ast_variable_new(fields[i].name, chunk); -+ ast_variable_append(cat, var); -+ } -+ } -+ } -+ ast_category_append(cfg, cat); -+ } -+ } else { -+ ast_log(LOG_WARNING, "MySQL RealTime: Could not find any rows in table %s.\n", table); -+ } -+ -+ mysql_free_result(result); -+ ast_mutex_unlock(&mysql_lock); -+ -+ return cfg; -+} -+ -+static int update_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap) -+{ -+ my_ulonglong numrows; -+ char sql[256]; -+ const char *newparam, *newval; -+ -+ if(!table) { -+ ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n"); -+ return -1; -+ } -+ -+ /* Get the first parameter and first value in our list of passed paramater/value pairs */ -+ newparam = va_arg(ap, const char *); -+ newval = va_arg(ap, const char *); -+ if(!newparam || !newval) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n"); -+ mysql_close(&mysql); -+ return -1; -+ } -+ -+ /* Create the first part of the query using the first parameter/value pairs we just extracted -+ If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ -+ -+ snprintf(sql, sizeof(sql), "UPDATE %s SET %s = '%s'", table, newparam, newval); -+ while((newparam = va_arg(ap, const char *))) { -+ newval = va_arg(ap, const char *); -+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s = '%s'", newparam, newval); -+ } -+ va_end(ap); -+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s = '%s'", keyfield, lookup); -+ -+ ast_log(LOG_DEBUG,"MySQL RealTime: Update SQL: %s\n", sql); -+ -+ /* We now have our complete statement; Lets connect to the server and execute it. */ -+ ast_mutex_lock(&mysql_lock); -+ if(!mysql_reconnect(database)) { -+ ast_mutex_unlock(&mysql_lock); -+ return -1; -+ } -+ -+ if(mysql_real_query(&mysql, sql, strlen(sql))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n"); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql)); -+ ast_mutex_unlock(&mysql_lock); -+ return -1; -+ } -+ -+ numrows = mysql_affected_rows(&mysql); -+ ast_mutex_unlock(&mysql_lock); -+ -+ ast_log(LOG_DEBUG,"MySQL RealTime: Updated %llu rows on table: %s\n", numrows, table); -+ -+ /* From http://dev.mysql.com/doc/mysql/en/mysql-affected-rows.html -+ * An integer greater than zero indicates the number of rows affected -+ * Zero indicates that no records were updated -+ * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.) -+ */ -+ -+ if(numrows >= 0) -+ return (int)numrows; -+ -+ return -1; -+} -+ -+static struct ast_config *config_mysql(const char *database, const char *table, const char *file, struct ast_config *cfg) -+{ -+ MYSQL_RES *result; -+ MYSQL_ROW row; -+ my_ulonglong num_rows; -+ struct ast_config *new; -+ struct ast_variable *cur_v, *new_v; -+ struct ast_category *cur_cat, *new_cat; -+ char sql[250] = ""; -+ char last[80] = ""; -+ int cat_started = 0; -+ int var_started = 0; -+ int last_cat_metric = 0; -+ -+ last[0] = '\0'; -+ -+ if(!file || !strcmp(file, RES_CONFIG_MYSQL_CONF)) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Cannot configure myself.\n"); -+ return NULL; -+ } -+ -+ snprintf(sql, sizeof(sql), "SELECT category, var_name, var_val, cat_metric FROM %s WHERE filename='%s' and commented=0 ORDER BY filename, cat_metric desc, var_metric asc, category, var_name, var_val, id", table, file); -+ -+ ast_log(LOG_DEBUG, "MySQL RealTime: Static SQL: %s\n", sql); -+ -+ /* We now have our complete statement; Lets connect to the server and execute it. */ -+ ast_mutex_lock(&mysql_lock); -+ if(!mysql_reconnect(database)) { -+ ast_mutex_unlock(&mysql_lock); -+ return NULL; -+ } -+ -+ if(mysql_real_query(&mysql, sql, strlen(sql))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n"); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql)); -+ ast_mutex_unlock(&mysql_lock); -+ return NULL; -+ } -+ -+ if((result = mysql_store_result(&mysql))) { -+ num_rows = mysql_num_rows(result); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Found %llu rows.\n", num_rows); -+ -+ /* There might exist a better way to access the column names other than counting, -+ but I believe that would require another loop that we don't need. */ -+ -+ while((row = mysql_fetch_row(result))) { -+ if(!strcmp(row[1], "#include")) { -+ if (!ast_config_internal_load(row[2], cfg)) { -+ mysql_free_result(result); -+ ast_mutex_unlock(&mysql_lock); -+ return NULL; -+ } -+ continue; -+ } -+ -+ if(strcmp(last, row[0]) || last_cat_metric != atoi(row[3])) { -+ cur_cat = ast_category_new(row[0]); -+ if (!cur_cat) { -+ ast_log(LOG_WARNING, "Out of memory!\n"); -+ break; -+ } -+ strcpy(last, row[0]); -+ last_cat_metric = atoi(row[3]); -+ ast_category_append(cfg, cur_cat); -+ } -+ new_v = ast_variable_new(row[1], row[2]); -+ ast_variable_append(cur_cat, new_v); -+ } -+ } else { -+ ast_log(LOG_WARNING, "MySQL RealTime: Could not find config '%s' in database.\n", file); -+ } -+ -+ mysql_free_result(result); -+ ast_mutex_unlock(&mysql_lock); -+ -+ return cfg; -+} -+ -+static struct ast_config_engine mysql_engine = { -+ .name = "mysql", -+ .load_func = config_mysql, -+ .realtime_func = realtime_mysql, -+ .realtime_multi_func = realtime_multi_mysql, -+ .update_func = update_mysql -+}; -+ -+int load_module (void) -+{ -+ parse_config(); -+ -+ ast_mutex_lock(&mysql_lock); -+ -+ if(!mysql_reconnect(NULL)) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Couldn't establish connection. Check debug.\n"); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Cannot Connect: %s\n", mysql_error(&mysql)); -+ } -+ -+ ast_config_engine_register(&mysql_engine); -+ if(option_verbose) { -+ ast_verbose("MySQL RealTime driver loaded.\n"); -+ } -+ ast_cli_register(&cli_realtime_mysql_status); -+ -+ ast_mutex_unlock(&mysql_lock); -+ -+ return 0; -+} -+ -+int unload_module (void) -+{ -+ /* Aquire control before doing anything to the module itself. */ -+ ast_mutex_lock(&mysql_lock); -+ -+ mysql_close(&mysql); -+ ast_cli_unregister(&cli_realtime_mysql_status); -+ ast_config_engine_deregister(&mysql_engine); -+ if(option_verbose) { -+ ast_verbose("MySQL RealTime unloaded.\n"); -+ } -+ -+ STANDARD_HANGUP_LOCALUSERS; -+ -+ /* Unlock so something else can destroy the lock. */ -+ ast_mutex_unlock(&mysql_lock); -+ -+ return 0; -+} -+ -+int reload (void) -+{ -+ /* Aquire control before doing anything to the module itself. */ -+ ast_mutex_lock(&mysql_lock); -+ -+ mysql_close(&mysql); -+ connected = 0; -+ parse_config(); -+ -+ if(!mysql_reconnect(NULL)) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Couldn't establish connection. Check debug.\n"); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Cannot Connect: %s\n", mysql_error(&mysql)); -+ } -+ -+ ast_verbose(VERBOSE_PREFIX_2 "MySQL RealTime reloaded.\n"); -+ -+ /* Done reloading. Release lock so others can now use driver. */ -+ ast_mutex_unlock(&mysql_lock); -+ -+ return 0; -+} -+ -+int parse_config (void) -+{ -+ struct ast_config *config; -+ char *s; -+ -+ config = ast_config_load(RES_CONFIG_MYSQL_CONF); -+ -+ if(config) { -+ if(!(s=ast_variable_retrieve(config, "general", "dbuser"))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: No database user found, using 'asterisk' as default.\n"); -+ strncpy(dbuser, "asterisk", sizeof(dbuser) - 1); -+ } else { -+ strncpy(dbuser, s, sizeof(dbuser) - 1); -+ } -+ -+ if(!(s=ast_variable_retrieve(config, "general", "dbpass"))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: No database password found, using 'asterisk' as default.\n"); -+ strncpy(dbpass, "asterisk", sizeof(dbpass) - 1); -+ } else { -+ strncpy(dbpass, s, sizeof(dbpass) - 1); -+ } -+ -+ if(!(s=ast_variable_retrieve(config, "general", "dbhost"))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: No database host found, using localhost via socket.\n"); -+ dbhost[0] = '\0'; -+ } else { -+ strncpy(dbhost, s, sizeof(dbhost) - 1); -+ } -+ -+ if(!(s=ast_variable_retrieve(config, "general", "dbname"))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: No database name found, using 'asterisk' as default.\n"); -+ strncpy(dbname, "asterisk", sizeof(dbname) - 1); -+ } else { -+ strncpy(dbname, s, sizeof(dbname) - 1); -+ } -+ -+ if(!(s=ast_variable_retrieve(config, "general", "dbport"))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: No database port found, using 3306 as default.\n"); -+ dbport = 3306; -+ } else { -+ dbport = atoi(s); -+ } -+ -+ if(dbhost && !(s=ast_variable_retrieve(config, "general", "dbsock"))) { -+ ast_log(LOG_WARNING, "MySQL RealTime: No database socket found, using '/tmp/mysql.sock' as default.\n"); -+ strncpy(dbsock, "/tmp/mysql.sock", sizeof(dbsock) - 1); -+ } else { -+ strncpy(dbsock, s, sizeof(dbsock) - 1); -+ } -+ } -+ ast_config_destroy(config); -+ -+ if(dbhost) { -+ ast_log(LOG_DEBUG, "MySQL RealTime Host: %s\n", dbhost); -+ ast_log(LOG_DEBUG, "MySQL RealTime Port: %i\n", dbport); -+ } else { -+ ast_log(LOG_DEBUG, "MySQL RealTime Socket: %s\n", dbsock); -+ } -+ ast_log(LOG_DEBUG, "MySQL RealTime User: %s\n", dbuser); -+ ast_log(LOG_DEBUG, "MySQL RealTime Password: %s\n", dbpass); -+ -+ return 1; -+} -+ -+char *description (void) -+{ -+ return res_config_mysql_desc; -+} -+ -+int usecount (void) -+{ -+ /* Try and get a lock. If unsuccessful, than that means another thread is using the mysql object. */ -+ if(ast_mutex_trylock(&mysql_lock)) { -+ ast_log(LOG_DEBUG, "MySQL RealTime: Module usage count is 1.\n"); -+ return 1; -+ } -+ ast_mutex_unlock(&mysql_lock); -+ return 0; -+} -+ -+char *key () -+{ -+ return ASTERISK_GPL_KEY; -+} -+ -+static int mysql_reconnect(const char *database) -+{ -+ char my_database[50]; -+ -+ if(!database || ast_strlen_zero(database)) -+ ast_copy_string(my_database, dbname, sizeof(my_database)); -+ else -+ ast_copy_string(my_database, database, sizeof(my_database)); -+ -+ /* mutex lock should have been locked before calling this function. */ -+ -+ if((!connected) && (dbhost || dbsock) && dbuser && dbpass && my_database) { -+ if(!mysql_init(&mysql)) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Insufficient memory to allocate MySQL resource.\n"); -+ connected = 0; -+ return 0; -+ } -+ if(mysql_real_connect(&mysql, dbhost, dbuser, dbpass, my_database, dbport, dbsock, 0)) { -+ ast_log(LOG_DEBUG, "MySQL RealTime: Successfully connected to database.\n"); -+ connected = 1; -+ connect_time = time(NULL); -+ return 1; -+ } else { -+ ast_log(LOG_ERROR, "MySQL RealTime: Failed to connect database server %s on %s. Check debug for more info.\n", dbname, dbhost); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Cannot Connect: %s\n", mysql_error(&mysql)); -+ connected = 0; -+ return 0; -+ } -+ } else { -+ if(mysql_ping(&mysql) != 0) { -+ connected = 0; -+ ast_log(LOG_ERROR, "MySQL RealTime: Failed to reconnect. Check debug for more info.\n"); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Server Error: %s\n", mysql_error(&mysql)); -+ return 0; -+ } -+ -+ connected = 1; -+ -+ if(mysql_select_db(&mysql, my_database) != 0) { -+ ast_log(LOG_WARNING, "MySQL RealTime: Unable to select database: %s. Still Connected.\n", my_database); -+ ast_log(LOG_DEBUG, "MySQL RealTime: Database Select Failed: %s\n", mysql_error(&mysql)); -+ return 0; -+ } -+ -+ ast_log(LOG_DEBUG, "MySQL RealTime: Everything is fine.\n"); -+ return 1; -+ } -+} -+ -+static int realtime_mysql_status(int fd, int argc, char **argv) -+{ -+ char status[256], status2[100] = ""; -+ int ctime = time(NULL) - connect_time; -+ -+ ast_mutex_lock(&mysql_lock); -+ if(mysql_reconnect(NULL)) { -+ if(dbhost) { -+ snprintf(status, 255, "Connected to %s@%s, port %d", dbname, dbhost, dbport); -+ } else if(dbsock) { -+ snprintf(status, 255, "Connected to %s on socket file %s", dbname, dbsock); -+ } else { -+ snprintf(status, 255, "Connected to %s@%s", dbname, dbhost); -+ } -+ -+ if(dbuser && *dbuser) { -+ snprintf(status2, 99, " with username %s", dbuser); -+ } -+ -+ if (ctime > 31536000) { -+ ast_cli(fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 31536000, (ctime % 31536000) / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60); -+ } else if (ctime > 86400) { -+ ast_cli(fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60); -+ } else if (ctime > 3600) { -+ ast_cli(fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 3600, (ctime % 3600) / 60, ctime % 60); -+ } else if (ctime > 60) { -+ ast_cli(fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60, ctime % 60); -+ } else { -+ ast_cli(fd, "%s%s for %d seconds.\n", status, status2, ctime); -+ } -+ -+ ast_mutex_unlock(&mysql_lock); -+ return RESULT_SUCCESS; -+ } else { -+ ast_mutex_unlock(&mysql_lock); -+ return RESULT_FAILURE; -+ } -+} diff --git a/src/patches/asterisk-1.2.4-ipfire-bristuff-0.3.0-PRE-1l.patch b/src/patches/asterisk.patch similarity index 89% rename from src/patches/asterisk-1.2.4-ipfire-bristuff-0.3.0-PRE-1l.patch rename to src/patches/asterisk.patch index 05aa370966..afc998e214 100644 --- a/src/patches/asterisk-1.2.4-ipfire-bristuff-0.3.0-PRE-1l.patch +++ b/src/patches/asterisk.patch @@ -1,12 +1,12 @@ -diff -urN asterisk-1.2.4.orig/.version asterisk-1.2.4/.version ---- asterisk-1.2.4.orig/.version 2006-01-31 04:55:50.000000000 +0100 -+++ asterisk-1.2.4/.version 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/.version asterisk-1.2.7.1/.version +--- asterisk-1.2.7.1.orig/.version 2006-04-13 19:50:06.000000000 +0200 ++++ asterisk-1.2.7.1/.version 2006-04-18 14:39:46.000000000 +0200 @@ -1 +1 @@ --1.2.4 -+1.2.4-BRIstuffed-0.3.0-PRE-1l-for-ipfire -diff -urN asterisk-1.2.4.orig/HARDWARE asterisk-1.2.4/HARDWARE ---- asterisk-1.2.4.orig/HARDWARE 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/HARDWARE 2006-01-31 09:41:43.000000000 +0100 +-1.2.7.1 ++1.2.7.1-BRIstuffed-0.3.0-PRE-1o-with-florz-patch-for-ipfire +diff -urN asterisk-1.2.7.1.orig/HARDWARE asterisk-1.2.7.1/HARDWARE +--- asterisk-1.2.7.1.orig/HARDWARE 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/HARDWARE 2006-04-18 14:39:28.000000000 +0200 @@ -37,6 +37,19 @@ * Wildcard TE410P - Quad T1/E1 switchable interface. Supports PRI and RBS signalling, as well as PPP, FR, and HDLC data modes. @@ -22,14 +22,14 @@ diff -urN asterisk-1.2.4.orig/HARDWARE asterisk-1.2.4/HARDWARE + + * doubleE1 PCI ISDN - Double E1 interface + -+ * quadGSM PCI ISDN - 4 channel GSM interface ++ * uno/duo/quad GSM PCI - 1/2/4 channel GSM interface cards + Non-zaptel compatible hardware ============================== -diff -urN asterisk-1.2.4.orig/LICENSE asterisk-1.2.4/LICENSE ---- asterisk-1.2.4.orig/LICENSE 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/LICENSE 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/LICENSE asterisk-1.2.7.1/LICENSE +--- asterisk-1.2.7.1.orig/LICENSE 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/LICENSE 2006-04-18 14:39:28.000000000 +0200 @@ -1,7 +1,7 @@ -Asterisk is distributed under the GNU General Public License version 2 -and is also available under alternative licenses negotiated directly @@ -42,10 +42,10 @@ diff -urN asterisk-1.2.4.orig/LICENSE asterisk-1.2.4/LICENSE except as defined below. The GPL (version 2) is included in this source tree in the file COPYING. -diff -urN asterisk-1.2.4.orig/Makefile asterisk-1.2.4/Makefile ---- asterisk-1.2.4.orig/Makefile 2005-12-05 07:47:51.000000000 +0100 -+++ asterisk-1.2.4/Makefile 2006-01-31 09:41:43.000000000 +0100 -@@ -759,6 +759,9 @@ +diff -urN asterisk-1.2.7.1.orig/Makefile asterisk-1.2.7.1/Makefile +--- asterisk-1.2.7.1.orig/Makefile 2006-04-11 23:58:47.000000000 +0200 ++++ asterisk-1.2.7.1/Makefile 2006-04-18 14:39:28.000000000 +0200 +@@ -760,6 +760,9 @@ echo ";astctlowner = root" ; \ echo ";astctlgroup = apache" ; \ echo ";astctl = asterisk.ctl" ; \ @@ -55,9 +55,9 @@ diff -urN asterisk-1.2.4.orig/Makefile asterisk-1.2.4/Makefile ) > $(DESTDIR)$(ASTCONFPATH) ; \ else \ echo "Skipping asterisk.conf creation"; \ -diff -urN asterisk-1.2.4.orig/README asterisk-1.2.4/README ---- asterisk-1.2.4.orig/README 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/README 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/README asterisk-1.2.7.1/README +--- asterisk-1.2.7.1.orig/README 2006-03-03 09:12:33.000000000 +0100 ++++ asterisk-1.2.7.1/README 2006-04-18 14:39:28.000000000 +0200 @@ -4,6 +4,8 @@ Copyright (C) 2001-2005 Digium, Inc. @@ -67,9 +67,9 @@ diff -urN asterisk-1.2.4.orig/README asterisk-1.2.4/README ================================================================ * SECURITY -diff -urN asterisk-1.2.4.orig/README.chan_capi asterisk-1.2.4/README.chan_capi ---- asterisk-1.2.4.orig/README.chan_capi 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/README.chan_capi 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/README.chan_capi asterisk-1.2.7.1/README.chan_capi +--- asterisk-1.2.7.1.orig/README.chan_capi 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/README.chan_capi 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,146 @@ +(CAPI*) chan_capi a Common ISDN API 2.0 implementation for Asterisk +(C) 2002, 2003, 2004, 2005 Junghanns.NET GmbH @@ -217,9 +217,9 @@ diff -urN asterisk-1.2.4.orig/README.chan_capi asterisk-1.2.4/README.chan_capi + + + -diff -urN asterisk-1.2.4.orig/agi/Makefile asterisk-1.2.4/agi/Makefile ---- asterisk-1.2.4.orig/agi/Makefile 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/agi/Makefile 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/agi/Makefile asterisk-1.2.7.1/agi/Makefile +--- asterisk-1.2.7.1.orig/agi/Makefile 2006-03-28 22:22:05.000000000 +0200 ++++ asterisk-1.2.7.1/agi/Makefile 2006-04-18 14:39:28.000000000 +0200 @@ -11,7 +11,7 @@ # the GNU General Public License # @@ -227,7 +227,7 @@ diff -urN asterisk-1.2.4.orig/agi/Makefile asterisk-1.2.4/agi/Makefile -AGIS=agi-test.agi eagi-test eagi-sphinx-test +AGIS=agi-test.agi eagi-test eagi-sphinx-test xagi-test - CFLAGS+= + CFLAGS+=-DNO_AST_MM @@ -37,7 +37,7 @@ $(CC) $(CFLAGS) -o eagi-sphinx-test eagi-sphinx-test.o $(LIBS) @@ -238,10 +238,10 @@ diff -urN asterisk-1.2.4.orig/agi/Makefile asterisk-1.2.4/agi/Makefile %.so : %.o $(CC) -shared -Xlinker -x -o $@ $< -diff -urN asterisk-1.2.4.orig/agi/xagi-test.c asterisk-1.2.4/agi/xagi-test.c ---- asterisk-1.2.4.orig/agi/xagi-test.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/agi/xagi-test.c 2006-01-31 09:41:43.000000000 +0100 -@@ -0,0 +1,176 @@ +diff -urN asterisk-1.2.7.1.orig/agi/xagi-test.c asterisk-1.2.7.1/agi/xagi-test.c +--- asterisk-1.2.7.1.orig/agi/xagi-test.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/agi/xagi-test.c 2006-04-24 09:55:45.000000000 +0200 +@@ -0,0 +1,175 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * @@ -321,11 +321,11 @@ diff -urN asterisk-1.2.4.orig/agi/xagi-test.c asterisk-1.2.4/agi/xagi-test.c + if (FD_ISSET(STDIN_FILENO, &fds)) { + fgets(astresp, sizeof(astresp), stdin); + if (feof(stdin)) { -+ return NULL; ++ return; + } + astresp[strlen(astresp) - 1] = '\0'; + fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp); -+ return astresp; ++ return; + } + if (FD_ISSET(AUDIO_FILENO_IN, &fds)) { + /* what goes in.... */ @@ -343,7 +343,6 @@ diff -urN asterisk-1.2.4.orig/agi/xagi-test.c asterisk-1.2.4/agi/xagi-test.c +{ + fd_set fds; + int res; -+ int bytes = 0; + static char astresp[256]; + char audiobuf[4096]; + for (;;) { @@ -418,9 +417,9 @@ diff -urN asterisk-1.2.4.orig/agi/xagi-test.c asterisk-1.2.4/agi/xagi-test.c + return -1; + exit(0); +} -diff -urN asterisk-1.2.4.orig/apps/Makefile asterisk-1.2.4/apps/Makefile ---- asterisk-1.2.4.orig/apps/Makefile 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/apps/Makefile 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/Makefile asterisk-1.2.7.1/apps/Makefile +--- asterisk-1.2.7.1.orig/apps/Makefile 2006-02-09 03:31:21.000000000 +0100 ++++ asterisk-1.2.7.1/apps/Makefile 2006-04-18 14:39:28.000000000 +0200 @@ -28,8 +28,15 @@ app_test.so app_forkcdr.so app_math.so app_realtime.so \ app_dumpchan.so app_waitforsilence.so app_while.so app_setrdnis.so \ @@ -438,9 +437,9 @@ diff -urN asterisk-1.2.4.orig/apps/Makefile asterisk-1.2.4/apps/Makefile # # Obsolete things... -diff -urN asterisk-1.2.4.orig/apps/app_callingpres.c asterisk-1.2.4/apps/app_callingpres.c ---- asterisk-1.2.4.orig/apps/app_callingpres.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/apps/app_callingpres.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_callingpres.c asterisk-1.2.7.1/apps/app_callingpres.c +--- asterisk-1.2.7.1.orig/apps/app_callingpres.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_callingpres.c 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,70 @@ +/* + * An application to change the CallingPresentation for an Asterisk channel. @@ -512,9 +511,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_callingpres.c asterisk-1.2.4/apps/app_cal +{ + return ASTERISK_GPL_KEY; +} -diff -urN asterisk-1.2.4.orig/apps/app_capiCD.c asterisk-1.2.4/apps/app_capiCD.c ---- asterisk-1.2.4.orig/apps/app_capiCD.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/apps/app_capiCD.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_capiCD.c asterisk-1.2.7.1/apps/app_capiCD.c +--- asterisk-1.2.7.1.orig/apps/app_capiCD.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_capiCD.c 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,172 @@ +/* + * (CAPI*) @@ -688,9 +687,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_capiCD.c asterisk-1.2.4/apps/app_capiCD.c +{ + return ASTERISK_GPL_KEY; +} -diff -urN asterisk-1.2.4.orig/apps/app_capiECT.c asterisk-1.2.4/apps/app_capiECT.c ---- asterisk-1.2.4.orig/apps/app_capiECT.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/apps/app_capiECT.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_capiECT.c asterisk-1.2.7.1/apps/app_capiECT.c +--- asterisk-1.2.7.1.orig/apps/app_capiECT.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_capiECT.c 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,210 @@ +/* + * (CAPI*) @@ -902,9 +901,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_capiECT.c asterisk-1.2.4/apps/app_capiECT +{ + return ASTERISK_GPL_KEY; +} -diff -urN asterisk-1.2.4.orig/apps/app_capiNoES.c asterisk-1.2.4/apps/app_capiNoES.c ---- asterisk-1.2.4.orig/apps/app_capiNoES.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/apps/app_capiNoES.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_capiNoES.c asterisk-1.2.7.1/apps/app_capiNoES.c +--- asterisk-1.2.7.1.orig/apps/app_capiNoES.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_capiNoES.c 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,96 @@ +/* + * (CAPI*) @@ -1002,9 +1001,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_capiNoES.c asterisk-1.2.4/apps/app_capiNo +{ + return ASTERISK_GPL_KEY; +} -diff -urN asterisk-1.2.4.orig/apps/app_chanisavail.c asterisk-1.2.4/apps/app_chanisavail.c ---- asterisk-1.2.4.orig/apps/app_chanisavail.c 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/apps/app_chanisavail.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_chanisavail.c asterisk-1.2.7.1/apps/app_chanisavail.c +--- asterisk-1.2.7.1.orig/apps/app_chanisavail.c 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_chanisavail.c 2006-04-18 14:39:28.000000000 +0200 @@ -118,7 +118,7 @@ snprintf(trychan, sizeof(trychan), "%s/%s",cur,number); status = inuse = ast_device_state(trychan); @@ -1014,9 +1013,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_chanisavail.c asterisk-1.2.4/apps/app_cha pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name); /* Store the originally used channel too */ snprintf(tmp, sizeof(tmp), "%s/%s", tech, number); -diff -urN asterisk-1.2.4.orig/apps/app_devstate.c asterisk-1.2.4/apps/app_devstate.c ---- asterisk-1.2.4.orig/apps/app_devstate.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/apps/app_devstate.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_devstate.c asterisk-1.2.7.1/apps/app_devstate.c +--- asterisk-1.2.7.1.orig/apps/app_devstate.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_devstate.c 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,219 @@ +/* + * Devstate application @@ -1237,9 +1236,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_devstate.c asterisk-1.2.4/apps/app_devsta +{ + return ASTERISK_GPL_KEY; +} -diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c ---- asterisk-1.2.4.orig/apps/app_dial.c 2006-01-25 02:50:52.000000000 +0100 -+++ asterisk-1.2.4/apps/app_dial.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_dial.c asterisk-1.2.7.1/apps/app_dial.c +--- asterisk-1.2.7.1.orig/apps/app_dial.c 2006-04-12 00:39:59.000000000 +0200 ++++ asterisk-1.2.7.1/apps/app_dial.c 2006-04-18 14:40:13.000000000 +0200 @@ -11,6 +11,10 @@ * the project provides a web site, mailing lists and IRC * channels for your use. @@ -1251,8 +1250,8 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c * This program is free software, distributed under the terms of * the GNU General Public License Version 2. See the LICENSE file * at the top of the source tree. -@@ -113,7 +117,8 @@ - " context may be specified. Otherwise, the current extension is used.\n" +@@ -114,7 +118,8 @@ + " Otherwise, the current extension is used.\n" " h - Allow the called party to hang up by sending the '*' DTMF digit.\n" " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n" -" j - Jump to priority n+101 if all of the requested channels were busy.\n" @@ -1261,7 +1260,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c " L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n" " left. Repeat the warning every 'z' ms. The following special\n" " variables can be used with this option:\n" -@@ -158,8 +163,11 @@ +@@ -159,8 +164,11 @@ " family/key is not specified.\n" " r - Indicate ringing to the calling party. Pass no audio to the calling\n" " party until the called channel has answered.\n" @@ -1274,7 +1273,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c " t - Allow the called party to transfer the calling party by sending the\n" " DTMF sequence defined in features.conf.\n" " T - Allow the calling party to transfer the called party by sending the\n" -@@ -210,6 +218,8 @@ +@@ -211,6 +219,8 @@ OPT_CALLEE_MONITOR = (1 << 21), OPT_CALLER_MONITOR = (1 << 22), OPT_GOTO = (1 << 23), @@ -1283,7 +1282,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c } dial_exec_option_flags; #define DIAL_STILLGOING (1 << 30) -@@ -248,6 +258,8 @@ +@@ -249,6 +259,8 @@ AST_APP_OPTION('p', OPT_SCREENING), AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY), AST_APP_OPTION('r', OPT_RINGBACK), @@ -1292,7 +1291,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP), AST_APP_OPTION('t', OPT_CALLEE_TRANSFER), AST_APP_OPTION('T', OPT_CALLER_TRANSFER), -@@ -383,7 +395,7 @@ +@@ -386,7 +398,7 @@ char *context = NULL; char cidname[AST_MAX_EXTENSION]; @@ -1301,7 +1300,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c if (single) { /* Turn off hold music, etc */ -@@ -462,7 +474,7 @@ +@@ -465,7 +477,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 */ @@ -1310,7 +1309,40 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c if (!o->chan) ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause); } else { -@@ -916,17 +928,24 @@ +@@ -581,12 +593,18 @@ + HANDLE_CAUSE(AST_CAUSE_CONGESTION, in); + break; + case AST_CONTROL_RINGING: +- if (option_verbose > 2) +- ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name); +- if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) { +- ast_indicate(in, AST_CONTROL_RINGING); +- (*sentringing)++; +- } ++ if (ast_test_flag(peerflags, OPT_CALLBACK_INIT)) { ++ if (option_verbose > 2) ++ ast_verbose( VERBOSE_PREFIX_3 "%s is ringing, hanging up.\n", o->chan->name); ++ return NULL; ++ } else { ++ if (option_verbose > 2) ++ ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name); ++ if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) { ++ ast_indicate(in, AST_CONTROL_RINGING); ++ (*sentringing)++; ++ } ++ } + break; + case AST_CONTROL_PROGRESS: + if (option_verbose > 2) +@@ -761,6 +779,7 @@ + int digit = 0, result = 0; + time_t start_time, answer_time, end_time; + struct ast_app *app = NULL; ++ char *aoceunits; + + char *parse; + AST_DECLARE_APP_ARGS(args, +@@ -934,17 +953,24 @@ } if( privdb_val == AST_PRIVACY_DENY ) { @@ -1337,7 +1369,16 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c res = 0; goto out; /* is this right??? */ -@@ -1005,7 +1024,7 @@ +@@ -981,7 +1007,7 @@ + /* If a channel group has been specified, get it for use when we create peer channels */ + outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"); + +- ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP); ++ ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP| OPT_CALLBACK_INIT | OPT_NOINBAND); + cur = args.peers; + do { + /* Remember where to start next time */ +@@ -1023,7 +1049,7 @@ ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst); } /* Request the peer */ @@ -1346,7 +1387,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c if (!tmp->chan) { /* If we can't, just go on to the next call */ ast_log(LOG_NOTICE, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause)); -@@ -1036,7 +1055,7 @@ +@@ -1054,7 +1080,7 @@ ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name); ast_hangup(tmp->chan); /* Setup parameters */ @@ -1355,7 +1396,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c if (!tmp->chan) ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause); } else { -@@ -1155,8 +1174,11 @@ +@@ -1173,8 +1199,11 @@ ast_indicate(chan, AST_CONTROL_RINGING); sentringing++; } @@ -1368,7 +1409,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c time(&start_time); peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result); -@@ -1285,6 +1307,8 @@ +@@ -1303,6 +1332,8 @@ opt_args[OPT_ARG_PRIVACY], privcid); ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY); } @@ -1377,9 +1418,27 @@ diff -urN asterisk-1.2.4.orig/apps/app_dial.c asterisk-1.2.4/apps/app_dial.c if (ast_test_flag(&opts, OPT_MUSICBACK)) { ast_moh_stop(chan); } else if (ast_test_flag(&opts, OPT_RINGBACK)) { -diff -urN asterisk-1.2.4.orig/apps/app_directed_pickup.c asterisk-1.2.4/apps/app_directed_pickup.c ---- asterisk-1.2.4.orig/apps/app_directed_pickup.c 2005-12-20 18:34:00.000000000 +0100 -+++ asterisk-1.2.4/apps/app_directed_pickup.c 2006-01-31 09:41:43.000000000 +0100 +@@ -1585,7 +1616,16 @@ + } + snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time)); + pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast); +- ++ ++ /* forward AOC-E units from peer, if possible */ ++ aoceunits = pbx_builtin_getvar_helper(peer, "AOCEUNITS"); ++ ++ if (aoceunits) { ++ snprintf(toast, sizeof(toast), "%d", atoi(aoceunits)); ++ // ast_log(LOG_NOTICE, "AOCEUNITS %s\n" , toast); ++ pbx_builtin_setvar_helper(chan, "AOCEUNITS", toast); ++ } ++ + if (res != AST_PBX_NO_HANGUP_PEER) { + if (!chan->_softhangup) + chan->hangupcause = peer->hangupcause; +diff -urN asterisk-1.2.7.1.orig/apps/app_directed_pickup.c asterisk-1.2.7.1/apps/app_directed_pickup.c +--- asterisk-1.2.7.1.orig/apps/app_directed_pickup.c 2006-04-06 19:00:10.000000000 +0200 ++++ asterisk-1.2.7.1/apps/app_directed_pickup.c 2006-04-18 14:39:28.000000000 +0200 @@ -41,7 +41,7 @@ #include "asterisk/app.h" @@ -1389,10 +1448,10 @@ diff -urN asterisk-1.2.4.orig/apps/app_directed_pickup.c asterisk-1.2.4/apps/app static const char *synopsis = "Directed Call Pickup"; static const char *descrip = " Pickup(extension[@context]): This application can pickup any ringing channel\n" -diff -urN asterisk-1.2.4.orig/apps/app_meetme.c asterisk-1.2.4/apps/app_meetme.c ---- asterisk-1.2.4.orig/apps/app_meetme.c 2006-01-18 22:02:06.000000000 +0100 -+++ asterisk-1.2.4/apps/app_meetme.c 2006-01-31 09:41:43.000000000 +0100 -@@ -454,7 +454,7 @@ +diff -urN asterisk-1.2.7.1.orig/apps/app_meetme.c asterisk-1.2.7.1/apps/app_meetme.c +--- asterisk-1.2.7.1.orig/apps/app_meetme.c 2006-04-07 00:15:20.000000000 +0200 ++++ asterisk-1.2.7.1/apps/app_meetme.c 2006-04-18 14:39:28.000000000 +0200 +@@ -455,7 +455,7 @@ ast_copy_string(cnf->pin, pin, sizeof(cnf->pin)); ast_copy_string(cnf->pinadmin, pinadmin, sizeof(cnf->pinadmin)); cnf->markedusers = 0; @@ -1401,7 +1460,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_meetme.c asterisk-1.2.4/apps/app_meetme.c if (cnf->chan) { cnf->fd = cnf->chan->fds[0]; /* for use by conf_play() */ } else { -@@ -822,8 +822,9 @@ +@@ -825,8 +825,9 @@ char exitcontext[AST_MAX_CONTEXT] = ""; char recordingtmp[AST_MAX_EXTENSION] = ""; int dtmf; @@ -1412,7 +1471,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_meetme.c asterisk-1.2.4/apps/app_meetme.c char *buf = __buf + AST_FRIENDLY_OFFSET; if (!user) { -@@ -986,7 +987,7 @@ +@@ -992,7 +993,7 @@ } /* Setup buffering information */ memset(&bi, 0, sizeof(bi)); @@ -1421,7 +1480,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_meetme.c asterisk-1.2.4/apps/app_meetme.c bi.txbufpolicy = ZT_POLICY_IMMEDIATE; bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; bi.numbufs = audio_buffers; -@@ -1271,6 +1272,14 @@ +@@ -1277,6 +1278,14 @@ f = ast_read(c); if (!f) break; @@ -1436,7 +1495,7 @@ diff -urN asterisk-1.2.4.orig/apps/app_meetme.c asterisk-1.2.4/apps/app_meetme.c if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) { if (user->talk.actual) ast_frame_adjust_volume(f, user->talk.actual); -@@ -1500,7 +1509,7 @@ +@@ -1508,7 +1517,7 @@ } ast_frfree(f); } else if (outfd > -1) { @@ -1445,9 +1504,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_meetme.c asterisk-1.2.4/apps/app_meetme.c if (res > 0) { memset(&fr, 0, sizeof(fr)); fr.frametype = AST_FRAME_VOICE; -diff -urN asterisk-1.2.4.orig/apps/app_milliwatt.c asterisk-1.2.4/apps/app_milliwatt.c ---- asterisk-1.2.4.orig/apps/app_milliwatt.c 2006-01-19 05:17:45.000000000 +0100 -+++ asterisk-1.2.4/apps/app_milliwatt.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_milliwatt.c asterisk-1.2.7.1/apps/app_milliwatt.c +--- asterisk-1.2.7.1.orig/apps/app_milliwatt.c 2006-01-19 05:17:45.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_milliwatt.c 2006-04-18 14:39:28.000000000 +0200 @@ -74,20 +74,28 @@ { struct ast_frame wf; @@ -1483,21 +1542,21 @@ diff -urN asterisk-1.2.4.orig/apps/app_milliwatt.c asterisk-1.2.4/apps/app_milli wf.src = "app_milliwatt"; wf.delivery.tv_sec = 0; wf.delivery.tv_usec = 0; -diff -urN asterisk-1.2.4.orig/apps/app_page.c asterisk-1.2.4/apps/app_page.c ---- asterisk-1.2.4.orig/apps/app_page.c 2005-12-02 01:51:15.000000000 +0100 -+++ asterisk-1.2.4/apps/app_page.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_page.c asterisk-1.2.7.1/apps/app_page.c +--- asterisk-1.2.7.1.orig/apps/app_page.c 2006-04-13 19:40:21.000000000 +0200 ++++ asterisk-1.2.7.1/apps/app_page.c 2006-04-18 14:39:28.000000000 +0200 @@ -85,7 +85,7 @@ { struct calloutdata *cd = data; ast_pbx_outgoing_app(cd->tech, AST_FORMAT_SLINEAR, cd->resource, 30000, -- "MeetMe", cd->meetmeopts, NULL, 0, cd->cidnum, cd->cidname, cd->variables, NULL); -+ "MeetMe", cd->meetmeopts, NULL, 0, 0, cd->cidnum, cd->cidname, cd->variables, NULL, NULL); +- "MeetMe", cd->meetmeopts, NULL, 0, cd->cidnum, cd->cidname, cd->variables, NULL, NULL); ++ "MeetMe", cd->meetmeopts, NULL, 0, 0, cd->cidnum, cd->cidname, cd->variables, NULL, NULL, NULL); free(cd); return NULL; } -diff -urN asterisk-1.2.4.orig/apps/app_parkandannounce.c asterisk-1.2.4/apps/app_parkandannounce.c ---- asterisk-1.2.4.orig/apps/app_parkandannounce.c 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/apps/app_parkandannounce.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_parkandannounce.c asterisk-1.2.7.1/apps/app_parkandannounce.c +--- asterisk-1.2.7.1.orig/apps/app_parkandannounce.c 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_parkandannounce.c 2006-04-18 14:39:28.000000000 +0200 @@ -183,7 +183,7 @@ memset(&oh, 0, sizeof(oh)); @@ -1507,9 +1566,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_parkandannounce.c asterisk-1.2.4/apps/app if(dchan) { if(dchan->_state == AST_STATE_UP) { -diff -urN asterisk-1.2.4.orig/apps/app_pickup.c asterisk-1.2.4/apps/app_pickup.c ---- asterisk-1.2.4.orig/apps/app_pickup.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/apps/app_pickup.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_pickup.c asterisk-1.2.7.1/apps/app_pickup.c +--- asterisk-1.2.7.1.orig/apps/app_pickup.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_pickup.c 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,319 @@ +/* + * Asterisk -- A telephony toolkit for Linux. @@ -1830,9 +1889,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_pickup.c asterisk-1.2.4/apps/app_pickup.c +{ + return ASTERISK_GPL_KEY; +} -diff -urN asterisk-1.2.4.orig/apps/app_queue.c asterisk-1.2.4/apps/app_queue.c ---- asterisk-1.2.4.orig/apps/app_queue.c 2006-01-22 20:03:53.000000000 +0100 -+++ asterisk-1.2.4/apps/app_queue.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_queue.c asterisk-1.2.7.1/apps/app_queue.c +--- asterisk-1.2.7.1.orig/apps/app_queue.c 2006-04-04 19:59:18.000000000 +0200 ++++ asterisk-1.2.7.1/apps/app_queue.c 2006-04-18 14:39:28.000000000 +0200 @@ -501,7 +501,7 @@ return NULL; } @@ -1860,9 +1919,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_queue.c asterisk-1.2.4/apps/app_queue.c if (status != o->oldstatus) update_dial_status(qe->parent, o->member, status); if (!o->chan) { -diff -urN asterisk-1.2.4.orig/apps/app_readfile.c asterisk-1.2.4/apps/app_readfile.c ---- asterisk-1.2.4.orig/apps/app_readfile.c 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/apps/app_readfile.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_readfile.c asterisk-1.2.7.1/apps/app_readfile.c +--- asterisk-1.2.7.1.orig/apps/app_readfile.c 2006-03-23 21:13:48.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_readfile.c 2006-04-18 14:39:28.000000000 +0200 @@ -40,7 +40,7 @@ #include "asterisk/app.h" #include "asterisk/module.h" @@ -1872,9 +1931,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_readfile.c asterisk-1.2.4/apps/app_readfi static char *app_readfile = "ReadFile"; -diff -urN asterisk-1.2.4.orig/apps/app_segfault.c asterisk-1.2.4/apps/app_segfault.c ---- asterisk-1.2.4.orig/apps/app_segfault.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/apps/app_segfault.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_segfault.c asterisk-1.2.7.1/apps/app_segfault.c +--- asterisk-1.2.7.1.orig/apps/app_segfault.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_segfault.c 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,75 @@ +/* + * Segfault application @@ -1951,9 +2010,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_segfault.c asterisk-1.2.4/apps/app_segfau +{ + return ASTERISK_GPL_KEY; +} -diff -urN asterisk-1.2.4.orig/apps/app_sms.c asterisk-1.2.4/apps/app_sms.c ---- asterisk-1.2.4.orig/apps/app_sms.c 2005-12-26 19:19:12.000000000 +0100 -+++ asterisk-1.2.4/apps/app_sms.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_sms.c asterisk-1.2.7.1/apps/app_sms.c +--- asterisk-1.2.7.1.orig/apps/app_sms.c 2005-12-26 19:19:12.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_sms.c 2006-04-18 14:39:28.000000000 +0200 @@ -1179,32 +1179,31 @@ { struct ast_frame f = { 0 }; @@ -2008,9 +2067,9 @@ diff -urN asterisk-1.2.4.orig/apps/app_sms.c asterisk-1.2.4/apps/app_sms.c } static void sms_process (sms_t * h, int samples, signed short *data) -diff -urN asterisk-1.2.4.orig/apps/app_zapras.c asterisk-1.2.4/apps/app_zapras.c ---- asterisk-1.2.4.orig/apps/app_zapras.c 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/apps/app_zapras.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/apps/app_zapras.c asterisk-1.2.7.1/apps/app_zapras.c +--- asterisk-1.2.7.1.orig/apps/app_zapras.c 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/apps/app_zapras.c 2006-04-18 14:39:28.000000000 +0200 @@ -182,7 +182,7 @@ } } @@ -2020,10 +2079,10 @@ diff -urN asterisk-1.2.4.orig/apps/app_zapras.c asterisk-1.2.4/apps/app_zapras.c ioctl(chan->fds[0], ZT_AUDIOMODE, &x); /* Restore saved values */ -diff -urN asterisk-1.2.4.orig/asterisk.c asterisk-1.2.4/asterisk.c ---- asterisk-1.2.4.orig/asterisk.c 2006-01-24 23:55:32.000000000 +0100 -+++ asterisk-1.2.4/asterisk.c 2006-01-31 09:41:43.000000000 +0100 -@@ -221,6 +221,7 @@ +diff -urN asterisk-1.2.7.1.orig/asterisk.c asterisk-1.2.7.1/asterisk.c +--- asterisk-1.2.7.1.orig/asterisk.c 2006-04-11 23:55:51.000000000 +0200 ++++ asterisk-1.2.7.1/asterisk.c 2006-04-18 14:39:28.000000000 +0200 +@@ -228,6 +228,7 @@ char ast_config_AST_CTL_OWNER[AST_CONFIG_MAX_PATH] = "\0"; char ast_config_AST_CTL_GROUP[AST_CONFIG_MAX_PATH] = "\0"; char ast_config_AST_CTL[AST_CONFIG_MAX_PATH] = "asterisk.ctl"; @@ -2031,7 +2090,7 @@ diff -urN asterisk-1.2.4.orig/asterisk.c asterisk-1.2.4/asterisk.c static char *_argv[256]; static int shuttingdown = 0; -@@ -1878,6 +1879,7 @@ +@@ -1887,6 +1888,7 @@ ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID)); ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET)); ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR)); @@ -2039,7 +2098,7 @@ diff -urN asterisk-1.2.4.orig/asterisk.c asterisk-1.2.4/asterisk.c /* no asterisk.conf? no problem, use buildtime config! */ if (!cfg) { -@@ -1916,6 +1918,8 @@ +@@ -1926,6 +1928,8 @@ ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR)); } else if (!strcasecmp(v->name, "astmoddir")) { ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR)); @@ -2048,9 +2107,9 @@ diff -urN asterisk-1.2.4.orig/asterisk.c asterisk-1.2.4/asterisk.c } v = v->next; } -diff -urN asterisk-1.2.4.orig/build_tools/make_defaults_h asterisk-1.2.4/build_tools/make_defaults_h ---- asterisk-1.2.4.orig/build_tools/make_defaults_h 2005-06-20 19:26:08.000000000 +0200 -+++ asterisk-1.2.4/build_tools/make_defaults_h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/build_tools/make_defaults_h asterisk-1.2.7.1/build_tools/make_defaults_h +--- asterisk-1.2.7.1.orig/build_tools/make_defaults_h 2005-06-20 19:26:08.000000000 +0200 ++++ asterisk-1.2.7.1/build_tools/make_defaults_h 2006-04-18 14:39:28.000000000 +0200 @@ -16,6 +16,7 @@ #define AST_KEY_DIR "${INSTALL_PATH}${ASTVARLIBDIR}/keys" #define AST_DB "${INSTALL_PATH}${ASTVARLIBDIR}/astdb" @@ -2059,9 +2118,9 @@ diff -urN asterisk-1.2.4.orig/build_tools/make_defaults_h asterisk-1.2.4/build_t #define AST_CONFIG_FILE "${INSTALL_PATH}${ASTCONFPATH}" -diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c ---- asterisk-1.2.4.orig/channel.c 2006-01-25 10:46:43.000000000 +0100 -+++ asterisk-1.2.4/channel.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/channel.c asterisk-1.2.7.1/channel.c +--- asterisk-1.2.7.1.orig/channel.c 2006-04-11 23:35:52.000000000 +0200 ++++ asterisk-1.2.7.1/channel.c 2006-04-18 14:39:28.000000000 +0200 @@ -94,8 +94,8 @@ */ static int shutting_down = 0; @@ -2211,7 +2270,7 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c } int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy) -@@ -2364,7 +2393,7 @@ +@@ -2362,7 +2391,7 @@ &chan->writetrans, 1); } @@ -2220,7 +2279,7 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c { int state = 0; int cause = 0; -@@ -2372,7 +2401,7 @@ +@@ -2370,7 +2399,7 @@ struct ast_frame *f; int res = 0; @@ -2235,9 +2294,9 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c + chan->cid.cid_pres = callingpres; if (!ast_call(chan, data, 0)) { - while(timeout && (chan->_state != AST_STATE_UP)) { - res = ast_waitfor(chan, timeout); -@@ -2406,6 +2436,7 @@ + res = 1; /* in case chan->_state is already AST_STATE_UP */ + while (timeout && (chan->_state != AST_STATE_UP)) { +@@ -2407,6 +2437,7 @@ if (f->subclass == AST_CONTROL_RINGING) state = AST_CONTROL_RINGING; else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { @@ -2245,7 +2304,7 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c state = f->subclass; ast_frfree(f); break; -@@ -2475,12 +2506,12 @@ +@@ -2476,12 +2507,12 @@ return chan; } @@ -2261,7 +2320,7 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c { struct chanlist *chan; struct ast_channel *c; -@@ -2517,6 +2548,7 @@ +@@ -2518,6 +2549,7 @@ if (!(c = chan->tech->requester(type, capabilities, data, cause))) return NULL; @@ -2269,7 +2328,7 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c if (c->_state == AST_STATE_DOWN) { manager_event(EVENT_FLAG_CALL, "Newchannel", "Channel: %s\r\n" -@@ -2764,6 +2796,29 @@ +@@ -2765,6 +2797,29 @@ return res; } @@ -2299,7 +2358,7 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c void ast_change_name(struct ast_channel *chan, char *newname) { char tmp[256]; -@@ -3130,15 +3185,14 @@ +@@ -3131,15 +3186,14 @@ ); } @@ -2317,7 +2376,7 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c manager_event(EVENT_FLAG_CALL, (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate", "Channel: %s\r\n" -@@ -3154,6 +3208,10 @@ +@@ -3155,6 +3209,10 @@ return 0; } @@ -2328,7 +2387,7 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c /*--- Find bridged channel */ struct ast_channel *ast_bridged_channel(struct ast_channel *chan) { -@@ -3331,6 +3389,7 @@ +@@ -3332,6 +3390,7 @@ char callee_warning = 0; int to; @@ -2336,7 +2395,7 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c if (c0->_bridge) { ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", c0->name, c0->_bridge->name); -@@ -3341,6 +3400,10 @@ +@@ -3342,6 +3401,10 @@ c1->name, c1->_bridge->name); return -1; } @@ -2347,10 +2406,22 @@ diff -urN asterisk-1.2.4.orig/channel.c asterisk-1.2.4/channel.c /* Stop if we're a zombie or need a soft hangup */ if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || -diff -urN asterisk-1.2.4.orig/channels/Makefile asterisk-1.2.4/channels/Makefile ---- asterisk-1.2.4.orig/channels/Makefile 2005-12-15 11:52:30.000000000 +0100 -+++ asterisk-1.2.4/channels/Makefile 2006-01-31 09:41:43.000000000 +0100 -@@ -122,6 +122,35 @@ +diff -urN asterisk-1.2.7.1.orig/channels/Makefile asterisk-1.2.7.1/channels/Makefile +--- asterisk-1.2.7.1.orig/channels/Makefile 2005-12-15 11:52:30.000000000 +0100 ++++ asterisk-1.2.7.1/channels/Makefile 2006-04-18 14:39:28.000000000 +0200 +@@ -102,6 +102,11 @@ + ZAPR2=-lmfcr2 + endif + ++ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/lib/libgsmat.so.1)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/lib/libgsmat.so.1),) ++ CFLAGS+=-DZAPATA_GSM ++ ZAPGSM=-lgsmat ++endif ++ + ALSA_SRC=chan_alsa.c + + ifneq ($(wildcard alsa-monitor.h),) +@@ -122,6 +127,35 @@ endif endif # WITHOUT_ZAPTEL @@ -2386,7 +2457,16 @@ diff -urN asterisk-1.2.4.orig/channels/Makefile asterisk-1.2.4/channels/Makefile ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/vpbapi.h),) CHANNEL_LIBS+=chan_vpb.so CFLAGS+=-DLINUX -@@ -220,6 +249,9 @@ +@@ -204,7 +238,7 @@ + $(CC) -c $(CFLAGS) -o chan_zap.o chan_zap.c + + chan_zap.so: chan_zap.o +- $(CC) $(SOLINK) -o $@ $< $(ZAPPRI) $(ZAPR2) -ltonezone ++ $(CC) $(SOLINK) -o $@ $< $(ZAPPRI) $(ZAPGSM) $(ZAPR2) -ltonezone + + chan_sip.so: chan_sip.o + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} chan_sip.o ${CYGSOLIB} +@@ -220,6 +254,9 @@ chan_nbs.so: chan_nbs.o $(CC) $(SOLINK) -o $@ $< -lnbs @@ -2396,9 +2476,9 @@ diff -urN asterisk-1.2.4.orig/channels/Makefile asterisk-1.2.4/channels/Makefile chan_vpb.o: chan_vpb.c $(CXX) -c $(CFLAGS) -o $@ chan_vpb.c -diff -urN asterisk-1.2.4.orig/channels/chan_agent.c asterisk-1.2.4/channels/chan_agent.c ---- asterisk-1.2.4.orig/channels/chan_agent.c 2006-01-13 07:07:39.000000000 +0100 -+++ asterisk-1.2.4/channels/chan_agent.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/channels/chan_agent.c asterisk-1.2.7.1/channels/chan_agent.c +--- asterisk-1.2.7.1.orig/channels/chan_agent.c 2006-02-15 02:21:33.000000000 +0100 ++++ asterisk-1.2.7.1/channels/chan_agent.c 2006-04-18 14:39:28.000000000 +0200 @@ -1331,7 +1331,7 @@ chan = agent_new(p, AST_STATE_DOWN); } else if (!p->owner && !ast_strlen_zero(p->loginchan)) { @@ -2408,9 +2488,9 @@ diff -urN asterisk-1.2.4.orig/channels/chan_agent.c asterisk-1.2.4/channels/chan if (p->chan) chan = agent_new(p, AST_STATE_DOWN); } -diff -urN asterisk-1.2.4.orig/channels/chan_capi.c asterisk-1.2.4/channels/chan_capi.c ---- asterisk-1.2.4.orig/channels/chan_capi.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/channels/chan_capi.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/channels/chan_capi.c asterisk-1.2.7.1/channels/chan_capi.c +--- asterisk-1.2.7.1.orig/channels/chan_capi.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/channels/chan_capi.c 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,2888 @@ +/* + * (CAPI*) @@ -5300,9 +5380,9 @@ diff -urN asterisk-1.2.4.orig/channels/chan_capi.c asterisk-1.2.4/channels/chan_ +{ + return ASTERISK_GPL_KEY; +} -diff -urN asterisk-1.2.4.orig/channels/chan_features.c asterisk-1.2.4/channels/chan_features.c ---- asterisk-1.2.4.orig/channels/chan_features.c 2006-01-25 19:39:44.000000000 +0100 -+++ asterisk-1.2.4/channels/chan_features.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/channels/chan_features.c asterisk-1.2.7.1/channels/chan_features.c +--- asterisk-1.2.7.1.orig/channels/chan_features.c 2006-01-25 19:39:44.000000000 +0100 ++++ asterisk-1.2.7.1/channels/chan_features.c 2006-04-18 14:39:28.000000000 +0200 @@ -438,7 +438,7 @@ } ast_mutex_unlock(&featurelock); @@ -5312,9 +5392,9 @@ diff -urN asterisk-1.2.4.orig/channels/chan_features.c asterisk-1.2.4/channels/c if (!chan) { ast_log(LOG_NOTICE, "Unable to allocate subchannel '%s/%s'\n", tech, dest); return NULL; -diff -urN asterisk-1.2.4.orig/channels/chan_iax2.c asterisk-1.2.4/channels/chan_iax2.c ---- asterisk-1.2.4.orig/channels/chan_iax2.c 2006-01-20 02:00:46.000000000 +0100 -+++ asterisk-1.2.4/channels/chan_iax2.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/channels/chan_iax2.c asterisk-1.2.7.1/channels/chan_iax2.c +--- asterisk-1.2.7.1.orig/channels/chan_iax2.c 2006-03-31 21:11:26.000000000 +0200 ++++ asterisk-1.2.7.1/channels/chan_iax2.c 2006-04-18 14:39:28.000000000 +0200 @@ -11,6 +11,9 @@ * the project provides a web site, mailing lists and IRC * channels for your use. @@ -5325,7 +5405,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_iax2.c asterisk-1.2.4/channels/chan_ * This program is free software, distributed under the terms of * the GNU General Public License Version 2. See the LICENSE file * at the top of the source tree. -@@ -3050,7 +3053,7 @@ +@@ -3065,7 +3068,7 @@ memset(&ied, 0, sizeof(ied)); ast_mutex_lock(&iaxsl[callno]); if (callno && iaxs[callno]) { @@ -5334,7 +5414,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_iax2.c asterisk-1.2.4/channels/chan_ alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); /* Send the hangup unless we have had a transmission error or are already gone */ iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); -@@ -3102,7 +3105,8 @@ +@@ -3117,7 +3120,8 @@ static struct ast_frame *iax2_read(struct ast_channel *c) { static struct ast_frame f = { AST_FRAME_NULL, }; @@ -5344,7 +5424,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_iax2.c asterisk-1.2.4/channels/chan_ return &f; } -@@ -6688,7 +6692,7 @@ +@@ -6702,7 +6706,7 @@ } if (f.frametype == AST_FRAME_IAX) { if (iaxs[fr.callno]->initid > -1) { @@ -5353,9 +5433,9 @@ diff -urN asterisk-1.2.4.orig/channels/chan_iax2.c asterisk-1.2.4/channels/chan_ ast_sched_del(sched, iaxs[fr.callno]->initid); iaxs[fr.callno]->initid = -1; } -diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_sip.c ---- asterisk-1.2.4.orig/channels/chan_sip.c 2006-01-28 14:52:15.000000000 +0100 -+++ asterisk-1.2.4/channels/chan_sip.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/channels/chan_sip.c asterisk-1.2.7.1/channels/chan_sip.c +--- asterisk-1.2.7.1.orig/channels/chan_sip.c 2006-04-07 16:16:41.000000000 +0200 ++++ asterisk-1.2.7.1/channels/chan_sip.c 2006-04-25 13:23:13.000000000 +0200 @@ -596,6 +596,7 @@ unsigned int flags; /*!< SIP_ flags */ int timer_t1; /*!< SIP timer T1, ms rtt */ @@ -5398,7 +5478,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s p->subscribed = NONE; append_history(p, "Subscribestatus", "timeout"); return 10000; /* Reschedule this destruction so that we know that it's gone */ -@@ -3109,16 +3112,30 @@ +@@ -3124,16 +3127,30 @@ /*! \brief find_call: Connect incoming SIP message to current dialog or create new dialog structure */ /* Called by handle_request, sipsock_read */ @@ -5430,7 +5510,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s if (pedanticsipchecking) { /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy we need more to identify a branch - so we have to check branch, from -@@ -4043,6 +4060,7 @@ +@@ -4058,6 +4075,7 @@ if (sipmethod == SIP_CANCEL) { c = p->initreq.rlPart2; /* Use original URI */ } else if (sipmethod == SIP_ACK) { @@ -5438,21 +5518,24 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s /* Use URI from Contact: in 200 OK (if INVITE) (we only have the contacturi on INVITEs) */ if (!ast_strlen_zero(p->okcontacturi)) -@@ -4808,10 +4826,12 @@ +@@ -4824,13 +4842,15 @@ ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); ast_copy_string(p->uri, invite_buf, sizeof(p->uri)); + ast_copy_string(p->origuri, invite, sizeof(p->origuri)); - /* If there is a VXML URL append it to the SIP URL */ - if (p->options && p->options->vxml_url) { + if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { + /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ + snprintf(to, sizeof(to), ";tag=%s", p->uri, p->theirtag); + } else if (p->options && p->options->vxml_url) { + /* If there is a VXML URL append it to the SIP URL */ - snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); +// snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); + snprintf(to, sizeof(to), "<%s;%s>", p->uri, p->options->vxml_url); } else { snprintf(to, sizeof(to), "<%s>", p->uri); } -@@ -4867,6 +4887,11 @@ +@@ -4887,6 +4907,11 @@ if (!ast_strlen_zero(p->referred_by)) add_header(&req, "Referred-By", p->referred_by); } @@ -5464,7 +5547,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s #ifdef OSP_SUPPORT if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) { ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken); -@@ -4941,8 +4966,7 @@ +@@ -4961,8 +4986,7 @@ } /*! \brief transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----*/ @@ -5474,7 +5557,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s char tmp[4000], from[256], to[256]; char *t = tmp, *c, *a, *mfrom, *mto; size_t maxbytes = sizeof(tmp); -@@ -5086,10 +5110,19 @@ +@@ -5106,10 +5130,19 @@ case DIALOG_INFO_XML: /* SNOM subscribes in this format */ ast_build_string(&t, &maxbytes, "\n"); ast_build_string(&t, &maxbytes, "\n", p->dialogver++, full ? "full":"partial", mto); @@ -5497,7 +5580,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s ast_build_string(&t, &maxbytes, "%s\n", statestring); ast_build_string(&t, &maxbytes, "\n\n"); break; -@@ -6299,7 +6332,7 @@ +@@ -6321,7 +6354,7 @@ /*! \brief cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---*/ /* If you add an "hint" priority to the extension in the dial plan, you will get notifications on device state changes */ @@ -5506,7 +5589,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s { struct sip_pvt *p = data; -@@ -6318,7 +6351,7 @@ +@@ -6340,7 +6373,7 @@ p->laststate = state; break; } @@ -5515,7 +5598,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s if (option_debug > 1) ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); -@@ -8584,6 +8617,7 @@ +@@ -8607,6 +8640,7 @@ char buf[1024]; unsigned int event; char *c; @@ -5523,7 +5606,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s /* Need to check the media/type */ if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") || -@@ -8647,6 +8681,19 @@ +@@ -8670,6 +8704,19 @@ ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); transmit_response(p, "200 OK", req); return; @@ -5543,7 +5626,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s } else if ((c = get_header(req, "X-ClientCode"))) { /* Client code (from SNOM phone) */ if (ast_test_flag(p, SIP_USECLIENTCODE)) { -@@ -8746,12 +8793,63 @@ +@@ -8769,12 +8816,63 @@ return RESULT_SUCCESS; } @@ -5608,7 +5691,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s if (argc < 4) return RESULT_SHOWUSAGE; -@@ -8768,41 +8866,13 @@ +@@ -8791,41 +8889,13 @@ } for (i = 3; i < argc; i++) { @@ -5655,7 +5738,13 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s /*! \brief sip_do_history: Enable SIP History logging (CLI) ---*/ static int sip_do_history(int fd, int argc, char *argv[]) { -@@ -9447,7 +9517,7 @@ +@@ -9468,12 +9538,13 @@ + case 100: /* Trying */ + sip_cancel_destroy(p); + break; ++ case 183: + case 180: /* 180 Ringing */ + sip_cancel_destroy(p); if (!ignore && p->owner) { ast_queue_control(p->owner, AST_CONTROL_RINGING); if (p->owner->_state != AST_STATE_UP) @@ -5664,7 +5753,37 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s } if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { process_sdp(p, req); -@@ -10801,7 +10871,7 @@ +@@ -9483,17 +9554,17 @@ + } + } + break; +- case 183: /* Session progress */ ++/* case 183: // Session progress + sip_cancel_destroy(p); +- /* Ignore 183 Session progress without SDP */ ++ // Ignore 183 Session progress without SDP + if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { + process_sdp(p, req); + if (!ignore && p->owner) { +- /* Queue a progress frame */ ++ // Queue a progress frame + ast_queue_control(p->owner, AST_CONTROL_PROGRESS); + } + } +- break; ++ break; */ + case 200: /* 200 OK on invite - someone's answering our call */ + sip_cancel_destroy(p); + p->authtries = 0; +@@ -10287,6 +10358,7 @@ + /* This is a call to ourself. Send ourselves an error code and stop + processing immediately, as SIP really has no good mechanism for + being able to call yourself */ ++ast_log(LOG_NOTICE, "to: %s uri: %s\n", get_header(req, "To"), p->origuri); + transmit_response(p, "482 Loop Detected", req); + /* We do NOT destroy p here, so that our response will be accepted */ + return 0; +@@ -10836,7 +10908,7 @@ struct sip_pvt *p_old; transmit_response(p, "200 OK", req); @@ -5673,7 +5792,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s append_history(p, "Subscribestatus", ast_extension_state2str(firststate)); /* remove any old subscription from this peer for the same exten/context, -@@ -11113,7 +11183,7 @@ +@@ -11148,7 +11220,7 @@ /* Process request, with netlock held */ retrylock: ast_mutex_lock(&netlock); @@ -5682,7 +5801,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s if (p) { /* Go ahead and lock the owner if it has one -- we may need it */ if (p->owner && ast_mutex_trylock(&p->owner->lock)) { -@@ -11435,6 +11505,52 @@ +@@ -11468,6 +11540,52 @@ return 0; } @@ -5735,7 +5854,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s /*! \brief sip_devicestate: Part of PBX channel interface ---*/ /* Return values:--- -@@ -13128,6 +13244,8 @@ +@@ -13167,6 +13285,8 @@ "List SIP peers (text format)", mandescr_show_peers); ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, "Show SIP peer (text format)", mandescr_show_peer); @@ -5744,7 +5863,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s sip_poke_all_peers(); sip_send_all_registers(); -@@ -13158,6 +13276,7 @@ +@@ -13197,6 +13317,7 @@ ast_rtp_proto_unregister(&sip_rtp); @@ -5752,21 +5871,31 @@ diff -urN asterisk-1.2.4.orig/channels/chan_sip.c asterisk-1.2.4/channels/chan_s ast_manager_unregister("SIPpeers"); ast_manager_unregister("SIPshowpeer"); -diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_zap.c ---- asterisk-1.2.4.orig/channels/chan_zap.c 2006-01-30 18:08:28.000000000 +0100 -+++ asterisk-1.2.4/channels/chan_zap.c 2006-01-31 09:46:14.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/channels/chan_zap.c asterisk-1.2.7.1/channels/chan_zap.c +--- asterisk-1.2.7.1.orig/channels/chan_zap.c 2006-04-04 20:28:14.000000000 +0200 ++++ asterisk-1.2.7.1/channels/chan_zap.c 2006-04-25 14:21:48.000000000 +0200 @@ -11,6 +11,10 @@ * the project provides a web site, mailing lists and IRC * channels for your use. * -+ * Copyright (C) 2003, 2004, 2005 Junghanns.NET GmbH ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH + * Klaus-Peter Junghanns + * + * * This program is free software, distributed under the terms of * the GNU General Public License Version 2. See the LICENSE file * at the top of the source tree. -@@ -96,6 +100,7 @@ +@@ -65,6 +69,9 @@ + #ifdef ZAPATA_R2 + #include + #endif ++#ifdef ZAPATA_GSM ++#include ++#endif + + #include "asterisk.h" + +@@ -96,6 +103,7 @@ #include "asterisk/term.h" #include "asterisk/utils.h" #include "asterisk/transcap.h" @@ -5774,7 +5903,15 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z #ifndef ZT_SIG_EM_E1 #error "Your zaptel is too old. please cvs update" -@@ -183,7 +188,7 @@ +@@ -173,6 +181,7 @@ + #define SIG_FXOGS ZT_SIG_FXOGS + #define SIG_FXOKS ZT_SIG_FXOKS + #define SIG_PRI ZT_SIG_CLEAR ++#define SIG_GSM (0x100000 | ZT_SIG_CLEAR) + #define SIG_R2 ZT_SIG_CAS + #define SIG_SF ZT_SIG_SF + #define SIG_SFWINK (0x0100000 | ZT_SIG_SF) +@@ -183,7 +192,7 @@ #define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) #define SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) @@ -5783,17 +5920,19 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z #define NUM_DCHANS 4 /*!< No more than 4 d-channels */ #define MAX_CHANNELS 672 /*!< No more than a DS3 per trunk group */ -@@ -201,6 +206,9 @@ +@@ -201,6 +210,11 @@ static char defaultcic[64] = ""; static char defaultozz[64] = ""; +static char nocid[256] = "No CID available"; +static char withheldcid[256] = "CID withheld"; ++static char gsm_modem_pin[20]; ++static char gsm_modem_exten[AST_MAX_EXTENSION]; + static char language[MAX_LANGUAGE] = ""; static char musicclass[MAX_MUSICCLASS] = ""; static char progzone[10]= ""; -@@ -287,6 +295,7 @@ +@@ -287,6 +301,7 @@ static int cur_priexclusive = 0; static int priindication_oob = 0; @@ -5801,7 +5940,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z #ifdef ZAPATA_PRI static int minunused = 2; -@@ -294,6 +303,7 @@ +@@ -294,6 +309,7 @@ static char idleext[AST_MAX_EXTENSION]; static char idledial[AST_MAX_EXTENSION]; static int overlapdial = 0; @@ -5809,7 +5948,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z static int facilityenable = 0; static char internationalprefix[10] = ""; static char nationalprefix[10] = ""; -@@ -305,8 +315,6 @@ +@@ -305,8 +321,6 @@ #ifdef PRI_GETSET_TIMERS static int pritimers[PRI_MAX_TIMERS]; #endif @@ -5818,7 +5957,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z #endif /*! \brief Wait up to 16 seconds for first digit (FXO logic) */ -@@ -327,10 +335,6 @@ +@@ -327,10 +341,6 @@ static int ifcount = 0; @@ -5829,7 +5968,26 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z /*! \brief Whether we answer on a Polarity Switch event */ static int answeronpolarityswitch = 0; -@@ -403,6 +407,27 @@ +@@ -389,6 +399,18 @@ + + struct zt_pvt; + ++#ifdef ZAPATA_GSM ++struct zt_gsm { ++ pthread_t master; ++ ast_mutex_t lock; /* Mutex */ ++ int fd; ++ int span; ++ struct gsm_modul *modul; ++ char pin[256]; ++ char exten[AST_MAX_EXTENSION]; /* Where to idle extra calls */ ++ struct zt_pvt *pvt; ++}; ++#endif + + #ifdef ZAPATA_R2 + static int r2prot = -1; +@@ -403,6 +425,28 @@ #define PRI_SPAN(p) (((p) >> 8) & 0xff) #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01) @@ -5853,11 +6011,12 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + q931_call *call; /* this also covers tei mumbojumbo */ + struct zt_holded_call *next; +}; ++ + struct zt_pri { pthread_t master; /*!< Thread of master */ ast_mutex_t lock; /*!< Mutex */ -@@ -416,6 +441,8 @@ +@@ -416,6 +460,8 @@ int nsf; /*!< Network-Specific Facilities */ int dialplan; /*!< Dialing plan */ int localdialplan; /*!< Local dialing plan */ @@ -5866,7 +6025,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z char internationalprefix[10]; /*!< country access code ('00' for european dialplans) */ char nationalprefix[10]; /*!< area access code ('0' for european dialplans) */ char localprefix[20]; /*!< area access code + area code ('0'+area code for european dialplans) */ -@@ -435,6 +462,7 @@ +@@ -435,6 +481,7 @@ int fds[NUM_DCHANS]; /*!< FD's for d-channels */ int offset; int span; @@ -5874,7 +6033,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z int resetting; int resetpos; time_t lastreset; /*!< time when unused channels were last reset */ -@@ -442,6 +470,9 @@ +@@ -442,6 +489,9 @@ struct zt_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */ struct zt_pvt *crvs; /*!< Member CRV structs */ struct zt_pvt *crvend; /*!< Pointer to end of CRV structs */ @@ -5884,7 +6043,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z }; -@@ -561,6 +592,8 @@ +@@ -561,6 +611,8 @@ unsigned int echocanbridged:1; unsigned int echocanon:1; unsigned int faxhandled:1; /*!< Has a fax tone already been handled? */ @@ -5893,7 +6052,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z unsigned int firstradio:1; unsigned int hanguponpolarityswitch:1; unsigned int hardwaredtmf:1; -@@ -573,7 +606,8 @@ +@@ -573,7 +625,8 @@ unsigned int overlapdial:1; unsigned int permcallwaiting:1; unsigned int permhidecallerid:1; /*!< Whether to hide our outgoing caller ID or not */ @@ -5903,7 +6062,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z unsigned int priexclusive:1; unsigned int pulse:1; unsigned int pulsedial:1; /*!< whether a pulse dial phone is detected */ -@@ -612,6 +646,7 @@ +@@ -612,6 +665,7 @@ #endif char cid_num[AST_MAX_EXTENSION]; int cid_ton; /*!< Type Of Number (TON) */ @@ -5911,7 +6070,14 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z char cid_name[AST_MAX_EXTENSION]; char lastcid_num[AST_MAX_EXTENSION]; char lastcid_name[AST_MAX_EXTENSION]; -@@ -676,6 +711,8 @@ +@@ -672,10 +726,15 @@ + int polarityonanswerdelay; + struct timeval polaritydelaytv; + int sendcalleridafter; ++#ifdef ZAPATA_GSM ++ struct zt_gsm gsm; ++#endif + #ifdef ZAPATA_PRI struct zt_pri *pri; struct zt_pvt *bearer; struct zt_pvt *realcall; @@ -5920,7 +6086,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z q931_call *call; int prioffset; int logicalspan; -@@ -701,11 +738,14 @@ +@@ -701,11 +760,14 @@ static int zt_indicate(struct ast_channel *chan, int condition); static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen); @@ -5936,7 +6102,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z .requester = zt_request, .send_digit = zt_digit, .send_text = zt_sendtext, -@@ -719,6 +759,7 @@ +@@ -719,6 +781,7 @@ .indicate = zt_indicate, .fixup = zt_fixup, .setoption = zt_setoption, @@ -5944,7 +6110,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z }; #ifdef ZAPATA_PRI -@@ -730,6 +771,13 @@ +@@ -730,6 +793,13 @@ struct zt_pvt *round_robin[32]; #ifdef ZAPATA_PRI @@ -5958,7 +6124,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri) { int res; -@@ -779,6 +827,112 @@ +@@ -779,6 +849,112 @@ #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) @@ -6071,7 +6237,16 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok) { int res; -@@ -1381,12 +1535,16 @@ +@@ -1181,6 +1357,8 @@ + return "GR-303 Signalling with FXOKS"; + case SIG_GR303FXSKS: + return "GR-303 Signalling with FXSKS"; ++ case SIG_GSM: ++ return "GSM Signalling"; + case 0: + return "Pseudo Signalling"; + default: +@@ -1381,12 +1559,16 @@ int res; if (!p) return; @@ -6089,7 +6264,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z return; } if (p->echocancel) { -@@ -1412,7 +1570,7 @@ +@@ -1412,7 +1594,7 @@ { int x; int res; @@ -6098,7 +6273,16 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z x = p->echotraining; res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x); if (res) -@@ -1774,7 +1932,13 @@ +@@ -1592,7 +1774,7 @@ + { + int x, y, res; + x = muted; +- if (p->sig == SIG_PRI) { ++ if ((p->sig == SIG_PRI) || (p->sig == SIG_GSM)) { + y = 1; + res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y); + if (res) +@@ -1774,7 +1956,12 @@ ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel); p->outgoing = 1; @@ -6109,11 +6293,37 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); + } + -+ disable_dtmf_detect(p); switch(p->sig) { case SIG_FXOLS: -@@ -2016,6 +2180,12 @@ +@@ -1998,6 +2185,26 @@ + case SIG_PRI: + /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ + p->dialdest[0] = '\0'; ++ disable_dtmf_detect(p); ++ break; ++ case SIG_GSM: ++#ifdef ZAPATA_GSM ++ if (p->gsm.modul) { ++ c = strchr(dest, '/'); ++ if (c) ++ c++; ++ else ++ c = dest; ++ ast_mutex_lock(&p->gsm.lock); ++ if (gsm_dial(p->gsm.modul, 0, c)) { ++ ast_log(LOG_WARNING, "dialing failed on channel %d\n", p->channel); ++ ast_mutex_unlock(&p->gsm.lock); ++ ast_mutex_unlock(&p->lock); ++ return -1; ++ } ++ ast_mutex_unlock(&p->gsm.lock); ++ } ++#endif + break; + default: + ast_log(LOG_DEBUG, "not yet implemented\n"); +@@ -2016,6 +2223,12 @@ int ldp_strip; int exclusive; @@ -6126,7 +6336,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z c = strchr(dest, '/'); if (c) c++; -@@ -2033,6 +2203,7 @@ +@@ -2033,6 +2246,7 @@ ast_mutex_unlock(&p->lock); return -1; } @@ -6134,7 +6344,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (p->sig != SIG_FXSKS) { p->dop.op = ZT_DIAL_OP_REPLACE; s = strchr(c + p->stripmsd, 'w'); -@@ -2056,6 +2227,8 @@ +@@ -2056,6 +2270,8 @@ pri_rel(p->pri); ast_mutex_unlock(&p->lock); return -1; @@ -6143,7 +6353,16 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } if (!(sr = pri_sr_new())) { ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); -@@ -2287,8 +2460,10 @@ +@@ -2085,7 +2301,7 @@ + pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); + pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, + (p->digital ? -1 : +- ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))); ++ ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)), ast->lowlayercompat); + if (p->pri->facilityenable) + pri_facility_enable(p->pri->pri); + +@@ -2287,8 +2503,10 @@ } if (newslot < 0) { newslot = 0; @@ -6155,7 +6374,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } if (old && (oldslot != newslot)) ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n", -@@ -2344,8 +2519,7 @@ +@@ -2344,8 +2562,7 @@ ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); @@ -6165,7 +6384,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (index > -1) { /* Real channel, do some fixup */ p->subs[index].owner = NULL; -@@ -2442,6 +2616,7 @@ +@@ -2442,6 +2659,7 @@ if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { @@ -6173,10 +6392,76 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z p->owner = NULL; p->ringt = 0; p->distinctivering = 0; -@@ -2505,6 +2680,26 @@ +@@ -2478,19 +2696,61 @@ + if (p->call && (!p->bearer || (p->bearer->call == p->call))) { + if (!pri_grab(p, p->pri)) { + if (p->alreadyhungup) { ++/* char *aoc = pbx_builtin_getvar_helper(ast,"AOCEUNITS"); ++ int iaoc = aoc ? atoi(aoc) : -1; ++ char *aocpm = pbx_builtin_getvar_helper(ast,"AOCEUNITSPERMIN"); ++ int iaocpm = aocpm ? atoi(aocpm) : -1; ++ ++ if (iaocpm > -1) { ++ if (ast->cdr) { ++ long bill_sec = ast->cdr->billsec; ++ long bill_min = 0; ++ if (bill_sec > 0) { ++ bill_min = bill_sec / 60; ++ if (bill_min < 1) bill_min = 1; ++ } ++ iaoc = bill_min * iaocpm; ++ } else { ++ ast_log(LOG_NOTICE, "no cdr \n"); ++ } ++ } else { ++ ast_log(LOG_NOTICE, "iaocpm %d \n", iaocpm); ++ } ++*/ + ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); + + #ifdef SUPPORT_USERUSER + pri_call_set_useruser(p->call, useruser); + #endif + +- pri_hangup(p->pri->pri, p->call, -1); ++ pri_hangup(p->pri->pri, p->call, -1, -1); + p->call = NULL; + if (p->bearer) + p->bearer->call = NULL; + } else { + char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); + int icause = ast->hangupcause ? ast->hangupcause : -1; ++/* char *aoc = pbx_builtin_getvar_helper(ast,"AOCEUNITS"); ++ int iaoc = aoc ? atoi(aoc) : -1; ++ char *aocpm = pbx_builtin_getvar_helper(ast,"AOCEUNITSPERMIN"); ++ int iaocpm = aocpm ? atoi(aocpm) : -1; ++ ++ if (iaocpm > -1) { ++ if (ast->cdr) { ++ long bill_sec = ast->cdr->billsec; ++ long bill_min = 0; ++ if (bill_sec > 0) { ++ bill_min = bill_sec / 60; ++ if (bill_min < 1) bill_min = 1; ++ } ++ iaoc = bill_min * iaocpm; ++ } else { ++ ast_log(LOG_NOTICE, "no cdr \n"); ++ } ++ } else { ++ ast_log(LOG_NOTICE, "iaocpm %d \n", iaocpm); ++ } ++*/ + ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); + + #ifdef SUPPORT_USERUSER +@@ -2504,7 +2764,28 @@ + if (atoi(cause)) icause = atoi(cause); } - pri_hangup(p->pri->pri, p->call, icause); +- pri_hangup(p->pri->pri, p->call, icause); ++ ++ pri_hangup(p->pri->pri, p->call, icause, -1); + + /* if we send a release complete we wont ge no hangup event, so clear the call here */ + if (icause == 34 || icause == 44 || icause == 82 || icause == 1 || icause == 81 || icause == 17) { @@ -6184,7 +6469,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + p->call = NULL; + } else { + ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state); -+ icause = 16; ++ icause = 16; /* Note, in pri_hangup() libpri will already override the cause */ + } + } + @@ -6200,7 +6485,22 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } if (res < 0) ast_log(LOG_WARNING, "pri_disconnect failed\n"); -@@ -2701,10 +2896,14 @@ +@@ -2532,7 +2813,13 @@ + + } + #endif +- if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_R2)) ++#ifdef ZAPATA_GSM ++ if (p->gsm.modul) { ++ if (!p->alreadyhungup) ++ gsm_hangup(p->gsm.modul); ++ } ++#endif ++ if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_R2) && (p->sig != SIG_GSM)) + res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); + if (res < 0) { + ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); +@@ -2701,10 +2988,14 @@ p->proceeding = 1; res = pri_answer(p->pri->pri, p->call, 0, !p->digital); pri_rel(p->pri); @@ -6215,7 +6515,21 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z break; #endif #ifdef ZAPATA_R2 -@@ -3274,6 +3473,15 @@ +@@ -2714,6 +3005,13 @@ + ast_log(LOG_WARNING, "R2 Answer call failed :( on %s\n", ast->name); + break; + #endif ++#ifdef ZAPATA_GSM ++ case SIG_GSM: ++ if (p->gsm.modul) { ++ gsm_answer(p->gsm.modul); ++ } ++ break; ++#endif + case 0: + ast_mutex_unlock(&p->lock); + return 0; +@@ -3274,6 +3572,15 @@ { struct zt_pvt *p = newchan->tech_pvt; int x; @@ -6231,7 +6545,16 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z 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) { -@@ -4600,7 +4808,7 @@ +@@ -3637,7 +3944,7 @@ + if (p->call) { + if (p->pri && p->pri->pri) { + if (!pri_grab(p, p->pri)) { +- pri_hangup(p->pri->pri, p->call, -1); ++ pri_hangup(p->pri->pri, p->call, -1, -1); + pri_destroycall(p->pri->pri, p->call); + p->call = NULL; + pri_rel(p->pri); +@@ -4600,7 +4907,7 @@ p->subs[index].f.data = NULL; p->subs[index].f.datalen= 0; } @@ -6240,19 +6563,32 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z /* Perform busy detection. etc on the zap line */ f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); if (f) { -@@ -4612,8 +4820,9 @@ +@@ -4612,8 +4919,9 @@ } } else if (f->frametype == AST_FRAME_DTMF) { #ifdef ZAPATA_PRI - if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) { - /* Don't accept in-band DTMF when in overlap dial mode */ -+ if (p->ignoredtmf) { ++ if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) { + /* Don't accept in-band DTMF when in overlap dial mode + or when in non-overlap overlapdialing mode ... */ f->frametype = AST_FRAME_NULL; f->subclass = 0; } -@@ -4748,7 +4957,9 @@ +@@ -4661,8 +4969,10 @@ + pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); + if (ast_async_goto(ast, target_context, "fax", 1)) + ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); +- } else +- ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); ++ } else { ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Fax detected, but no fax extension\n"); ++ } + } else + ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); + } else +@@ -4748,7 +5058,9 @@ #endif /* Write a frame of (presumably voice) data */ if (frame->frametype != AST_FRAME_VOICE) { @@ -6263,7 +6599,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); return 0; } -@@ -4819,7 +5030,7 @@ +@@ -4819,7 +5131,7 @@ switch(condition) { case AST_CONTROL_BUSY: #ifdef ZAPATA_PRI @@ -6272,7 +6608,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z chan->hangupcause = AST_CAUSE_USER_BUSY; chan->_softhangup |= AST_SOFTHANGUP_DEV; res = 0; -@@ -4901,7 +5112,7 @@ +@@ -4901,7 +5213,7 @@ case AST_CONTROL_CONGESTION: chan->hangupcause = AST_CAUSE_CONGESTION; #ifdef ZAPATA_PRI @@ -6281,7 +6617,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; chan->_softhangup |= AST_SOFTHANGUP_DEV; res = 0; -@@ -5086,8 +5297,12 @@ +@@ -5086,8 +5398,12 @@ if (state == AST_STATE_RING) tmp->rings = 1; tmp->tech_pvt = i; @@ -6296,7 +6632,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z tmp->callgroup = i->callgroup; tmp->pickupgroup = i->pickupgroup; } -@@ -5217,6 +5432,7 @@ +@@ -5217,6 +5533,7 @@ int len = 0; int res; int index; @@ -6304,7 +6640,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name); index = zt_get_index(chan, p, 1); -@@ -5235,10 +5451,17 @@ +@@ -5235,10 +5552,17 @@ len = strlen(exten); res = 0; while((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { @@ -6325,7 +6661,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) timeout = matchdigittimeout; else -@@ -6720,6 +6943,8 @@ +@@ -6719,6 +7043,8 @@ } else { if (si->totalchans == 31) { /* if it's an E1 */ pris[*span].dchannels[0] = 16 + offset; @@ -6334,7 +6670,18 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } else { pris[*span].dchannels[0] = 24 + offset; } -@@ -6965,6 +7190,11 @@ +@@ -6806,6 +7132,10 @@ + + #endif + ++#ifdef ZAPATA_GSM ++static void *gsm_dchannel(void *vgsm); ++#endif ++ + static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_pri *pri, int reloading) + { + /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ +@@ -6964,6 +7294,11 @@ destroy_zt_pvt(&tmp); return NULL; } @@ -6346,7 +6693,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z 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); -@@ -6992,6 +7222,17 @@ +@@ -6991,6 +7326,17 @@ return NULL; } pris[span].nodetype = pritype; @@ -6364,7 +6711,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z pris[span].switchtype = myswitchtype; pris[span].nsf = nsf; pris[span].dialplan = dialplan; -@@ -7000,9 +7241,14 @@ +@@ -6999,9 +7345,14 @@ pris[span].minunused = minunused; pris[span].minidle = minidle; pris[span].overlapdial = overlapdial; @@ -6379,7 +6726,44 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z ast_copy_string(pris[span].internationalprefix, internationalprefix, sizeof(pris[span].internationalprefix)); ast_copy_string(pris[span].nationalprefix, nationalprefix, sizeof(pris[span].nationalprefix)); ast_copy_string(pris[span].localprefix, localprefix, sizeof(pris[span].localprefix)); -@@ -7156,6 +7402,7 @@ +@@ -7022,6 +7373,36 @@ + tmp->prioffset = 0; + } + #endif ++#ifdef ZAPATA_GSM ++ if (signalling == SIG_GSM) { ++ struct zt_bufferinfo bi; ++ ast_mutex_init(&tmp->gsm.lock); ++ strncpy(tmp->gsm.pin, gsm_modem_pin, sizeof(tmp->gsm.pin) - 1); ++ strncpy(tmp->gsm.exten, gsm_modem_exten, sizeof(tmp->gsm.exten) - 1); ++ snprintf(fn, sizeof(fn), "%d", channel + 1); ++ /* Open non-blocking */ ++ tmp->gsm.fd = zt_open(fn); ++ bi.txbufpolicy = ZT_POLICY_IMMEDIATE; ++ bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; ++ bi.numbufs = 16; ++ bi.bufsize = 1024; ++ if (ioctl(tmp->gsm.fd, ZT_SET_BUFINFO, &bi)) { ++ ast_log(LOG_ERROR, "Unable to set buffer info on channel '%s': %s\n", fn, strerror(errno)); ++ return NULL; ++ } ++ tmp->gsm.pvt = tmp; ++ tmp->gsm.span = tmp->span; ++ tmp->gsm.modul = gsm_new(tmp->gsm.fd, 0, tmp->gsm.pin, tmp->span); ++ if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, tmp->channel)) { ++ ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d: %s\n", tmp->channel, strerror(errno)); ++ destroy_zt_pvt(&tmp); ++ return NULL; ++ } ++ if (ast_pthread_create(&tmp->gsm.master, NULL, gsm_dchannel, &tmp->gsm)) { ++ zt_close(tmp->gsm.fd); ++ } ++ } ++#endif + #ifdef ZAPATA_R2 + if (signalling == SIG_R2) { + if (r2prot < 0) { +@@ -7155,6 +7536,7 @@ tmp->restrictcid = restrictcid; tmp->use_callingpres = use_callingpres; tmp->priindication_oob = priindication_oob; @@ -6387,7 +6771,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z tmp->priexclusive = cur_priexclusive; if (tmp->usedistinctiveringdetection) { if (!tmp->use_callerid) { -@@ -7429,7 +7676,7 @@ +@@ -7428,7 +7810,7 @@ break; if (!backwards && (x >= pri->numchans)) break; @@ -6396,7 +6780,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset); return x; -@@ -7476,7 +7723,7 @@ +@@ -7475,7 +7857,7 @@ end = ifend; /* We do signed linear */ oldformat = format; @@ -6405,7 +6789,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (!format) { ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat); return NULL; -@@ -7636,6 +7883,11 @@ +@@ -7635,6 +8017,11 @@ p->digital = 1; if (tmp) tmp->transfercapability = AST_TRANS_CAP_DIGITAL; @@ -6417,7 +6801,172 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } else { ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); } -@@ -7689,6 +7941,57 @@ +@@ -7674,6 +8061,164 @@ + return tmp; + } + ++#ifdef ZAPATA_GSM ++static void handle_gsm_event(struct zt_gsm *gsm, gsm_event *e) ++{ ++ struct ast_channel *c = NULL; ++ int law = ZT_LAW_ALAW; ++ int res = 0; ++ ++ switch(e->e) { ++ case GSM_EVENT_DCHAN_UP: ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d registered to network!\n", gsm->span); ++ break; ++ case GSM_EVENT_DCHAN_DOWN: ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d unregistered from network!\n", gsm->span); ++ break; ++ case GSM_EVENT_RING: ++ ast_mutex_lock(&gsm->pvt->lock); ++ if (!ast_strlen_zero(e->ring.callingnum)) { ++ strncpy(gsm->pvt->cid_num, e->ring.callingnum, sizeof(gsm->pvt->cid_num) - 1); ++ } ++ if (!ast_strlen_zero(gsm->exten)) { ++ strncpy(gsm->pvt->exten, gsm->exten, sizeof(gsm->pvt->exten) - 1); ++ } else { ++ gsm->pvt->exten[0] = 's'; ++ gsm->pvt->exten[1] = '\0'; ++ } ++ c = zt_new(gsm->pvt, AST_STATE_RING, 1, SUB_REAL, ZT_LAW_ALAW, AST_TRANS_CAP_SPEECH); ++ if (c) { ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Ring on channel %d (from %s to %s)\n", e->ring.channel, e->ring.callingnum, gsm->exten); ++ gsm->pvt->owner = c; ++ if (ioctl(gsm->pvt->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1) ++ ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", gsm->pvt->channel, law); ++ res = zt_setlaw(gsm->pvt->subs[SUB_REAL].zfd, law); ++ res = set_actual_gain(gsm->pvt->subs[SUB_REAL].zfd, 0, gsm->pvt->rxgain, gsm->pvt->txgain, law); ++ if (res < 0) { ++ ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", gsm->pvt->channel); ++// } else { ++// ast_log(LOG_NOTICE, "tx gain %f rx gain %f law %d pvt->law %d\n", gsm->pvt->txgain, gsm->pvt->rxgain, law, gsm->pvt->law); ++ } ++ } ++ ast_mutex_unlock(&gsm->pvt->lock); ++ break; ++ case GSM_EVENT_HANGUP: ++ ast_verbose(VERBOSE_PREFIX_3 "Got hang up on channel %d\n", e->hangup.channel); ++ ast_mutex_lock(&gsm->pvt->lock); ++ gsm->pvt->alreadyhungup = 1; ++ if (gsm->pvt->owner) { ++ gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; ++ } ++ ast_mutex_unlock(&gsm->pvt->lock); ++ break; ++ case GSM_EVENT_ALERTING: ++ ast_mutex_lock(&gsm->pvt->lock); ++ gsm->pvt->subs[SUB_REAL].needringing =1; ++ ast_mutex_unlock(&gsm->pvt->lock); ++ break; ++ case GSM_EVENT_ANSWER: ++ ast_mutex_lock(&gsm->pvt->lock); ++ gsm->pvt->dialing = 0; ++ gsm->pvt->subs[SUB_REAL].needanswer =1; ++ gsm->pvt->ignoredtmf = 0; ++ ast_mutex_unlock(&gsm->pvt->lock); ++ break; ++ case GSM_EVENT_PIN_REQUIRED: ++ gsm_send_pin(gsm->modul, gsm->pin); ++ break; ++ case GSM_EVENT_SM_RECEIVED: ++ ast_verbose(VERBOSE_PREFIX_3 "SMS received on span %d. PDU: %s\n", gsm->span, e->sm_received.pdu); ++ break; ++ default: ++ ast_log(LOG_WARNING,"!! Unknown GSM event %d !!\n", e->e); ++ } ++} ++ ++static void *gsm_dchannel(void *vgsm) ++{ ++ struct zt_gsm *gsm = vgsm; ++ gsm_event *e; ++ struct timeval tv = {0,0}, *next; ++ fd_set rfds, efds; ++ int res,x; ++ ++ if (!gsm) return NULL; ++ ++ if (!gsm->modul) { ++ fprintf(stderr, "No gsm_mod\n"); ++ return NULL; ++ } ++ gsm_set_debug(gsm->modul, 1); ++ for (;;) { ++ ++ /* Run the D-Channel */ ++ FD_ZERO(&rfds); ++ FD_ZERO(&efds); ++ FD_SET(gsm->fd, &rfds); ++ FD_SET(gsm->fd, &efds); ++ ++ if ((next = gsm_schedule_next(gsm->modul))) { ++ gettimeofday(&tv, NULL); ++ tv.tv_sec = next->tv_sec - tv.tv_sec; ++ tv.tv_usec = next->tv_usec - tv.tv_usec; ++ if (tv.tv_usec < 0) { ++ tv.tv_usec += 1000000; ++ tv.tv_sec -= 1; ++ } ++ if (tv.tv_sec < 0) { ++ tv.tv_sec = 0; ++ tv.tv_usec = 0; ++ } ++ } ++ res = select(gsm->fd + 1, &rfds, NULL, &efds, next ? &tv : NULL); ++ e = NULL; ++ ++ ast_mutex_lock(&gsm->lock); ++ if (!res) { ++ e = gsm_schedule_run(gsm->modul); ++ } else if (res > 0) { ++ e = gsm_check_event(gsm->modul, 1); ++ } else if (errno == ELAST) { ++ res = ioctl(gsm->fd, ZT_GETEVENT, &x); ++ printf("Got Zaptel event: %d\n", x); ++ } else if (errno != EINTR) ++ fprintf(stderr, "Error (%d) on select: %s\n", ELAST, strerror(errno)); ++ ++ if (!e) { ++ e = gsm_check_event(gsm->modul, 0); ++ } ++ ++ if (e) { ++ handle_gsm_event(gsm, e); ++ } ++ ast_mutex_unlock(&gsm->lock); ++ ++ res = ioctl(gsm->fd, ZT_GETEVENT, &x); ++ ++ if (!res && x) { ++ switch (x) { ++ case ZT_EVENT_NOALARM: ++ ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", gsm->span); ++ usleep(1000); ++ gsm_restart(gsm->modul); ++ break; ++ case ZT_EVENT_ALARM: ++ ast_log(LOG_NOTICE, "Alarm detected on span %d\n", gsm->span); ++ break; ++ default: ++ fprintf(stderr, "Got event on GSM interface: %d\n", x); ++ } ++ } ++ ++ ++ } ++ return NULL; ++} ++ ++#endif + + #ifdef ZAPATA_PRI + static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv) +@@ -7688,6 +8233,57 @@ return NULL; } @@ -6475,7 +7024,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z static int pri_find_principle(struct zt_pri *pri, int channel) { -@@ -7721,7 +8024,9 @@ +@@ -7720,7 +8316,9 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c) { int x; @@ -6485,7 +7034,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (!c) { if (principle < 0) return -1; -@@ -7735,6 +8040,7 @@ +@@ -7734,6 +8332,7 @@ /* First, check for other bearers */ for (x=0;xnumchans;x++) { if (!pri->pvts[x]) continue; @@ -6493,7 +7042,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (pri->pvts[x]->call == c) { /* Found our call */ if (principle != x) { -@@ -7748,19 +8054,56 @@ +@@ -7747,19 +8346,56 @@ } /* Fix it all up now */ pri->pvts[principle]->owner = pri->pvts[x]->owner; @@ -6551,7 +7100,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } return principle; } -@@ -7789,7 +8132,9 @@ +@@ -7788,7 +8424,9 @@ } crv = crv->next; } @@ -6562,7 +7111,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z return -1; } -@@ -7851,86 +8196,21 @@ +@@ -7850,86 +8488,33 @@ #ifndef PRI_RESTART #error "Upgrade your libpri" #endif @@ -6640,13 +7189,23 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z - ast_log(LOG_WARNING, "%s", s); - - ast_mutex_lock(&pridebugfdlock); -- ++ ast_log(LOG_WARNING, "%d %s", span, s); ++} + - if (pridebugfd >= 0) - write(pridebugfd, s, strlen(s)); -- ++#ifdef ZAPATA_GSM ++static void zt_gsm_message(char *s, int span) ++{ ++// ast_verbose("%d %s", span, s); ++} + - ast_mutex_unlock(&pridebugfdlock); -+ ast_log(LOG_WARNING, "%d %s", span, s); ++static void zt_gsm_error(char *s, int span) ++{ ++ ast_log(LOG_WARNING, "GSM: %d %s", span, s); } ++#endif static int pri_check_restart(struct zt_pri *pri) { @@ -6656,7 +7215,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z do { pri->resetpos++; } while((pri->resetpos < pri->numchans) && -@@ -8013,6 +8293,32 @@ +@@ -8012,6 +8597,32 @@ } } @@ -6689,7 +7248,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z static void *pri_dchannel(void *vpri) { struct zt_pri *pri = vpri; -@@ -8104,6 +8410,8 @@ +@@ -8103,6 +8714,8 @@ } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) activeidles++; } @@ -6698,7 +7257,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z #if 0 printf("nextidle: %d, haveidles: %d, minunsed: %d\n", nextidle, haveidles, minunused); -@@ -8205,9 +8513,36 @@ +@@ -8204,9 +8817,36 @@ if (x == ZT_EVENT_ALARM) { pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP); pri_find_dchan(pri); @@ -6737,7 +7296,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } if (option_debug) -@@ -8219,8 +8554,7 @@ +@@ -8218,8 +8858,7 @@ break; } } else if (errno != EINTR) @@ -6747,7 +7306,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (e) { if (pri->debug) pri_dump_event(pri->dchans[which], e); -@@ -8228,32 +8562,101 @@ +@@ -8227,32 +8866,102 @@ pri->dchanavail[which] |= DCHAN_UP; switch(e->e) { case PRI_EVENT_DCHAN_UP: @@ -6815,11 +7374,12 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + if (p->owner->_state != AST_STATE_UP) { + p->owner->_softhangup |= AST_SOFTHANGUP_DEV; + pri_destroycall(p->pri->pri, p->call); ++ p->call = NULL; + } + } else { + pri_destroycall(p->pri->pri, p->call); ++ p->call = NULL; + } -+ p->call = NULL; + } + } + } @@ -6845,7 +7405,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + if (p->tei == e->gen.tei) { + if (p->call) { + if (p->pri && p->pri->pri) { -+ pri_hangup(p->pri->pri, p->call, -1); ++ // pri_hangup(p->pri->pri, p->call, -1); + pri_destroycall(p->pri->pri, p->call); + p->tei = -1; + p->call = NULL; @@ -6873,24 +7433,44 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z pri->resetting = 0; /* Hangup active channels and put them in alarm mode */ for (i=0; inumchans; i++) { -@@ -8261,7 +8664,7 @@ +@@ -8260,19 +8969,29 @@ if (p) { if (p->call) { if (p->pri && p->pri->pri) { - pri_hangup(p->pri->pri, p->call, -1); -+ // pri_hangup(p->pri->pri, p->call, -1); - pri_destroycall(p->pri->pri, p->call); - p->call = NULL; +- pri_destroycall(p->pri->pri, p->call); +- p->call = NULL; ++ if (p->owner) { ++ if (p->owner->_state != AST_STATE_UP) { ++ // pri_hangup(p->pri->pri, p->call, -1); ++ pri_destroycall(p->pri->pri, p->call); ++ p->call = NULL; ++ p->owner->_softhangup |= AST_SOFTHANGUP_DEV; ++ p->inalarm = 1; ++ } ++ } else { ++ pri_destroycall(p->pri->pri, p->call); ++ p->call = NULL; ++ p->inalarm = 1; ++ } } else -@@ -8274,6 +8677,7 @@ - p->inalarm = 1; + ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n"); + } + if (p->realcall) { +- pri_hangup_all(p->realcall, pri); +- } else if (p->owner) +- p->owner->_softhangup |= AST_SOFTHANGUP_DEV; +- p->inalarm = 1; ++ pri_hangup_all(p->realcall, pri); ++ p->inalarm = 1; ++ } } } + } } break; case PRI_EVENT_RESTART: -@@ -8308,8 +8712,8 @@ +@@ -8307,8 +9026,8 @@ pri_destroycall(pri->pri, pri->pvts[x]->call); pri->pvts[x]->call = NULL; } @@ -6901,7 +7481,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z else if (pri->pvts[x]->owner) pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; ast_mutex_unlock(&pri->pvts[x]->lock); -@@ -8343,7 +8747,6 @@ +@@ -8342,7 +9061,6 @@ } } break; @@ -6909,7 +7489,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z case PRI_EVENT_INFO_RECEIVED: chanpos = pri_find_principle(pri, e->ring.channel); if (chanpos < 0) { -@@ -8352,9 +8755,11 @@ +@@ -8351,9 +9069,11 @@ } else { chanpos = pri_fixup_principle(pri, chanpos, e->ring.call); if (chanpos > -1) { @@ -6922,7 +7502,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z /* how to do that */ int digitlen = strlen(e->ring.callednum); char digit; -@@ -8366,6 +8771,14 @@ +@@ -8365,6 +9085,14 @@ zap_queue_frame(pri->pvts[chanpos], &f, pri); } } @@ -6937,7 +7517,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } ast_mutex_unlock(&pri->pvts[chanpos]->lock); } -@@ -8373,39 +8786,55 @@ +@@ -8372,39 +9100,55 @@ break; case PRI_EVENT_RING: crv = NULL; @@ -6957,7 +7537,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + if (e->ring.channel == -1) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Ignoring callwaiting SETUP on channel %d/%d span %d %d\n", PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span, e->ring.channel); -+ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_USER_BUSY); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_USER_BUSY, -1); + break; + } } else { @@ -7015,7 +7595,15 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z 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)); -@@ -8426,6 +8855,7 @@ +@@ -8418,13 +9162,14 @@ + ast_log(LOG_WARNING, "Call received for busy CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span); + } else + ast_log(LOG_NOTICE, "Call received for unconfigured CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span); +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE, -1); + if (crv) + ast_mutex_unlock(&crv->lock); + ast_mutex_unlock(&pri->pvts[chanpos]->lock); break; } } @@ -7023,7 +7611,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z pri->pvts[chanpos]->call = e->ring.call; apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan); if (pri->pvts[chanpos]->use_callerid) { -@@ -8450,29 +8880,78 @@ +@@ -8449,29 +9194,78 @@ } apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri, e->ring.redirectingnum, e->ring.callingplanrdnis); @@ -7115,7 +7703,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z /* Make sure extension exists (or in overlap dial mode, can exist) */ if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) || ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { -@@ -8491,22 +8970,38 @@ +@@ -8490,22 +9284,38 @@ res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law); if (res < 0) ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel); @@ -7161,10 +7749,20 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { /* Release the PRI lock while we create the channel */ ast_mutex_unlock(&pri->lock); -@@ -8518,10 +9013,21 @@ +@@ -8513,14 +9323,31 @@ + /* Set bearer and such */ + pri_assign_bearer(crv, pri, pri->pvts[chanpos]); + c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype); ++ if (c && (e->ring.lowlayercompat[0] > 0)) { ++ memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat)); ++ } + pri->pvts[chanpos]->owner = &inuse; ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel); } else { c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype); ++ if (c && (e->ring.lowlayercompat[0] > 0)) { ++ memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat)); ++ } + zt_enable_ec(pri->pvts[chanpos]); } if (!ast_strlen_zero(e->ring.callingsubaddr)) { @@ -7178,12 +7776,12 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + if (!ast_strlen_zero(e->ring.callingani)) { + char tmpstr[256]; + pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingani, sizeof(e->ring.callingani), e->ring.callingplanuser, e->ring.callingpresuser, 0); -+ pbx_builtin_setvar_helper(c, "PRI_USER_CID", e->ring.callednum); ++ pbx_builtin_setvar_helper(c, "PRI_USER_CID", tmpstr); + } if(e->ring.ani2 >= 0) { snprintf(ani2str, 5, "%.2d", e->ring.ani2); pbx_builtin_setvar_helper(c, "ANI2", ani2str); -@@ -8541,8 +9047,8 @@ +@@ -8540,8 +9367,8 @@ ast_mutex_lock(&pri->lock); if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) { if (option_verbose > 2) @@ -7194,7 +7792,13 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z 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", -@@ -8555,6 +9061,7 @@ +@@ -8549,14 +9376,18 @@ + if (c) + ast_hangup(c); + else { +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1); + pri->pvts[chanpos]->call = NULL; } } } else { @@ -7202,7 +7806,13 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z ast_mutex_unlock(&pri->lock); /* Release PRI lock while we create the channel */ c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype); -@@ -8578,10 +9085,26 @@ ++ if (c && (e->ring.lowlayercompat[0] > 0)) { ++ memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat)); ++ } + ast_mutex_lock(&pri->lock); + if (c) { + char calledtonstr[10]; +@@ -8577,23 +9408,40 @@ snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan); pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); if (option_verbose > 2) @@ -7231,7 +7841,9 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } 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); -@@ -8590,6 +9113,7 @@ +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1); + pri->pvts[chanpos]->call = NULL; } } } else { @@ -7239,7 +7851,22 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist. Rejecting call on channel %d/%d, span %d\n", pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, -@@ -8620,7 +9144,7 @@ + pri->pvts[chanpos]->prioffset, pri->span); +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED, -1); + pri->pvts[chanpos]->call = NULL; + pri->pvts[chanpos]->exten[0] = '\0'; + } +@@ -8601,7 +9449,7 @@ + ast_mutex_unlock(&crv->lock); + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } else +- pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); ++ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL, -1); + break; + case PRI_EVENT_RINGING: + chanpos = pri_find_principle(pri, e->ringing.channel); +@@ -8619,7 +9467,7 @@ } else { ast_mutex_lock(&pri->pvts[chanpos]->lock); if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) { @@ -7248,7 +7875,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1; pri->pvts[chanpos]->alerting = 1; } else -@@ -8649,9 +9173,15 @@ +@@ -8648,9 +9496,15 @@ } break; case PRI_EVENT_PROGRESS: @@ -7265,7 +7892,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z #ifdef PRI_PROGRESS_MASK if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) { #else -@@ -8698,6 +9228,12 @@ +@@ -8697,6 +9551,12 @@ case PRI_EVENT_PROCEEDING: chanpos = pri_find_principle(pri, e->proceeding.channel); if (chanpos > -1) { @@ -7278,7 +7905,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z if (!pri->pvts[chanpos]->proceeding) { struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, }; -@@ -8748,6 +9284,295 @@ +@@ -8747,6 +9607,295 @@ } } break; @@ -7574,7 +8201,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z case PRI_EVENT_ANSWER: chanpos = pri_find_principle(pri, e->answer.channel); if (chanpos < 0) { -@@ -8763,6 +9588,7 @@ +@@ -8762,6 +9911,7 @@ chanpos = -1; } else { ast_mutex_lock(&pri->pvts[chanpos]->lock); @@ -7582,7 +8209,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z /* Now we can do call progress detection */ /* We changed this so it turns on the DSP no matter what... progress or no progress. -@@ -8792,11 +9618,15 @@ +@@ -8791,11 +9941,15 @@ ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr); pri->pvts[chanpos]->dop.dialstr[0] = '\0'; } else if (pri->pvts[chanpos]->confirmanswer) { @@ -7599,7 +8226,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } #ifdef SUPPORT_USERUSER -@@ -8845,18 +9675,21 @@ +@@ -8844,23 +9998,32 @@ } } if (option_verbose > 2) @@ -7608,7 +8235,8 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause); } else { - pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); +- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); ++ pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1); pri->pvts[chanpos]->call = NULL; + pri->pvts[chanpos]->tei = -1; } @@ -7624,9 +8252,21 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + pri->pvts[chanpos]->resetting = 1; + } } - if (e->hangup.aoc_units > -1) +- if (e->hangup.aoc_units > -1) ++ if (e->hangup.aoc_units > -1) { ++ if (pri->pvts[chanpos]->owner) { ++ char tmpstr[256]; ++ snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units); ++ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr); ++ } if (option_verbose > 2) -@@ -8871,8 +9704,20 @@ + ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); ++ } + + #ifdef SUPPORT_USERUSER + if (!ast_strlen_zero(e->hangup.useruserinfo)) { +@@ -8870,8 +10033,20 @@ ast_mutex_unlock(&pri->pvts[chanpos]->lock); } else { @@ -7638,7 +8278,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + + 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_hangup(pri->pri, onhold->call, e->hangup.cause, -1); + pri_destroy_callonhold(pri, onhold); + onhold = NULL; + } else { @@ -7649,14 +8289,14 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } } break; -@@ -8882,17 +9727,25 @@ +@@ -8881,17 +10056,25 @@ case PRI_EVENT_HANGUP_REQ: chanpos = pri_find_principle(pri, e->hangup.channel); if (chanpos < 0) { - ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", - PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); + if (pri->nodetype == BRI_NETWORK_PTMP) { -+ pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); ++ pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1); + } else { + ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", + PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); @@ -7678,10 +8318,24 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; switch(e->hangup.cause) { case PRI_CAUSE_USER_BUSY: -@@ -8915,16 +9768,73 @@ - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", - pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); +@@ -8910,20 +10093,87 @@ + } + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup request\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); +- if (e->hangup.aoc_units > -1) +- if (option_verbose > 2) +- ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", +- pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); ++ if (e->hangup.aoc_units > -1) { ++ if (pri->pvts[chanpos]->owner) { ++ char tmpstr[256]; ++ snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units); ++ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr); ++ } ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", ++ pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); ++ } + if (pri->nodetype == BRI_NETWORK_PTMP) { + // check for bri transfers, not everybody uses ECT... + if (pri->pvts[chanpos]->owner) { @@ -7727,16 +8381,21 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + + if (transfer_ok) { + onhold->alreadyhungup = 1; -+ pri_hangup(pri->pri, onhold->call, e->hangup.cause); ++ pri_hangup(pri->pri, onhold->call, e->hangup.cause, -1); + onhold = NULL; + } + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + break; -+ } ++ } else { ++ pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1); ++ pri->pvts[chanpos]->call = NULL; ++ pri->pvts[chanpos]->tei = -1; ++ } + } + } } else { - pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); +- pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); ++ pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1); pri->pvts[chanpos]->call = NULL; + pri->pvts[chanpos]->tei = -1; } @@ -7757,7 +8416,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } #ifdef SUPPORT_USERUSER -@@ -8935,9 +9845,28 @@ +@@ -8934,9 +10184,36 @@ ast_mutex_unlock(&pri->pvts[chanpos]->lock); } else { @@ -7771,7 +8430,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + onhold = pri_get_callonhold(pri, e->hangup.cref, e->hangup.tei); + + if (onhold) { -+ pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); ++ pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1); + ast_retrieve_call_to_death(onhold->uniqueid); + pri_destroy_callonhold(pri, onhold); + onhold = NULL; @@ -7782,12 +8441,20 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } } + if ((chanpos > -1) && (pri->pvts[chanpos]->owner) && (pri->pvts[chanpos]->priindication_oob == 2) && (e->hangup.inband_progress) && (pri->pvts[chanpos]->outgoing)) { ++ if (e->hangup.aoc_units > -1) { ++ char tmpstr[256]; ++ snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units); ++ pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr); ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", ++ pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); ++ } + ast_channel_setwhentohangup(pri->pvts[chanpos]->owner, 5); + } break; case PRI_EVENT_HANGUP_ACK: chanpos = pri_find_principle(pri, e->hangup.channel); -@@ -8951,6 +9880,7 @@ +@@ -8950,6 +10227,7 @@ if (chanpos > -1) { ast_mutex_lock(&pri->pvts[chanpos]->lock); pri->pvts[chanpos]->call = NULL; @@ -7795,7 +8462,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z pri->pvts[chanpos]->resetting = 0; if (pri->pvts[chanpos]->owner) { if (option_verbose > 2) -@@ -8964,7 +9894,9 @@ +@@ -8963,7 +10241,9 @@ #endif ast_mutex_unlock(&pri->pvts[chanpos]->lock); @@ -7805,38 +8472,39 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } break; case PRI_EVENT_CONFIG_ERR: -@@ -9031,15 +9963,25 @@ +@@ -9030,7 +10310,7 @@ 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;xpvts[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;xpvts[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_NOTIFY: -@@ -9063,6 +10005,78 @@ +- chanpos = pri_fixup_principle(pri, chanpos, e->ring.call); ++ chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call); + if (chanpos > -1) { + ast_mutex_lock(&pri->pvts[chanpos]->lock); + pri->pvts[chanpos]->setup_ack = 1; +@@ -9055,10 +10335,22 @@ + ast_mutex_lock(&pri->pvts[chanpos]->lock); + switch(e->notify.info) { + case PRI_NOTIFY_REMOTE_HOLD: ++ if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) { ++ ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on NETWORK channel. Starting MoH\n"); ++ ast_moh_start(ast_bridged_channel(pri->pvts[chanpos]->owner), NULL); ++ } else { ++ ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on CPE channel. Not Starting MoH\n"); ++ } + f.subclass = AST_CONTROL_HOLD; + zap_queue_frame(pri->pvts[chanpos], &f, pri); + break; + case PRI_NOTIFY_REMOTE_RETRIEVAL: ++ if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) { ++ ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on NETWORK channel. Stopping MoH\n"); ++ ast_moh_stop(ast_bridged_channel(pri->pvts[chanpos]->owner)); ++ } else { ++ ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on CPE channel.\n"); ++ } + f.subclass = AST_CONTROL_UNHOLD; + zap_queue_frame(pri->pvts[chanpos], &f, pri); + break; +@@ -9066,6 +10358,77 @@ ast_mutex_unlock(&pri->pvts[chanpos]->lock); } break; @@ -7855,14 +8523,14 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + onhold = NULL; + if (!chan) { + /* hang up */ -+ pri_hangup(pri->pri, e->facility.call, 16); ++ pri_hangup(pri->pri, e->facility.call, 16, -1); + break; + } + } else { + /* unknown cref/tei */ + ast_log(LOG_WARNING, "did not find call on hold for cref %d tei %d\n", e->facility.tei, e->facility.cref); + /* hang up */ -+ pri_hangup(pri->pri, e->facility.call, 16); ++ pri_hangup(pri->pri, e->facility.call, 16, -1); + break; + } + @@ -7898,16 +8566,15 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } + /* disconnect */ -+ pri_hangup(pri->pri, e->facility.call, 16); ++ pri_hangup(pri->pri, e->facility.call, 16, -1); + } else if (e->facility.operation == 0x0D) { + ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum); -+ /* mmmmmkay */ -+ -+ /* lock the channel */ -+ -+ /* async goto */ -+ -+ /* disconnect isdn layer */ ++ ast_mutex_lock(&pri->pvts[chanpos]->lock); ++ /* transfer */ ++ if (pri->pvts[chanpos]->owner) { ++ snprintf(pri->pvts[chanpos]->owner->call_forward, sizeof(pri->pvts[chanpos]->owner->call_forward), "Local/%s@%s", e->facility.forwardnum, pri->pvts[chanpos]->owner->context); ++ } ++ ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } else { + ast_log(LOG_WARNING, "Unknown facility operation %#x requested.\n", e->facility.operation); + } @@ -7915,7 +8582,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z default: ast_log(LOG_DEBUG, "Event: %d\n", e->e); } -@@ -9124,7 +10138,7 @@ +@@ -9127,7 +10490,7 @@ pri->fds[i] = -1; return -1; } @@ -7924,7 +8591,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z /* Force overlap dial if we're doing GR-303! */ if (pri->switchtype == PRI_SWITCH_GR303_TMC) pri->overlapdial = 1; -@@ -9193,39 +10207,77 @@ +@@ -9196,39 +10559,77 @@ static int handle_pri_set_debug_file(int fd, int argc, char **argv) { @@ -8024,7 +8691,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } return RESULT_SUCCESS; -@@ -9257,6 +10309,7 @@ +@@ -9260,6 +10661,7 @@ @@ -8032,7 +8699,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z static int handle_pri_no_debug(int fd, int argc, char *argv[]) { int span; -@@ -9363,36 +10416,6 @@ +@@ -9366,36 +10768,6 @@ return RESULT_SUCCESS; } @@ -8069,7 +8736,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z static char pri_debug_help[] = "Usage: pri debug span \n" " Enables debugging on a given PRI span\n"; -@@ -9409,6 +10432,18 @@ +@@ -9412,6 +10784,18 @@ "Usage: pri show span \n" " Displays PRI Information\n"; @@ -8088,7 +8755,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z static struct ast_cli_entry zap_pri_cli[] = { { { "pri", "debug", "span", NULL }, handle_pri_debug, "Enables PRI debugging on a span", pri_debug_help, complete_span_4 }, -@@ -9416,19 +10451,77 @@ +@@ -9419,19 +10803,207 @@ "Disables PRI debugging on a span", pri_no_debug_help, complete_span_5 }, { { "pri", "intense", "debug", "span", NULL }, handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging", pri_really_debug_help, complete_span_5 }, @@ -8126,6 +8793,136 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z #endif /* ZAPATA_PRI */ ++#ifdef ZAPATA_GSM ++ ++static char gsm_send_pdu_help[] = ++ "Usage: gsm send pdu \n" ++ " Sends a PDU on a GSM channel\n"; ++ ++ ++static int handle_gsm_send_pdu(int fd, int argc, char *argv[]) ++{ ++/* gsm send sms */ ++ int channel; ++ int len; ++ struct zt_pvt *pvt = NULL; ++ if (argc < 6) { ++ return RESULT_SHOWUSAGE; ++ } ++ channel = atoi(argv[3]); ++ if (channel < 1) { ++ ast_cli(fd, "Invalid channel %s. Should be a number.\n", argv[3]); ++ return RESULT_SUCCESS; ++ } ++ len = atoi(argv[4]); ++ if (len < 1) { ++ ast_cli(fd, "Invalid length %s. Should be a number.\n", argv[4]); ++ return RESULT_SUCCESS; ++ } ++ pvt = iflist; ++ while (pvt) { ++ if (pvt->channel == channel) { ++ if (pvt->owner) { ++ ast_cli(fd, "Channel in use.\n"); ++ return RESULT_FAILURE; ++ } else { ++ ast_mutex_lock(&pvt->lock); ++ gsm_sms_send_pdu(pvt->gsm.modul, argv[5], len); ++ ast_mutex_unlock(&pvt->lock); ++ return RESULT_SUCCESS; ++ } ++ } ++ pvt = pvt->next; ++ } ++ ++ return RESULT_SUCCESS; ++} ++ ++static struct ast_cli_entry gsm_send_pdu = { ++ { "gsm", "send", "pdu", NULL }, handle_gsm_send_pdu, "Sends a SM on a GSM channel", gsm_send_pdu_help, complete_span_4 }; ++ ++ ++static char gsm_send_sms_help[] = ++ "Usage: gsm send sms \n" ++ " Sends a SM on a GSM channel\n"; ++ ++ ++static int handle_gsm_send_sms(int fd, int argc, char *argv[]) ++{ ++/* gsm send sms */ ++ int channel; ++ struct zt_pvt *pvt = NULL; ++ if (argc < 6) { ++ return RESULT_SHOWUSAGE; ++ } ++ channel = atoi(argv[3]); ++ if (channel < 1) { ++ ast_cli(fd, "Invalid channel %s. Should be a number.\n", argv[3]); ++ return RESULT_SUCCESS; ++ } ++ pvt = iflist; ++ while (pvt) { ++ if (pvt->channel == channel) { ++ if (pvt->owner) { ++ ast_cli(fd, "Channel in use.\n"); ++ return RESULT_FAILURE; ++ } else { ++ ast_mutex_lock(&pvt->lock); ++ gsm_sms_send_text(pvt->gsm.modul, argv[4], argv[5]); ++ ast_mutex_unlock(&pvt->lock); ++ return RESULT_SUCCESS; ++ } ++ } ++ pvt = pvt->next; ++ } ++ ++ return RESULT_SUCCESS; ++} ++ ++static struct ast_cli_entry gsm_send_sms = { ++ { "gsm", "send", "sms", NULL }, handle_gsm_send_sms, "Sends a SM on a GSM channel", gsm_send_sms_help, complete_span_4 }; ++ ++static char gsm_show_status_help[] = ++ "Usage: gsm show status >\n" ++ " Displays status information about the GSM channel.\n"; ++ ++ ++static int handle_gsm_show_status(int fd, int argc, char *argv[]) ++{ ++ int channel; ++ struct zt_pvt *pvt = NULL; ++ if (argc < 4) { ++ return RESULT_SHOWUSAGE; ++ } ++ channel = atoi(argv[3]); ++ if (channel < 1) { ++ ast_cli(fd, "Invalid channel %s. Should be a number.\n", argv[3]); ++ return RESULT_SUCCESS; ++ } ++ pvt = iflist; ++ while (pvt) { ++ if (pvt->channel == channel) { ++ if (pvt->owner) { ++ ast_cli(fd, "Channel in use.\n"); ++ return RESULT_FAILURE; ++ } else { ++ ast_mutex_lock(&pvt->lock); ++ gsm_request_status(pvt->gsm.modul); ++ ast_mutex_unlock(&pvt->lock); ++ return RESULT_SUCCESS; ++ } ++ } ++ pvt = pvt->next; ++ } ++ ++ return RESULT_SUCCESS; ++} ++ ++static struct ast_cli_entry gsm_show_status = { ++ { "gsm", "show", "status", NULL }, handle_gsm_show_status, "Displays status information about the GSM channel.", gsm_show_status_help, complete_span_4 }; ++ ++#endif /* ZAPATA_GSM */ ++ +static int app_zapEC(struct ast_channel *chan, void *data) +{ + int res=-1; @@ -8169,7 +8966,19 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z #ifdef ZAPATA_R2 static int handle_r2_no_debug(int fd, int argc, char *argv[]) { -@@ -10051,6 +11144,7 @@ +@@ -10044,6 +11616,11 @@ + } + ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0])); + #endif ++#ifdef ZAPATA_GSM ++ ast_cli_unregister(&gsm_send_sms); ++ ast_cli_unregister(&gsm_send_pdu); ++ ast_cli_unregister(&gsm_show_status); ++#endif + #ifdef ZAPATA_R2 + ast_cli_unregister_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0])); + #endif +@@ -10054,6 +11631,7 @@ ast_manager_unregister( "ZapDNDoff" ); ast_manager_unregister( "ZapDNDon" ); ast_manager_unregister("ZapShowChannels"); @@ -8177,7 +8986,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z ast_channel_unregister(&zap_tech); if (!ast_mutex_lock(&iflock)) { /* Hangup all interfaces if they have an owner */ -@@ -10409,8 +11503,8 @@ +@@ -10412,8 +11990,8 @@ } } else if (!strcasecmp(v->name, "echotraining")) { if (sscanf(v->value, "%d", &y) == 1) { @@ -8188,7 +8997,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } else { echotraining = y; } -@@ -10596,6 +11690,22 @@ +@@ -10599,12 +12177,33 @@ cur_signalling = SIG_GR303FXSKS; cur_radio = 0; pritype = PRI_CPE; @@ -8211,7 +9020,18 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z #endif #ifdef ZAPATA_R2 } else if (!strcasecmp(v->value, "r2")) { -@@ -10684,8 +11794,20 @@ + cur_signalling = SIG_R2; + cur_radio = 0; + #endif ++#ifdef ZAPATA_GSM ++ } else if (!strcasecmp(v->value, "gsm")) { ++ cur_signalling = SIG_GSM; ++ cur_radio = 0; ++#endif + } else { + ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); + } +@@ -10687,8 +12286,20 @@ priindication_oob = 1; else if (!strcasecmp(v->value, "inband")) priindication_oob = 0; @@ -8233,7 +9053,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z v->value, v->lineno); } else if (!strcasecmp(v->name, "priexclusive")) { cur_priexclusive = ast_true(v->value); -@@ -10699,6 +11821,10 @@ +@@ -10702,6 +12313,14 @@ ast_copy_string(privateprefix, v->value, sizeof(privateprefix)); } else if (!strcasecmp(v->name, "unknownprefix")) { ast_copy_string(unknownprefix, v->value, sizeof(unknownprefix)); @@ -8241,10 +9061,14 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z + ast_copy_string(nocid, v->value, sizeof(nocid) - 1); + } else if (!strcasecmp(v->name, "withheldcid")) { + ast_copy_string(withheldcid, v->value, sizeof(withheldcid) - 1); ++ } else if (!strcasecmp(v->name, "pin")) { ++ ast_copy_string(gsm_modem_pin, v->value, sizeof(gsm_modem_pin) - 1); ++ } else if (!strcasecmp(v->name, "exten")) { ++ ast_copy_string(gsm_modem_exten, v->value, sizeof(gsm_modem_exten) - 1); } else if (!strcasecmp(v->name, "resetinterval")) { if (!strcasecmp(v->value, "never")) resetinterval = -1; -@@ -10713,6 +11839,8 @@ +@@ -10716,6 +12335,8 @@ ast_copy_string(idleext, v->value, sizeof(idleext)); } else if (!strcasecmp(v->name, "idledial")) { ast_copy_string(idledial, v->value, sizeof(idledial)); @@ -8253,7 +9077,7 @@ diff -urN asterisk-1.2.4.orig/channels/chan_zap.c asterisk-1.2.4/channels/chan_z } else if (!strcasecmp(v->name, "overlapdial")) { overlapdial = ast_true(v->value); } else if (!strcasecmp(v->name, "pritimer")) { -@@ -10898,6 +12026,7 @@ +@@ -10901,6 +12522,7 @@ #ifdef ZAPATA_PRI if (!reload) { for (x=0;x 30 -diff -urN asterisk-1.2.4.orig/configs/modules.conf.sample asterisk-1.2.4/configs/modules.conf.sample ---- asterisk-1.2.4.orig/configs/modules.conf.sample 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/configs/modules.conf.sample 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/configs/modules.conf.sample asterisk-1.2.7.1/configs/modules.conf.sample +--- asterisk-1.2.7.1.orig/configs/modules.conf.sample 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/configs/modules.conf.sample 2006-04-18 14:39:28.000000000 +0200 @@ -51,3 +51,4 @@ ; exported to modules loaded after them. ; [global] +chan_capi.so=yes -diff -urN asterisk-1.2.4.orig/configs/watchdog.conf.sample asterisk-1.2.4/configs/watchdog.conf.sample ---- asterisk-1.2.4.orig/configs/watchdog.conf.sample 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/configs/watchdog.conf.sample 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/configs/watchdog.conf.sample asterisk-1.2.7.1/configs/watchdog.conf.sample +--- asterisk-1.2.7.1.orig/configs/watchdog.conf.sample 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/configs/watchdog.conf.sample 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,22 @@ +; +; Configuration file for res_watchdog @@ -8411,9 +9258,9 @@ diff -urN asterisk-1.2.4.orig/configs/watchdog.conf.sample asterisk-1.2.4/config +;device = /dev/watchdog +;interval = 100 + -diff -urN asterisk-1.2.4.orig/configs/zapata.conf.sample asterisk-1.2.4/configs/zapata.conf.sample ---- asterisk-1.2.4.orig/configs/zapata.conf.sample 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/configs/zapata.conf.sample 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/configs/zapata.conf.sample asterisk-1.2.7.1/configs/zapata.conf.sample +--- asterisk-1.2.7.1.orig/configs/zapata.conf.sample 2006-03-06 03:32:35.000000000 +0100 ++++ asterisk-1.2.7.1/configs/zapata.conf.sample 2006-04-18 14:39:28.000000000 +0200 @@ -121,9 +121,20 @@ ; ; outofband: Signal Busy/Congestion out of band with RELEASE/DISCONNECT @@ -8435,9 +9282,9 @@ diff -urN asterisk-1.2.4.orig/configs/zapata.conf.sample asterisk-1.2.4/configs/ ; If you need to override the existing channels selection routine and force all ; PRI channels to be marked as exclusively selected, set this to yes. ; priexclusive = yes -diff -urN asterisk-1.2.4.orig/db.c asterisk-1.2.4/db.c ---- asterisk-1.2.4.orig/db.c 2006-01-09 19:09:53.000000000 +0100 -+++ asterisk-1.2.4/db.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/db.c asterisk-1.2.7.1/db.c +--- asterisk-1.2.7.1.orig/db.c 2006-01-09 19:09:53.000000000 +0100 ++++ asterisk-1.2.7.1/db.c 2006-04-18 14:39:28.000000000 +0200 @@ -516,11 +516,18 @@ struct ast_cli_entry cli_database_deltree = { { "database", "deltree", NULL }, database_deltree, "Removes database keytree/values", database_deltree_usage }; @@ -8531,9 +9378,9 @@ diff -urN asterisk-1.2.4.orig/db.c asterisk-1.2.4/db.c + ast_manager_register("DBdel", EVENT_FLAG_SYSTEM, manager_dbdel, mandescr_dbdel); return 0; } -diff -urN asterisk-1.2.4.orig/devicestate.c asterisk-1.2.4/devicestate.c ---- asterisk-1.2.4.orig/devicestate.c 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/devicestate.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/devicestate.c asterisk-1.2.7.1/devicestate.c +--- asterisk-1.2.7.1.orig/devicestate.c 2006-02-10 21:38:59.000000000 +0100 ++++ asterisk-1.2.7.1/devicestate.c 2006-04-18 14:39:28.000000000 +0200 @@ -62,6 +62,8 @@ struct state_change { @@ -8650,9 +9497,9 @@ diff -urN asterisk-1.2.4.orig/devicestate.c asterisk-1.2.4/devicestate.c free(cur); AST_LIST_LOCK(&state_changes); } else { -diff -urN asterisk-1.2.4.orig/doc/README.asterisk.conf asterisk-1.2.4/doc/README.asterisk.conf ---- asterisk-1.2.4.orig/doc/README.asterisk.conf 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/doc/README.asterisk.conf 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/doc/README.asterisk.conf asterisk-1.2.7.1/doc/README.asterisk.conf +--- asterisk-1.2.7.1.orig/doc/README.asterisk.conf 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/doc/README.asterisk.conf 2006-04-18 14:39:28.000000000 +0200 @@ -62,6 +62,7 @@ maxcalls = 255 ; The maximum number of concurrent calls you want to allow execincludes = yes | no ; Allow #exec entries in configuration files @@ -8661,9 +9508,9 @@ diff -urN asterisk-1.2.4.orig/doc/README.asterisk.conf asterisk-1.2.4/doc/README [files] ; Changing the following lines may compromise your security -diff -urN asterisk-1.2.4.orig/editline/cygdef.h asterisk-1.2.4/editline/cygdef.h ---- asterisk-1.2.4.orig/editline/cygdef.h 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/editline/cygdef.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/editline/cygdef.h asterisk-1.2.7.1/editline/cygdef.h +--- asterisk-1.2.7.1.orig/editline/cygdef.h 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/editline/cygdef.h 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,11 @@ +/* cygdef.h. Generated automatically by configure. */ +#ifndef _CYGDEF_H_ @@ -8676,9 +9523,9 @@ diff -urN asterisk-1.2.4.orig/editline/cygdef.h asterisk-1.2.4/editline/cygdef.h + + +#endif /* _CYGDEF_H_ */ -diff -urN asterisk-1.2.4.orig/include/asterisk/agi.h asterisk-1.2.4/include/asterisk/agi.h ---- asterisk-1.2.4.orig/include/asterisk/agi.h 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/include/asterisk/agi.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/include/asterisk/agi.h asterisk-1.2.7.1/include/asterisk/agi.h +--- asterisk-1.2.7.1.orig/include/asterisk/agi.h 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/include/asterisk/agi.h 2006-04-18 14:39:28.000000000 +0200 @@ -29,7 +29,8 @@ typedef struct agi_state { @@ -8689,9 +9536,9 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/agi.h asterisk-1.2.4/include/aste int ctrl; /* FD for input control */ } AGI; -diff -urN asterisk-1.2.4.orig/include/asterisk/chan_capi.h asterisk-1.2.4/include/asterisk/chan_capi.h ---- asterisk-1.2.4.orig/include/asterisk/chan_capi.h 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/include/asterisk/chan_capi.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/include/asterisk/chan_capi.h asterisk-1.2.7.1/include/asterisk/chan_capi.h +--- asterisk-1.2.7.1.orig/include/asterisk/chan_capi.h 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/include/asterisk/chan_capi.h 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,276 @@ +/* + * (CAPI*) @@ -8969,9 +9816,9 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/chan_capi.h asterisk-1.2.4/includ +#define CAPI_ETSI_NPLAN_INTERNAT 0x10 + +#endif -diff -urN asterisk-1.2.4.orig/include/asterisk/chan_capi_app.h asterisk-1.2.4/include/asterisk/chan_capi_app.h ---- asterisk-1.2.4.orig/include/asterisk/chan_capi_app.h 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/include/asterisk/chan_capi_app.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/include/asterisk/chan_capi_app.h asterisk-1.2.7.1/include/asterisk/chan_capi_app.h +--- asterisk-1.2.7.1.orig/include/asterisk/chan_capi_app.h 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/include/asterisk/chan_capi_app.h 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,30 @@ +/* + * (CAPI*) @@ -9003,9 +9850,9 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/chan_capi_app.h asterisk-1.2.4/in +extern MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG); + +#endif -diff -urN asterisk-1.2.4.orig/include/asterisk/channel.h asterisk-1.2.4/include/asterisk/channel.h ---- asterisk-1.2.4.orig/include/asterisk/channel.h 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/include/asterisk/channel.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/include/asterisk/channel.h asterisk-1.2.7.1/include/asterisk/channel.h +--- asterisk-1.2.7.1.orig/include/asterisk/channel.h 2006-02-11 19:15:00.000000000 +0100 ++++ asterisk-1.2.7.1/include/asterisk/channel.h 2006-04-18 14:39:28.000000000 +0200 @@ -86,6 +86,9 @@ #ifndef _ASTERISK_CHANNEL_H #define _ASTERISK_CHANNEL_H @@ -9025,7 +9872,20 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/channel.h asterisk-1.2.4/include/ /* Why is the channel hanged up */ int hangupcause; -@@ -531,6 +534,11 @@ +@@ -397,6 +400,12 @@ + /*! ISDN Transfer Capbility - AST_FLAG_DIGITAL is not enough */ + unsigned short transfercapability; + ++ /*! ISDN Low Layer Compatibility */ ++ char lowlayercompat[16]; ++ ++ /*! ISDN High Layer Compatibility */ ++ char highlayercompat[4]; ++ + struct ast_frame *readq; + int alertpipe[2]; + /*! Write translation path */ +@@ -533,6 +542,11 @@ #define AST_STATE_MUTE (1 << 16) /*! @} */ @@ -9037,7 +9897,7 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/channel.h asterisk-1.2.4/include/ /*! \brief Change the state of a channel */ int ast_setstate(struct ast_channel *chan, int state); -@@ -567,7 +575,7 @@ +@@ -569,7 +583,7 @@ * by the low level module * \return Returns an ast_channel on success, NULL on failure. */ @@ -9046,7 +9906,7 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/channel.h asterisk-1.2.4/include/ /*! * \brief Request a channel of a given type, with data as optional information used -@@ -582,9 +590,9 @@ +@@ -584,9 +598,9 @@ * \return Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state * to know if the call was answered or not. */ @@ -9058,7 +9918,7 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/channel.h asterisk-1.2.4/include/ /*!\brief Register a channel technology (a new channel driver) * Called by a channel module to register the kind of channels it supports. -@@ -837,6 +845,10 @@ +@@ -839,6 +853,10 @@ /*--- ast_get_channel_by_exten_locked: Get channel by exten (and optionally context) and lock it */ struct ast_channel *ast_get_channel_by_exten_locked(const char *exten, const char *context); @@ -9069,7 +9929,7 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/channel.h asterisk-1.2.4/include/ /*! Waits for a digit */ /*! * \param c channel to wait for a digit on -@@ -907,6 +919,9 @@ +@@ -909,6 +927,9 @@ p->owner pointer) that is affected by the change. The physical layer of the original channel is hung up. */ int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone); @@ -9079,9 +9939,9 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/channel.h asterisk-1.2.4/include/ /*! Gives the string form of a given cause code */ /*! -diff -urN asterisk-1.2.4.orig/include/asterisk/devicestate.h asterisk-1.2.4/include/asterisk/devicestate.h ---- asterisk-1.2.4.orig/include/asterisk/devicestate.h 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/include/asterisk/devicestate.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/include/asterisk/devicestate.h asterisk-1.2.7.1/include/asterisk/devicestate.h +--- asterisk-1.2.7.1.orig/include/asterisk/devicestate.h 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/include/asterisk/devicestate.h 2006-04-18 14:39:28.000000000 +0200 @@ -42,7 +42,7 @@ /*! Device is ringing */ #define AST_DEVICE_RINGING 6 @@ -9100,9 +9960,9 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/devicestate.h asterisk-1.2.4/incl /*! \brief Registers a device state change callback * \param callback Callback -diff -urN asterisk-1.2.4.orig/include/asterisk/features.h asterisk-1.2.4/include/asterisk/features.h ---- asterisk-1.2.4.orig/include/asterisk/features.h 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/include/asterisk/features.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/include/asterisk/features.h asterisk-1.2.7.1/include/asterisk/features.h +--- asterisk-1.2.7.1.orig/include/asterisk/features.h 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/include/asterisk/features.h 2006-04-18 14:39:28.000000000 +0200 @@ -45,6 +45,8 @@ }; @@ -9145,9 +10005,9 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/features.h asterisk-1.2.4/include +extern struct ast_call_feature *ast_find_builtin_feature(char *name); + #endif /* _AST_FEATURES_H */ -diff -urN asterisk-1.2.4.orig/include/asterisk/pbx.h asterisk-1.2.4/include/asterisk/pbx.h ---- asterisk-1.2.4.orig/include/asterisk/pbx.h 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/include/asterisk/pbx.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/include/asterisk/pbx.h asterisk-1.2.7.1/include/asterisk/pbx.h +--- asterisk-1.2.7.1.orig/include/asterisk/pbx.h 2006-03-29 21:11:18.000000000 +0200 ++++ asterisk-1.2.7.1/include/asterisk/pbx.h 2006-04-18 14:39:28.000000000 +0200 @@ -57,7 +57,7 @@ AST_EXTENSION_BUSY = 1 << 1, /*! All devices UNAVAILABLE/UNREGISTERED */ @@ -9179,28 +10039,28 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/pbx.h asterisk-1.2.4/include/aste /* Synchronously or asynchronously make an outbound call and send it to a particular extension */ --int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, struct ast_channel **locked_channel); -+int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, struct ast_channel **locked_channel, char *uniqueid); +-int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel); ++int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, char *uniqueid); /* Synchronously or asynchronously make an outbound call and send it to a particular application with given extension */ --int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, struct ast_channel **locked_channel); -+int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, struct ast_channel **locked_channel, char *uniqueid); +-int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel); ++int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, char *uniqueid); - /* Functions for returning values from structures */ - const char *ast_get_context_name(struct ast_context *con); -@@ -656,7 +658,7 @@ + /* Evaluate a condition for non-falseness and return a boolean */ + int pbx_checkcondition(char *condition); +@@ -659,7 +661,7 @@ */ void ast_func_write(struct ast_channel *chan, const char *in, const char *value); -void ast_hint_state_changed(const char *device); -+void ast_hint_state_changed(const char *device, const char *cid_num, const char *cid_name); ++void ast_hint_state_changed(const char *device, char *cid_num, char *cid_name); #if defined(__cplusplus) || defined(c_plusplus) } -diff -urN asterisk-1.2.4.orig/include/asterisk/xlaw.h asterisk-1.2.4/include/asterisk/xlaw.h ---- asterisk-1.2.4.orig/include/asterisk/xlaw.h 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/include/asterisk/xlaw.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/include/asterisk/xlaw.h asterisk-1.2.7.1/include/asterisk/xlaw.h +--- asterisk-1.2.7.1.orig/include/asterisk/xlaw.h 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/include/asterisk/xlaw.h 2006-04-18 14:39:28.000000000 +0200 @@ -0,0 +1,1665 @@ +#ifndef _ASTERISK_XLAW_H +#define _ASTERISK_XLAW_H @@ -10867,9 +11727,9 @@ diff -urN asterisk-1.2.4.orig/include/asterisk/xlaw.h asterisk-1.2.4/include/ast +#endif // CAPI_ULAW +#endif + -diff -urN asterisk-1.2.4.orig/include/asterisk.h asterisk-1.2.4/include/asterisk.h ---- asterisk-1.2.4.orig/include/asterisk.h 2005-11-30 04:37:37.000000000 +0100 -+++ asterisk-1.2.4/include/asterisk.h 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/include/asterisk.h asterisk-1.2.7.1/include/asterisk.h +--- asterisk-1.2.7.1.orig/include/asterisk.h 2005-11-30 04:37:37.000000000 +0100 ++++ asterisk-1.2.7.1/include/asterisk.h 2006-04-18 14:39:28.000000000 +0200 @@ -36,6 +36,7 @@ extern char ast_config_AST_PID[AST_CONFIG_MAX_PATH]; extern char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH]; @@ -10878,9 +11738,9 @@ diff -urN asterisk-1.2.4.orig/include/asterisk.h asterisk-1.2.4/include/asterisk extern char ast_config_AST_CTL_PERMISSIONS[AST_CONFIG_MAX_PATH]; extern char ast_config_AST_CTL_OWNER[AST_CONFIG_MAX_PATH]; extern char ast_config_AST_CTL_GROUP[AST_CONFIG_MAX_PATH]; -diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c ---- asterisk-1.2.4.orig/manager.c 2006-01-09 05:52:16.000000000 +0100 -+++ asterisk-1.2.4/manager.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/manager.c asterisk-1.2.7.1/manager.c +--- asterisk-1.2.7.1.orig/manager.c 2006-02-11 19:15:00.000000000 +0100 ++++ asterisk-1.2.7.1/manager.c 2006-04-18 14:39:28.000000000 +0200 @@ -11,6 +11,9 @@ * the project provides a web site, mailing lists and IRC * channels for your use. @@ -10898,17 +11758,17 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c +#include "asterisk/astdb.h" struct fast_originate_helper { - char tech[256]; -@@ -75,6 +79,8 @@ - char exten[256]; - char idtext[256]; + char tech[AST_MAX_MANHEADER_LEN]; +@@ -76,6 +80,8 @@ + char idtext[AST_MAX_MANHEADER_LEN]; + char account[AST_MAX_ACCOUNT_CODE]; int priority; + int callingpres; + char uniqueid[64]; struct ast_variable *vars; }; -@@ -656,11 +662,17 @@ +@@ -657,11 +663,17 @@ { struct ast_channel *c = NULL; char *name = astman_get_header(m, "Channel"); @@ -10929,7 +11789,7 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c if (!c) { astman_send_error(s, m, "No such channel"); return 0; -@@ -759,6 +771,7 @@ +@@ -760,6 +772,7 @@ } @@ -10937,7 +11797,7 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c /*! \brief action_status: Manager "status" command to show channels */ /* Needs documentation... */ static int action_status(struct mansession *s, struct message *m) -@@ -865,32 +878,50 @@ +@@ -866,32 +879,50 @@ char *exten = astman_get_header(m, "Exten"); char *context = astman_get_header(m, "Context"); char *priority = astman_get_header(m, "Priority"); @@ -10994,7 +11854,7 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c else res = -1; if (!res) -@@ -936,15 +967,15 @@ +@@ -937,15 +968,15 @@ struct ast_channel *chan = NULL; if (!ast_strlen_zero(in->app)) { @@ -11002,19 +11862,19 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c + res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, in->callingpres, !ast_strlen_zero(in->cid_num) ? in->cid_num : NULL, !ast_strlen_zero(in->cid_name) ? in->cid_name : NULL, -- in->vars, &chan); -+ in->vars, &chan, in->uniqueid); +- in->vars, in->account, &chan); ++ in->vars, in->account, &chan, in->uniqueid); } else { - res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, + res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, in->callingpres, !ast_strlen_zero(in->cid_num) ? in->cid_num : NULL, !ast_strlen_zero(in->cid_name) ? in->cid_name : NULL, -- in->vars, &chan); -+ in->vars, &chan, in->uniqueid); +- in->vars, in->account, &chan); ++ in->vars, in->account, &chan, in->uniqueid); } if (!res) manager_event(EVENT_FLAG_CALL, -@@ -955,7 +986,7 @@ +@@ -956,7 +987,7 @@ "Exten: %s\r\n" "Reason: %d\r\n" "Uniqueid: %s\r\n", @@ -11023,7 +11883,7 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c else manager_event(EVENT_FLAG_CALL, "OriginateFailure", -@@ -965,7 +996,7 @@ +@@ -966,7 +997,7 @@ "Exten: %s\r\n" "Reason: %d\r\n" "Uniqueid: %s\r\n", @@ -11032,7 +11892,7 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ if (chan) -@@ -998,6 +1029,7 @@ +@@ -999,6 +1030,7 @@ char *priority = astman_get_header(m, "Priority"); char *timeout = astman_get_header(m, "Timeout"); char *callerid = astman_get_header(m, "CallerID"); @@ -11040,7 +11900,7 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c char *account = astman_get_header(m, "Account"); char *app = astman_get_header(m, "Application"); char *appdata = astman_get_header(m, "Data"); -@@ -1006,12 +1038,15 @@ +@@ -1007,12 +1039,15 @@ struct ast_variable *vars = astman_get_variables(m); char *tech, *data; char *l=NULL, *n=NULL; @@ -11056,7 +11916,7 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c pthread_t th; pthread_attr_t attr; -@@ -1027,6 +1062,10 @@ +@@ -1028,6 +1063,10 @@ astman_send_error(s, m, "Invalid timeout\n"); return 0; } @@ -11067,18 +11927,18 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c ast_copy_string(tmp, name, sizeof(tmp)); tech = tmp; data = strchr(tmp, '/'); -@@ -1053,6 +1092,7 @@ - newvar->next = vars; - vars = newvar; +@@ -1048,6 +1087,7 @@ + if (ast_strlen_zero(l)) + l = NULL; } + uniqueid = ast_alloc_uniqueid(); if (ast_true(async)) { struct fast_originate_helper *fast = malloc(sizeof(struct fast_originate_helper)); if (!fast) { -@@ -1072,8 +1112,10 @@ - fast->vars = vars; +@@ -1068,8 +1108,10 @@ ast_copy_string(fast->context, context, sizeof(fast->context)); ast_copy_string(fast->exten, exten, sizeof(fast->exten)); + ast_copy_string(fast->account, account, sizeof(fast->account)); + ast_copy_string(fast->uniqueid, uniqueid, sizeof(fast->uniqueid)); fast->timeout = to; fast->priority = pi; @@ -11086,16 +11946,16 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (ast_pthread_create(&th, &attr, fast_originate, fast)) { -@@ -1083,19 +1125,28 @@ +@@ -1079,19 +1121,28 @@ } } } else if (!ast_strlen_zero(app)) { -- res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, NULL); -+ res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, cpresi, l, n, vars, NULL, uniqueid); +- res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); ++ res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, cpresi, l, n, vars, account, NULL, uniqueid); } else { if (exten && context && pi) -- res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, NULL); -+ res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, cpresi, l, n, vars, NULL, uniqueid); +- res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); ++ res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, cpresi, l, n, vars, account, NULL, uniqueid); else { astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); return 0; @@ -11106,7 +11966,7 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c - else + if (!res) { + if (id && !ast_strlen_zero(id)) { -+ snprintf(idText,256,"ActionID: %s\r\n",id); ++ snprintf(idText,256,"ActionID: %s\r\n",id); + } + ast_cli(s->fd, "Response: Success\r\n" + "%s" @@ -11120,7 +11980,7 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c return 0; } -@@ -1569,10 +1620,10 @@ +@@ -1565,10 +1616,10 @@ return 0; } @@ -11133,27 +11993,27 @@ diff -urN asterisk-1.2.4.orig/manager.c asterisk-1.2.4/manager.c return 0; } -diff -urN asterisk-1.2.4.orig/pbx/pbx_spool.c asterisk-1.2.4/pbx/pbx_spool.c ---- asterisk-1.2.4.orig/pbx/pbx_spool.c 2006-01-09 21:08:24.000000000 +0100 -+++ asterisk-1.2.4/pbx/pbx_spool.c 2006-01-31 09:41:43.000000000 +0100 -@@ -260,11 +260,11 @@ +diff -urN asterisk-1.2.7.1.orig/pbx/pbx_spool.c asterisk-1.2.7.1/pbx/pbx_spool.c +--- asterisk-1.2.7.1.orig/pbx/pbx_spool.c 2006-02-11 19:15:00.000000000 +0100 ++++ asterisk-1.2.7.1/pbx/pbx_spool.c 2006-04-18 14:39:28.000000000 +0200 +@@ -259,11 +259,11 @@ if (!ast_strlen_zero(o->app)) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries); -- res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, NULL); -+ res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, 0, o->cid_num, o->cid_name, o->vars, NULL, NULL); +- res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL); ++ res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, 0, o->cid_num, o->cid_name, o->vars, o->account, NULL, NULL); } else { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries); -- res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, NULL); -+ res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, 0, o->cid_num, o->cid_name, o->vars, NULL, NULL); +- res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL); ++ res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, 0, o->cid_num, o->cid_name, o->vars, o->account, NULL, NULL); } if (res) { ast_log(LOG_NOTICE, "Call failed to go through, reason %d\n", reason); -diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c ---- asterisk-1.2.4.orig/pbx.c 2006-01-22 03:05:41.000000000 +0100 -+++ asterisk-1.2.4/pbx.c 2006-01-31 09:41:43.000000000 +0100 -@@ -350,7 +350,8 @@ +diff -urN asterisk-1.2.7.1.orig/pbx.c asterisk-1.2.7.1/pbx.c +--- asterisk-1.2.7.1.orig/pbx.c 2006-04-13 17:56:35.000000000 +0200 ++++ asterisk-1.2.7.1/pbx.c 2006-04-18 14:39:28.000000000 +0200 +@@ -353,7 +353,8 @@ { "Hangup", pbx_builtin_hangup, "Hang up the calling channel", @@ -11163,16 +12023,16 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c }, { "NoOp", pbx_builtin_noop, -@@ -1871,7 +1872,7 @@ +@@ -1880,7 +1881,7 @@ return ast_extension_state2(e); /* Check all devices in the hint */ } -void ast_hint_state_changed(const char *device) -+void ast_hint_state_changed(const char *device, const char *cid_num, const char *cid_name) ++void ast_hint_state_changed(const char *device, char *cid_num, char *cid_name) { struct ast_hint *hint; struct ast_state_cb *cblist; -@@ -1899,11 +1900,11 @@ +@@ -1908,11 +1909,11 @@ /* For general callbacks */ for (cblist = statecbs; cblist; cblist = cblist->next) @@ -11186,7 +12046,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c hint->laststate = state; break; -@@ -2144,7 +2145,7 @@ +@@ -2153,7 +2154,7 @@ /* Notify with -1 and remove all callbacks */ cbprev = cblist; cblist = cblist->next; @@ -11195,7 +12055,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c free(cbprev); } list->callbacks = NULL; -@@ -3758,7 +3759,7 @@ +@@ -3774,7 +3775,7 @@ while (thiscb) { prevcb = thiscb; thiscb = thiscb->next; @@ -11204,16 +12064,16 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c free(prevcb); } } else { -@@ -4957,7 +4958,7 @@ +@@ -4976,7 +4977,7 @@ return 0; /* success */ } --int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, struct ast_channel **channel) -+int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, struct ast_channel **channel, char *uniqueid) +-int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel) ++int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel, char *uniqueid) { struct ast_channel *chan; struct async_stat *as; -@@ -4967,7 +4968,7 @@ +@@ -4986,7 +4987,7 @@ if (sync) { LOAD_OH(oh); @@ -11222,7 +12082,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c if (channel) { *channel = chan; if (chan) -@@ -5063,7 +5064,7 @@ +@@ -5088,7 +5089,7 @@ goto outgoing_exten_cleanup; } memset(as, 0, sizeof(struct async_stat)); @@ -11231,7 +12091,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c if (channel) { *channel = chan; if (chan) -@@ -5105,7 +5106,7 @@ +@@ -5134,7 +5135,7 @@ pthread_t t; }; @@ -11240,16 +12100,16 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c { struct app_tmp *tmp = data; struct ast_app *app; -@@ -5121,7 +5122,7 @@ +@@ -5150,7 +5151,7 @@ return NULL; } --int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, struct ast_channel **locked_channel) -+int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, struct ast_channel **locked_channel, char *uniqueid) +-int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) ++int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, char *uniqueid) { struct ast_channel *chan; struct async_stat *as; -@@ -5140,7 +5141,7 @@ +@@ -5170,7 +5171,7 @@ goto outgoing_app_cleanup; } if (sync) { @@ -11258,7 +12118,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c if (chan) { if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); -@@ -5225,7 +5226,8 @@ +@@ -5257,7 +5258,8 @@ goto outgoing_app_cleanup; } memset(as, 0, sizeof(struct async_stat)); @@ -11268,7 +12128,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c if (!chan) { free(as); res = -1; -@@ -5510,6 +5512,9 @@ +@@ -5544,6 +5546,9 @@ */ static int pbx_builtin_hangup(struct ast_channel *chan, void *data) { @@ -11278,7 +12138,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c /* Just return non-zero and it will hang up */ if (!chan->hangupcause) chan->hangupcause = AST_CAUSE_NORMAL_CLEARING; -@@ -6151,6 +6156,9 @@ +@@ -6200,6 +6205,9 @@ return -1; } } @@ -11288,7 +12148,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options); } -@@ -6158,8 +6166,12 @@ +@@ -6207,8 +6215,12 @@ { int res = 0; @@ -11302,7 +12162,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c return res; } -@@ -6167,8 +6179,12 @@ +@@ -6216,8 +6228,12 @@ { int res = 0; @@ -11316,7 +12176,7 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c return res; } -@@ -6176,8 +6192,12 @@ +@@ -6225,8 +6241,12 @@ { int res = 0; @@ -11330,9 +12190,9 @@ diff -urN asterisk-1.2.4.orig/pbx.c asterisk-1.2.4/pbx.c return res; } -diff -urN asterisk-1.2.4.orig/res/Makefile asterisk-1.2.4/res/Makefile ---- asterisk-1.2.4.orig/res/Makefile 2005-11-29 19:24:39.000000000 +0100 -+++ asterisk-1.2.4/res/Makefile 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/res/Makefile asterisk-1.2.7.1/res/Makefile +--- asterisk-1.2.7.1.orig/res/Makefile 2005-11-29 19:24:39.000000000 +0100 ++++ asterisk-1.2.7.1/res/Makefile 2006-04-18 14:39:28.000000000 +0200 @@ -11,7 +11,7 @@ # the GNU General Public License # @@ -11342,9 +12202,9 @@ diff -urN asterisk-1.2.4.orig/res/Makefile asterisk-1.2.4/res/Makefile ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/odbcinst.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/odbcinst.h),) ifneq (${OSARCH},FreeBSD) -diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c ---- asterisk-1.2.4.orig/res/res_agi.c 2005-12-20 21:21:26.000000000 +0100 -+++ asterisk-1.2.4/res/res_agi.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/res/res_agi.c asterisk-1.2.7.1/res/res_agi.c +--- asterisk-1.2.7.1.orig/res/res_agi.c 2006-02-28 19:31:04.000000000 +0100 ++++ asterisk-1.2.7.1/res/res_agi.c 2006-04-18 14:39:28.000000000 +0200 @@ -11,6 +11,9 @@ * the project provides a web site, mailing lists and IRC * channels for your use. @@ -11376,18 +12236,16 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c "program on a channel. AGI allows Asterisk to launch external programs\n" "written in any language to control a telephony channel, play audio,\n" "read DTMF digits, etc. by communicating with the AGI protocol on stdin\n" -@@ -91,7 +97,9 @@ - "Returns -1 on hangup (except for DeadAGI) or if application requested\n" +@@ -92,6 +98,8 @@ " hangup, or 0 on non-hangup exit. \n" - "Using 'EAGI' provides enhanced AGI, with incoming audio available out of band" --"on file descriptor 3\n\n" -+" on file descriptor 3\n" + "Using 'EAGI' provides enhanced AGI, with incoming audio available out of band\n" + "on file descriptor 3\n\n" +"Using 'XAGI' provides enhanced AGI, with incoming audio available out of band" +" on file descriptor 3 and outgoing audio available out of band on file descriptor 4\n\n" "Use the CLI command 'show agi' to list available agi commands\n"; static int agidebug = 0; -@@ -214,13 +222,14 @@ +@@ -220,13 +228,14 @@ return 0; } @@ -11403,7 +12261,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c int x; int res; sigset_t signal_set; -@@ -265,6 +274,33 @@ +@@ -271,6 +280,33 @@ return -1; } } @@ -11437,7 +12295,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c pid = fork(); if (pid < 0) { ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); -@@ -279,15 +315,19 @@ +@@ -285,15 +321,19 @@ } else { close(STDERR_FILENO + 1); } @@ -11459,7 +12317,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c close(x); /* Don't run AGI scripts with realtime priority -- it causes audio stutter */ -@@ -306,6 +346,9 @@ +@@ -312,6 +352,9 @@ if (efd) { *efd = audio[1]; } @@ -11469,7 +12327,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c /* close what we're not using in the parent */ close(toast[1]); close(fromast[0]); -@@ -314,6 +357,9 @@ +@@ -320,6 +363,9 @@ /* [PHM 12/18/03] */ close(audio[0]); } @@ -11479,7 +12337,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c *opid = pid; return 0; -@@ -344,7 +390,7 @@ +@@ -350,7 +396,7 @@ fdprintf(fd, "agi_context: %s\n", chan->context); fdprintf(fd, "agi_extension: %s\n", chan->exten); fdprintf(fd, "agi_priority: %d\n", chan->priority); @@ -11488,7 +12346,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c /* User information */ fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : ""); -@@ -376,7 +422,7 @@ +@@ -382,7 +428,7 @@ return RESULT_SHOWUSAGE; if (sscanf(argv[3], "%d", &to) != 1) return RESULT_SHOWUSAGE; @@ -11497,7 +12355,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c fdprintf(agi->fd, "200 result=%d\n", res); if (res >= 0) return RESULT_SUCCESS; -@@ -552,7 +598,7 @@ +@@ -558,7 +604,7 @@ else return RESULT_FAILURE; } @@ -11506,7 +12364,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c /* this is to check for if ast_waitstream closed the stream, we probably are at * the end of the stream, return that amount, else check for the amount */ sample_offset = (chan->stream) ? ast_tellstream(fs) : max_length; -@@ -612,7 +658,7 @@ +@@ -618,7 +664,7 @@ else return RESULT_FAILURE; } @@ -11515,7 +12373,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c /* this is to check for if ast_waitstream closed the stream, we probably are at * the end of the stream, return that amount, else check for the amount */ sample_offset = (chan->stream)?ast_tellstream(fs):max_length; -@@ -624,7 +670,7 @@ +@@ -630,7 +676,7 @@ /* If the user didnt press a key, wait for digitTimeout*/ if (res == 0 ) { @@ -11524,7 +12382,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c /* Make sure the new result is in the escape digits of the GET OPTION */ if ( !strchr(edigits,res) ) res=0; -@@ -651,7 +697,7 @@ +@@ -657,7 +703,7 @@ return RESULT_SHOWUSAGE; if (sscanf(argv[2], "%d", &num) != 1) return RESULT_SHOWUSAGE; @@ -11533,7 +12391,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c if (res == 1) return RESULT_SUCCESS; fdprintf(agi->fd, "200 result=%d\n", res); -@@ -671,7 +717,7 @@ +@@ -677,7 +723,7 @@ if (sscanf(argv[2], "%d", &num) != 1) return RESULT_SHOWUSAGE; @@ -11542,7 +12400,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c if (res == 1) /* New command */ return RESULT_SUCCESS; fdprintf(agi->fd, "200 result=%d\n", res); -@@ -688,7 +734,7 @@ +@@ -694,7 +740,7 @@ if (argc != 4) return RESULT_SHOWUSAGE; @@ -11551,7 +12409,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c if (res == 1) /* New command */ return RESULT_SUCCESS; fdprintf(agi->fd, "200 result=%d\n", res); -@@ -778,7 +824,7 @@ +@@ -784,7 +830,7 @@ if (argc != 4) return RESULT_SHOWUSAGE; @@ -11560,7 +12418,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c if (res == 1) /* New command */ return RESULT_SUCCESS; fdprintf(agi->fd, "200 result=%d\n", res); -@@ -805,7 +851,7 @@ +@@ -811,7 +857,7 @@ max = atoi(argv[4]); else max = 1024; @@ -11569,7 +12427,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c if (res == 2) /* New command */ return RESULT_SUCCESS; else if (res == 1) -@@ -1843,7 +1889,12 @@ +@@ -1849,7 +1895,12 @@ int ms; int returnstatus = 0; struct ast_frame *f; @@ -11582,7 +12440,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c FILE *readf; /* how many times we'll retry if ast_waitfor_nandfs will return without either channel or file descriptor in case select is interrupted by a system call (EINTR) */ -@@ -1857,10 +1908,22 @@ +@@ -1863,10 +1914,22 @@ return -1; } setlinebuf(readf); @@ -11607,7 +12465,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c if (c) { retry = RETRY; /* Idle the channel until we get a command */ -@@ -1871,13 +1934,24 @@ +@@ -1877,13 +1940,24 @@ break; } else { /* If it's voice, write it to the audio pipe */ @@ -11634,7 +12492,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c retry = RETRY; if (!fgets(buf, sizeof(buf), readf)) { /* Program terminated */ -@@ -1899,6 +1973,7 @@ +@@ -1905,6 +1979,7 @@ if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) { break; } @@ -11642,7 +12500,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c } else { if (--retry <= 0) { ast_log(LOG_WARNING, "No channel, no fd?\n"); -@@ -2005,6 +2080,7 @@ +@@ -2011,6 +2086,7 @@ int argc = 0; int fds[2]; int efd = -1; @@ -11650,7 +12508,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c int pid; char *stringp; AGI agi; -@@ -2030,15 +2106,18 @@ +@@ -2036,15 +2112,18 @@ } } #endif @@ -11671,7 +12529,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c } LOCAL_USER_REMOVE(u); return res; -@@ -2072,6 +2151,35 @@ +@@ -2078,6 +2157,35 @@ return res; } @@ -11707,7 +12565,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c static int deadagi_exec(struct ast_channel *chan, void *data) { return agi_exec_full(chan, data, 0, 1); -@@ -2101,6 +2209,7 @@ +@@ -2107,6 +2215,7 @@ ast_cli_unregister(&dumpagihtml); ast_cli_unregister(&cli_debug); ast_cli_unregister(&cli_no_debug); @@ -11715,7 +12573,7 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c ast_unregister_application(eapp); ast_unregister_application(deadapp); return ast_unregister_application(app); -@@ -2114,6 +2223,7 @@ +@@ -2120,6 +2229,7 @@ ast_cli_register(&cli_no_debug); ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip); ast_register_application(eapp, eagi_exec, esynopsis, descrip); @@ -11723,9 +12581,9 @@ diff -urN asterisk-1.2.4.orig/res/res_agi.c asterisk-1.2.4/res/res_agi.c return ast_register_application(app, agi_exec, synopsis, descrip); } -diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features.c ---- asterisk-1.2.4.orig/res/res_features.c 2006-01-17 19:29:57.000000000 +0100 -+++ asterisk-1.2.4/res/res_features.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/res/res_features.c asterisk-1.2.7.1/res/res_features.c +--- asterisk-1.2.7.1.orig/res/res_features.c 2006-04-10 19:29:51.000000000 +0200 ++++ asterisk-1.2.7.1/res/res_features.c 2006-04-18 14:39:28.000000000 +0200 @@ -11,6 +11,10 @@ * the project provides a web site, mailing lists and IRC * channels for your use. @@ -11844,7 +12702,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features "CallerID: %s\r\n" "CallerIDName: %s\r\n" + "Unqiueid: %s\r\n\r\n" - ,pu->parkingnum, pu->chan->name, peer->name + ,pu->parkingnum, pu->chan->name, peer ? peer->name : "" ,(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL) ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "") - ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "") @@ -11921,7 +12779,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features ast_set_callerid(chan, cid_num, cid_name, cid_num); ast_channel_inherit_variables(caller, chan); if (!ast_call(chan, data, timeout)) { -@@ -1538,9 +1616,10 @@ +@@ -1541,9 +1619,10 @@ "Channel: %s\r\n" "CallerID: %s\r\n" "CallerIDName: %s\r\n" @@ -11933,7 +12791,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features ); if (option_verbose > 1) -@@ -1583,9 +1662,10 @@ +@@ -1586,9 +1665,10 @@ "Channel: %s\r\n" "CallerID: %s\r\n" "CallerIDName: %s\r\n" @@ -11945,7 +12803,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features ); /* There's a problem, hang them up*/ -@@ -1672,6 +1752,280 @@ +@@ -1675,6 +1755,280 @@ return res; } @@ -12226,7 +13084,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features static int park_exec(struct ast_channel *chan, void *data) { int res=0; -@@ -1720,9 +2074,10 @@ +@@ -1723,9 +2077,10 @@ "From: %s\r\n" "CallerID: %s\r\n" "CallerIDName: %s\r\n" @@ -12238,7 +13096,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features ); free(pu); -@@ -1890,12 +2245,13 @@ +@@ -1893,12 +2248,13 @@ "Timeout: %ld\r\n" "CallerID: %s\r\n" "CallerIDName: %s\r\n" @@ -12253,7 +13111,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features ,idText); cur = cur->next; -@@ -1911,6 +2267,386 @@ +@@ -1914,6 +2270,386 @@ return RESULT_SUCCESS; } @@ -12640,7 +13498,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features int ast_pickup_call(struct ast_channel *chan) { -@@ -2064,7 +2800,7 @@ +@@ -2068,7 +2804,7 @@ } { @@ -12649,7 +13507,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features int mallocd=0; if (!feature) { -@@ -2140,14 +2876,22 @@ +@@ -2144,14 +2880,22 @@ if ((res = load_config())) return res; ast_cli_register(&showparked); @@ -12672,7 +13530,7 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features return res; } -@@ -2158,7 +2902,11 @@ +@@ -2162,7 +2906,11 @@ ast_manager_unregister("ParkedCalls"); ast_cli_unregister(&showfeatures); @@ -12684,10 +13542,10 @@ diff -urN asterisk-1.2.4.orig/res/res_features.c asterisk-1.2.4/res/res_features ast_unregister_application(parkcall); return ast_unregister_application(parkedcall); } -diff -urN asterisk-1.2.4.orig/res/res_watchdog.c asterisk-1.2.4/res/res_watchdog.c ---- asterisk-1.2.4.orig/res/res_watchdog.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-1.2.4/res/res_watchdog.c 2006-01-31 09:41:43.000000000 +0100 -@@ -0,0 +1,148 @@ +diff -urN asterisk-1.2.7.1.orig/res/res_watchdog.c asterisk-1.2.7.1/res/res_watchdog.c +--- asterisk-1.2.7.1.orig/res/res_watchdog.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-1.2.7.1/res/res_watchdog.c 2006-04-24 09:39:12.000000000 +0200 +@@ -0,0 +1,149 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * @@ -12815,6 +13673,7 @@ diff -urN asterisk-1.2.4.orig/res/res_watchdog.c asterisk-1.2.4/res/res_watchdog + dogs = watchdogs; + while (dogs) { + pthread_cancel(dogs->watchdog_thread); ++ close(dogs->fd); + woof = dogs->next; + free(dogs); + dogs = woof; @@ -12836,9 +13695,9 @@ diff -urN asterisk-1.2.4.orig/res/res_watchdog.c asterisk-1.2.4/res/res_watchdog +{ + return ASTERISK_GPL_KEY; +} -diff -urN asterisk-1.2.4.orig/rtp.c asterisk-1.2.4/rtp.c ---- asterisk-1.2.4.orig/rtp.c 2005-11-30 15:27:59.000000000 +0100 -+++ asterisk-1.2.4/rtp.c 2006-01-31 09:41:43.000000000 +0100 +diff -urN asterisk-1.2.7.1.orig/rtp.c asterisk-1.2.7.1/rtp.c +--- asterisk-1.2.7.1.orig/rtp.c 2006-03-15 19:07:06.000000000 +0100 ++++ asterisk-1.2.7.1/rtp.c 2006-04-18 14:39:28.000000000 +0200 @@ -442,6 +442,11 @@ struct rtpPayloadType rtpPT; diff --git a/src/patches/asterisk-1.2.4-libpri-bristuff-0.3.0-PRE-1l.patch b/src/patches/libpri.patch similarity index 90% rename from src/patches/asterisk-1.2.4-libpri-bristuff-0.3.0-PRE-1l.patch rename to src/patches/libpri.patch index a74496406f..ae61c78c26 100644 --- a/src/patches/asterisk-1.2.4-libpri-bristuff-0.3.0-PRE-1l.patch +++ b/src/patches/libpri.patch @@ -62,8 +62,17 @@ diff -urN libpri-1.2.2.orig/TODO libpri-1.2.2/TODO +-- more facilities diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h --- libpri-1.2.2.orig/libpri.h 2005-11-29 19:39:18.000000000 +0100 -+++ libpri-1.2.2/libpri.h 2006-01-18 12:28:07.000000000 +0100 -@@ -26,8 +26,12 @@ ++++ libpri-1.2.2/libpri.h 2006-04-15 21:56:47.000000000 +0200 +@@ -5,6 +5,8 @@ + * + * Copyright (C) 2001, Linux Support Services, Inc. + * All Rights Reserved. ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -26,8 +28,12 @@ #define _LIBPRI_H /* Node types */ @@ -77,7 +86,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h /* Debugging */ #define PRI_DEBUG_Q921_RAW (1 << 0) /* Show raw HDLC frames */ -@@ -76,6 +80,12 @@ +@@ -76,6 +82,12 @@ #define PRI_EVENT_NOTIFY 16 /* Notification received */ #define PRI_EVENT_PROGRESS 17 /* When we get CALL_PROCEEDING or PROGRESS */ #define PRI_EVENT_KEYPAD_DIGIT 18 /* When we receive during ACTIVE state */ @@ -90,7 +99,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h /* Simple states */ #define PRI_STATE_DOWN 0 -@@ -250,11 +260,13 @@ +@@ -250,11 +262,13 @@ #define PRI_NSF_ATT_MULTIQUEST 0xF0 #define PRI_NSF_CALL_REDIRECTION_SERVICE 0xF7 @@ -104,7 +113,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h } pri_event_generic; typedef struct pri_event_error { -@@ -273,18 +285,19 @@ +@@ -273,18 +287,19 @@ int cref; int progress; int progressmask; @@ -126,7 +135,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h } pri_event_answer; typedef struct pri_event_facname { -@@ -302,26 +315,29 @@ +@@ -302,32 +317,37 @@ int e; int channel; /* Channel requested */ int callingpres; /* Presentation of Calling CallerID */ @@ -165,7 +174,15 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h int progress; int progressmask; char origcalledname[256]; -@@ -335,6 +351,8 @@ + char origcallednum[256]; + int callingplanorigcalled; /* Dialing plan of Originally Called Number */ + int origredirectingreason; ++ char lowlayercompat[16]; ++ char highlayercompat[4]; + } pri_event_ring; + + typedef struct pri_event_hangup { +@@ -335,6 +355,8 @@ int channel; /* Channel requested */ int cause; int cref; @@ -174,7 +191,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h q931_call *call; /* Opaque call pointer */ long aoc_units; /* Advise of Charge number of charged units */ char useruserinfo[260]; /* User->User info */ -@@ -359,6 +377,7 @@ +@@ -359,6 +381,7 @@ typedef struct pri_event_setup_ack { int e; int channel; @@ -182,7 +199,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h } pri_event_setup_ack; typedef struct pri_event_notify { -@@ -374,20 +393,80 @@ +@@ -374,20 +397,80 @@ char digits[64]; } pri_event_keypad_digit; @@ -264,7 +281,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h pri_event_keypad_digit digit; /* Digits that come during a call */ } pri_event; -@@ -402,7 +481,9 @@ +@@ -402,7 +485,9 @@ channel operating in HDLC mode with FCS computed by the fd's driver. Also it must be NON-BLOCKING! Frames received on the fd should include FCS. Nodetype must be one of PRI_NETWORK or PRI_CPE. switchtype should be PRI_SWITCH_* */ @@ -275,7 +292,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h /* Create D-channel just as above with user defined I/O callbacks and data */ extern struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata); -@@ -426,6 +507,9 @@ +@@ -426,6 +511,9 @@ /* Enable transmission support of Facility IEs on the pri */ extern void pri_facility_enable(struct pri *pri); @@ -285,7 +302,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h /* Run PRI on the given D-channel, taking care of any events that need to be handled. If block is set, it will block until an event occurs which needs to be handled */ -@@ -462,6 +546,12 @@ +@@ -462,6 +550,12 @@ /* Send a digit in overlap mode */ extern int pri_information(struct pri *pri, q931_call *call, char digit); @@ -298,7 +315,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h /* Answer the incomplete(call without called number) call on the given channel. Set non-isdn to non-zero if you are not connecting to ISDN equipment */ extern int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn); -@@ -470,6 +560,35 @@ +@@ -470,6 +564,35 @@ Set non-isdn to non-zero if you are not connecting to ISDN equipment */ extern int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn); @@ -334,7 +351,33 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h /* Set CRV reference for GR-303 calls */ -@@ -525,7 +644,6 @@ +@@ -478,14 +601,14 @@ + + /* backwards compatibility for those who don't use asterisk with libpri */ + #define pri_release(a,b,c) \ +- pri_hangup(a,b,c) ++ pri_hangup(a,b,c, -1) + + #define pri_disconnect(a,b,c) \ +- pri_hangup(a,b,c) ++ pri_hangup(a,b,c, -1) + + /* Hangup a call */ + #define PRI_HANGUP +-extern int pri_hangup(struct pri *pri, q931_call *call, int cause); ++extern int pri_hangup(struct pri *pri, q931_call *call, int cause, int aocunits); + + #define PRI_DESTROYCALL + extern void pri_destroycall(struct pri *pri, q931_call *call); +@@ -518,14 +641,13 @@ + extern void pri_sr_free(struct pri_sr *sr); + + extern int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn); +-extern int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1); ++extern int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1, char *llc); + extern int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete); + extern int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres); + extern int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason); #define PRI_USER_USER_TX /* Set the user user field. Warning! don't send binary data accross this field */ extern void pri_sr_set_useruser(struct pri_sr *sr, char *userchars); @@ -342,7 +385,7 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h extern void pri_call_set_useruser(q931_call *sr, char *userchars); extern int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req); -@@ -546,8 +664,8 @@ +@@ -546,8 +668,8 @@ /* Override message and error stuff */ #define PRI_NEW_SET_API @@ -355,8 +398,8 @@ diff -urN libpri-1.2.2.orig/libpri.h libpri-1.2.2/libpri.h #define PRI_SET_OVERLAPDIAL diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c --- libpri-1.2.2.orig/pri.c 2005-11-29 19:39:18.000000000 +0100 -+++ libpri-1.2.2/pri.c 2006-01-18 12:28:07.000000000 +0100 -@@ -1,24 +1,12 @@ ++++ libpri-1.2.2/pri.c 2006-04-15 21:57:09.000000000 +0200 +@@ -1,24 +1,14 @@ /* * libpri: An implementation of Primary Rate ISDN * @@ -365,7 +408,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c * - * Copyright (C) 2001-2005, Digium - * All Rights Reserved. -+ * This program is confidential ++ * This program is confidential ( <- I dont think so! ) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by @@ -382,10 +425,12 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Copyright (C) 2001, Linux Support Services, Inc. + * All Rights Reserved. ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns * */ -@@ -48,6 +36,14 @@ +@@ -48,6 +38,14 @@ return "Network"; case PRI_CPE: return "CPE"; @@ -400,7 +445,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c default: return "Invalid value"; } -@@ -187,7 +183,7 @@ +@@ -187,7 +185,7 @@ return res; } @@ -409,7 +454,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c { struct pri *p; p = malloc(sizeof(struct pri)); -@@ -207,6 +203,8 @@ +@@ -207,6 +205,8 @@ p->master = master; p->callpool = &p->localpool; pri_default_timers(p, switchtype); @@ -418,7 +463,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c #ifdef LIBPRI_COUNTERS p->q921_rxcount = 0; p->q921_txcount = 0; -@@ -217,7 +215,7 @@ +@@ -217,7 +217,7 @@ p->protodisc = GR303_PROTOCOL_DISCRIMINATOR; p->sapi = Q921_SAPI_GR303_EOC; p->tei = Q921_TEI_GR303_EOC_OPS; @@ -427,7 +472,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c if (!p->subchannel) { free(p); p = NULL; -@@ -226,7 +224,7 @@ +@@ -226,7 +226,7 @@ p->protodisc = GR303_PROTOCOL_DISCRIMINATOR; p->sapi = Q921_SAPI_GR303_TMC_CALLPROC; p->tei = Q921_TEI_GR303_TMC_CALLPROC; @@ -436,7 +481,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c if (!p->subchannel) { free(p); p = NULL; -@@ -242,7 +240,7 @@ +@@ -242,7 +242,7 @@ } /* Start Q.921 layer, Wait if we're the network */ if (p) @@ -445,7 +490,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c } return p; } -@@ -262,15 +260,16 @@ +@@ -262,15 +262,16 @@ { /* Restart Q.921 layer */ if (pri) { @@ -466,7 +511,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c } struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata) -@@ -279,7 +278,7 @@ +@@ -279,7 +280,7 @@ io_read = __pri_read; if (!io_write) io_write = __pri_write; @@ -475,16 +520,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c } void *pri_get_userdata(struct pri *pri) -@@ -385,7 +384,7 @@ - { - /* Return a configuration error */ - pri->ev.err.e = PRI_EVENT_CONFIG_ERR; -- libpri_copy_string(pri->ev.err.err, errstr, sizeof(pri->ev.err.err)); -+ strncpy(pri->ev.err.err, errstr, sizeof(pri->ev.err.err) - 1); - return &pri->ev; - } - -@@ -443,6 +442,15 @@ +@@ -443,6 +444,15 @@ return; } @@ -500,7 +536,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info) { if (!pri || !call) -@@ -478,6 +486,21 @@ +@@ -478,6 +488,21 @@ return q931_notify(pri, call, channel, info); } @@ -522,7 +558,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c void pri_destroycall(struct pri *pri, q931_call *call) { if (pri && call) -@@ -499,6 +522,76 @@ +@@ -499,6 +524,76 @@ return q931_connect(pri, call, channel, nonisdn); } @@ -599,9 +635,12 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c #if 0 /* deprecated routines, use pri_hangup */ int pri_release(struct pri *pri, q931_call *call, int cause) -@@ -543,12 +636,29 @@ +@@ -541,14 +636,35 @@ + return 0; + } - int pri_hangup(struct pri *pri, q931_call *call, int cause) +-int pri_hangup(struct pri *pri, q931_call *call, int cause) ++int pri_hangup(struct pri *pri, q931_call *call, int cause, int aocunits) { + int res=0; if (!pri || !call) @@ -615,6 +654,10 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c + cause = 16; + } + ++ if (aocunits > -1) { ++ call->aoc_units = aocunits; ++ } ++ + if (pri->localtype == BRI_NETWORK_PTMP) { + res = q921_hangup(pri, call, 127); + if (res) { @@ -630,7 +673,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c } int pri_reset(struct pri *pri, int channel) -@@ -688,15 +798,15 @@ +@@ -688,15 +804,15 @@ return q931_setup(pri, c, &req); } @@ -650,7 +693,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c { __pri_error = func; } -@@ -708,10 +818,14 @@ +@@ -708,10 +824,14 @@ va_start(ap, fmt); vsnprintf(tmp, sizeof(tmp), fmt, ap); va_end(ap); @@ -669,7 +712,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c } void pri_error(struct pri *pri, char *fmt, ...) -@@ -721,10 +835,14 @@ +@@ -721,10 +841,14 @@ va_start(ap, fmt); vsnprintf(tmp, sizeof(tmp), fmt, ap); va_end(ap); @@ -688,7 +731,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c } /* Set overlap mode */ -@@ -765,11 +883,13 @@ +@@ -765,11 +889,13 @@ } len += sprintf(buf + len, "Q921 Outstanding: %d\n", q921outstanding); #endif @@ -707,7 +750,7 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c len += sprintf(buf + len, "Overlap Dial: %d\n", pri->overlapdial); len += sprintf(buf + len, "T200 Timer: %d\n", pri->timers[PRI_TIMER_T200]); len += sprintf(buf + len, "T203 Timer: %d\n", pri->timers[PRI_TIMER_T203]); -@@ -778,6 +898,7 @@ +@@ -778,6 +904,7 @@ len += sprintf(buf + len, "T313 Timer: %d\n", pri->timers[PRI_TIMER_T313]); len += sprintf(buf + len, "N200 Counter: %d\n", pri->timers[PRI_TIMER_N200]); @@ -715,7 +758,20 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c return strdup(buf); } -@@ -851,3 +972,10 @@ +@@ -819,10 +946,11 @@ + return 0; + } + +-int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1) ++int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1, char *llc) + { + sr->transmode = transmode; + sr->userl1 = userl1; ++ sr->llc = llc; + return 0; + } + +@@ -851,3 +979,10 @@ sr->redirectingreason = reason; return 0; } @@ -728,8 +784,8 @@ diff -urN libpri-1.2.2.orig/pri.c libpri-1.2.2/pri.c +} diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c --- libpri-1.2.2.orig/pri_facility.c 2005-11-29 19:39:18.000000000 +0100 -+++ libpri-1.2.2/pri_facility.c 2006-01-19 11:55:21.000000000 +0100 -@@ -1,26 +1,13 @@ ++++ libpri-1.2.2/pri_facility.c 2006-04-15 21:56:10.000000000 +0200 +@@ -1,26 +1,17 @@ -/* - * libpri: An implementation of Primary Rate ISDN - * @@ -762,11 +818,15 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c + + by Matthew Fredrickson + Copyright (C) 2004-2005 Digium, Inc ++ ++ Copyright (C) 2005-2006 Junghanns.NET GmbH ++ Klaus-Peter Junghanns ++ +*/ #include "compat.h" #include "libpri.h" -@@ -208,9 +195,9 @@ +@@ -208,9 +199,9 @@ if (datalen > buflen) { /* Truncate */ datalen = buflen; @@ -778,7 +838,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c } int asn1_string_encode(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len) -@@ -305,7 +292,7 @@ +@@ -305,12 +296,55 @@ return -1; value->ton = ton; @@ -787,7 +847,55 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c } while(0); return -1; -@@ -375,11 +362,10 @@ + } + ++static int rose_cd_destination_decode(struct pri *pri, q931_call *call, unsigned char *data, int len) ++{ ++ unsigned char *vdata = data; ++ struct rose_component *comp1 = NULL, *comp2 = NULL; ++ int pos1 = 0, pos2, sublen2; ++ ++ if (pri->debug & PRI_DEBUG_AOC) ++ dump_apdu (pri, data, len); ++ ++ do { ++ GET_COMPONENT(comp1, pos1, vdata, len); ++ CHECK_COMPONENT(comp1, ASN1_SEQUENCE, "!! Invalid CD destination argument. Expected Sequence (0x30) but Received 0x%02X\n"); ++ SUB_COMPONENT(comp1, pos1); ++ GET_COMPONENT(comp1, pos1, vdata, len); ++ switch (comp1->type) { ++ case (ASN1_SEQUENCE | ASN1_CONSTRUCTOR): ++ sublen2 = comp1->len; ++ pos2 = pos1; ++ comp2 = comp1; ++ SUB_COMPONENT(comp2, pos2); ++ do { ++ GET_COMPONENT(comp2, pos2, vdata, len); ++ switch (comp2->type) { ++ case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0): ++ memcpy(call->redirectingnum, comp2->data, comp2->len); ++ call->redirectingnum[comp2->len] = '\0'; ++ return 0; ++ break; ++ default: ++ pri_message(pri, "!! Don't know how to handle 0x%02X in CD destination argument\n", comp2->type); ++ } ++ NEXT_COMPONENT(comp2, pos2); ++ } while (pos2 < sublen2); ++ break; ++ default: ++ pri_message(pri, "!! Invalid CD destination argument. Expected Sequence (0x30) or Object Identifier (0x81/0x01) but received 0x%02X\n", comp1->type); ++ } ++ NEXT_COMPONENT(comp1, pos1); ++ } while (pos1 < len); ++ ++ return 0; ++} ++ + static int rose_address_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value) + { + int i = 0; +@@ -375,11 +409,10 @@ pri_message(pri, "!! Unknown Party number component received 0x%X\n", comp->type); return -1; } @@ -800,7 +908,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c } while (0); -@@ -389,7 +375,6 @@ +@@ -389,7 +422,6 @@ static int rose_presented_number_unscreened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value) { int i = 0; @@ -808,7 +916,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c struct rose_component *comp = NULL; unsigned char *vdata = data; -@@ -404,9 +389,7 @@ +@@ -404,9 +436,7 @@ switch(comp->type) { case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* [0] presentationAllowedNumber */ value->pres = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; @@ -819,7 +927,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1): /* [1] IMPLICIT presentationRestricted */ if (comp->len != 0) { /* must be NULL */ pri_error(pri, "!! Invalid PresentationRestricted component received (len != 0)\n"); -@@ -423,9 +406,7 @@ +@@ -423,9 +453,7 @@ return 2; case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): /* [3] presentationRestrictedNumber */ value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED; @@ -830,7 +938,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c default: pri_message(pri, "Invalid PresentedNumberUnscreened component 0x%X\n", comp->type); } -@@ -436,7 +417,7 @@ +@@ -436,7 +464,7 @@ return -1; } @@ -839,7 +947,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c { int i = 0; int diversion_counter; -@@ -445,21 +426,9 @@ +@@ -445,21 +473,9 @@ struct addressingdataelements_presentednumberunscreened divertingnr; struct addressingdataelements_presentednumberunscreened originalcallednr; struct rose_component *comp = NULL; @@ -862,7 +970,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c do { /* diversionCounter stuff */ GET_COMPONENT(comp, i, vdata, len); -@@ -477,20 +446,18 @@ +@@ -477,20 +493,18 @@ if(pri->debug & PRI_DEBUG_APDU) pri_message(pri, " Redirection reason: %d, total diversions: %d\n", diversion_reason, diversion_counter); @@ -886,7 +994,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c comp->len = res; if (res < 0) return -1; -@@ -499,64 +466,62 @@ +@@ -499,43 +513,33 @@ pri_message(pri, " ton = %d, pres = %d, npi = %d\n", divertingnr.ton, divertingnr.pres, divertingnr.npi); } break; @@ -937,29 +1045,18 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c if (divertingnr.pres >= 0) { call->redirectingplan = divertingnr.npi; - call->redirectingpres = divertingnr.pres; - call->redirectingreason = diversion_reason; -- libpri_copy_string(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum)); -+ strncpy(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum)-1); -+ call->redirectingnum[sizeof(call->redirectingnum)-1] = '\0'; - } - if (originalcallednr.pres >= 0) { - call->origcalledplan = originalcallednr.npi; +@@ -548,15 +552,19 @@ call->origcalledpres = originalcallednr.pres; -- libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum)); -+ strncpy(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum)-1); -+ call->origcallednum[sizeof(call->origcallednum)-1] = '\0'; -+ } -+ if (strlen(redirectingname) > 0) { -+ strncpy(call->redirectingname, redirectingname, sizeof(call->redirectingname)); -+ call->redirectingname[sizeof(call->redirectingname)-1] = '\0'; -+ } -+ if (strlen(origcalledname) > 0) { -+ strncpy(call->origcalledname, origcalledname, sizeof(call->origcalledname)); -+ call->origcalledname[sizeof(call->origcalledname)-1] = '\0'; + libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum)); } - libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname)); - libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname)); ++ if (strlen(redirectingname) > 0) { ++ libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname)); ++ } ++ if (strlen(origcalledname) > 0) { ++ libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname)); ++ } return 0; } while (0); @@ -971,7 +1068,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c static int rose_diverting_leg_information2_encode(struct pri *pri, q931_call *call) { int i = 0, j, compsp = 0; -@@ -694,6 +659,64 @@ +@@ -694,6 +702,64 @@ return 0; } @@ -1036,15 +1133,51 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c /* Sending callername information functions */ static int add_callername_facility_ies(struct pri *pri, q931_call *c, int cpe) { -@@ -1132,6 +1155,7 @@ - int operation_tag; - unsigned char *vdata = data; - struct rose_component *comp = NULL, *invokeid = NULL, *operationid = NULL; -+ struct addressingdataelements_presentednumberunscreened value; - - do { - /* Invoke ID stuff */ -@@ -1148,13 +1172,15 @@ +@@ -936,7 +1002,7 @@ + CHECK_COMPONENT(comp, ASN1_ENUMERATED, "!! Invalid AOC Charging Request argument. Expected Enumerated (0x0A) but Received 0x%02X\n"); + ASN1_GET_INTEGER(comp, chargingcase); + if (chargingcase >= 0 && chargingcase <= 2) { +- if (pri->debug & PRI_DEBUG_APDU) ++// if (pri->debug & PRI_DEBUG_APDU) + pri_message(pri, "Channel %d/%d, Call %d - received AOC charging request - charging case: %i\n", + call->ds1no, call->channelno, call->cr, chargingcase); + } else { +@@ -1054,7 +1120,7 @@ + return 0; + } + +-static int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long chargedunits) ++int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long chargedunits, int msgtype) + { + /* sample data: [ 91 a1 12 02 02 3a 78 02 01 24 30 09 30 07 a1 05 30 03 02 01 01 ] */ + int i = 0, res = 0, compsp = 0; +@@ -1108,18 +1174,20 @@ + dump_apdu (pri, buffer, i); + + /* code below is untested */ +- res = pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL); ++ res = pri_call_apdu_queue(c, msgtype, buffer, i, NULL, NULL); + if (res) { + pri_message(pri, "Could not queue ADPU in facility message\n"); + return -1; + } + +- /* Remember that if we queue a facility IE for a facility message we +- * have to explicitly send the facility message ourselves */ +- res = q931_facility(c->pri, c); +- if (res) { ++ if (msgtype == Q931_FACILITY) { ++ /* Remember that if we queue a facility IE for a facility message we ++ * have to explicitly send the facility message ourselves */ ++ res = q931_facility(c->pri, c); ++ if (res) { + pri_message(pri, "Could not schedule facility message for call %d\n", c->cr); + return -1; ++ } + } + + return 0; +@@ -1148,13 +1216,15 @@ NEXT_COMPONENT(comp, i); /* No argument - return with error */ @@ -1065,7 +1198,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, " [ Handling operation %d ]\n", operation_tag); -@@ -1178,7 +1204,11 @@ +@@ -1178,7 +1248,11 @@ case ROSE_DIVERTING_LEG_INFORMATION2: if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, " Handle DivertingLegInformation2\n"); @@ -1078,44 +1211,49 @@ diff -urN libpri-1.2.2.orig/pri_facility.c libpri-1.2.2/pri_facility.c case ROSE_AOC_NO_CHARGING_INFO_AVAILABLE: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "ROSE %i: AOC No Charging Info Available - not handled!", operation_tag); -@@ -1229,6 +1259,34 @@ +@@ -1206,6 +1280,7 @@ + } + return -1; + case ROSE_AOC_AOCD_CHARGING_UNIT: ++// return aoc_aoce_charging_unit_decode(pri, call, (u_int8_t *)comp, comp->len + 2); + if (pri->debug & PRI_DEBUG_APDU) { + pri_message(pri, "ROSE %i: AOC-D Charging Unit - not handled!", operation_tag); + dump_apdu (pri, (u_int8_t *)comp, comp->len + 2); +@@ -1220,7 +1295,7 @@ + case ROSE_AOC_AOCE_CHARGING_UNIT: + return aoc_aoce_charging_unit_decode(pri, call, (u_int8_t *)comp, comp->len + 2); + if (0) { /* the following function is currently not used - just to make the compiler happy */ +- aoc_aoce_charging_unit_encode(pri, call, call->aoc_units); /* use this function to forward the aoc-e on a bridged channel */ ++ aoc_aoce_charging_unit_encode(pri, call, call->aoc_units, 1); /* use this function to forward the aoc-e on a bridged channel */ + return 0; + } + case ROSE_AOC_IDENTIFICATION_OF_CHARGE: +@@ -1229,6 +1304,22 @@ dump_apdu (pri, (u_int8_t *)comp, comp->len + 2); } return -1; + case ROSE_CALLDEFLECTION: -+ // if (pri->debug & PRI_DEBUG_APDU) { -+ pri_message(pri, "ROSE %i: CD - not handled!", operation_tag); -+ dump_apdu (pri, comp->data, comp->len); -+ rose_public_party_number_decode(pri, call, comp->data + 2 , comp->len - 2, &value); -+ pri_message(pri, "party address %s\n", value.partyaddress); -+ // } -+/* GET_COMPONENT(comp, i, vdata, len); -+ if (comp->type == ASN1_SEQUENCE | ASN1_CONSTRUCTOR | ASN1_TAG_0) { -+ int j=0; -+ for (j=0;jlen;j++) { -+ pri_error(pri, "comp->data %#x\n",comp->data[j]); -+ } -+ -+ pri_error(pri, "c type %#x, c len %#x\n", comp->type, comp->len); -+ if (comp->type == ASN1_SEQUENCE | ASN1_CONSTRUCTOR) { -+ pri_error(pri, "c type %#x, c len %#x\n", comp->type, comp->len); -+ } -+ -+ } -+ */ ++ call->facility = operation_tag; ++ return rose_cd_destination_decode(pri, call, (u_int8_t *)comp, comp->len + 2); + return -1; + case ROSE_EXPLICIT_CALL_TRANSFER: + call->facility = operation_tag; + if (pri->debug & PRI_DEBUG_APDU) { + pri_message(pri, "ROSE %i: received ECT execute!", operation_tag); + } ++ return 0; ++ case ROSE_MALICIOUS_CID: ++// call->facility = operation_tag; ++// if (pri->debug & PRI_DEBUG_APDU) { ++ pri_message(pri, "ROSE %i: received MALICIOUS CID!", operation_tag); ++ // } + return 0; default: if (pri->debug & PRI_DEBUG_APDU) { pri_message(pri, "!! Unable to handle ROSE operation %d", operation_tag); diff -urN libpri-1.2.2.orig/pri_facility.h libpri-1.2.2/pri_facility.h --- libpri-1.2.2.orig/pri_facility.h 2005-11-29 19:39:18.000000000 +0100 -+++ libpri-1.2.2/pri_facility.h 2006-01-19 11:51:18.000000000 +0100 ++++ libpri-1.2.2/pri_facility.h 2006-04-15 21:35:05.000000000 +0200 @@ -34,7 +34,7 @@ /* Operation ID values */ /* Q.952 ROSE operations (Diverting) */ @@ -1125,7 +1263,7 @@ diff -urN libpri-1.2.2.orig/pri_facility.h libpri-1.2.2/pri_facility.h #define ROSE_DIVERTING_LEG_INFORMATION3 19 /* Q.956 ROSE operations (Advice Of Charge) */ #define ROSE_AOC_NO_CHARGING_INFO_AVAILABLE 26 -@@ -48,11 +48,14 @@ +@@ -48,11 +48,15 @@ #define ROSE_AOC_IDENTIFICATION_OF_CHARGE 37 /* Q.SIG operations */ #define SS_CNID_CALLINGNAME 0 @@ -1137,11 +1275,12 @@ diff -urN libpri-1.2.2.orig/pri_facility.h libpri-1.2.2/pri_facility.h +#define ROSE_CALLDEFLECTION 0x0D +#define ROSE_EXPLICIT_CALL_TRANSFER 0x06 ++#define ROSE_MALICIOUS_CID 0x31 + /* ROSE definitions and data structures */ #define INVOKE_IDENTIFIER 0x02 #define INVOKE_LINKED_IDENTIFIER 0x80 -@@ -180,12 +183,6 @@ +@@ -180,12 +184,6 @@ (variable) = ((variable) << 8) | (component)->data[comp_idx]; \ } while (0) @@ -1154,17 +1293,28 @@ diff -urN libpri-1.2.2.orig/pri_facility.h libpri-1.2.2/pri_facility.h #define ASN1_ADD_SIMPLE(component, comptype, ptr, idx) \ do { \ (component) = (struct rose_component *)&((ptr)[(idx)]); \ -@@ -260,4 +257,6 @@ +@@ -260,4 +258,8 @@ /* Adds the "standard" ADPUs to a call */ extern int pri_call_add_standard_apdus(struct pri *pri, q931_call *call); +extern int add_call_deflection_facility_ie(struct pri *pri, q931_call *c, char *destination); ++ ++extern int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long chargedunits, int send_facility_message); + #endif /* _PRI_FACILITY_H */ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h --- libpri-1.2.2.orig/pri_internal.h 2005-11-29 19:39:18.000000000 +0100 -+++ libpri-1.2.2/pri_internal.h 2006-01-18 12:28:07.000000000 +0100 -@@ -30,7 +30,10 @@ ++++ libpri-1.2.2/pri_internal.h 2006-04-15 21:57:19.000000000 +0200 +@@ -5,6 +5,8 @@ + * + * Copyright (C) 2001, Linux Support Services, Inc. + * All Rights Reserved. ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -30,7 +32,10 @@ struct pri_sched { struct timeval when; void (*callback)(void *data); @@ -1175,7 +1325,7 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h }; struct q921_frame; -@@ -38,8 +41,15 @@ +@@ -38,8 +43,15 @@ enum q931_mode; /* No more than 128 scheduled events */ @@ -1191,7 +1341,7 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h #define MAX_TIMERS 32 struct pri { -@@ -51,6 +61,7 @@ +@@ -51,6 +63,7 @@ struct pri *master; /* Master channel if appropriate */ struct pri_sched pri_sched[MAX_SCHED]; /* Scheduled events */ int debug; /* Debug stuff */ @@ -1199,7 +1349,7 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h int state; /* State of D-channel */ int switchtype; /* Switch type */ int nsf; /* Network-Specific Facility (if any) */ -@@ -62,25 +73,42 @@ +@@ -62,25 +75,42 @@ int protodisc; /* Q.921 State */ @@ -1259,7 +1409,7 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h /* All ISDN Timer values */ int timers[MAX_TIMERS]; -@@ -89,8 +117,8 @@ +@@ -89,8 +119,8 @@ int schedev; pri_event ev; /* Static event thingy */ @@ -1270,7 +1420,7 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h /* Q.931 calls */ q931_call **callpool; -@@ -109,6 +137,9 @@ +@@ -109,6 +139,9 @@ unsigned char last_invoke; /* Last ROSE invoke ID */ unsigned char sendfacility; @@ -1280,7 +1430,7 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h }; struct pri_sr { -@@ -118,6 +149,7 @@ +@@ -118,6 +151,7 @@ int nonisdn; char *caller; int callerplan; @@ -1288,7 +1438,15 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h char *callername; int callerpres; char *called; -@@ -167,8 +199,13 @@ +@@ -130,6 +164,7 @@ + int redirectingreason; + int justsignalling; + char *useruserinfo; ++ char *llc; + }; + + /* Internal switch types */ +@@ -167,8 +202,13 @@ int alive; /* Whether or not the call is alive */ int acked; /* Whether setup has been acked or not */ @@ -1302,7 +1460,7 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h int ri; /* Restart Indicator (Restart Indicator IE) */ -@@ -202,15 +239,18 @@ +@@ -202,15 +242,18 @@ int callerplan; int callerplanani; int callerpres; /* Caller presentation */ @@ -1325,7 +1483,7 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h int nonisdn; char callednum[256]; /* Called Number */ int complete; /* no more digits coming */ -@@ -225,16 +265,27 @@ +@@ -225,23 +268,36 @@ char redirectingnum[256]; /* Number of redirecting party */ char redirectingname[256]; /* Name of redirecting party */ @@ -1356,7 +1514,8 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h long aoc_units; /* Advice of Charge Units */ -@@ -242,6 +293,7 @@ ++ char llc[16]; /* low layer compatibility */ + struct apdu_event *apdus; /* APDU queue for call */ }; extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data); @@ -1364,7 +1523,7 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h extern pri_event *pri_schedule_run(struct pri *pri); -@@ -250,7 +302,7 @@ +@@ -250,7 +306,7 @@ extern pri_event *pri_mkerror(struct pri *pri, char *errstr); extern void pri_message(struct pri *pri, char *fmt, ...); @@ -1375,8 +1534,17 @@ diff -urN libpri-1.2.2.orig/pri_internal.h libpri-1.2.2/pri_internal.h void libpri_copy_string(char *dst, const char *src, size_t size); diff -urN libpri-1.2.2.orig/pri_q921.h libpri-1.2.2/pri_q921.h --- libpri-1.2.2.orig/pri_q921.h 2005-11-29 19:39:18.000000000 +0100 -+++ libpri-1.2.2/pri_q921.h 2006-01-18 12:28:07.000000000 +0100 -@@ -47,6 +47,13 @@ ++++ libpri-1.2.2/pri_q921.h 2006-04-15 21:57:24.000000000 +0200 +@@ -5,6 +5,8 @@ + * + * Copyright (C) 2001, Linux Support Services, Inc. + * All Rights Reserved. ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -47,6 +49,13 @@ #define Q921_FRAMETYPE_S 0x1 #define Q921_TEI_GROUP 127 @@ -1390,7 +1558,7 @@ diff -urN libpri-1.2.2.orig/pri_q921.h libpri-1.2.2/pri_q921.h #define Q921_TEI_GR303_EOC_PATH 0 #define Q921_TEI_GR303_EOC_OPS 4 #define Q921_TEI_GR303_TMC_SWITCHING 0 -@@ -164,12 +171,14 @@ +@@ -164,12 +173,14 @@ extern void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx); /* Bring up the D-channel */ @@ -1410,8 +1578,17 @@ diff -urN libpri-1.2.2.orig/pri_q921.h libpri-1.2.2/pri_q921.h #endif diff -urN libpri-1.2.2.orig/pri_q931.h libpri-1.2.2/pri_q931.h --- libpri-1.2.2.orig/pri_q931.h 2005-11-29 19:39:18.000000000 +0100 -+++ libpri-1.2.2/pri_q931.h 2006-01-18 12:28:07.000000000 +0100 -@@ -190,6 +190,10 @@ ++++ libpri-1.2.2/pri_q931.h 2006-04-15 21:57:29.000000000 +0200 +@@ -5,6 +5,8 @@ + * + * Copyright (C) 2001, Linux Support Services, Inc. + * All Rights Reserved. ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -190,6 +192,10 @@ #define Q931_IE_CODESET(x) ((x) >> 8) #define Q931_IE_IE(x) ((x) & 0xff) #define Q931_FULL_IE(codeset, ie) (((codeset) << 8) | ((ie) & 0xff)) @@ -1422,7 +1599,7 @@ diff -urN libpri-1.2.2.orig/pri_q931.h libpri-1.2.2/pri_q931.h #define Q931_DISPLAY 0x28 #define Q931_IE_SEGMENTED_MSG 0x00 -@@ -218,6 +222,8 @@ +@@ -218,6 +224,8 @@ #define Q931_IE_USER_USER 0x7E #define Q931_IE_ESCAPE_FOR_EXT 0x7F @@ -1431,7 +1608,7 @@ diff -urN libpri-1.2.2.orig/pri_q931.h libpri-1.2.2/pri_q931.h /* Call state stuff */ #define Q931_CALL_STATE_NULL 0 -@@ -243,7 +249,7 @@ +@@ -243,7 +251,7 @@ /* EuroISDN */ #define Q931_SENDING_COMPLETE 0xa1 @@ -1440,7 +1617,7 @@ diff -urN libpri-1.2.2.orig/pri_q931.h libpri-1.2.2/pri_q931.h extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info); -@@ -257,6 +263,10 @@ +@@ -257,6 +265,10 @@ extern int q931_information(struct pri *pri, q931_call *call, char digit); @@ -1451,7 +1628,7 @@ diff -urN libpri-1.2.2.orig/pri_q931.h libpri-1.2.2/pri_q931.h extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn); extern int q931_release(struct pri *pri, q931_call *call, int cause); -@@ -265,6 +275,10 @@ +@@ -265,6 +277,10 @@ extern int q931_hangup(struct pri *pri, q931_call *call, int cause); @@ -1462,7 +1639,7 @@ diff -urN libpri-1.2.2.orig/pri_q931.h libpri-1.2.2/pri_q931.h extern int q931_restart(struct pri *pri, int channel); extern int q931_facility(struct pri *pri, q931_call *call); -@@ -279,5 +293,23 @@ +@@ -279,5 +295,23 @@ extern void q931_dump(struct pri *pri, q931_h *h, int len, int txrx); extern void __q931_destroycall(struct pri *pri, q931_call *c); @@ -1529,8 +1706,8 @@ diff -urN libpri-1.2.2.orig/pridump.c libpri-1.2.2/pridump.c * This program is free software; you can redistribute it and/or modify diff -urN libpri-1.2.2.orig/prisched.c libpri-1.2.2/prisched.c --- libpri-1.2.2.orig/prisched.c 2005-11-29 19:39:18.000000000 +0100 -+++ libpri-1.2.2/prisched.c 2006-01-18 12:28:07.000000000 +0100 -@@ -1,9 +1,9 @@ ++++ libpri-1.2.2/prisched.c 2006-04-15 21:57:42.000000000 +0200 +@@ -1,10 +1,12 @@ /* * libpri: An implementation of Primary Rate ISDN * @@ -1540,9 +1717,12 @@ diff -urN libpri-1.2.2.orig/prisched.c libpri-1.2.2/prisched.c - * Copyright (C) 2001-2005, Digium + * Copyright (C) 2001, Linux Support Services, Inc. * All Rights Reserved. ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH ++ * Klaus-Peter Junghanns * * This program is free software; you can redistribute it and/or modify -@@ -22,10 +22,9 @@ + * it under the terms of the GNU General Public License as published by +@@ -22,10 +24,9 @@ * */ @@ -1554,7 +1734,7 @@ diff -urN libpri-1.2.2.orig/prisched.c libpri-1.2.2/prisched.c static int maxsched = 0; -@@ -36,7 +35,7 @@ +@@ -36,7 +37,7 @@ int x; struct timeval tv; for (x=1;xpri_sched[x].when = tv; pri->pri_sched[x].callback = function; @@ -1603,7 +1783,7 @@ diff -urN libpri-1.2.2.orig/prisched.c libpri-1.2.2/prisched.c return x; } -@@ -65,7 +96,7 @@ +@@ -65,7 +98,7 @@ if (pri->subchannel) closest = pri_schedule_next(pri->subchannel); for (x=1;xtv_sec > pri->pri_sched[x].when.tv_sec) || ((closest->tv_sec == pri->pri_sched[x].when.tv_sec) && (closest->tv_usec > pri->pri_sched[x].when.tv_usec)))) -@@ -76,26 +107,38 @@ +@@ -76,26 +109,38 @@ static pri_event *__pri_schedule_run(struct pri *pri, struct timeval *tv) { @@ -1656,7 +1836,7 @@ diff -urN libpri-1.2.2.orig/prisched.c libpri-1.2.2/prisched.c if (pri->schedev) return &pri->ev; } -@@ -116,4 +159,6 @@ +@@ -116,4 +161,6 @@ if ((id >= MAX_SCHED) || (id < 0)) pri_error(pri, "Asked to delete sched id %d???\n", id); pri->pri_sched[id].callback = NULL; @@ -1726,7 +1906,7 @@ diff -urN libpri-1.2.2.orig/pritest.c libpri-1.2.2/pritest.c } diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c --- libpri-1.2.2.orig/q921.c 2005-12-06 22:35:50.000000000 +0100 -+++ libpri-1.2.2/q921.c 2006-01-18 12:28:07.000000000 +0100 ++++ libpri-1.2.2/q921.c 2006-04-24 13:44:24.000000000 +0200 @@ -1,10 +1,12 @@ /* * libpri: An implementation of Primary Rate ISDN @@ -1737,7 +1917,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c - * Copyright (C) 2001-2005, Digium + * Copyright (C) 2001, Linux Support Services, Inc. * All Rights Reserved. -+ * Copyright (C) 2003,2004,2005 Junghanns.NET GmbH ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH + * Klaus-Peter Junghanns * * This program is free software; you can redistribute it and/or modify @@ -2065,7 +2245,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c +static void q921_send_teiverify(struct pri *pri,int tei) { + q921_u *f; + -+ if (pri->localtype != BRI_CPE_PTMP) { ++ if ((pri->localtype != BRI_CPE) && (pri->localtype != BRI_CPE_PTMP)) { + pri_error(pri, "TEI verify for non-ptmp???\n"); + return; + } @@ -3150,7 +3330,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c return NULL; } if (len < 4) { -@@ -731,80 +1447,122 @@ +@@ -731,80 +1447,128 @@ switch(h->s.ss) { case 0: /* Receiver Ready */ @@ -3226,6 +3406,11 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c sendnow = 0; +// XXX + q921_ack_rx(pri, h->s.n_r, h->h.tei); ++ /* Reset t200 timer if it was somehow going */ ++ if (pri->t200_timer[teio]) { ++ pri_schedule_del(pri, pri->t200_timer[teio]); ++ pri->t200_timer[teio] = 0; ++ } /* Resend the proper I-frame */ - for(f=pri->txqueue;f;f=f->next) { + for(f=pri->txqueue[teio];f;f=f->next) { @@ -3236,6 +3421,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c - sendnow = 1; - pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s); - f->h.n_r = pri->v_r; +- q921_transmit(pri, (q921_h *)(&f->h), f->len); + + /* multiframe established */ + f->transmitted = 0; @@ -3246,9 +3432,10 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c + sendnow = 0; + } else { + f->h.p_f = 0; -+ sendnow = 1; ++ sendnow = 1; + pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s); - q921_transmit(pri, (q921_h *)(&f->h), f->len); ++ q921_transmit(pri, (q921_h *)(&f->h), f->len); ++ f->transmitted++; + } } } @@ -3267,17 +3454,14 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c - pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r); - pri->v_a = h->s.n_r; - pri->v_s = h->s.n_r; -+/* pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r); -+ pri->v_a[teio] = h->s.n_r; -+ pri->v_s[teio] = h->s.n_r; */ - /* Reset t200 timer if it was somehow going */ +- /* Reset t200 timer if it was somehow going */ - if (pri->t200_timer) { - pri_schedule_del(pri, pri->t200_timer); - pri->t200_timer = 0; -+ if (pri->t200_timer[teio]) { -+ pri_schedule_del(pri, pri->t200_timer[teio]); -+ pri->t200_timer[teio] = 0; - } +- } ++/* pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r); ++ pri->v_a[teio] = h->s.n_r; ++ pri->v_s[teio] = h->s.n_r; */ /* Reset and restart t203 timer */ - if (pri->t203_timer) - pri_schedule_del(pri, pri->t203_timer); @@ -3292,6 +3476,11 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c + if (h->s.p_f) { + /* If it has the poll bit set (and an iframe was retransmitted), send an appropriate supervisory response */ +// q921_rr(pri, 1, 0, h->h.tei); ++ /* Reset t200 timer if it was somehow going */ ++ if (pri->t200_timer[teio]) { ++ pri_schedule_del(pri, pri->t200_timer[teio]); ++ pri->t200_timer[teio] = 0; ++ } + /* Reset and restart t203 timer */ + pri->solicitfbit[teio] = 0; + if (pri->t203_timer[teio]) @@ -3307,7 +3496,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c } break; case 3: -@@ -821,8 +1579,16 @@ +@@ -821,8 +1585,16 @@ if (pri->debug & PRI_DEBUG_Q921_STATE) pri_message(pri, "-- Got DM Mode from peer.\n"); /* Disconnected mode, try again after T200 */ @@ -3326,7 +3515,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c return ev; } else { -@@ -830,21 +1596,144 @@ +@@ -830,21 +1602,144 @@ pri_message(pri, "-- Ignoring unsolicited DM with p/f set to 0\n"); #if 0 /* Requesting that we start */ @@ -3477,7 +3666,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c return ev; case 3: if (h->u.m2 == 3) { -@@ -866,17 +1755,26 @@ +@@ -866,17 +1761,28 @@ } } /* Send Unnumbered Acknowledgement */ @@ -3504,13 +3693,15 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c + } else { + /* send DM */ + // q921_send_dm(pri, 1, h->h.tei); ++#ifndef RELAX_TRB + q921_reset(pri, h->h.tei, 1); ++#endif + } + } } else pri_error(pri, "!! Weird frame received (m3=3, m2 = %d)\n", h->u.m2); break; -@@ -901,19 +1799,42 @@ +@@ -901,19 +1807,42 @@ /* Discard FCS */ len -= 2; @@ -3560,7 +3751,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c #ifdef PROCESS_SUBCHANNELS /* If it's not us, try any subchannels we have */ if (pri->subchannel) -@@ -921,10 +1842,16 @@ +@@ -921,10 +1850,16 @@ else #endif return NULL; @@ -3579,7 +3770,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c return ev; } -@@ -938,14 +1865,58 @@ +@@ -938,14 +1873,58 @@ return e; } @@ -3648,7 +3839,7 @@ diff -urN libpri-1.2.2.orig/q921.c libpri-1.2.2/q921.c } diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c --- libpri-1.2.2.orig/q931.c 2006-01-17 14:43:18.000000000 +0100 -+++ libpri-1.2.2/q931.c 2006-01-27 05:41:13.000000000 +0100 ++++ libpri-1.2.2/q931.c 2006-04-24 10:35:43.000000000 +0200 @@ -1,10 +1,12 @@ /* * libpri: An implementation of Primary Rate ISDN @@ -3659,7 +3850,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c - * Copyright (C) 2001-2005, Digium + * Copyright (C) 2001, Linux Support Services, Inc. * All Rights Reserved. -+ * Copyright (C) 2003,2004,2005 Junghanns.NET GmbH ++ * Copyright (C) 2003-2006 Junghanns.NET GmbH + * Klaus-Peter Junghanns * * This program is free software; you can redistribute it and/or modify @@ -3704,7 +3895,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c c->alive = 0; c->sendhangupack = 0; c->forceinvert = -1; -@@ -253,6 +265,10 @@ +@@ -253,8 +265,16 @@ c->next = NULL; c->sentchannel = 0; c->newcall = 1; @@ -3714,8 +3905,14 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c + c->phones = NULL; c->ourcallstate = Q931_CALL_STATE_NULL; c->peercallstate = Q931_CALL_STATE_NULL; ++ c->llc[0] = '\0'; ++ c->cause = -1; ++ c->causecode = -1; ++ c->causeloc = -1; } -@@ -272,14 +288,17 @@ + + static char *binary(int b, int len) { +@@ -272,14 +292,17 @@ { int x; int pos=0; @@ -3739,7 +3936,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c case 0: call->justsignalling = 1; break; -@@ -288,6 +307,7 @@ +@@ -288,6 +311,7 @@ default: pri_error(pri, "!! Unexpected Channel selection %d\n", ie->data[0] & 3); return -1; @@ -3747,7 +3944,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c } #endif if (ie->data[0] & 0x08) -@@ -349,10 +369,16 @@ +@@ -349,10 +373,16 @@ } /* Start with standard stuff */ @@ -3766,7 +3963,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c /* Add exclusive flag if necessary */ if (call->chanflags & FLAG_EXCLUSIVE) ie->data[pos] |= 0x08; -@@ -369,6 +395,7 @@ +@@ -369,6 +399,7 @@ } else pos++; if ((call->channelno > -1) || (call->slotmap != -1)) { @@ -3774,7 +3971,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c /* We'll have the octet 8.2 and 8.3's present */ ie->data[pos++] = 0x83; if (call->channelno > -1) { -@@ -384,11 +411,43 @@ +@@ -384,11 +415,43 @@ ie->data[pos++] = (call->slotmap & 0xff); return pos + 2; } @@ -3819,7 +4016,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c pri_error(pri, "!! No channel map, no channel, and no ds1? What am I supposed to identify?\n"); return -1; } -@@ -734,8 +793,12 @@ +@@ -734,8 +797,12 @@ return code2str(pres, press, sizeof(press) / sizeof(press[0])); } @@ -3833,7 +4030,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (len > maxlen - 1) { num[0] = 0; return; -@@ -746,50 +809,75 @@ +@@ -746,50 +813,75 @@ static FUNC_DUMP(dump_called_party_number) { @@ -3937,7 +4134,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c int i = 0; /* To follow Q.931 (4.5.1), we must search for start of octet 4 by walking through all bytes until one with ext bit (8) set to 1 */ -@@ -810,13 +898,17 @@ +@@ -810,13 +902,17 @@ } } while(!(ie->data[i++]& 0x80)); @@ -3958,7 +4155,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c int i = 0; /* To follow Q.931 (4.5.1), we must search for start of octet 4 by walking through all bytes until one with ext bit (8) set to 1 */ -@@ -833,8 +925,12 @@ +@@ -833,8 +929,12 @@ } } while(!(ie->data[i++]& 0x80)); @@ -3973,7 +4170,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c } -@@ -858,7 +954,7 @@ +@@ -858,7 +958,7 @@ } } while(!(ie->data[i++] & 0x80)); @@ -3982,7 +4179,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c return 0; } -@@ -866,7 +962,7 @@ +@@ -866,7 +966,7 @@ { if (order > 1) return 0; @@ -3991,7 +4188,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c ie->data[0] = call->redirectingplan; ie->data[1] = call->redirectingpres; ie->data[2] = (call->redirectingreason & 0x0f) | 0x80; -@@ -878,67 +974,90 @@ +@@ -878,67 +978,90 @@ static FUNC_DUMP(dump_redirecting_subaddr) { @@ -4104,7 +4301,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c + } else { + pri_error(call->pri, "Calling Party Number (len=%2d) too short.\n", len); + } -+ } else { ++ } else { + if (len >= 4) { + if (strlen(call->callernum)) { + q931_get_number(call->callerani, sizeof(call->callerani), ie->data + 2, len - 4); @@ -4120,7 +4317,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c return 0; } -@@ -946,7 +1065,7 @@ +@@ -946,7 +1069,7 @@ { ie->data[0] = call->callerplan; ie->data[1] = 0x80 | call->callerpres; @@ -4129,7 +4326,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c memcpy(ie->data + 2, call->callernum, strlen(call->callernum)); return strlen(call->callernum) + 4; } -@@ -964,11 +1083,58 @@ +@@ -964,11 +1087,89 @@ static FUNC_RECV(receive_user_user) { call->useruserprotocoldisc = ie->data[0] & 0xff; @@ -4186,11 +4383,42 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c + pri_message(pri, " ]\n"); +} + ++ ++static FUNC_RECV(receive_low_layer_compat) ++{ ++ if (len > 0) { ++ if (len > 16) { ++ pri_error(pri, "%d bytes LLC too long\n", len); ++ call->llc[0] = 0; ++ } else { ++ pri_error(pri, "copying %d bytes LLC \n", len); ++ call->llc[0] = len; ++ memcpy(call->llc+1, ie->data, len); ++ } ++ } ++ return 0; ++} ++ ++static FUNC_SEND(transmit_low_layer_compat) ++{ ++ if (call->llc[0] == 0) return 0; ++ memcpy(ie->data, call->llc + 1, call->llc[0]); ++ return call->llc[0] + 2; ++} ++ ++static FUNC_DUMP(dump_low_layer_compat) ++{ ++ int x; ++ pri_message(pri, "%c Low-layer compatibilty (len=%2d) [ ", prefix, len); ++ for (x=0;xlen;x++) ++ pri_message(pri, "0x%02X ", ie->data[x]); ++ pri_message(pri, " ]\n"); ++} + static FUNC_SEND(transmit_user_user) { int datalen = strlen(call->useruserinfo); -@@ -1050,22 +1216,41 @@ +@@ -1050,22 +1251,41 @@ data++; len--; } @@ -4237,7 +4465,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c } return 0; } -@@ -1112,6 +1297,111 @@ +@@ -1112,6 +1332,111 @@ return 0; } @@ -4349,7 +4577,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c static FUNC_SEND(transmit_facility) { struct apdu_event *tmp; -@@ -1138,6 +1428,182 @@ +@@ -1138,6 +1463,182 @@ return i + 2; } @@ -4532,7 +4760,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c static FUNC_RECV(receive_facility) { int i = 0; -@@ -1346,6 +1812,7 @@ +@@ -1346,6 +1847,7 @@ pri_message(pri, " ]\n"); } @@ -4540,7 +4768,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c static FUNC_DUMP(dump_time_date) { pri_message(pri, "%c Time Date (len=%2d) [ ", prefix, len); -@@ -1366,39 +1833,60 @@ +@@ -1366,7 +1868,7 @@ static FUNC_DUMP(dump_keypad_facility) { @@ -4549,11 +4777,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (ie->len == 0 || ie->len > sizeof(tmp)) return; - -- libpri_copy_string(tmp, (char *) ie->data, sizeof(tmp)); -+ strncpy(tmp, (char *) ie->data, sizeof(tmp)); - pri_message(pri, "%c Keypad Facility (len=%2d) [ %s ]\n", prefix, ie->len, tmp ); - } +@@ -1377,28 +1879,49 @@ static FUNC_RECV(receive_keypad_facility) { @@ -4608,7 +4832,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (buf) { x=y=0; if ((x < ie->len) && (ie->data[x] & 0x80)) { -@@ -1413,7 +1901,7 @@ +@@ -1413,7 +1936,7 @@ } } @@ -4617,7 +4841,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c { char tmp[1024] = ""; int x=0; -@@ -1423,7 +1911,7 @@ +@@ -1423,7 +1946,7 @@ ((*c >= 'a') && (*c <= 'z')) || ((*c >= '0') && (*c <= '9'))) { if (!lastascii) { @@ -4626,7 +4850,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c tmp[x++] = ','; tmp[x++] = ' '; } -@@ -1435,7 +1923,7 @@ +@@ -1435,7 +1958,7 @@ if (lastascii) { tmp[x++] = '\''; } @@ -4635,7 +4859,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c tmp[x++] = ','; tmp[x++] = ' '; } -@@ -1448,14 +1936,14 @@ +@@ -1448,14 +1971,14 @@ } if (lastascii) tmp[x++] = '\''; @@ -4653,7 +4877,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c } static FUNC_DUMP(dump_network_spec_fac) -@@ -1465,7 +1953,7 @@ +@@ -1465,7 +1988,7 @@ pri_message(pri, code2str(ie->data[1], facilities, sizeof(facilities) / sizeof(facilities[0]))); } else @@ -4662,16 +4886,18 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c pri_message(pri, " ]\n"); } -@@ -1933,7 +2421,7 @@ +@@ -1932,8 +2455,8 @@ + { 1, Q931_REDIRECTING_SUBADDR, "Redirecting Subaddress", dump_redirecting_subaddr }, { 0, Q931_TRANSIT_NET_SELECT, "Transit Network Selection" }, { 1, Q931_RESTART_INDICATOR, "Restart Indicator", dump_restart_indicator, receive_restart_indicator, transmit_restart_indicator }, - { 0, Q931_LOW_LAYER_COMPAT, "Low-layer Compatibility" }, +- { 0, Q931_LOW_LAYER_COMPAT, "Low-layer Compatibility" }, - { 0, Q931_HIGH_LAYER_COMPAT, "High-layer Compatibility" }, ++ { 0, Q931_LOW_LAYER_COMPAT, "Low-layer Compatibility" , dump_low_layer_compat, receive_low_layer_compat, transmit_low_layer_compat }, + { 1, Q931_HIGH_LAYER_COMPAT, "High-layer Compatibility" , dump_high_layer_compat, receive_high_layer_compat, transmit_high_layer_compat }, { 1, Q931_PACKET_SIZE, "Packet Size" }, { 1, Q931_IE_FACILITY, "Facility" , dump_facility, receive_facility, transmit_facility }, { 1, Q931_IE_REDIRECTION_NUMBER, "Redirection Number" }, -@@ -1942,11 +2430,11 @@ +@@ -1942,11 +2465,11 @@ { 1, Q931_IE_INFO_REQUEST, "Feature Request" }, { 1, Q931_IE_FEATURE_IND, "Feature Indication" }, { 1, Q931_IE_SEGMENTED_MSG, "Segmented Message" }, @@ -4685,7 +4911,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c { 1, Q931_IE_KEYPAD_FACILITY, "Keypad Facility", dump_keypad_facility, receive_keypad_facility }, { 0, Q931_IE_SIGNAL, "Signal", dump_signal }, { 1, Q931_IE_SWITCHHOOK, "Switch-hook" }, -@@ -1954,6 +2442,7 @@ +@@ -1954,6 +2477,7 @@ { 1, Q931_IE_ESCAPE_FOR_EXT, "Escape for Extension" }, { 1, Q931_IE_CALL_STATUS, "Call Status" }, { 1, Q931_IE_CHANGE_STATUS, "Change Status" }, @@ -4693,7 +4919,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c { 1, Q931_IE_CONNECTED_ADDR, "Connected Number", dump_connected_number }, { 1, Q931_IE_CONNECTED_NUM, "Connected Number", dump_connected_number }, { 1, Q931_IE_ORIGINAL_CALLED_NUMBER, "Original Called Number", dump_redirecting_number, receive_redirecting_number, transmit_redirecting_number }, -@@ -2024,7 +2513,7 @@ +@@ -2024,7 +2548,7 @@ { if ((ie->ie & 0x80) != 0) return 1; @@ -4702,7 +4928,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c return 2 + ie->len; } -@@ -2054,10 +2543,10 @@ +@@ -2054,10 +2578,10 @@ break; case 1: cr = h->crv[0]; @@ -4715,7 +4941,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c break; default: pri_error(NULL, "Call Reference Length not supported: %d\n", h->crlen); -@@ -2071,14 +2560,14 @@ +@@ -2071,14 +2595,14 @@ int full_ie = Q931_FULL_IE(codeset, ie->ie); int base_ie; @@ -4735,7 +4961,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c /* Special treatment for shifts */ if((full_ie & 0xf0) == Q931_LOCKING_SHIFT) -@@ -2098,14 +2587,46 @@ +@@ -2098,14 +2622,46 @@ pri_error(pri, "!! %c Unknown IE %d (len = %d)\n", prefix, base_ie, ielen(ie)); } @@ -4785,7 +5011,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c prev = cur; cur = cur->next; } -@@ -2118,6 +2639,7 @@ +@@ -2118,6 +2674,7 @@ /* Call reference */ cur->cr = cr; cur->pri = pri; @@ -4793,7 +5019,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c /* Append to end of list */ if (prev) prev->next = cur; -@@ -2133,24 +2655,42 @@ +@@ -2133,24 +2690,42 @@ do { cur = *pri->callpool; pri->cref++; @@ -4843,7 +5069,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (prev) prev->next = cur->next; else -@@ -2159,6 +2699,8 @@ +@@ -2159,6 +2734,8 @@ pri_message(pri, "NEW_HANGUP DEBUG: Destroying the call, ourstate %s, peerstate %s\n",callstate2str(cur->ourcallstate),callstate2str(cur->peercallstate)); if (cur->retranstimer) pri_schedule_del(pri, cur->retranstimer); @@ -4852,7 +5078,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c pri_call_apdu_queue_cleanup(cur); free(cur); return; -@@ -2169,16 +2711,16 @@ +@@ -2169,16 +2746,16 @@ pri_error(pri, "Can't destroy call %d!\n", cr); } @@ -4872,7 +5098,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c return; } -@@ -2290,6 +2832,10 @@ +@@ -2290,6 +2867,10 @@ { unsigned int x; int full_ie = Q931_FULL_IE(codeset, ie->ie); @@ -4883,7 +5109,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (pri->debug & PRI_DEBUG_Q931_STATE) pri_message(pri, "-- Processing IE %d (cs%d, %s)\n", ie->ie, codeset, ie2str(full_ie)); for (x=0;xsubchannel) { /* On GR-303, top bit is always 0 */ -@@ -2330,13 +2891,23 @@ +@@ -2330,13 +2926,23 @@ mh->f = 0; *hb = h; *mhb = mh; @@ -4953,7 +5179,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c /* The transmit operation might dump the q921 header, so logging the q931 message body after the transmit puts the sections of the message in the right order in the log */ -@@ -2362,7 +2933,11 @@ +@@ -2362,7 +2968,11 @@ memset(buf, 0, sizeof(buf)); len = sizeof(buf); @@ -4966,7 +5192,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c mh->msg = msgtype; x=0; codeset = 0; -@@ -2397,11 +2972,34 @@ +@@ -2397,11 +3007,34 @@ } /* Invert the logic */ len = sizeof(buf) - len; @@ -5002,7 +5228,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c static int status_ies[] = { Q931_CAUSE, Q931_CALL_STATE, -1 }; static int q931_status(struct pri *pri, q931_call *c, int cause) -@@ -2439,17 +3037,45 @@ +@@ -2439,17 +3072,45 @@ return send_message(pri, c, Q931_INFORMATION, information_ies); } @@ -5050,7 +5276,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c int q931_facility(struct pri*pri, q931_call *c) { return send_message(pri, c, Q931_FACILITY, facility_ies); -@@ -2463,7 +3089,6 @@ +@@ -2463,7 +3124,6 @@ if ((info > 0x2) || (info < 0x00)) return 0; } @@ -5058,7 +5284,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (info >= 0) c->notify = info & 0x7F; else -@@ -2506,6 +3131,8 @@ +@@ -2506,6 +3166,8 @@ int q931_call_proceeding(struct pri *pri, q931_call *c, int channel, int info) { @@ -5067,38 +5293,35 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (channel) { c->ds1no = (channel & 0xff00) >> 8; c->ds1explicit = (channel & 0x10000) >> 16; -@@ -2532,8 +3159,14 @@ +@@ -2532,8 +3194,12 @@ static int alerting_ies[] = { -1 }; #endif -+// static int alerting_BRI_ies[] = { -1 }; ++static int alerting_BRI_ies[] = { -1 }; + int q931_alerting(struct pri *pri, q931_call *c, int channel, int info) { + // never send two ALERTINGs! + if (c->alert > 0) return 0; -+ // XXX novo vox hack -+// if ((!c->proc) && (pri->localtype != BRI_CPE_PTMP)) if (!c->proc) q931_call_proceeding(pri, c, channel, 0); if (info) { -@@ -2544,11 +3177,127 @@ +@@ -2544,14 +3210,130 @@ c->progressmask = 0; c->ourcallstate = Q931_CALL_STATE_CALL_RECEIVED; c->peercallstate = Q931_CALL_STATE_CALL_DELIVERED; + c->alert = 1; - c->alive = 1; - return send_message(pri, c, Q931_ALERTING, alerting_ies); -+/* if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) { ++ c->alive = 1; ++ if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) { + return send_message(pri, c, Q931_ALERTING, alerting_ies); + } else { + if ((pri->localtype == BRI_NETWORK) || (pri->localtype == BRI_NETWORK_PTMP)) { + return send_message(pri, c, Q931_ALERTING, alerting_ies); + } else { -+ // no PROGRESS_IND for BRI please ++ /* no PROGRESS_INDICATOR for BRI please */ + return send_message(pri, c, Q931_ALERTING, alerting_BRI_ies); + } -+ } */ ++ } +} + +static int hold_acknowledge_ies[] = { -1 }; @@ -5194,7 +5417,8 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c + c->channelno = channel; + c->chanflags &= ~FLAG_PREFERRED; + c->chanflags |= FLAG_EXCLUSIVE; -+ c->alive = 1; + c->alive = 1; +- return send_message(pri, c, Q931_ALERTING, alerting_ies); + c->ourcallstate = Q931_CALL_STATE_ACTIVE; + c->peercallstate = Q931_CALL_STATE_ACTIVE; + strncpy(tempcallername,c->callername,sizeof(tempcallername)); @@ -5211,14 +5435,18 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c int q931_setup_ack(struct pri *pri, q931_call *c, int channel, int nonisdn) { -@@ -2569,9 +3318,36 @@ ++ int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP; + if (channel) { + c->ds1no = (channel & 0xff00) >> 8; + c->ds1explicit = (channel & 0x10000) >> 16; +@@ -2569,9 +3351,36 @@ c->ourcallstate = Q931_CALL_STATE_OVERLAP_RECEIVING; c->peercallstate = Q931_CALL_STATE_OVERLAP_SENDING; c->alive = 1; -+ if (pri->localtype == BRI_NETWORK_PTMP) { ++ if (network) { + c->progloc = LOC_PRIV_NET_LOCAL_USER; + c->progcode = CODE_CCITT; -+ c->progress = Q931_PROG_INBAND_AVAILABLE; ++ c->progressmask = Q931_PROG_INBAND_AVAILABLE; + } return send_message(pri, c, Q931_SETUP_ACKNOWLEDGE, connect_ies); } @@ -5248,7 +5476,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c static void pri_connect_timeout(void *data) { struct q931_call *c = data; -@@ -2624,6 +3400,7 @@ +@@ -2624,6 +3433,7 @@ int q931_connect(struct pri *pri, q931_call *c, int channel, int nonisdn) { @@ -5256,7 +5484,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (channel) { c->ds1no = (channel & 0xff00) >> 8; c->ds1explicit = (channel & 0x10000) >> 16; -@@ -2638,16 +3415,29 @@ +@@ -2638,22 +3448,37 @@ c->progressmask = PRI_PROG_CALLED_NOT_ISDN; } else c->progressmask = 0; @@ -5288,8 +5516,32 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c + } } ++static int release_aoce_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, Q931_IE_FACILITY, -1 }; static int release_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, -1 }; -@@ -2681,7 +3471,7 @@ + + int q931_release(struct pri *pri, q931_call *c, int cause) + { ++ int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP; + c->ourcallstate = Q931_CALL_STATE_RELEASE_REQUEST; + /* c->peercallstate stays the same */ + if (c->alive) { +@@ -2669,7 +3494,14 @@ + } else { + c->retranstimer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T308], pri_release_finaltimeout, c); + } +- return send_message(pri, c, Q931_RELEASE, release_ies); ++ if (network && (c->aoc_units > -1)) { ++ /* include FACILITY IE for AOC-E */ ++ aoc_aoce_charging_unit_encode(pri, c , c->aoc_units, Q931_RELEASE); ++ c->aoc_units = -1; ++ return send_message(pri, c, Q931_RELEASE, release_aoce_ies); ++ } else { ++ return send_message(pri, c, Q931_RELEASE, release_ies); ++ } + } else + return send_message(pri, c, Q931_RELEASE_COMPLETE, release_ies); /* Yes, release_ies, not release_complete_ies */ + } else +@@ -2681,7 +3513,7 @@ int q931_restart(struct pri *pri, int channel) { struct q931_call *c; @@ -5298,7 +5550,33 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (!c) return -1; if (!channel) -@@ -2718,9 +3508,15 @@ +@@ -2698,10 +3530,12 @@ + return send_message(pri, c, Q931_RESTART, restart_ies); + } + ++static int disconnect_aoce_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, Q931_IE_FACILITY, -1 }; + static int disconnect_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, -1 }; + + int q931_disconnect(struct pri *pri, q931_call *c, int cause) + { ++ int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP; + c->ourcallstate = Q931_CALL_STATE_DISCONNECT_REQUEST; + c->peercallstate = Q931_CALL_STATE_DISCONNECT_INDICATION; + if (c->alive) { +@@ -2713,14 +3547,27 @@ + if (c->retranstimer) + pri_schedule_del(pri, c->retranstimer); + c->retranstimer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T305], pri_disconnect_timeout, c); +- return send_message(pri, c, Q931_DISCONNECT, disconnect_ies); ++ if (network && (c->aoc_units > -1)) { ++ /* include FACILITY IE for AOC-E */ ++ aoc_aoce_charging_unit_encode(pri, c , c->aoc_units, Q931_DISCONNECT); ++ c->aoc_units = -1; ++ return send_message(pri, c, Q931_DISCONNECT, disconnect_aoce_ies); ++ } else { ++ return send_message(pri, c, Q931_DISCONNECT, disconnect_ies); ++ } + } else return 0; } @@ -5309,12 +5587,12 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, -1 }; +static int setup_bri_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY, Q931_IE_USER_USER, -+ Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, Q931_HIGH_LAYER_COMPAT, -1 }; ++ Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, Q931_HIGH_LAYER_COMPAT, Q931_LOW_LAYER_COMPAT, -1 }; + static int gr303_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, -1 }; static int cis_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_CALLED_PARTY_NUMBER, -1 }; -@@ -2728,7 +3524,12 @@ +@@ -2728,7 +3575,12 @@ int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req) { int res; @@ -5328,56 +5606,15 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c c->transcapability = req->transmode; c->transmoderate = TRANS_MODE_64_CIRCUIT; -@@ -2754,12 +3555,12 @@ +@@ -2753,6 +3605,7 @@ + c->chanflags = FLAG_EXCLUSIVE; else if (c->channelno) c->chanflags = FLAG_PREFERRED; ++ memcpy(c->llc, req->llc, sizeof(c->llc)); if (req->caller) { -- libpri_copy_string(c->callernum, req->caller, sizeof(c->callernum)); -+ strncpy(c->callernum, req->caller, sizeof(c->callernum) - 1); + libpri_copy_string(c->callernum, req->caller, sizeof(c->callernum)); c->callerplan = req->callerplan; - if (req->callername) -- libpri_copy_string(c->callername, req->callername, sizeof(c->callername)); -+ strncpy(c->callername, req->callername, sizeof(c->callername) - 1); - else -- c->callername[0] = '\0'; -+ strcpy(c->callername, ""); - if ((pri->switchtype == PRI_SWITCH_DMS100) || - (pri->switchtype == PRI_SWITCH_ATT4ESS)) { - /* Doesn't like certain presentation types */ -@@ -2768,13 +3569,13 @@ - } - c->callerpres = req->callerpres; - } else { -- c->callernum[0] = '\0'; -- c->callername[0] = '\0'; -+ strcpy(c->callernum, ""); -+ strcpy(c->callername, ""); - c->callerplan = PRI_UNKNOWN; - c->callerpres = PRES_NUMBER_NOT_AVAILABLE; - } - if (req->redirectingnum) { -- libpri_copy_string(c->redirectingnum, req->redirectingnum, sizeof(c->redirectingnum)); -+ strncpy(c->redirectingnum, req->redirectingnum, sizeof(c->redirectingnum) - 1); - c->redirectingplan = req->redirectingplan; - if ((pri->switchtype == PRI_SWITCH_DMS100) || - (pri->switchtype == PRI_SWITCH_ATT4ESS)) { -@@ -2785,13 +3586,13 @@ - c->redirectingpres = req->redirectingpres; - c->redirectingreason = req->redirectingreason; - } else { -- c->redirectingnum[0] = '\0'; -+ strcpy(c->redirectingnum, ""); - c->redirectingplan = PRI_UNKNOWN; - c->redirectingpres = PRES_NUMBER_NOT_AVAILABLE; - c->redirectingreason = PRI_REDIR_UNKNOWN; - } - if (req->called) { -- libpri_copy_string(c->callednum, req->called, sizeof(c->callednum)); -+ strncpy(c->callednum, req->called, sizeof(c->callednum) - 1); - c->calledplan = req->calledplan; - } else - return -1; -@@ -2812,14 +3613,19 @@ +@@ -2812,14 +3665,19 @@ res = send_message(pri, c, Q931_SETUP, gr303_setup_ies); else if (c->justsignalling) res = send_message(pri, c, Q931_SETUP, cis_setup_ies); @@ -5397,7 +5634,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c } return res; -@@ -2835,7 +3641,11 @@ +@@ -2835,7 +3693,11 @@ if (cause > -1) { c->cause = cause; c->causecode = CODE_CCITT; @@ -5410,7 +5647,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c /* release_ies has CAUSE in it */ res = send_message(pri, c, Q931_RELEASE_COMPLETE, release_ies); } else -@@ -2860,6 +3670,117 @@ +@@ -2860,6 +3722,117 @@ return 0; } @@ -5528,7 +5765,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c int q931_hangup(struct pri *pri, q931_call *c, int cause) { int disconnect = 1; -@@ -2871,7 +3792,7 @@ +@@ -2871,7 +3844,7 @@ /* If mandatory IE was missing, insist upon that cause code */ if (c->cause == PRI_CAUSE_MANDATORY_IE_MISSING) cause = c->cause; @@ -5537,7 +5774,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c /* We'll send RELEASE_COMPLETE with these causes */ disconnect = 0; release_compl = 1; -@@ -2885,7 +3806,7 @@ +@@ -2885,7 +3858,7 @@ case Q931_CALL_STATE_NULL: if (c->peercallstate == Q931_CALL_STATE_NULL) /* free the resources if we receive or send REL_COMPL */ @@ -5546,7 +5783,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c else if (c->peercallstate == Q931_CALL_STATE_RELEASE_REQUEST) q931_release_complete(pri,c,cause); break; -@@ -2911,6 +3832,11 @@ +@@ -2911,6 +3884,11 @@ /* received SETUP_ACKNOWLEDGE */ /* send DISCONNECT in general */ if (c->peercallstate != Q931_CALL_STATE_NULL && c->peercallstate != Q931_CALL_STATE_DISCONNECT_REQUEST && c->peercallstate != Q931_CALL_STATE_DISCONNECT_INDICATION && c->peercallstate != Q931_CALL_STATE_RELEASE_REQUEST && c->peercallstate != Q931_CALL_STATE_RESTART_REQUEST && c->peercallstate != Q931_CALL_STATE_RESTART) { @@ -5558,7 +5795,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (disconnect) q931_disconnect(pri,c,cause); else if (release_compl) -@@ -2926,8 +3852,14 @@ +@@ -2926,8 +3904,14 @@ break; case Q931_CALL_STATE_DISCONNECT_INDICATION: /* received DISCONNECT */ @@ -5573,7 +5810,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c q931_release(pri,c,cause); } break; -@@ -2941,19 +3873,17 @@ +@@ -2941,19 +3925,17 @@ pri_error(pri, "q931_hangup shouldn't be called in this state, ourstate %s, peerstate %s\n",callstate2str(c->ourcallstate),callstate2str(c->peercallstate)); break; default: @@ -5596,7 +5833,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c q931_call *c; q931_ie *ie; unsigned int x; -@@ -2965,6 +3895,7 @@ +@@ -2965,6 +3947,7 @@ int codeset, cur_codeset; int last_ie[8]; struct apdu_event *cur = NULL; @@ -5604,7 +5841,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c memset(last_ie, 0, sizeof(last_ie)); if (pri->debug & PRI_DEBUG_Q931_DUMP) -@@ -2978,13 +3909,13 @@ +@@ -2978,13 +3961,13 @@ KLUDGE this by changing byte 4 from a 0xf (SERVICE) to a 0x7 (SERVICE ACKNOWLEDGE) */ h->raw[h->crlen + 2] -= 0x8; @@ -5620,13 +5857,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (!c) { pri_error(pri, "Unable to locate call %d\n", q931_cr(h)); return -1; -@@ -3002,11 +3933,12 @@ - c->ri = -1; - break; - case Q931_FACILITY: -- c->callername[0] = '\0'; -+ strcpy(c->callername, ""); - break; +@@ -3007,6 +3990,7 @@ case Q931_SETUP: if (pri->debug & PRI_DEBUG_Q931_STATE) pri_message(pri, "-- Processing Q.931 Call Setup\n"); @@ -5634,16 +5865,8 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c c->channelno = -1; c->slotmap = -1; c->chanflags = 0; -@@ -3022,33 +3954,49 @@ - c->calledplan = -1; - c->callerplan = -1; - c->callerpres = -1; -- c->callernum[0] = '\0'; -- c->callednum[0] = '\0'; -- c->callername[0] = '\0'; -+ strcpy(c->callernum, ""); -+ strcpy(c->callednum, ""); -+ strcpy(c->callername, ""); +@@ -3027,28 +4011,44 @@ + c->callername[0] = '\0'; c->callerani[0] = '\0'; c->callerplanani = -1; - c->redirectingplan = -1; @@ -5652,30 +5875,25 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c - c->origcalledplan = -1; - c->origcalledpres = -1; - c->origredirectingreason = -1; -- c->redirectingnum[0] = '\0'; -- c->origcallednum[0] = '\0'; -- c->redirectingname[0] = '\0'; -- c->origcalledname[0] = '\0'; -- c->useruserprotocoldisc = -1; -- c->useruserinfo[0] = '\0'; + c->redirectingplan = -1; + c->redirectingpres = -1; + c->redirectingreason = -1; + c->origcalledplan = -1; + c->origcalledpres = -1; + c->origredirectingreason = -1; -+ strcpy(c->redirectingnum, ""); -+ strcpy(c->origcallednum, ""); -+ strcpy(c->redirectingname, ""); -+ strcpy(c->origcalledname, ""); + c->redirectingnum[0] = '\0'; + c->origcallednum[0] = '\0'; + c->redirectingname[0] = '\0'; + c->origcalledname[0] = '\0'; +- c->useruserprotocoldisc = -1; + c->useruserprotocoldisc = -1; -+ strcpy(c->useruserinfo, ""); + c->useruserinfo[0] = '\0'; c->complete = 0; c->nonisdn = 0; c->aoc_units = -1; - /* Fall through */ -+ strcpy(c->digits, ""); -+ strcpy(c->display, ""); ++ c->digits[0] = '\0'; ++ c->display[0] = '\0'; + c->progress = -1; + c->progressmask = 0; + break; @@ -5702,10 +5920,15 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c c->progress = -1; c->progressmask = 0; break; -@@ -3063,16 +4011,21 @@ - c->causecode = -1; - c->causeloc = -1; - c->aoc_units = -1; +@@ -3059,20 +4059,22 @@ + break; + case Q931_RELEASE: + case Q931_DISCONNECT: +- c->cause = -1; +- c->causecode = -1; +- c->causeloc = -1; +- c->aoc_units = -1; ++// c->aoc_units = -1; + c->useruserinfo[0] = '\0'; if (c->retranstimer) pri_schedule_del(pri, c->retranstimer); @@ -5727,7 +5950,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c case Q931_STATUS: c->cause = -1; c->causecode = -1; -@@ -3089,22 +4042,32 @@ +@@ -3089,22 +4091,32 @@ case Q931_STATUS_ENQUIRY: break; case Q931_SETUP_ACKNOWLEDGE: @@ -5764,7 +5987,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c case Q931_SUSPEND_ACKNOWLEDGE: case Q931_SUSPEND_REJECT: pri_error(pri, "!! Not yet handling pre-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg); -@@ -3113,7 +4076,7 @@ +@@ -3113,7 +4125,7 @@ pri_error(pri, "!! Don't know how to post-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg); q931_status(pri,c, PRI_CAUSE_MESSAGE_TYPE_NONEXIST); if (c->newcall) @@ -5773,7 +5996,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c return -1; } memset(mandies, 0, sizeof(mandies)); -@@ -3193,12 +4156,19 @@ +@@ -3193,12 +4205,19 @@ missingmand = 0; for (x=0;xourcallstate = Q931_CALL_STATE_RESTART; -@@ -3225,6 +4195,7 @@ +@@ -3225,6 +4244,7 @@ } /* Must be new call */ if (!c->newcall) { @@ -5815,7 +6038,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c break; } if (c->progressmask & PRI_PROG_CALLER_NOT_ISDN) -@@ -3242,27 +4213,31 @@ +@@ -3242,16 +4262,20 @@ pri->ev.ring.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16); pri->ev.ring.callingpres = c->callerpres; pri->ev.ring.callingplan = c->callerplan; @@ -5823,32 +6046,22 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c pri->ev.ring.callingplanrdnis = c->redirectingplan; pri->ev.ring.callingplanorigcalled = c->origcalledplan; pri->ev.ring.ani2 = c->ani2; -- libpri_copy_string(pri->ev.ring.callingani, c->callerani, sizeof(pri->ev.ring.callingani)); -- libpri_copy_string(pri->ev.ring.callingnum, c->callernum, sizeof(pri->ev.ring.callingnum)); -- libpri_copy_string(pri->ev.ring.callingname, c->callername, sizeof(pri->ev.ring.callingname)); + libpri_copy_string(pri->ev.ring.callingani, c->callerani, sizeof(pri->ev.ring.callingani)); + pri->ev.ring.callingplanani = c->callerplanani; -+ strncpy(pri->ev.ring.callingnum, c->callernum, sizeof(pri->ev.ring.callingnum) - 1); -+ strncpy(pri->ev.ring.callingname, c->callername, sizeof(pri->ev.ring.callingname) - 1); + libpri_copy_string(pri->ev.ring.callingnum, c->callernum, sizeof(pri->ev.ring.callingnum)); + libpri_copy_string(pri->ev.ring.callingname, c->callername, sizeof(pri->ev.ring.callingname)); pri->ev.ring.calledplan = c->calledplan; -- libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr)); + libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr)); - libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum)); -- libpri_copy_string(pri->ev.ring.origcalledname, c->origcalledname, sizeof(pri->ev.ring.origcalledname)); -- libpri_copy_string(pri->ev.ring.origcallednum, c->origcallednum, sizeof(pri->ev.ring.origcallednum)); -- libpri_copy_string(pri->ev.ring.redirectingnum, c->redirectingnum, sizeof(pri->ev.ring.redirectingnum)); -- libpri_copy_string(pri->ev.ring.redirectingname, c->redirectingname, sizeof(pri->ev.ring.redirectingname)); -- libpri_copy_string(pri->ev.ring.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo)); -+ strncpy(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr) - 1); + if (!strlen(c->callednum) && strlen(c->digitbuf)) { -+ strncpy(pri->ev.ring.callednum, c->digitbuf, sizeof(pri->ev.ring.callednum) - 1); ++ libpri_copy_string(pri->ev.ring.callednum, c->digitbuf, sizeof(pri->ev.ring.callednum)); + } else { -+ strncpy(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum) - 1); ++ libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum)); + } -+ strncpy(pri->ev.ring.origcalledname, c->origcalledname, sizeof(pri->ev.ring.origcalledname) - 1); -+ strncpy(pri->ev.ring.origcallednum, c->origcallednum, sizeof(pri->ev.ring.origcallednum) - 1); -+ strncpy(pri->ev.ring.redirectingnum, c->redirectingnum, sizeof(pri->ev.ring.redirectingnum) - 1); -+ strncpy(pri->ev.ring.redirectingname, c->redirectingname, sizeof(pri->ev.ring.redirectingname) - 1); -+ strncpy(pri->ev.ring.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo) - 1); - c->useruserinfo[0] = '\0'; + libpri_copy_string(pri->ev.ring.origcalledname, c->origcalledname, sizeof(pri->ev.ring.origcalledname)); + libpri_copy_string(pri->ev.ring.origcallednum, c->origcallednum, sizeof(pri->ev.ring.origcallednum)); + libpri_copy_string(pri->ev.ring.redirectingnum, c->redirectingnum, sizeof(pri->ev.ring.redirectingnum)); +@@ -3261,11 +4285,13 @@ pri->ev.ring.redirectingreason = c->redirectingreason; pri->ev.ring.origredirectingreason = c->origredirectingreason; pri->ev.ring.flexible = ! (c->chanflags & FLAG_EXCLUSIVE); @@ -5859,7 +6072,11 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c pri->ev.ring.layer1 = c->userl1; pri->ev.ring.complete = c->complete; pri->ev.ring.ctype = c->transcapability; -@@ -3275,6 +4250,9 @@ ++ memcpy(pri->ev.ring.lowlayercompat, c->llc, sizeof(pri->ev.ring.lowlayercompat)); + pri->ev.ring.redirectingreason = c->redirectingreason; + pri->ev.ring.progress = c->progress; + pri->ev.ring.progressmask = c->progressmask; +@@ -3275,6 +4301,9 @@ q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE); break; } @@ -5869,7 +6086,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c c->ourcallstate = Q931_CALL_STATE_CALL_DELIVERED; c->peercallstate = Q931_CALL_STATE_CALL_RECEIVED; pri->ev.e = PRI_EVENT_RINGING; -@@ -3295,17 +4273,24 @@ +@@ -3295,17 +4324,24 @@ q931_status(pri, c, PRI_CAUSE_WRONG_MESSAGE); break; } @@ -5894,7 +6111,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c if (c->justsignalling) { /* Make sure WE release when we initiatie a signalling only connection */ q931_release(pri, c, PRI_CAUSE_NORMAL_CLEARING); break; -@@ -3313,23 +4298,43 @@ +@@ -3313,23 +4349,43 @@ return Q931_RES_HAVEEVENT; case Q931_FACILITY: if (c->newcall) { @@ -5929,15 +6146,15 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c + break; + case 0x0D: /* CD */ + pri->ev.facility.operation = 0x0D; -+ strncpy(pri->ev.facility.forwardnum, c->redirectingnum, sizeof(pri->ev.facility.forwardnum) - 1); ++ libpri_copy_string(pri->ev.facility.forwardnum, c->redirectingnum, sizeof(pri->ev.facility.forwardnum)); + break; + default: + pri->ev.facility.operation = c->facility; + } + } else { + pri->ev.e = PRI_EVENT_FACNAME; -+ strncpy(pri->ev.facname.callingname, c->callername, sizeof(pri->ev.facname.callingname) - 1); -+ strncpy(pri->ev.facname.callingnum, c->callernum, sizeof(pri->ev.facname.callingname) - 1); ++ libpri_copy_string(pri->ev.facname.callingname, c->callername, sizeof(pri->ev.facname.callingname)); ++ libpri_copy_string(pri->ev.facname.callingnum, c->callernum, sizeof(pri->ev.facname.callingname)); + pri->ev.facname.channel = c->channelno | (c->ds1no << 8); + pri->ev.facname.cref = c->cr; + pri->ev.facname.call = c; @@ -5951,7 +6168,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c break; } pri->ev.e = PRI_EVENT_PROGRESS; -@@ -3347,6 +4352,11 @@ +@@ -3347,6 +4403,11 @@ q931_status(pri,c,PRI_CAUSE_WRONG_MESSAGE); break; } @@ -5963,7 +6180,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c pri->ev.proceeding.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16); if (mh->msg == Q931_CALL_PROCEEDING) { pri->ev.e = PRI_EVENT_PROCEEDING; -@@ -3364,16 +4374,21 @@ +@@ -3364,16 +4425,21 @@ break; } if (c->ourcallstate != Q931_CALL_STATE_CONNECT_REQUEST) { @@ -5987,7 +6204,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c break; } if (c->newcall) { -@@ -3410,31 +4425,69 @@ +@@ -3410,31 +4476,69 @@ if (res) return res; } @@ -6064,7 +6281,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c + } else if (c->sendhangupack) { + res = Q931_RES_HAVEEVENT; + pri->ev.e = PRI_EVENT_HANGUP_ACK; -+ pri_hangup(pri, c, c->cause); ++ pri_hangup(pri, c, c->cause, -1); + } else + res = 0; + if (res) @@ -6081,7 +6298,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c break; case Q931_RELEASE: if (missingmand) { -@@ -3450,6 +4503,7 @@ +@@ -3450,6 +4554,7 @@ pri->ev.e = PRI_EVENT_HANGUP; pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16); pri->ev.hangup.cref = c->cr; @@ -6089,40 +6306,33 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c pri->ev.hangup.cause = c->cause; pri->ev.hangup.call = c; pri->ev.hangup.aoc_units = c->aoc_units; -@@ -3478,8 +4532,14 @@ +@@ -3478,9 +4583,16 @@ pri->ev.e = PRI_EVENT_HANGUP_REQ; pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16); pri->ev.hangup.cref = c->cr; + pri->ev.hangup.tei = c->tei; pri->ev.hangup.cause = c->cause; pri->ev.hangup.call = c; + pri->ev.hangup.aoc_units = c->aoc_units; + if (c->progressmask & PRI_PROG_INBAND_AVAILABLE) { + pri->ev.hangup.inband_progress = 1; + } else { + pri->ev.hangup.inband_progress = 0; + } - pri->ev.hangup.aoc_units = c->aoc_units; ++ pri->ev.hangup.aoc_units = c->aoc_units; if (c->alive) return Q931_RES_HAVEEVENT; -@@ -3505,14 +4565,14 @@ - pri->ev.e = PRI_EVENT_KEYPAD_DIGIT; - pri->ev.digit.call = c; - pri->ev.digit.channel = c->channelno | (c->ds1no << 8); -- libpri_copy_string(pri->ev.digit.digits, c->digitbuf, sizeof(pri->ev.digit.digits)); -+ strncpy(pri->ev.digit.digits, c->digitbuf, sizeof(pri->ev.digit.digits)); - return Q931_RES_HAVEEVENT; - } + else +@@ -3511,7 +4623,7 @@ pri->ev.e = PRI_EVENT_INFO_RECEIVED; pri->ev.ring.call = c; pri->ev.ring.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16); - libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum)); -- libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr)); -+ strncpy(pri->ev.ring.callednum, c->digits, sizeof(pri->ev.ring.callednum) - 1); -+ strncpy(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr) - 1); ++ libpri_copy_string(pri->ev.ring.callednum, c->digits, sizeof(pri->ev.ring.callednum) ); + libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr)); pri->ev.ring.complete = c->complete; /* this covers IE 33 (Sending Complete) */ return Q931_RES_HAVEEVENT; - case Q931_STATUS_ENQUIRY: -@@ -3530,7 +4590,7 @@ +@@ -3530,7 +4642,7 @@ c->peercallstate = Q931_CALL_STATE_OVERLAP_RECEIVING; pri->ev.e = PRI_EVENT_SETUP_ACK; pri->ev.setup_ack.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16); @@ -6131,7 +6341,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c cur = c->apdus; while (cur) { if (!cur->sent && cur->message == Q931_FACILITY) { -@@ -3546,19 +4606,53 @@ +@@ -3546,19 +4658,53 @@ pri->ev.notify.channel = c->channelno; pri->ev.notify.info = c->notify; return Q931_RES_HAVEEVENT; @@ -6189,7 +6399,7 @@ diff -urN libpri-1.2.2.orig/q931.c libpri-1.2.2/q931.c case Q931_SUSPEND_ACKNOWLEDGE: case Q931_SUSPEND_REJECT: pri_error(pri, "!! Not yet handling post-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg); -@@ -3568,7 +4662,7 @@ +@@ -3568,7 +4714,7 @@ pri_error(pri, "!! Don't know how to post-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg); q931_status(pri,c, PRI_CAUSE_MESSAGE_TYPE_NONEXIST); if (c->newcall) diff --git a/src/patches/zaphfc_0.3.0-PRE-1o_florz-12.diff b/src/patches/zaphfc_0.3.0-PRE-1o_florz-12.diff new file mode 100644 index 0000000000..7d8fa4b195 --- /dev/null +++ b/src/patches/zaphfc_0.3.0-PRE-1o_florz-12.diff @@ -0,0 +1,1293 @@ +diff -urN bristuff-0.3.0-PRE-1o/zaphfc/Makefile zaphfc_0.3.0-PRE-1o_florz-12/Makefile +--- bristuff-0.3.0-PRE-1o/zaphfc/Makefile 2006-02-09 10:11:05.000000000 +0100 ++++ zaphfc_0.3.0-PRE-1o_florz-12/Makefile 2006-05-02 03:24:31.000000000 +0200 +@@ -1,15 +1,15 @@ +-KINCLUDES = /usr/src/linux/include ++KSRC=/usr/src/linux/ ++KINCLUDES = $(KSRC)include + BRISTUFFBASE = $(shell dirname `pwd`) + + ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel") +-RTAI = $(shell [ -f /usr/realtime/include/rtai.h ] && echo "-DRTAITIMING -I/usr/realtime/include") + + HOSTCC=gcc + +-CFLAGS+=-I. $(ZAP) $(RTAI) -O2 -g -Wall -DBUILDING_TONEZONE ++CFLAGS+=-I. $(ZAP) -O2 -g -Wall -DBUILDING_TONEZONE + CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi) + +-KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) $(RTAI) -Wall ++KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) -Wall + KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h") + KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char"; fi) + +@@ -105,8 +105,8 @@ + zaphfc.ko: zaphfc.c zaphfc.h + + linux26: +- @if ! [ -d /usr/src/linux-2.6 ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi +- make -C /usr/src/linux-2.6 SUBDIRS=$(PWD) ZAP=$(ZAP) modules ++ @if ! [ -d $(KSRC) ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi ++ make -C $(KSRC) SUBDIRS=$(PWD) ZAP=$(ZAP) modules + + install: install$(BUILDVER) + +diff -urN bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.c zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.c +--- bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.c 2006-04-25 15:38:47.000000000 +0200 ++++ zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.c 2006-05-02 03:24:31.000000000 +0200 +@@ -7,19 +7,21 @@ + * + * Klaus-Peter Junghanns + * ++ * Copyright (C) 2004, 2005, 2006 Florian Zumbiehl ++ * - support for slave mode of the HFC-S chip which allows it to ++ * sync its sample clock to an external source/another HFC chip ++ * - support for "interrupt bundling" (let only one card generate ++ * 8 kHz timing interrupt no matter how many cards there are ++ * in the system) ++ * - interrupt loss tolerant b channel handling ++ * + * This program is free software and may be modified and +- * distributed under the terms of the GNU Public License. ++ * distributed under the terms of the GNU General Public License. + * + */ + + #include + #include +-#ifdef RTAITIMING +-#include +-#include +-#include +-#include +-#endif + #include + #include + #include +@@ -27,6 +29,8 @@ + #include + #include "zaphfc.h" + ++#define log2(n) ffz(~(n)) ++ + #if CONFIG_PCI + + #define CLKDEL_TE 0x0f /* CLKDEL in TE mode */ +@@ -69,41 +73,30 @@ + static int hfc_dev_count = 0; + static int modes = 0; // all TE + static int debug = 0; ++static int sync_slave = 0; // all master ++static int timer_card = 0; ++static int jitterbuffer = 1; + static struct pci_dev *multi_hfc = NULL; + static spinlock_t registerlock = SPIN_LOCK_UNLOCKED; + +-void hfc_shutdownCard(struct hfc_card *hfctmp) { +- unsigned long flags; +- +- if (hfctmp == NULL) { +- return; +- } +- +- if (hfctmp->pci_io == NULL) { +- return; +- } +- +- spin_lock_irqsave(&hfctmp->lock,flags); +- ++void hfc_shutdownCard1(struct hfc_card *hfctmp) { + printk(KERN_INFO "zaphfc: shutting down card at %p.\n",hfctmp->pci_io); + + /* Clear interrupt mask */ + hfctmp->regs.int_m2 = 0; + hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2); + +- /* Reset pending interrupts */ +- hfc_inb(hfctmp, hfc_INT_S1); ++ /* Remove interrupt handler */ ++ free_irq(hfctmp->irq,hfctmp); ++} ++ ++void hfc_shutdownCard2(struct hfc_card *hfctmp) { ++ unsigned long flags; + +- /* Wait for interrupts that might still be pending */ +- spin_unlock_irqrestore(&hfctmp->lock, flags); +- set_current_state(TASK_UNINTERRUPTIBLE); +- schedule_timeout((30 * HZ) / 1000); // wait 30 ms + spin_lock_irqsave(&hfctmp->lock,flags); + +- /* Remove interrupt handler */ +- if (hfctmp->irq) { +- free_irq(hfctmp->irq, hfctmp); +- } ++ /* Reset pending interrupts */ ++ hfc_inb(hfctmp, hfc_INT_S1); + + /* Soft-reset the card */ + hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on +@@ -117,8 +110,8 @@ + + pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0); // disable memio and bustmaster + +- if (hfctmp->fifomem != NULL) { +- kfree(hfctmp->fifomem); ++ if (hfctmp->fifos != NULL) { ++ free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES)); + } + iounmap((void *) hfctmp->pci_io); + hfctmp->pci_io = NULL; +@@ -128,11 +121,24 @@ + spin_unlock_irqrestore(&hfctmp->lock,flags); + if (hfctmp->ztdev != NULL) { + zt_unregister(&hfctmp->ztdev->span); +- kfree(hfctmp->ztdev); ++ vfree(hfctmp->ztdev); + printk(KERN_INFO "unregistered from zaptel.\n"); + } + } + ++void hfc_shutdownCard(struct hfc_card *hfctmp) { ++ if (hfctmp == NULL) { ++ return; ++ } ++ ++ if (hfctmp->pci_io == NULL) { ++ return; ++ } ++ ++ hfc_shutdownCard1(hfctmp); ++ hfc_shutdownCard2(hfctmp); ++} ++ + void hfc_resetCard(struct hfc_card *hfctmp) { + unsigned long flags; + +@@ -176,14 +182,14 @@ + hfctmp->regs.ctmt = hfc_CTMT_TRANSB1 | hfc_CTMT_TRANSB2; // all bchans are transparent , no freaking hdlc + hfc_outb(hfctmp, hfc_CTMT, hfctmp->regs.ctmt); + +- hfctmp->regs.int_m1 = 0; ++ hfctmp->regs.int_m1=hfc_INTS_L1STATE; ++ if(hfctmp->cardno==timer_card){ ++ hfctmp->regs.int_m2=hfc_M2_PROC_TRANS; ++ }else{ ++ hfctmp->regs.int_m1|=hfc_INTS_DREC; ++ hfctmp->regs.int_m2=0; ++ } + hfc_outb(hfctmp, hfc_INT_M1, hfctmp->regs.int_m1); +- +-#ifdef RTAITIMING +- hfctmp->regs.int_m2 = 0; +-#else +- hfctmp->regs.int_m2 = hfc_M2_PROC_TRANS; +-#endif + hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2); + + /* Clear already pending ints */ +@@ -195,8 +201,8 @@ + hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_TE; /* set tx_lo mode, error in datasheet ! */ + } + +- hfctmp->regs.mst_mode = hfc_MST_MODE_MASTER; /* HFC Master Mode */ + hfc_outb(hfctmp, hfc_MST_MODE, hfctmp->regs.mst_mode); ++ hfc_outb(hfctmp, hfc_MST_EMOD, hfctmp->regs.mst_emod); + + hfc_outb(hfctmp, hfc_SCTRL, hfctmp->regs.sctrl); + hfctmp->regs.sctrl_r = 3; +@@ -208,10 +214,8 @@ + hfc_outb(hfctmp, hfc_CIRM, 0x80 | 0x40); // bit order + + /* Finally enable IRQ output */ +-#ifndef RTAITIMING + hfctmp->regs.int_m2 |= hfc_M2_IRQ_ENABLE; + hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2); +-#endif + + /* clear pending ints */ + hfc_inb(hfctmp, hfc_INT_S1); +@@ -228,374 +232,219 @@ + spin_unlock(®isterlock); + } + +-static void hfc_btrans(struct hfc_card *hfctmp, char whichB) { +- // we are called with irqs disabled from the irq handler +- int count, maxlen, total; +- unsigned char *f1, *f2; +- unsigned short *z1, *z2, newz1; +- int freebytes; +- +- if (whichB == 1) { +- f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F1); +- f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F2); +- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z1 + (*f1 * 4)); +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z2 + (*f1 * 4)); +- } else { +- f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F1); +- f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F2); +- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z1 + (*f1 * 4)); +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z2 + (*f1 * 4)); +- } +- +- freebytes = *z2 - *z1; +- if (freebytes <= 0) { +- freebytes += hfc_B_FIFO_SIZE; +- } +- count = ZT_CHUNKSIZE; +- +- total = count; +- if (freebytes < count) { +- hfctmp->clicks++; +- /* only spit out this warning once per second to not make things worse! */ +- if (hfctmp->clicks > 100) { +- printk(KERN_CRIT "zaphfc: bchan tx fifo full, dropping audio! (z1=%d, z2=%d)\n",*z1,*z2); +- hfctmp->clicks = 0; +- } +- return; +- } +- +- maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z1; +- if (maxlen > count) { +- maxlen = count; +- } +- newz1 = *z1 + total; +- if (newz1 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { newz1 -= hfc_B_FIFO_SIZE; } ++/*===========================================================================*/ + +- if (whichB == 1) { +- memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + *z1),hfctmp->ztdev->chans[0].writechunk, maxlen); +- } else { +- memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + *z1),hfctmp->ztdev->chans[1].writechunk, maxlen); +- } +- +- count -= maxlen; +- if (count > 0) { +- // Buffer wrap +- if (whichB == 1) { +- memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[0].writechunk+maxlen, count); +- } else { +- memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[1].writechunk+maxlen, count); +- } +- } ++#if hfc_B_FIFO_SIZE%ZT_CHUNKSIZE ++#error hfc_B_FIFO_SIZE is not a multiple of ZT_CHUNKSIZE even though the code assumes this ++#endif ++ ++static void hfc_dch_init(struct hfc_card *hfctmp){ ++ struct dch *chtmp=&hfctmp->dch; + +- *z1 = newz1; /* send it now */ ++ chtmp->rx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DRX_F1); ++ chtmp->rx.f2.v=0x1f; ++ chtmp->rx.f2.z2.v=0x1ff; + +-// if (count > 0) printk(KERN_CRIT "zaphfc: bchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2); +- return; ++ chtmp->tx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F1); ++ chtmp->tx.f1.v=0x1f; ++ chtmp->tx.f1.z1.v=0x1ff; ++ chtmp->tx.f2.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F2); + } + +-static void hfc_brec(struct hfc_card *hfctmp, char whichB) { +- // we are called with irqs disabled from the irq handler +- int count, maxlen, drop; +- volatile unsigned char *f1, *f2; +- volatile unsigned short *z1, *z2, newz2; +- int bytes = 0; +- +- if (whichB == 1) { +- f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F1); +- f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F2); +- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z1 + (*f1 * 4)); +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4)); +- } else { +- f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F1); +- f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F2); +- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z1 + (*f1 * 4)); +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4)); +- } ++static void hfc_bch_init(struct hfc_card *hfctmp){ ++ struct bch *chtmp=&hfctmp->bch; + +- bytes = *z1 - *z2; +- if (bytes < 0) { +- bytes += hfc_B_FIFO_SIZE; +- } +- count = ZT_CHUNKSIZE; +- +- if (bytes < ZT_CHUNKSIZE) { +-#ifndef RTAITIMING +- printk(KERN_CRIT "zaphfc: bchan rx fifo not enough bytes to receive! (z1=%d, z2=%d, wanted %d got %d), probably a buffer overrun.\n",*z1,*z2,ZT_CHUNKSIZE,bytes); +-#endif +- return; +- } ++ chtmp->checkcnt=0; ++ chtmp->fill_fifo=0; + +- /* allowing the buffering of hfc_BCHAN_BUFFER bytes of audio data works around irq jitter */ +- if (bytes > hfc_BCHAN_BUFFER + ZT_CHUNKSIZE) { +- /* if the system is too slow to handle it, we will have to drop it all (except 1 zaptel chunk) */ +- drop = bytes - ZT_CHUNKSIZE; +- hfctmp->clicks++; +- /* only spit out this warning once per second to not make things worse! */ +- if (hfctmp->clicks > 100) { +- printk(KERN_CRIT "zaphfc: dropped audio (z1=%d, z2=%d, wanted %d got %d, dropped %d).\n",*z1,*z2,count,bytes,drop); +- hfctmp->clicks = 0; +- } +- /* hm, we are processing the b chan data tooooo slowly... let's drop the lost audio */ +- newz2 = *z2 + drop; +- if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { +- newz2 -= hfc_B_FIFO_SIZE; +- } +- *z2 = newz2; +- } ++ chtmp->rx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1RX_Z1+0x1f*4); ++ chtmp->rx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1RX_ZOFF); ++ chtmp->rx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2RX_Z1+0x1f*4); ++ chtmp->rx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2RX_ZOFF); ++ chtmp->rx.z2=hfc_B_SUB_VAL; ++ chtmp->rx.diff=0; + +- +- maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z2; +- if (maxlen > count) { +- maxlen = count; +- } +- if (whichB == 1) { +- memcpy(hfctmp->ztdev->chans[0].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + *z2), maxlen); +- } else { +- memcpy(hfctmp->ztdev->chans[1].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + *z2), maxlen); +- } +- newz2 = *z2 + count; +- if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { +- newz2 -= hfc_B_FIFO_SIZE; ++ chtmp->tx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z1+0x1f*4); ++ chtmp->tx.c[0].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z2+0x1f*4); ++ chtmp->tx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1TX_ZOFF); ++ chtmp->tx.c[0].filled=0; ++ chtmp->tx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z1+0x1f*4); ++ chtmp->tx.c[1].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z2+0x1f*4); ++ chtmp->tx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2TX_ZOFF); ++ chtmp->tx.c[1].filled=0; ++ chtmp->tx.z1=hfc_B_SUB_VAL; ++ chtmp->tx.diff=0; ++ ++ hfc_dch_init(hfctmp); ++ ++ chtmp->initialized=0; ++} ++ ++static int hfc_bch_check(struct hfc_card *hfctmp){ ++ struct bch *chtmp=&hfctmp->bch; ++ int x,r; ++ ++ for(x=0;x<2;x++){ ++ chtmp->tx.c[x].filled=(chtmp->tx.z1-*chtmp->tx.c[x].z2p+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE; ++ chtmp->rx.c[x].filled=(*chtmp->rx.c[x].z1p-chtmp->rx.z2+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE; + } +- *z2 = newz2; +- +- count -= maxlen; +- if (count > 0) { +- // Buffer wrap +- if (whichB == 1) { +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4)); +- memcpy(hfctmp->ztdev->chans[0].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + hfc_B_SUB_VAL), count); +- } else { +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4)); +- memcpy(hfctmp->ztdev->chans[1].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + hfc_B_SUB_VAL), count); +- } +- newz2 = *z2 + count; +- if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { +- newz2 -= hfc_B_FIFO_SIZE; ++ if(chtmp->fill_fifo){ ++ chtmp->checkcnt++; ++ chtmp->checkcnt%=ZT_CHUNKSIZE; ++ r=!chtmp->checkcnt; ++ }else{ ++ x=chtmp->tx.c[0].filled-chtmp->tx.c[1].filled; ++ if(abs(x-chtmp->tx.diff)>1){ ++ printk(KERN_CRIT "zaphfc[%d]: tx sync changed: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled); ++ chtmp->tx.diff=x; + } ++ r=chtmp->tx.c[0].filled<=ZT_CHUNKSIZE*jitterbuffer&&chtmp->tx.c[1].filled<=ZT_CHUNKSIZE*jitterbuffer; + } ++ return(r); ++} + ++#define hfc_bch_inc_z(a,b) (a)=((a)-hfc_B_SUB_VAL+(b))%hfc_B_FIFO_SIZE+hfc_B_SUB_VAL + +- if (whichB == 1) { +- zt_ec_chunk(&hfctmp->ztdev->chans[0], hfctmp->ztdev->chans[0].readchunk, hfctmp->ztdev->chans[0].writechunk); +- } else { +- zt_ec_chunk(&hfctmp->ztdev->chans[1], hfctmp->ztdev->chans[1].readchunk, hfctmp->ztdev->chans[1].writechunk); ++static void hfc_bch_tx(struct hfc_card *hfctmp){ ++ struct bch *chtmp=&hfctmp->bch; ++ int x; ++ ++ for(x=0;x<2;x++) ++ memcpy((void *)(chtmp->tx.c[x].fifo_base+chtmp->tx.z1),hfctmp->ztdev->chans[x].writechunk,ZT_CHUNKSIZE); ++ hfc_bch_inc_z(chtmp->tx.z1,ZT_CHUNKSIZE); ++ if(chtmp->fill_fifo){ ++ chtmp->fill_fifo--; ++ }else if(chtmp->tx.c[0].filled<=1||chtmp->tx.c[1].filled<=1){ ++ chtmp->fill_fifo=jitterbuffer; ++ if(chtmp->initialized) ++ printk(KERN_CRIT "zaphfc[%d]: b channel buffer underrun: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled); + } +- return; ++ if(!chtmp->fill_fifo) ++ for(x=0;x<2;x++)*chtmp->tx.c[x].z1p=chtmp->tx.z1; + } + +- +-static void hfc_dtrans(struct hfc_card *hfctmp) { +- // we are called with irqs disabled from the irq handler ++static void hfc_bch_rx(struct hfc_card *hfctmp){ ++ struct bch *chtmp=&hfctmp->bch; + int x; +- int count, maxlen, total; +- unsigned char *f1, *f2, newf1; +- unsigned short *z1, *z2, newz1; +- int frames, freebytes; + +- if (hfctmp->ztdev->chans[2].bytes2transmit == 0) { +- return; ++ x=chtmp->rx.c[0].filled-chtmp->rx.c[1].filled; ++ if(abs(x-chtmp->rx.diff)>1){ ++ printk(KERN_CRIT "zaphfc[%d]: rx sync changed: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled); ++ chtmp->rx.diff=x; + } +- +- f1 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F1); +- f2 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F2); +- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4)); +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z2 + (*f1 * 4)); +- +- frames = (*f1 - *f2) & hfc_FMASK; +- if (frames < 0) { +- frames += hfc_MAX_DFRAMES + 1; ++ if(chtmp->rx.c[0].filled>=ZT_CHUNKSIZE&&chtmp->rx.c[1].filled>=ZT_CHUNKSIZE){ ++ if((chtmp->rx.c[0].filled>=ZT_CHUNKSIZE*(jitterbuffer+2)&&chtmp->rx.c[1].filled>=ZT_CHUNKSIZE*(jitterbuffer+2))||!chtmp->initialized){ ++ if(chtmp->initialized) ++ printk(KERN_CRIT "zaphfc[%d]: b channel buffer overflow: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled); ++ hfc_bch_inc_z(chtmp->rx.z2,chtmp->rx.c[0].filled-chtmp->rx.c[0].filled%ZT_CHUNKSIZE-ZT_CHUNKSIZE); ++ chtmp->initialized=1; ++ } ++ for(x=0;x<2;x++){ ++ memcpy(hfctmp->ztdev->chans[x].readchunk,(void *)(chtmp->rx.c[x].fifo_base+chtmp->rx.z2),ZT_CHUNKSIZE); ++ zt_ec_chunk(&hfctmp->ztdev->chans[x],hfctmp->ztdev->chans[x].readchunk,hfctmp->ztdev->chans[x].writechunk); ++ } ++ hfc_bch_inc_z(chtmp->rx.z2,ZT_CHUNKSIZE); + } ++} + +- if (frames >= hfc_MAX_DFRAMES) { +- printk(KERN_CRIT "zaphfc: dchan tx fifo total number of frames exceeded!\n"); +- return; +- } ++/*===========================================================================*/ + +- freebytes = *z2 - *z1; +- if (freebytes <= 0) { +- freebytes += hfc_D_FIFO_SIZE; +- } +- count = hfctmp->ztdev->chans[2].bytes2transmit; +- +- total = count; +- if (freebytes < count) { +- printk(KERN_CRIT "zaphfc: dchan tx fifo not enough free bytes! (z1=%d, z2=%d)\n",*z1,*z2); +- return; +- } +- +- newz1 = (*z1 + count) & hfc_ZMASK; +- newf1 = ((*f1 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1); // next frame +- +- if (count > 0) { +- if (debug) { +- printk(KERN_CRIT "zaphfc: card %d TX [ ", hfctmp->cardno); +- for (x=0; xdch; ++ u8 tx_f2_v; ++ u16 x; ++ ++ if(hfctmp->ztdev->chans[2].bytes2transmit){ ++ if(debug){ ++ printk(KERN_CRIT "zaphfc[%d]: card TX [ ",hfctmp->cardno); ++ for(x=0;xztdev->chans[2].bytes2transmit;x++){ + printk("%#2x ",hfctmp->dtransbuf[x]); + } +- if (hfctmp->ztdev->chans[2].eoftx == 1) { +- printk("] %d bytes\n", count); +- } else { +- printk("..] %d bytes\n", count); +- } +- } +- maxlen = hfc_D_FIFO_SIZE - *z1; +- if (maxlen > count) { +- maxlen = count; ++ printk("] %d bytes\n",hfctmp->ztdev->chans[2].bytes2transmit); + } +- memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF + *z1),hfctmp->ztdev->chans[2].writechunk, maxlen); +- count -= maxlen; +- if (count > 0) { +- memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF),(char *)(hfctmp->ztdev->chans[2].writechunk + maxlen), count); ++ tx_f2_v=*chtmp->tx.f2.p; ++ if(!(tx_f2_v-chtmp->tx.f1.v+hfc_MAX_DFRAMES+1-1)&(hfc_MAX_DFRAMES+1-1)){ ++ printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo total number of frames exceeded!\n",hfctmp->cardno); ++ }else{ ++ if(((*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z2+tx_f2_v*4)-chtmp->tx.f1.z1.v+hfc_D_FIFO_SIZE-1)&(hfc_D_FIFO_SIZE-1))ztdev->chans[2].bytes2transmit){ ++ printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo not enough space for frame!\n",hfctmp->cardno); ++ }else{ ++ chtmp->tx.f1.v=((chtmp->tx.f1.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1); ++ x=min(hfctmp->ztdev->chans[2].bytes2transmit,hfc_D_FIFO_SIZE-chtmp->tx.f1.z1.v); ++ memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF+chtmp->tx.f1.z1.v,hfctmp->ztdev->chans[2].writechunk,x); ++ memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF,hfctmp->ztdev->chans[2].writechunk+x,hfctmp->ztdev->chans[2].bytes2transmit-x); ++ *(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z2+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v; ++ chtmp->tx.f1.z1.v=(chtmp->tx.f1.z1.v+hfctmp->ztdev->chans[2].bytes2transmit+hfc_D_FIFO_SIZE)&(hfc_D_FIFO_SIZE-1); ++ *(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z1+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v; ++ *chtmp->tx.f1.p=chtmp->tx.f1.v; ++ } + } + } +- +- *z1 = newz1; +- +- if (hfctmp->ztdev->chans[2].eoftx == 1) { +- *f1 = newf1; +- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4)); +- *z1 = newz1; +- hfctmp->ztdev->chans[2].eoftx = 0; +- } +-// printk(KERN_CRIT "zaphfc: dchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2); +- return; + } + +-/* receive a complete hdlc frame, skip broken or short frames */ +-static void hfc_drec(struct hfc_card *hfctmp) { +- int count=0, maxlen=0, framelen=0; +- unsigned char *f1, *f2, *crcstat; +- unsigned short *z1, *z2, oldz2, newz2; ++static void hfc_dch_rx(struct hfc_card *hfctmp){ ++ struct dch *chtmp=&hfctmp->dch; ++ u16 size; + + hfctmp->ztdev->chans[2].bytes2receive=0; +- hfctmp->ztdev->chans[2].eofrx = 0; +- +- /* put the received data into the zaptel buffer +- we'll call zt_receive() later when the timer fires. */ +- f1 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F1); +- f2 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F2); +- +- if (*f1 == *f2) return; /* nothing received, strange eh? */ +- +- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z1 + (*f2 * 4)); +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4)); +- +- /* calculate length of frame, including 2 bytes CRC and 1 byte STAT */ +- count = *z1 - *z2; +- +- if (count < 0) { +- count += hfc_D_FIFO_SIZE; /* ring buffer wrapped */ +- } +- count++; +- framelen = count; +- +- crcstat = (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z1); +- +- if ((framelen < 4) || (*crcstat != 0x0)) { +- /* the frame is too short for a valid HDLC frame or the CRC is borked */ +- printk(KERN_CRIT "zaphfc: empty HDLC frame or bad CRC received (framelen = %d, stat = %#x, card = %d).\n", framelen, *crcstat, hfctmp->cardno); +- oldz2 = *z2; +- *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1); /* NEXT!!! */ +- // recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!! +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4)); +- *z2 = (oldz2 + framelen) & hfc_ZMASK; +- hfctmp->drecinframe = 0; +- hfctmp->regs.int_drec--; +- /* skip short or broken frames */ +- hfctmp->ztdev->chans[2].bytes2receive = 0; +- return; +- } +- +- count -= 1; /* strip STAT */ +- hfctmp->ztdev->chans[2].eofrx = 1; +- +- if (count + *z2 <= hfc_D_FIFO_SIZE) { +- maxlen = count; +- } else { +- maxlen = hfc_D_FIFO_SIZE - *z2; ++ hfctmp->ztdev->chans[2].eofrx=0; ++ if(*chtmp->rx.f1.p==chtmp->rx.f2.v){ ++ hfctmp->regs.int_drec=0; ++ }else{ ++ size=((*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DRX_Z1+chtmp->rx.f2.v*4)-chtmp->rx.f2.z2.v+hfc_D_FIFO_SIZE)&(hfc_D_FIFO_SIZE-1))+1; ++ if(size<4){ ++ printk(KERN_CRIT "zaphfc[%d]: empty HDLC frame received.\n",hfctmp->cardno); ++ }else{ ++ u16 x=min(size,(u16)(hfc_D_FIFO_SIZE-chtmp->rx.f2.z2.v)); ++ memcpy(hfctmp->drecbuf,hfctmp->fifos+hfc_FIFO_DRX_ZOFF+chtmp->rx.f2.z2.v,x); ++ memcpy(hfctmp->drecbuf+x,hfctmp->fifos+hfc_FIFO_DRX_ZOFF,size-x); ++ if(hfctmp->drecbuf[size-1]){ ++ printk(KERN_CRIT "zaphfc[%d]: received d channel frame with bad CRC.\n",hfctmp->cardno); ++ }else{ ++ hfctmp->ztdev->chans[2].bytes2receive=size-1; ++ hfctmp->ztdev->chans[2].eofrx=1; ++ } ++ } ++ chtmp->rx.f2.z2.v=(chtmp->rx.f2.z2.v+size)&(hfc_D_FIFO_SIZE-1); ++ chtmp->rx.f2.v=((chtmp->rx.f2.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1); + } +- +- /* copy first part */ +- memcpy(hfctmp->drecbuf, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z2), maxlen); +- hfctmp->ztdev->chans[2].bytes2receive += maxlen; +- +- count -= maxlen; +- if (count > 0) { +- /* ring buffer wrapped, copy rest from start of d fifo */ +- memcpy(hfctmp->drecbuf + maxlen, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF), count); +- hfctmp->ztdev->chans[2].bytes2receive += count; +- } +- +- /* frame read */ +- oldz2 = *z2; +- newz2 = (oldz2 + framelen) & hfc_ZMASK; +- *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1); /* NEXT!!! */ +- /* recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!! */ +- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4)); +- *z2 = newz2; +- hfctmp->drecinframe = 0; +- hfctmp->regs.int_drec--; + } + +-#ifndef RTAITIMING ++/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ ++ + #ifdef LINUX26 + static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + #else + static void hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + #endif + struct hfc_card *hfctmp = dev_id; +- unsigned long flags = 0; +- unsigned char stat; +-#else +-static void hfc_service(struct hfc_card *hfctmp) { +-#endif ++ struct hfc_card *hfctmp2; + struct zt_hfc *zthfc; +- unsigned char s1, s2, l1state; ++ unsigned char stat, s1, s2, l1state; ++ unsigned long flags; ++ unsigned long flags2=0; + int x; + + if (!hfctmp) { +-#ifndef RTAITIMING + #ifdef LINUX26 + return IRQ_NONE; + #else + return; + #endif +-#else +- /* rtai */ +- return; +-#endif + } + + if (!hfctmp->pci_io) { + printk(KERN_WARNING "%s: IO-mem disabled, cannot handle interrupt\n", + __FUNCTION__); +-#ifndef RTAITIMING + #ifdef LINUX26 + return IRQ_NONE; + #else + return; + #endif +-#else +- /* rtai */ +- return; +-#endif + } +- +- /* we assume a few things in this irq handler: +- - the hfc-pci will only generate "timer" irqs (proc/non-proc) +- - we need to use every 8th IRQ (to generate 1khz timing) +- OR +- - if we use rtai for timing the hfc-pci will not generate ANY irq, +- instead rtai will call this "fake" irq with a 1khz realtime timer. :) +- - rtai will directly service the card, not like it used to by triggering +- the linux irq +- */ + +-#ifndef RTAITIMING + spin_lock_irqsave(&hfctmp->lock, flags); + stat = hfc_inb(hfctmp, hfc_STATUS); +- + if ((stat & hfc_STATUS_ANYINT) == 0) { + // maybe we are sharing the irq + spin_unlock_irqrestore(&hfctmp->lock,flags); +@@ -605,8 +454,6 @@ + return; + #endif + } +-#endif +- + s1 = hfc_inb(hfctmp, hfc_INT_S1); + s2 = hfc_inb(hfctmp, hfc_INT_S2); + if (s1 != 0) { +@@ -625,18 +472,10 @@ + } + switch (l1state) { + case 3: +-#ifdef RTAITIMING +- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state); +-#else + sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d)", hfctmp->cardno, l1state); +-#endif + break; + default: +-#ifdef RTAITIMING +- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state); +-#else + sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d)", hfctmp->cardno, l1state); +-#endif + } + if (l1state == 2) { + hfc_outb(hfctmp, hfc_STATES, hfc_STATES_ACTIVATE | hfc_STATES_DO_ACTION | hfc_STATES_NT_G2_G3); +@@ -650,18 +489,10 @@ + } + switch (l1state) { + case 7: +-#ifdef RTAITIMING +- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state); +-#else + sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d)", hfctmp->cardno, l1state); +-#endif + break; + default: +-#ifdef RTAITIMING +- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state); +-#else + sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d)", hfctmp->cardno, l1state); +-#endif + } + if (l1state == 3) { + hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE); +@@ -671,7 +502,7 @@ + } + if (s1 & hfc_INTS_DREC) { + // D chan RX (bit 5) +- hfctmp->regs.int_drec++; ++ hfctmp->regs.int_drec = 1; + // mr. zapata there is something for you! + // printk(KERN_CRIT "d chan rx\n"); + } +@@ -692,14 +523,10 @@ + // B1 chan TX (bit 0) + } + } +-#ifdef RTAITIMING +- /* fake an irq */ +- s2 |= hfc_M2_PROC_TRANS; +-#endif + if (s2 != 0) { + if (s2 & hfc_M2_PMESEL) { + // kaboom irq (bit 7) +- printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n"); ++ // printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n"); + } + if (s2 & hfc_M2_GCI_MON_REC) { + // RxR monitor channel (bit 2) +@@ -707,32 +534,30 @@ + if (s2 & hfc_M2_GCI_I_CHG) { + // GCI I-change (bit 1) + } +- if (s2 & hfc_M2_PROC_TRANS) { ++ if((s2&hfc_M2_PROC_TRANS)&&(hfctmp->cardno==timer_card)){ + // processing/non-processing transition (bit 0) +- hfctmp->ticks++; +-#ifndef RTAITIMING +- if (hfctmp->ticks > 7) { +- // welcome to zaptel timing :) +-#endif +- hfctmp->ticks = 0; +- ++ hfctmp2=hfctmp; ++ hfctmp=hfc_dev_list; ++ while(hfctmp){ ++ if(hfctmp->active){ ++ if(hfctmp!=hfctmp2)spin_lock_irqsave(&hfctmp->lock, flags2); ++ if(hfc_bch_check(hfctmp)){ + if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) { + // clear dchan buffer ++ // memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf)); ++ + hfctmp->ztdev->chans[2].bytes2transmit = 0; + hfctmp->ztdev->chans[2].maxbytes2transmit = hfc_D_FIFO_SIZE; + + zt_transmit(&(hfctmp->ztdev->span)); + +- hfc_btrans(hfctmp,1); +- hfc_btrans(hfctmp,2); +- hfc_dtrans(hfctmp); ++ hfc_bch_tx(hfctmp); ++ hfc_dch_tx(hfctmp); + } +- +- hfc_brec(hfctmp,1); +- hfc_brec(hfctmp,2); +- if (hfctmp->regs.int_drec > 0) { ++ hfc_bch_rx(hfctmp); ++ if (hfctmp->regs.int_drec) { + // dchan data to read +- hfc_drec(hfctmp); ++ hfc_dch_rx(hfctmp); + if (hfctmp->ztdev->chans[2].bytes2receive > 0) { + if (debug) { + printk(KERN_CRIT "zaphfc: card %d RX [ ", hfctmp->cardno); +@@ -757,19 +582,18 @@ + if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) { + zt_receive(&(hfctmp->ztdev->span)); + } +- +-#ifndef RTAITIMING + } +-#endif ++ if(hfctmp!=hfctmp2)spin_unlock_irqrestore(&hfctmp->lock,flags2); ++ } ++ hfctmp=hfctmp->next; ++ } ++ hfctmp=hfctmp2; + } +- + } +-#ifndef RTAITIMING + spin_unlock_irqrestore(&hfctmp->lock,flags); + #ifdef LINUX26 + return IRQ_RETVAL(1); + #endif +-#endif + } + + +@@ -826,22 +650,21 @@ + } + alreadyrunning = span->flags & ZT_FLAG_RUNNING; + +- if (!alreadyrunning) { +- span->chans[2].flags &= ~ZT_FLAG_HDLC; +- span->chans[2].flags |= ZT_FLAG_BRIDCHAN; +- +- span->flags |= ZT_FLAG_RUNNING; ++ if (alreadyrunning) return 0; + +- hfctmp->ticks = -2; +- hfctmp->clicks = 0; +- hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2; +- hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en); +- } else { +- return 0; +- } ++ span->chans[2].flags &= ~ZT_FLAG_HDLC; ++ span->chans[2].flags |= ZT_FLAG_BRIDCHAN; ++ ++ span->flags |= ZT_FLAG_RUNNING; ++ ++ hfctmp->ticks = -2; ++ hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2; ++ hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en); + ++ hfc_bch_init(hfctmp); + // drivers, start engines! + hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE); ++ hfctmp->active=1; + return 0; + } + +@@ -871,17 +694,9 @@ + + sprintf(zthfc->span.name, "ZTHFC%d", hfc_dev_count + 1); + if (hfctmp->regs.nt_mode == 1) { +-#ifdef RTAITIMING +- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] [realtime]", hfc_dev_count + 1); +-#else + sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT]", hfc_dev_count + 1); +-#endif + } else { +-#ifdef RTAITIMING +- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] [realtime]", hfc_dev_count + 1); +-#else + sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE]", hfc_dev_count + 1); +-#endif + } + + zthfc->span.spanconfig = zthfc_spanconfig; +@@ -918,32 +733,6 @@ + return 0; + } + +-#ifdef RTAITIMING +-#define TICK_PERIOD 1000000 +-#define TICK_PERIOD2 1000000000 +-#define TASK_PRIORITY 1 +-#define STACK_SIZE 10000 +- +-static RT_TASK rt_task; +-static struct hfc_card *rtai_hfc_list[hfc_MAX_CARDS]; +-static unsigned char rtai_hfc_counter = 0; +- +-static void rtai_register_hfc(struct hfc_card *hfctmp) { +- rtai_hfc_list[rtai_hfc_counter++] = hfctmp; +-} +- +-static void rtai_loop(int t) { +- int i=0; +- for (;;) { +- for (i=0; i < rtai_hfc_counter; i++) { +- if (rtai_hfc_list[i] != NULL) +- hfc_service(rtai_hfc_list[i]); +- } +- rt_task_wait_period(); +- } +-} +-#endif +- + int hfc_findCards(int pcivendor, int pcidevice, char *vendor_name, char *card_name) { + struct pci_dev *tmp; + struct hfc_card *hfctmp = NULL; +@@ -959,9 +748,9 @@ + } + pci_set_master(tmp); + +- hfctmp = kmalloc(sizeof(struct hfc_card), GFP_KERNEL); ++ hfctmp = vmalloc(sizeof(struct hfc_card)); + if (!hfctmp) { +- printk(KERN_WARNING "zaphfc: unable to kmalloc!\n"); ++ printk(KERN_WARNING "zaphfc: unable to vmalloc!\n"); + pci_disable_device(tmp); + multi_hfc = NULL; + return -ENOMEM; +@@ -969,6 +758,7 @@ + memset(hfctmp, 0x0, sizeof(struct hfc_card)); + spin_lock_init(&hfctmp->lock); + ++ hfctmp->active=0; + hfctmp->pcidev = tmp; + hfctmp->pcibus = tmp->bus->number; + hfctmp->pcidevfn = tmp->devfn; +@@ -982,49 +772,39 @@ + hfctmp->pci_io = (char *) tmp->resource[1].start; + if (!hfctmp->pci_io) { + printk(KERN_WARNING "zaphfc: no iomem!\n"); +- kfree(hfctmp); ++ vfree(hfctmp); + pci_disable_device(tmp); + multi_hfc = NULL; + return -1; + } +- +- hfctmp->fifomem = kmalloc(65536, GFP_KERNEL); +- if (!hfctmp->fifomem) { +- printk(KERN_WARNING "zaphfc: unable to kmalloc fifomem!\n"); +- kfree(hfctmp); ++ ++ hfctmp->fifos=(void *)__get_free_pages(GFP_KERNEL,log2(hfc_FIFO_MEM_SIZE_PAGES)); ++ if (!hfctmp->fifos) { ++ printk(KERN_WARNING "zaphfc: unable to __get_free_pages fifomem!\n"); ++ vfree(hfctmp); + pci_disable_device(tmp); + multi_hfc = NULL; + return -ENOMEM; + } else { +- memset(hfctmp->fifomem, 0x0, 65536); +- hfctmp->fifos = (void *)(((ulong) hfctmp->fifomem) & ~0x7FFF) + 0x8000; + pci_write_config_dword(hfctmp->pcidev, 0x80, (u_int) virt_to_bus(hfctmp->fifos)); + hfctmp->pci_io = ioremap((ulong) hfctmp->pci_io, 256); + } + +-#ifdef RTAITIMING +- /* we need no stinking irq */ +- hfctmp->irq = 0; +-#else + if (request_irq(hfctmp->irq, &hfc_interrupt, SA_INTERRUPT | SA_SHIRQ, "zaphfc", hfctmp)) { + printk(KERN_WARNING "zaphfc: unable to register irq\n"); +- kfree(hfctmp->fifomem); +- kfree(hfctmp); ++ free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES)); ++ vfree(hfctmp); + iounmap((void *) hfctmp->pci_io); + pci_disable_device(tmp); + multi_hfc = NULL; + return -EIO; + } +-#endif + +-#ifdef RTAITIMING +- rtai_register_hfc(hfctmp); +-#endif + printk(KERN_INFO +- "zaphfc: %s %s configured at mem %lx fifo %lx(%#x) IRQ %d HZ %d\n", ++ "zaphfc: %s %s configured at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n", + vendor_name, card_name, +- (unsigned long) hfctmp->pci_io, +- (unsigned long) hfctmp->fifos, ++ (u_int) hfctmp->pci_io, ++ (u_int) hfctmp->fifos, + (u_int) virt_to_bus(hfctmp->fifos), + hfctmp->irq, HZ); + pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY); // enable memio +@@ -1041,11 +821,21 @@ + hfctmp->regs.nt_mode = 0; + } + +- zthfc = kmalloc(sizeof(struct zt_hfc),GFP_KERNEL); ++ if(sync_slave&(1<regs.mst_mode=hfc_MST_MODE_SLAVE|hfc_MST_MODE_F0_LONG_DURATION; ++ hfctmp->regs.mst_emod=hfc_MST_EMOD_SLOW_CLOCK_ADJ; ++ }else{ ++ printk(KERN_INFO "zaphfc: Card %d configured for master mode\n",hfc_dev_count); ++ hfctmp->regs.mst_mode=hfc_MST_MODE_MASTER|hfc_MST_MODE_F0_LONG_DURATION; ++ hfctmp->regs.mst_emod=0; ++ } ++ ++ zthfc = vmalloc(sizeof(struct zt_hfc)); + if (!zthfc) { +- printk(KERN_CRIT "zaphfc: unable to kmalloc!\n"); ++ printk(KERN_CRIT "zaphfc: unable to vmalloc!\n"); + hfc_shutdownCard(hfctmp); +- kfree(hfctmp); ++ vfree(hfctmp); + multi_hfc = NULL; + return -ENOMEM; + } +@@ -1071,7 +861,6 @@ + memset(hfctmp->btransbuf[1], 0x0, sizeof(hfctmp->btransbuf[1])); + hfctmp->ztdev->chans[1].writechunk = hfctmp->btransbuf[1]; + +- + hfc_registerCard(hfctmp); + hfc_resetCard(hfctmp); + tmp = pci_find_device(pcivendor, pcidevice, multi_hfc); +@@ -1079,58 +868,42 @@ + return 0; + } + +- +- + int init_module(void) { + int i = 0; +-#ifdef RTAITIMING +- RTIME tick_period; +- for (i=0; i < hfc_MAX_CARDS; i++) { +- rtai_hfc_list[i] = NULL; ++ if(jitterbuffer<1){ ++ printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to minimum of 1\n",jitterbuffer); ++ jitterbuffer=1; ++ }else if(jitterbuffer>500){ ++ printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to maximum of 500\n",jitterbuffer); ++ jitterbuffer=500; + } +- rt_set_periodic_mode(); +-#endif +- i = 0; ++ printk(KERN_INFO "zaphfc: jitterbuffer size: %d\n",jitterbuffer); + while (id_list[i].vendor_id) { + multi_hfc = NULL; + hfc_findCards(id_list[i].vendor_id, id_list[i].device_id, id_list[i].vendor_name, id_list[i].card_name); + i++; + } +-#ifdef RTAITIMING +- for (i=0; i < hfc_MAX_CARDS; i++) { +- if (rtai_hfc_list[i]) { +- printk(KERN_INFO +- "zaphfc: configured %d at mem %#x fifo %#x(%#x) for realtime servicing\n", +- rtai_hfc_list[i]->cardno, +- (u_int) rtai_hfc_list[i]->pci_io, +- (u_int) rtai_hfc_list[i]->fifos, +- (u_int) virt_to_bus(rtai_hfc_list[i]->fifos)); +- +- } +- } +- rt_task_init(&rt_task, rtai_loop, 1, STACK_SIZE, TASK_PRIORITY, 0, 0); +- tick_period = start_rt_timer(nano2count(TICK_PERIOD)); +- rt_task_make_periodic(&rt_task, rt_get_time() + tick_period, tick_period); +-#endif + printk(KERN_INFO "zaphfc: %d hfc-pci card(s) in this box.\n", hfc_dev_count); + return 0; + } + + void cleanup_module(void) { + struct hfc_card *tmpcard; +-#ifdef RTAITIMING +- stop_rt_timer(); +- rt_task_delete(&rt_task); +-#endif ++ + printk(KERN_INFO "zaphfc: stop\n"); + // spin_lock(®isterlock); ++ tmpcard=hfc_dev_list; ++ while(tmpcard){ ++ hfc_shutdownCard1(tmpcard); ++ tmpcard=tmpcard->next; ++ } + while (hfc_dev_list != NULL) { + if (hfc_dev_list == NULL) break; +- hfc_shutdownCard(hfc_dev_list); ++ hfc_shutdownCard2(hfc_dev_list); + tmpcard = hfc_dev_list; + hfc_dev_list = hfc_dev_list->next; + if (tmpcard != NULL) { +- kfree(tmpcard); ++ vfree(tmpcard); + tmpcard = NULL; + printk(KERN_INFO "zaphfc: freed one card.\n"); + } +@@ -1141,11 +914,17 @@ + + + #ifdef LINUX26 +-module_param(modes, int, 0600); ++module_param(modes, int, 0400); + module_param(debug, int, 0600); ++module_param(sync_slave, int, 0400); ++module_param(timer_card, int, 0400); ++module_param(jitterbuffer, int, 0400); + #else + MODULE_PARM(modes,"i"); + MODULE_PARM(debug,"i"); ++MODULE_PARM(sync_slave,"i"); ++MODULE_PARM(timer_card,"i"); ++MODULE_PARM(jitterbuffer,"i"); + #endif + + MODULE_DESCRIPTION("HFC-S PCI A Zaptel Driver"); +@@ -1153,3 +932,6 @@ + #ifdef MODULE_LICENSE + MODULE_LICENSE("GPL"); + #endif ++ ++/* vim:set sw=4: */ ++ +diff -urN bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.h zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.h +--- bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.h 2005-02-26 23:30:32.000000000 +0100 ++++ zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.h 2005-03-02 20:43:04.000000000 +0100 +@@ -135,8 +135,12 @@ + /* bits in HFCD_MST_MODE */ + #define hfc_MST_MODE_MASTER 0x01 + #define hfc_MST_MODE_SLAVE 0x00 ++#define hfc_MST_MODE_F0_LONG_DURATION 0x08 + /* remaining bits are for codecs control */ + ++/* bits in HFCD_MST_EMOD */ ++#define hfc_MST_EMOD_SLOW_CLOCK_ADJ 0x01 ++ + /* bits in HFCD_SCTRL */ + #define hfc_SCTRL_B1_ENA 0x01 + #define hfc_SCTRL_B2_ENA 0x02 +@@ -236,6 +240,9 @@ + #define hfc_BTRANS_THRESHOLD 128 + #define hfc_BTRANS_THRESMASK 0x00 + ++#define hfc_FIFO_MEM_SIZE_BYTES (32*1024) ++#define hfc_FIFO_MEM_SIZE_PAGES ((hfc_FIFO_MEM_SIZE_BYTES+PAGE_SIZE-1)/PAGE_SIZE) ++ + /* Structures */ + + typedef struct hfc_regs { +@@ -249,20 +256,67 @@ + unsigned char connect; + unsigned char trm; + unsigned char mst_mode; ++ unsigned char mst_emod; + unsigned char bswapped; + unsigned char nt_mode; + unsigned char int_drec; + } hfc_regs; + ++struct bch { ++ int fill_fifo,checkcnt,initialized; ++ struct { ++ u16 z2; ++ struct { ++ volatile u16 *z1p; ++ volatile u8 *fifo_base; ++ int filled; ++ } c[2]; ++ int diff; ++ } rx; ++ struct { ++ u16 z1; ++ struct { ++ volatile u16 *z1p,*z2p; ++ volatile u8 *fifo_base; ++ int filled; ++ } c[2]; ++ int diff; ++ } tx; ++}; ++ ++struct dch { ++ struct { ++ struct { ++ volatile u8 *p; ++ } f1; ++ struct { ++ u8 v; ++ struct { ++ u16 v; ++ } z2; ++ } f2; ++ } rx; ++ struct { ++ struct { ++ u8 v; ++ volatile u8 *p; ++ struct { ++ u16 v; ++ } z1; ++ } f1; ++ struct { ++ volatile u8 *p; ++ } f2; ++ } tx; ++}; ++ + typedef struct hfc_card { + spinlock_t lock; + unsigned int irq; + unsigned int iomem; + int ticks; +- int clicks; + unsigned char *pci_io; +- void *fifomem; // start of the shared mem +- volatile void *fifos; // 32k aligned mem for the fifos ++ void *fifos; // 32k aligned mem for the fifos + struct hfc_regs regs; + unsigned int pcibus; + unsigned int pcidevfn; +@@ -274,6 +328,9 @@ + unsigned char brecbuf[2][ZT_CHUNKSIZE]; + unsigned char btransbuf[2][ZT_CHUNKSIZE]; + unsigned char cardno; ++ int active; ++ struct bch bch; ++ struct dch dch; + struct hfc_card *next; + } hfc_card; + +@@ -284,6 +341,5 @@ + struct hfc_card *card; + } zt_hfc; + +-/* tune this */ +-#define hfc_BCHAN_BUFFER 8 +-#define hfc_MAX_CARDS 8 ++/* vim:set sw=4: */ ++ diff --git a/src/patches/asterisk-1.2.4-zaptel-bristuff-0.3.0-PRE-1l.patch b/src/patches/zaptel.patch similarity index 88% rename from src/patches/asterisk-1.2.4-zaptel-bristuff-0.3.0-PRE-1l.patch rename to src/patches/zaptel.patch index 96783c046c..c0d85877f0 100644 --- a/src/patches/asterisk-1.2.4-zaptel-bristuff-0.3.0-PRE-1l.patch +++ b/src/patches/zaptel.patch @@ -1,6 +1,8 @@ -diff -ur zaptel-1.2.3.orig/zaptel.c zaptel-1.2.3/zaptel.c ---- zaptel-1.2.3.orig/zaptel.c 2005-12-17 03:04:05.000000000 +0100 -+++ zaptel-1.2.3/zaptel.c 2006-01-31 09:28:29.000000000 +0100 +Only in zaptel-1.2.5: version.h +Only in zaptel-1.2.5: zaptel +diff -ur zaptel-1.2.5.orig/zaptel.c zaptel-1.2.5/zaptel.c +--- zaptel-1.2.5.orig/zaptel.c 2005-12-17 03:04:05.000000000 +0100 ++++ zaptel-1.2.5/zaptel.c 2006-04-10 10:39:37.000000000 +0200 @@ -4913,11 +4913,40 @@ *(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc); } @@ -114,9 +116,9 @@ diff -ur zaptel-1.2.3.orig/zaptel.c zaptel-1.2.3/zaptel.c } else { /* Not HDLC */ memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left); -diff -ur zaptel-1.2.3.orig/zaptel.h zaptel-1.2.3/zaptel.h ---- zaptel-1.2.3.orig/zaptel.h 2005-12-17 03:04:05.000000000 +0100 -+++ zaptel-1.2.3/zaptel.h 2006-01-31 09:28:29.000000000 +0100 +diff -ur zaptel-1.2.5.orig/zaptel.h zaptel-1.2.5/zaptel.h +--- zaptel-1.2.5.orig/zaptel.h 2005-12-17 03:04:05.000000000 +0100 ++++ zaptel-1.2.5/zaptel.h 2006-04-10 10:39:37.000000000 +0200 @@ -994,6 +994,13 @@ int do_ppp_error; struct sk_buff_head ppp_rq; @@ -151,9 +153,9 @@ diff -ur zaptel-1.2.3.orig/zaptel.h zaptel-1.2.3/zaptel.h struct zt_span { spinlock_t lock; void *pvt; /* Private stuff */ -diff -ur zaptel-1.2.3.orig/zconfig.h zaptel-1.2.3/zconfig.h ---- zaptel-1.2.3.orig/zconfig.h 2005-11-29 19:42:08.000000000 +0100 -+++ zaptel-1.2.3/zconfig.h 2006-01-31 09:28:29.000000000 +0100 +diff -ur zaptel-1.2.5.orig/zconfig.h zaptel-1.2.5/zconfig.h +--- zaptel-1.2.5.orig/zconfig.h 2005-11-29 19:42:08.000000000 +0100 ++++ zaptel-1.2.5/zconfig.h 2006-04-10 10:39:37.000000000 +0200 @@ -152,4 +152,10 @@ */ /* #define FXSFLASH */ -- 2.39.2