include "logger.h" and errno.h from asterisk.h - usage shows that they
[asterisk/asterisk.git] / channels / chan_zap.c
index 12aa7a8..633d7b9 100644 (file)
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
-#include <stdio.h>
-#include <string.h>
 #ifdef __NetBSD__
 #include <pthread.h>
 #include <signal.h>
 #else
 #include <sys/signal.h>
 #endif
-#include <errno.h>
-#include <stdlib.h>
-#if !defined(SOLARIS) && !defined(__FreeBSD__)
-#include <stdint.h>
-#endif
-#include <unistd.h>
 #include <sys/ioctl.h>
 #include <math.h>
 #include <ctype.h>
@@ -80,7 +72,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/lock.h"
 #include "asterisk/channel.h"
 #include "asterisk/config.h"
-#include "asterisk/logger.h"
 #include "asterisk/module.h"
 #include "asterisk/pbx.h"
 #include "asterisk/options.h"
@@ -111,6 +102,19 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
 
+#ifdef ZT_SPANINFO_HAS_LINECONFIG
+static const char *lbostr[] = {
+"0 db (CSU)/0-133 feet (DSX-1)",
+"133-266 feet (DSX-1)",
+"266-399 feet (DSX-1)",
+"399-533 feet (DSX-1)",
+"533-655 feet (DSX-1)",
+"-7.5db (CSU)",
+"-15db (CSU)",
+"-22.5db (CSU)"
+};
+#endif
+
 /*! Global jitterbuffer configuration - by default, jb is disabled */
 static struct ast_jb_conf default_jbconf =
 {
@@ -166,8 +170,8 @@ static const char tdesc[] = "Zapata Telephony Driver"
 #ifdef HAVE_PRI
                " w/PRI"
 #endif
-#ifdef HAVEL_SS7
-              "w/SS7"
+#ifdef HAVE_SS7
+              " w/SS7"
 #endif
 ;
 
@@ -321,6 +325,8 @@ static int ringt_base = DEFAULT_RINGT;
 #define LINKSTATE_UP           (1 << 2)
 #define LINKSTATE_DOWN         (1 << 3)
 
+#define SS7_NAI_DYNAMIC                -1
+
 struct zt_ss7 {
        pthread_t master;                                               /*!< Thread of master */
        ast_mutex_t lock;
@@ -333,6 +339,12 @@ struct zt_ss7 {
                LINKSET_STATE_DOWN = 0,
                LINKSET_STATE_UP
        } state;
+       char called_nai;                                                /*!< Called Nature of Address Indicator */
+       char calling_nai;                                               /*!< Calling Nature of Address Indicator */
+       char internationalprefix[10];                                   /*!< country access code ('00' for european dialplans) */
+       char nationalprefix[10];                                        /*!< area access code ('0' for european dialplans) */
+       char subscriberprefix[20];                                      /*!< area access code + area code ('0'+area code for european dialplans) */
+       char unknownprefix[20];                                         /*!< for unknown dialplans */
        struct ss7 *ss7;
        struct zt_pvt *pvts[MAX_CHANNELS];                              /*!< Member channel pvt structs */
 };
@@ -542,7 +554,7 @@ static struct zt_pvt {
        unsigned int inservice:1;
        unsigned int locallyblocked:1;
        unsigned int remotelyblocked:1;
-#if defined(HAVE_PRI)
+#if defined(HAVE_PRI) || defined(HAVE_SS7)
        unsigned int alerting:1;
        unsigned int alreadyhungup:1;
        unsigned int isidlecall:1;
@@ -562,9 +574,10 @@ static struct zt_pvt {
        char language[MAX_LANGUAGE];
        char mohinterpret[MAX_MUSICCLASS];
        char mohsuggest[MAX_MUSICCLASS];
-#ifdef PRI_ANI
+#if defined(PRI_ANI) || defined(HAVE_SS7)
        char cid_ani[AST_MAX_EXTENSION];
 #endif
+       int cid_ani2;
        char cid_num[AST_MAX_EXTENSION];
        int cid_ton;                                    /*!< Type Of Number (TON) */
        char cid_name[AST_MAX_EXTENSION];
@@ -576,13 +589,14 @@ static struct zt_pvt {
        char callwait_name[AST_MAX_EXTENSION];
        char rdnis[AST_MAX_EXTENSION];
        char dnid[AST_MAX_EXTENSION];
-       unsigned int group;
+       ast_group_t group;
        int law;
        int confno;                                     /*!< Our conference */
        int confusers;                                  /*!< Who is using our conference */
        int propconfno;                                 /*!< Propagated conference number */
        ast_group_t callgroup;
        ast_group_t pickupgroup;
+       struct ast_variable *vars;
        int channel;                                    /*!< Channel Number or CRV */
        int span;                                       /*!< Span number */
        time_t guardtime;                               /*!< Must wait this much time before using for new call */
@@ -641,9 +655,16 @@ static struct zt_pvt {
 #ifdef HAVE_SS7
        struct zt_ss7 *ss7;
        struct isup_call *ss7call;
+       char charge_number[50];
+       char gen_add_number[50];
+       unsigned char gen_add_num_plan;
+       unsigned char gen_add_nai;
+       unsigned char gen_add_pres_ind;
+       unsigned char gen_add_type;
        int transcap;
        int cic;                                                        /*!< CIC associated with channel */
        unsigned int dpc;                                               /*!< CIC's DPC */
+       unsigned int loopedback:1;
 #endif
        char begindigit;
 } *iflist = NULL, *ifend = NULL;
@@ -663,6 +684,10 @@ struct zt_chan_conf {
 #ifdef HAVE_PRI
        struct zt_pri pri;
 #endif
+
+#ifdef HAVE_SS7
+       struct zt_ss7 ss7;
+#endif
        ZT_PARAMS timing;
 
        char smdi_port[SMDI_MAX_FILENAME_LEN];
@@ -690,8 +715,17 @@ static struct zt_chan_conf zt_chan_conf_default(void) {
                        .localprefix = "",
                        .privateprefix = "",
                        .unknownprefix = "",
-
-                       .resetinterval = 3600
+                       .resetinterval = -1,
+               },
+#endif
+#ifdef HAVE_SS7
+               .ss7 = {
+                       .called_nai = SS7_NAI_NATIONAL,
+                       .calling_nai = SS7_NAI_NATIONAL,
+                       .internationalprefix = "",
+                       .nationalprefix = "",
+                       .subscriberprefix = "",
+                       .unknownprefix = ""
                },
 #endif
                .chan = {
@@ -888,13 +922,13 @@ static void wakeup_sub(struct zt_pvt *p, int a, void *pri)
 #endif                 
        for (;;) {
                if (p->subs[a].owner) {
-                       if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
+                       if (ast_channel_trylock(p->subs[a].owner)) {
                                ast_mutex_unlock(&p->lock);
                                usleep(1);
                                ast_mutex_lock(&p->lock);
                        } else {
                                ast_queue_frame(p->subs[a].owner, &ast_null_frame);
-                               ast_mutex_unlock(&p->subs[a].owner->lock);
+                               ast_channel_unlock(p->subs[a].owner);
                                break;
                        }
                } else
@@ -935,13 +969,13 @@ static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *data)
 #endif         
        for (;;) {
                if (p->owner) {
-                       if (ast_mutex_trylock(&p->owner->lock)) {
+                       if (ast_channel_trylock(p->owner)) {
                                ast_mutex_unlock(&p->lock);
                                usleep(1);
                                ast_mutex_lock(&p->lock);
                        } else {
                                ast_queue_frame(p->owner, f);
-                               ast_mutex_unlock(&p->owner->lock);
+                               ast_channel_unlock(p->owner);
                                break;
                        }
                } else
@@ -976,8 +1010,7 @@ static void swap_subs(struct zt_pvt *p, int a, int b)
        int tinthreeway;
        struct ast_channel *towner;
 
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
+       ast_debug(1, "Swapping %d and %d\n", a, b);
 
        tchan = p->subs[a].chan;
        towner = p->subs[a].owner;
@@ -992,9 +1025,9 @@ static void swap_subs(struct zt_pvt *p, int a, int b)
        p->subs[b].inthreeway = tinthreeway;
 
        if (p->subs[a].owner) 
-               p->subs[a].owner->fds[0] = p->subs[a].zfd;
+               ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].zfd);
        if (p->subs[b].owner) 
-               p->subs[b].owner->fds[0] = p->subs[b].zfd;
+               ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].zfd);
        wakeup_sub(p, a, NULL);
        wakeup_sub(p, b, NULL);
 }
@@ -1036,7 +1069,13 @@ static int zt_open(char *fn)
                }
        }
        bs = READ_SIZE;
-       if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) return -1;
+       if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) {
+               ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
+               x = errno;
+               close(fd);
+               errno = x;
+               return -1;
+       }
        return fd;
 }
 
@@ -1080,8 +1119,7 @@ static int alloc_sub(struct zt_pvt *p, int x)
                                p->subs[x].zfd = -1;
                                return -1;
                        }
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
+                       ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
                        return 0;
                } else
                        ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
@@ -1097,8 +1135,7 @@ static int unalloc_sub(struct zt_pvt *p, int x)
                ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
                return -1;
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
+       ast_debug(1, "Released sub %d of channel %d\n", x, p->channel);
        if (p->subs[x].zfd > -1) {
                zt_close(p->subs[x].zfd);
        }
@@ -1153,8 +1190,7 @@ static int zt_digit_begin(struct ast_channel *chan, char digit)
                                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
                } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
                        int res;
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
+                       ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", digit);
                        res = strlen(pvt->dialdest);
                        pvt->dialdest[res++] = digit;
                        pvt->dialdest[res] = '\0';
@@ -1179,8 +1215,7 @@ static int zt_digit_begin(struct ast_channel *chan, char digit)
                else
                        pvt->dialing = 1;
        } else {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
+               ast_debug(1, "Started VLDTMF digit '%c'\n", digit);
                pvt->dialing = 1;
                pvt->begindigit = digit;
        }
@@ -1215,8 +1250,7 @@ static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int durat
 
        if (pvt->begindigit) {
                x = -1;
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
+               ast_debug(1, "Ending VLDTMF digit '%c'\n", digit);
                res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x);
                pvt->dialing = 0;
                pvt->begindigit = 0;
@@ -1329,25 +1363,25 @@ static char *zap_sig2str(int sig)
        case SIG_FXOKS:
                return "FXO Kewlstart";
        case SIG_PRI:
-               return "PRI Signalling";
+               return "ISDN PRI";
        case SIG_SS7:
-               return "SS7 Signalling";
+               return "SS7";
        case SIG_SF:
-               return "SF (Tone) Signalling Immediate";
+               return "SF (Tone) Immediate";
        case SIG_SFWINK:
-               return "SF (Tone) Signalling Wink";
+               return "SF (Tone) Wink";
        case SIG_SF_FEATD:
-               return "SF (Tone) Signalling with Feature Group D (DTMF)";
+               return "SF (Tone) with Feature Group D (DTMF)";
        case SIG_SF_FEATDMF:
-               return "SF (Tone) Signalling with Feature Group D (MF)";
+               return "SF (Tone) with Feature Group D (MF)";
        case SIG_SF_FEATB:
-               return "SF (Tone) Signalling with Feature Group B (MF)";
+               return "SF (Tone) with Feature Group B (MF)";
        case SIG_GR303FXOKS:
-               return "GR-303 Signalling with FXOKS";
+               return "GR-303 with FXOKS";
        case SIG_GR303FXSKS:
-               return "GR-303 Signalling with FXSKS";
+               return "GR-303 with FXSKS";
        case 0:
-               return "Pseudo Signalling";
+               return "Pseudo";
        default:
                snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
                return buf;
@@ -1390,8 +1424,7 @@ static int conf_add(struct zt_pvt *p, struct zt_subchannel *c, int index, int sl
                p->confno = zi.confno;
        }
        memcpy(&c->curconf, &zi, sizeof(c->curconf));
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
+       ast_debug(1, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
        return 0;
 }
 
@@ -1423,8 +1456,7 @@ static int conf_del(struct zt_pvt *p, struct zt_subchannel *c, int index)
                ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
                return -1;
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
+       ast_debug(1, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
        memcpy(&c->curconf, &zi, sizeof(c->curconf));
        return 0;
 }
@@ -1538,8 +1570,7 @@ static int update_conf(struct zt_pvt *p)
                   Kill it. */
                p->confno = -1;
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
+       ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
        return 0;
 }
 
@@ -1550,13 +1581,11 @@ static void zt_enable_ec(struct zt_pvt *p)
        if (!p)
                return;
        if (p->echocanon) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
+               ast_debug(1, "Echo cancellation already on\n");
                return;
        }
        if (p->digital) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
+               ast_debug(1, "Echo cancellation isn't required on digital connection\n");
                return;
        }
        if (p->echocancel) {
@@ -1572,11 +1601,10 @@ static void zt_enable_ec(struct zt_pvt *p)
                        ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
                else {
                        p->echocanon = 1;
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
+                       ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel);
                }
-       } else if (option_debug)
-               ast_log(LOG_DEBUG, "No echo cancellation requested\n");
+       } else
+               ast_debug(1, "No echo cancellation requested\n");
 }
 
 static void zt_train_ec(struct zt_pvt *p)
@@ -1588,14 +1616,10 @@ static void zt_train_ec(struct zt_pvt *p)
                res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
                if (res)
                        ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
-               else {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
-               }
-       } else {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "No echo training requested\n");
-       }
+               else
+                       ast_debug(1, "Engaged echo training on channel %d\n", p->channel);
+       } else
+               ast_debug(1, "No echo training requested\n");
 }
 
 static void zt_disable_ec(struct zt_pvt *p)
@@ -1607,8 +1631,8 @@ static void zt_disable_ec(struct zt_pvt *p)
                res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
                if (res)
                        ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
-               else if (option_debug)
-                       ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
+               else
+                       ast_debug(1, "disabled echo cancellation on channel %d\n", p->channel);
        }
        p->echocanon = 0;
 }
@@ -1690,8 +1714,7 @@ static int set_actual_txgain(int fd, int chan, float gain, int law)
        g.chan = chan;
        res = ioctl(fd, ZT_GETGAINS, &g);
        if (res) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
+               ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
                return res;
        }
 
@@ -1709,8 +1732,7 @@ static int set_actual_rxgain(int fd, int chan, float gain, int law)
        g.chan = chan;
        res = ioctl(fd, ZT_GETGAINS, &g);
        if (res) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
+               ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
                return res;
        }
 
@@ -1754,13 +1776,16 @@ static int restore_gains(struct zt_pvt *p)
 static inline int zt_set_hook(int fd, int hs)
 {
        int x, res;
+
        x = hs;
        res = ioctl(fd, ZT_HOOK, &x);
-       if (res < 0) 
-       {
-               if (errno == EINPROGRESS) return 0;
+
+       if (res < 0) {
+               if (errno == EINPROGRESS)
+                       return 0;
                ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
        }
+
        return res;
 }
 
@@ -1803,8 +1828,7 @@ static int save_conference(struct zt_pvt *p)
                ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
                return -1;
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Disabled conferencing\n");
+       ast_debug(1, "Disabled conferencing\n");
        return 0;
 }
 
@@ -1819,8 +1843,7 @@ static int restore_conference(struct zt_pvt *p)
                        return -1;
                }
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Restored conferencing\n");
+       ast_debug(1, "Restored conferencing\n");
        return 0;
 }
 
@@ -1837,8 +1860,7 @@ static int send_cwcidspill(struct zt_pvt *p)
        p->cidlen += READ_SIZE * 4;
        p->cidpos = 0;
        send_callerid(p);
-       if (option_verbose > 2)
-               ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
+       ast_verb(3, "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
        return 0;
 }
 
@@ -1846,9 +1868,16 @@ static int has_voicemail(struct zt_pvt *p)
 {
        int new_msgs;
        struct ast_event *event;
+       char *mailbox, *context;
+
+       mailbox = context = ast_strdupa(p->mailbox);
+       strsep(&context, "@");
+       if (ast_strlen_zero(context))
+               context = "default";
 
        event = ast_event_get_cached(AST_EVENT_MWI,
-               AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, p->mailbox,
+               AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
+               AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
                AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
                AST_EVENT_IE_END);
 
@@ -1922,6 +1951,18 @@ static int zt_callwait(struct ast_channel *ast)
        return 0;
 }
 
+#ifdef HAVE_SS7
+static unsigned char cid_pres2ss7pres(int cid_pres)
+{
+        return (cid_pres >> 5) & 0x03;
+}
+
+static unsigned char cid_pres2ss7screen(int cid_pres)
+{
+       return cid_pres & 0x03;
+}
+#endif
+
 static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
 {
        struct zt_pvt *p = ast->tech_pvt;
@@ -2008,8 +2049,7 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                        if (c) {
                                p->dop.op = ZT_DIAL_OP_REPLACE;
                                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
+                               ast_debug(1, "FXO: setup deferred dialstring: %s\n", c);
                        } else {
                                p->dop.dialstr[0] = '\0';
                        }
@@ -2101,8 +2141,7 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
 #ifdef HAVE_PRI
                }
 #endif
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
+               ast_debug(1, "Dialing '%s'\n", c);
                p->dop.op = ZT_DIAL_OP_REPLACE;
 
                c += p->stripmsd;
@@ -2177,10 +2216,9 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                                ast_mutex_unlock(&p->lock);
                                return -1;
                        }
-               } else {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Deferring dialing...\n");
-               }
+               } else
+                       ast_debug(1, "Deferring dialing...\n");
+
                p->dialing = 1;
                if (ast_strlen_zero(c))
                        p->dialednone = 1;
@@ -2196,13 +2234,21 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                p->dialdest[0] = '\0';
                break;
        default:
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "not yet implemented\n");
+               ast_debug(1, "not yet implemented\n");
                ast_mutex_unlock(&p->lock);
                return -1;
        }
 #ifdef HAVE_SS7
        if (p->ss7) {
+               char ss7_called_nai;
+               int called_nai_strip;
+               char ss7_calling_nai;
+               int calling_nai_strip;
+               const char *charge_str = NULL;
+#if 0
+               const char *gen_address = NULL;
+#endif
+
                c = strchr(dest, '/');
                if (c)
                        c++;
@@ -2215,7 +2261,11 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                        l = NULL;
                }
 
-               ss7_grab(p, p->ss7);
+               if (ss7_grab(p, p->ss7)) {
+                       ast_log(LOG_WARNING, "Failed to grab SS7!\n");
+                       ast_mutex_unlock(&p->lock);
+                       return -1;
+               }
                p->digital = IS_DIGITAL(ast->transfercapability);
                p->ss7call = isup_new_call(p->ss7->ss7);
 
@@ -2226,9 +2276,55 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                        return -1;
                }
 
-               isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc, c + p->stripmsd, l);
+               called_nai_strip = 0;
+               ss7_called_nai = p->ss7->called_nai;
+               if (ss7_called_nai == SS7_NAI_DYNAMIC) { /* compute dynamically */
+                       if (strncmp(c + p->stripmsd, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
+                               called_nai_strip = strlen(p->ss7->internationalprefix);
+                               ss7_called_nai = SS7_NAI_INTERNATIONAL;
+                       } else if (strncmp(c + p->stripmsd, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
+                               called_nai_strip = strlen(p->ss7->nationalprefix);
+                               ss7_called_nai = SS7_NAI_NATIONAL;
+                       } else {
+                               ss7_called_nai = SS7_NAI_SUBSCRIBER;
+                       }
+               }
+               isup_set_called(p->ss7call, c + p->stripmsd + called_nai_strip, ss7_called_nai, p->ss7->ss7);
+
+               calling_nai_strip = 0;
+               ss7_calling_nai = p->ss7->calling_nai;
+               if ((l != NULL) && (ss7_calling_nai == SS7_NAI_DYNAMIC)) { /* compute dynamically */
+                       if (strncmp(l, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
+                               calling_nai_strip = strlen(p->ss7->internationalprefix);
+                               ss7_calling_nai = SS7_NAI_INTERNATIONAL;
+                       } else if (strncmp(l, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
+                               calling_nai_strip = strlen(p->ss7->nationalprefix);
+                               ss7_calling_nai = SS7_NAI_NATIONAL;
+                       } else {
+                               ss7_calling_nai = SS7_NAI_SUBSCRIBER;
+                       }
+               }
+               isup_set_calling(p->ss7call, l ? (l + calling_nai_strip) : NULL, ss7_calling_nai,
+                       p->use_callingpres ? cid_pres2ss7pres(ast->cid.cid_pres) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
+                       p->use_callingpres ? cid_pres2ss7screen(ast->cid.cid_pres) : SS7_SCREENING_USER_PROVIDED );
+
+               isup_set_oli(p->ss7call, ast->cid.cid_ani2);
+               isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc);
 
+               /* Set the charge number if it is set */
+               charge_str = pbx_builtin_getvar_helper(ast, "SS7_CHARGE_NUMBER");
+               if (charge_str)
+                       isup_set_charge(p->ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
+               
+#if 0
+               /* Set the generic address if it is set */
+               gen_address = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_ADDRESS");
+               if (gen_address)
+                       isup_set_gen_address(p->ss7call, gen_address, p->gen_add_nai,p->gen_add_pres_ind, p->gen_add_num_plan,p->gen_add_type); /* need to add some types here for NAI,PRES,TYPE */
+#endif
+               
                isup_iam(p->ss7->ss7, p->ss7call);
+               ast_setstate(ast, AST_STATE_DIALING);
                ss7_rel(p->ss7);
        }
 #endif /* HAVE_SS7 */
@@ -2251,17 +2347,17 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                        c++;
                else
                        c = dest;
-               if (!p->hidecalleridname)
-                       n = ast->cid.cid_name;
-               else
-                       n = NULL;
+
+               l = NULL;
+               n = NULL;
+
                if (!p->hidecallerid) {
                        l = ast->cid.cid_num;
-                       n = ast->cid.cid_name;
-               } else {
-                       l = NULL;
-                       n = NULL;
+                       if (!p->hidecalleridname) {
+                               n = ast->cid.cid_name;
+                       }
                }
+
                if (strlen(c) < p->stripmsd) {
                        ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
                        ast_mutex_unlock(&p->lock);
@@ -2298,13 +2394,11 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                }
                if (p->bearer || (mysig == SIG_FXSKS)) {
                        if (p->bearer) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
+                               ast_debug(1, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
                                p->bearer->call = p->call;
-                       } else {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
-                       }
+                       } else
+                               ast_debug(1, "I'm being setup with no bearer right now...\n");
+
                        pri_set_crv(p->pri->pri, p->call, p->channel, 0);
                }
                p->digital = IS_DIGITAL(ast->transfercapability);
@@ -2326,8 +2420,7 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                if (p->pri->facilityenable)
                        pri_facility_enable(p->pri->pri);
 
-               if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
+               ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
                dp_strip = 0;
                pridialplan = p->pri->dialplan - 1;
                if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */
@@ -2345,6 +2438,56 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                                pridialplan = PRI_LOCAL_ISDN;
                        }
                }
+               while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
+                       switch (c[p->stripmsd]) {
+                       case 'U':
+                               pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'I':
+                               pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'N':
+                               pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'L':
+                               pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'S':
+                               pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'A':
+                               pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'R':
+                               pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'u':
+                               pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
+                               break;
+                       case 'e':
+                               pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
+                               break;
+                       case 'x':
+                               pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
+                               break;
+                       case 'f':
+                               pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
+                               break;
+                       case 'n':
+                               pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
+                               break;
+                       case 'p':
+                               pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
+                               break;
+                       case 'r':
+                               pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
+                               break;
+                       default:
+                               if (isalpha(*c))
+                                       ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", *c > 'Z' ? "NPI" : "TON", *c);
+                       }
+                       c++;
+               }
                pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
 
                ldp_strip = 0;
@@ -2364,6 +2507,58 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                                prilocaldialplan = PRI_LOCAL_ISDN;
                        }
                }
+               if (l != NULL) {
+                       while (*l > '9' && *l != '*' && *l != '#') {
+                               switch (*l) {
+                               case 'U':
+                                       prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'I':
+                                       prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'N':
+                                       prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'L':
+                                       prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'S':
+                                       prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'A':
+                                       prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'R':
+                                       prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'u':
+                                       prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'e':
+                                       prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'x':
+                                       prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'f':
+                                       prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'n':
+                                       prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'p':
+                                       prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'r':
+                                       prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
+                                       break;
+                               default:
+                                       if (isalpha(*l))
+                                               ast_log(LOG_WARNING, "Unrecognized prilocaldialplan %s modifier: %c\n", *c > 'Z' ? "NPI" : "TON", *c);
+                               }
+                               l++;
+                       }
+               }
                pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
                        p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
                if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
@@ -2418,6 +2613,8 @@ static void destroy_zt_pvt(struct zt_pvt **pvt)
                ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy);
        if (p->mwi_event_sub)
                ast_event_unsubscribe(p->mwi_event_sub);
+       if (p->vars)
+               ast_variables_destroy(p->vars);
        ast_mutex_destroy(&p->lock);
        ast_free(p);
        *pvt = NULL;
@@ -2495,24 +2692,21 @@ static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
        char *digits = (char *) data;
 
        if (ast_strlen_zero(digits)) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
+               ast_debug(1, "No digit string sent to application!\n");
                return -1;
        }
 
        p = (struct zt_pvt *)chan->tech_pvt;
 
        if (!p) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Unable to find technology private\n");
+               ast_debug(1, "Unable to find technology private\n");
                return -1;
        }
 
        ast_mutex_lock(&p->lock);
 
        if (!p->pri || !p->call) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
+               ast_debug(1, "Unable to find pri or call on channel!\n");
                ast_mutex_unlock(&p->lock);
                return -1;
        }
@@ -2521,8 +2715,7 @@ static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
                pri_keypad_facility(p->pri->pri, p->call, digits);
                pri_rel(p->pri);
        } else {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
+               ast_debug(1, "Unable to grab pri to send keypad facility!\n");
                ast_mutex_unlock(&p->lock);
                return -1;
        }
@@ -2548,7 +2741,7 @@ static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_p
        bearer->realcall = crv;
        crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
        if (crv->subs[SUB_REAL].owner)
-               crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
+               ast_channel_set_fd(crv->subs[SUB_REAL].owner, 0, crv->subs[SUB_REAL].zfd);
        crv->bearer = bearer;
        crv->call = bearer->call;
        crv->pri = pri;
@@ -2621,8 +2814,7 @@ static int zt_hangup(struct ast_channel *ast)
        struct zt_pvt *prev = NULL;
        ZT_PARAMS par;
 
-       if (option_debug)
-               ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
+       ast_debug(1, "zt_hangup(%s)\n", ast->name);
        if (!ast->tech_pvt) {
                ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
                return 0;
@@ -2655,9 +2847,8 @@ static int zt_hangup(struct ast_channel *ast)
        if (p->exten)
                p->exten[0] = '\0';
 
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
-                       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
+       ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
+               p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
        p->ignoredtmf = 0;
        
        if (index > -1) {
@@ -2674,32 +2865,27 @@ static int zt_hangup(struct ast_channel *ast)
                zt_setlinear(p->subs[index].zfd, 0);
                if (index == SUB_REAL) {
                        if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
+                               ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
                                if (p->subs[SUB_CALLWAIT].inthreeway) {
                                        /* We had flipped over to answer a callwait and now it's gone */
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
+                                       ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n");
                                        /* Move to the call-wait, but un-own us until they flip back. */
                                        swap_subs(p, SUB_CALLWAIT, SUB_REAL);
                                        unalloc_sub(p, SUB_CALLWAIT);
                                        p->owner = NULL;
                                } else {
                                        /* The three way hung up, but we still have a call wait */
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
+                                       ast_debug(1, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
                                        swap_subs(p, SUB_THREEWAY, SUB_REAL);
                                        unalloc_sub(p, SUB_THREEWAY);
                                        if (p->subs[SUB_REAL].inthreeway) {
                                                /* This was part of a three way call.  Immediately make way for
                                                   another call */
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
+                                               ast_debug(1, "Call was complete, setting owner to former third call\n");
                                                p->owner = p->subs[SUB_REAL].owner;
                                        } else {
                                                /* This call hasn't been completed yet...  Set owner to NULL */
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
+                                               ast_debug(1, "Call was incomplete, setting owner to NULL\n");
                                                p->owner = NULL;
                                        }
                                        p->subs[SUB_REAL].inthreeway = 0;
@@ -2719,13 +2905,11 @@ static int zt_hangup(struct ast_channel *ast)
                                if (p->subs[SUB_REAL].inthreeway) {
                                        /* This was part of a three way call.  Immediately make way for
                                           another call */
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
+                                       ast_debug(1, "Call was complete, setting owner to former third call\n");
                                        p->owner = p->subs[SUB_REAL].owner;
                                } else {
                                        /* This call hasn't been completed yet...  Set owner to NULL */
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
+                                       ast_debug(1, "Call was incomplete, setting owner to NULL\n");
                                        p->owner = NULL;
                                }
                                p->subs[SUB_REAL].inthreeway = 0;
@@ -2828,8 +3012,7 @@ static int zt_hangup(struct ast_channel *ast)
                        if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
                                if (!pri_grab(p, p->pri)) {
                                        if (p->alreadyhungup) {
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
+                                               ast_debug(1, "Already hungup...  Calling hangup once, and clearing call\n");
 
 #ifdef SUPPORT_USERUSER
                                                pri_call_set_useruser(p->call, useruser);
@@ -2842,8 +3025,7 @@ static int zt_hangup(struct ast_channel *ast)
                                        } else {
                                                const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
                                                int icause = ast->hangupcause ? ast->hangupcause : -1;
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
+                                               ast_debug(1, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
 
 #ifdef SUPPORT_USERUSER
                                                pri_call_set_useruser(p->call, useruser);
@@ -2867,8 +3049,7 @@ static int zt_hangup(struct ast_channel *ast)
                                }
                        } else {
                                if (p->bearer)
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
+                                       ast_debug(1, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
                                p->call = NULL;
                                res = 0;
                        }
@@ -2886,8 +3067,7 @@ static int zt_hangup(struct ast_channel *ast)
                        res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
                        if (!res) {
 #if 0
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
+                               ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
 #endif
                                /* If they're off hook, try playing congestion */
                                if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
@@ -2932,8 +3112,7 @@ static int zt_hangup(struct ast_channel *ast)
                }
 #ifdef HAVE_PRI
                if (p->bearer) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
+                       ast_debug(1, "Freeing up bearer channel %d\n", p->bearer->channel);
                        /* Free up the bearer channel as well, and
                           don't use its file descriptor anymore */
                        update_conf(p->bearer);
@@ -2954,8 +3133,7 @@ static int zt_hangup(struct ast_channel *ast)
        ast->tech_pvt = NULL;
        ast_mutex_unlock(&p->lock);
        ast_module_unref(ast_module_info->self);
-       if (option_verbose > 2) 
-               ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
+       ast_verb(3, "Hungup '%s'\n", ast->name);
 
        ast_mutex_lock(&iflock);
        tmp = iflist;
@@ -3016,18 +3194,16 @@ static int zt_answer(struct ast_channel *ast)
        case SIG_FXOGS:
        case SIG_FXOKS:
                /* Pick up the line */
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
+               ast_debug(1, "Took %s off hook\n", ast->name);
                if (p->hanguponpolarityswitch) {
-                       gettimeofday(&p->polaritydelaytv, NULL);
+                       p->polaritydelaytv = ast_tvnow();
                }
                res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
                tone_zone_play_tone(p->subs[index].zfd, -1);
                p->dialing = 0;
                if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
                        if (oldstate == AST_STATE_RINGING) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
+                               ast_debug(1, "Finally swapping real and threeway\n");
                                tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
                                swap_subs(p, SUB_THREEWAY, SUB_REAL);
                                p->owner = p->subs[SUB_REAL].owner;
@@ -3098,8 +3274,7 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
                        ast_log(LOG_WARNING, "No index in TXGAIN?\n");
                        return -1;
                }
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
+               ast_debug(1, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
                return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
        case AST_OPTION_RXGAIN:
                scp = (signed char *) data;
@@ -3108,8 +3283,7 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
                        ast_log(LOG_WARNING, "No index in RXGAIN?\n");
                        return -1;
                }
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
+               ast_debug(1, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
                return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
        case AST_OPTION_TONE_VERIFY:
                if (!p->dsp)
@@ -3117,18 +3291,15 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
                cp = (char *) data;
                switch (*cp) {
                case 1:
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
+                       ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
                        ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
                        break;
                case 2:
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
+                       ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
                        ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
                        break;
                default:
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
+                       ast_debug(1, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
                        ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
                        break;
                }
@@ -3138,16 +3309,14 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
                cp = (char *) data;
                p->mate = 0;
                if (!*cp) { /* turn it off */
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
+                       ast_debug(1, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
                        if (p->tdd)
                                tdd_free(p->tdd);
                        p->tdd = 0;
                        break;
                }
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
-                               (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
+               ast_debug(1, "Set option TDD MODE, value: %s(%d) on %s\n",
+                       (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
                zt_disable_ec(p);
                /* otherwise, turn it on */
                if (!p->didtdd) { /* if havent done it yet */
@@ -3176,23 +3345,20 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
                                fds[0].revents = 0;
                                res = poll(fds, 1, -1);
                                if (!res) {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
+                                       ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel);
                                        continue;
                                }
                                /* if got exception */
                                if (fds[0].revents & POLLPRI)
                                        return -1;
                                if (!(fds[0].revents & POLLOUT)) {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
+                                       ast_debug(1, "write fd not ready on channel %d\n", p->channel);
                                        continue;
                                }
                                res = write(fd, buf, size);
                                if (res != size) {
                                        if (res == -1) return -1;
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
+                                       ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
                                        break;
                                }
                                len -= size;
@@ -3215,21 +3381,18 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
                if (!p->dsp)
                        break;
                cp = (char *) data;
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
-                               *cp ? "ON" : "OFF", (int) *cp, chan->name);
+               ast_debug(1, "Set option RELAX DTMF, value: %s(%d) on %s\n",
+                       *cp ? "ON" : "OFF", (int) *cp, chan->name);
                ast_dsp_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax);
                break;
        case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
                cp = (char *) data;
                if (!*cp) {             
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
+                       ast_debug(1, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
                        x = 0;
                        zt_disable_ec(p);
                } else {                
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
+                       ast_debug(1, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
                        x = 1;
                }
                if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
@@ -3248,19 +3411,16 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
                        pp->oprmode = oprmode->mode;
                        p->oprmode = -oprmode->mode;
                }
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
-                               oprmode->mode, chan->name,oprmode->peer->name);
+               ast_debug(1, "Set Operator Services mode, value: %d on %s/%s\n",
+                       oprmode->mode, chan->name,oprmode->peer->name);
                break;
        case AST_OPTION_ECHOCAN:
                cp = (char *) data;
                if (*cp) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
+                       ast_debug(1, "Enabling echo cancelation on %s\n", chan->name);
                        zt_enable_ec(p);
                } else {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
+                       ast_debug(1, "Disabling echo cancelation on %s\n", chan->name);
                        zt_disable_ec(p);
                }
                break;
@@ -3311,8 +3471,7 @@ static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
                if (master->slaves[x]) {
                        if (!slave || (master->slaves[x] == slave)) {
                                /* Take slave out of the conference */
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
+                               ast_debug(1, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
                                conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
                                conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
                                master->slaves[x]->master = NULL;
@@ -3368,8 +3527,7 @@ static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
                ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
        slave->master = master;
        
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
+       ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
 }
 
 static void disable_dtmf_detect(struct zt_pvt *p)
@@ -3439,23 +3597,27 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
        if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
                return AST_BRIDGE_FAILED_NOWARN;
 
-       ast_mutex_lock(&c0->lock);
-       ast_mutex_lock(&c1->lock);
+       ast_channel_lock(c0);
+       while (ast_channel_trylock(c1)) {
+               ast_channel_unlock(c0);
+               usleep(1);
+               ast_channel_lock(c0);
+       }
 
        p0 = c0->tech_pvt;
        p1 = c1->tech_pvt;
        /* cant do pseudo-channels here */
        if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
-               ast_mutex_unlock(&c0->lock);
-               ast_mutex_unlock(&c1->lock);
+               ast_channel_unlock(c0);
+               ast_channel_unlock(c1);
                return AST_BRIDGE_FAILED_NOWARN;
        }
 
        oi0 = zt_get_index(c0, p0, 0);
        oi1 = zt_get_index(c1, p1, 0);
        if ((oi0 < 0) || (oi1 < 0)) {
-               ast_mutex_unlock(&c0->lock);
-               ast_mutex_unlock(&c1->lock);
+               ast_channel_unlock(c0);
+               ast_channel_unlock(c1);
                return AST_BRIDGE_FAILED;
        }
 
@@ -3468,16 +3630,16 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
 
        if (ast_mutex_trylock(&p0->lock)) {
                /* Don't block, due to potential for deadlock */
-               ast_mutex_unlock(&c0->lock);
-               ast_mutex_unlock(&c1->lock);
+               ast_channel_unlock(c0);
+               ast_channel_unlock(c1);
                ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
                return AST_BRIDGE_RETRY;
        }
        if (ast_mutex_trylock(&p1->lock)) {
                /* Don't block, due to potential for deadlock */
                ast_mutex_unlock(&p0->lock);
-               ast_mutex_unlock(&c0->lock);
-               ast_mutex_unlock(&c1->lock);
+               ast_channel_unlock(c0);
+               ast_channel_unlock(c1);
                ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
                return AST_BRIDGE_RETRY;
        }
@@ -3532,9 +3694,8 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
                        nothingok = 0;
                }
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
-                       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
+       ast_debug(1, "master: %d, slave: %d, nothingok: %d\n",
+               master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
        if (master && slave) {
                /* Stop any tones, or play ringtone as appropriate.  If they're bridged
                   in an active threeway call with a channel that is ringing, we should
@@ -3544,13 +3705,11 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
                    p1->subs[SUB_REAL].owner && 
                    p1->subs[SUB_REAL].inthreeway && 
                    (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
+                       ast_debug(1, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
                        tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
                        os1 = p1->subs[SUB_REAL].owner->_state;
                } else {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
+                       ast_debug(1, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
                        tone_zone_play_tone(p0->subs[oi0].zfd, -1);
                }
                if ((oi0 == SUB_THREEWAY) && 
@@ -3558,13 +3717,11 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
                    p0->subs[SUB_REAL].owner && 
                    p0->subs[SUB_REAL].inthreeway && 
                    (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
+                       ast_debug(1, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
                        tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
                        os0 = p0->subs[SUB_REAL].owner->_state;
                } else {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
+                       ast_debug(1, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
                        tone_zone_play_tone(p1->subs[oi0].zfd, -1);
                }
                if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
@@ -3587,8 +3744,8 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
        ast_mutex_unlock(&p0->lock);
        ast_mutex_unlock(&p1->lock);
 
-       ast_mutex_unlock(&c0->lock);
-       ast_mutex_unlock(&c1->lock);
+       ast_channel_unlock(c0);
+       ast_channel_unlock(c1);
 
        /* Native bridge failed */
        if ((!master || !slave) && !nothingok) {
@@ -3597,8 +3754,7 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
                return AST_BRIDGE_FAILED;
        }
        
-       if (option_verbose > 2) 
-               ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
+       ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name);
 
        if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
                disable_dtmf_detect(op0);
@@ -3612,8 +3768,14 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
 
                /* Here's our main loop...  Start by locking things, looking for private parts, 
                   and then balking if anything is wrong */
-               ast_mutex_lock(&c0->lock);
-               ast_mutex_lock(&c1->lock);
+               
+               ast_channel_lock(c0);
+               while (ast_channel_trylock(c1)) {
+                       ast_channel_unlock(c0);
+                       usleep(1);
+                       ast_channel_lock(c0);
+               }
+
                p0 = c0->tech_pvt;
                p1 = c1->tech_pvt;
 
@@ -3621,8 +3783,9 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
                        i0 = zt_get_index(c0, p0, 1);
                if (op1 == p1)
                        i1 = zt_get_index(c1, p1, 1);
-               ast_mutex_unlock(&c0->lock);
-               ast_mutex_unlock(&c1->lock);
+
+               ast_channel_unlock(c0);
+               ast_channel_unlock(c1);
 
                if (!timeoutms || 
                    (op0 != p0) ||
@@ -3637,9 +3800,8 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
                    (t1 != p1->subs[SUB_REAL].inthreeway) ||
                    (oi0 != i0) ||
                    (oi1 != i1)) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
-                                       op0->channel, oi0, op1->channel, oi1);
+                       ast_debug(1, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
+                               op0->channel, oi0, op1->channel, oi1);
                        res = AST_BRIDGE_RETRY;
                        goto return_from_bridge;
                }
@@ -3657,8 +3819,7 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
 
                who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
                if (!who) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Ooh, empty read...\n");
+                       ast_debug(1, "Ooh, empty read...\n");
                        continue;
                }
                f = ast_read(who);
@@ -3709,8 +3870,7 @@ static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
        struct zt_pvt *p = newchan->tech_pvt;
        int x;
        ast_mutex_lock(&p->lock);
-       if (option_debug)
-               ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
+       ast_debug(1, "New owner for channel %d is %s\n", p->channel, newchan->name);
        if (p->owner == oldchan) {
                p->owner = newchan;
        }
@@ -3795,7 +3955,7 @@ static int attempt_transfer(struct zt_pvt *p)
                        return -1;
                }
                /* Orphan the channel after releasing the lock */
-               ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
+               ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
                unalloc_sub(p, SUB_THREEWAY);
        } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
@@ -3824,14 +3984,13 @@ static int attempt_transfer(struct zt_pvt *p)
                }
                /* Three-way is now the REAL */
                swap_subs(p, SUB_THREEWAY, SUB_REAL);
-               ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
+               ast_channel_unlock(p->subs[SUB_REAL].owner);
                unalloc_sub(p, SUB_THREEWAY);
                /* Tell the caller not to hangup */
                return 1;
        } else {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
-                                               p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
+               ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
+                       p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
                p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
                return -1;
        }
@@ -3853,8 +4012,7 @@ static int check_for_conference(struct zt_pvt *p)
           if we're in a conference, it's probably a MeetMe room or
           some such, so don't let us 3-way out! */
        if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
-               if (option_verbose > 2) 
-                       ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
+               ast_verb(3, "Avoiding 3-way call when in an external conference\n");
                return 1;
        }
        return 0;
@@ -3879,12 +4037,10 @@ static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_fram
        struct zt_pvt *p = ast->tech_pvt;
        struct ast_frame *f = *dest;
 
-       if (option_debug)
-               ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
+       ast_debug(1, "DTMF digit: %c on %s\n", f->subclass, ast->name);
 
        if (p->confirmanswer) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
+               ast_debug(1, "Confirm answer on %s!\n", ast->name);
                /* Upon receiving a DTMF digit, consider this an answer confirmation instead
                   of a DTMF digit */
                p->subs[index].f.frametype = AST_FRAME_CONTROL;
@@ -3894,8 +4050,7 @@ static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_fram
                p->confirmanswer = 0;
        } else if (p->callwaitcas) {
                if ((f->subclass == 'A') || (f->subclass == 'D')) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
+                       ast_debug(1, "Got some DTMF, but it's for the CAS\n");
                        if (p->cidspill)
                                ast_free(p->cidspill);
                        send_cwcidspill(p);
@@ -3913,18 +4068,17 @@ static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_fram
                                const char *target_context = S_OR(ast->macrocontext, ast->context);
 
                                if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
+                                       ast_verb(3, "Redirecting %s to fax extension\n", ast->name);
                                        /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
                                        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_debug)
-                               ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
-               } else if (option_debug)
-                               ast_log(LOG_DEBUG, "Fax already handled\n");
+                       } else
+                               ast_debug(1, "Already in a fax extension, not redirecting\n");
+               } else
+                       ast_debug(1, "Fax already handled\n");
                zt_confmute(p, 0);
                p->subs[index].f.frametype = AST_FRAME_NULL;
                p->subs[index].f.subclass = 0;
@@ -3977,13 +4131,11 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
        } else
                res = zt_get_event(p->subs[index].zfd);
 
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
+       ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
 
        if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
                p->pulsedial =  (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
+               ast_debug(1, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
 #ifdef HAVE_PRI
                if (!p->proceeding && p->sig == SIG_PRI && p->pri && (p->pri->overlapdial & ZAP_OVERLAPDIAL_INCOMING)) {
                        /* absorb event */
@@ -3999,8 +4151,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
        }
 
        if (res & ZT_EVENT_DTMFDOWN) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
+               ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
                /* Mute conference */
                zt_confmute(p, 1);
                p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
@@ -4011,8 +4162,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
        switch (res) {
 #ifdef ZT_EVENT_EC_DISABLED
                case ZT_EVENT_EC_DISABLED:
-                       if (option_verbose > 2) 
-                               ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
+                       ast_verb(3, "Channel %d echo canceler disabled due to CED detection\n", p->channel);
                        p->echocanon = 0;
                        break;
 #endif
@@ -4027,8 +4177,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                        if (p->inalarm) break;
                        if ((p->radio || (p->oprmode < 0))) break;
                        if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
+                               ast_debug(1, "ZT_DIALING ioctl failed on %s\n",ast->name);
                                return NULL;
                        }
                        if (!x) { /* if not still dialing in driver */
@@ -4055,8 +4204,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                        }
                                        if (ast->_state == AST_STATE_DIALING) {
                                                if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
-                                                       if (option_debug)
-                                                               ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
+                                                       ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n");
                                                } else if (p->confirmanswer || (!p->dialednone && ((mysig == SIG_EM) || (mysig == SIG_EM_E1) ||  (mysig == SIG_EMWINK) || (mysig == SIG_FEATD) || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF) || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB) || (mysig == SIG_SF) || (mysig == SIG_SFWINK) || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF) || (mysig == SIG_SF_FEATB)))) {
                                                        ast_setstate(ast, AST_STATE_RINGING);
                                                } else if (!p->answeronpolarityswitch) {
@@ -4070,22 +4218,24 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                        break;
                case ZT_EVENT_ALARM:
 #ifdef HAVE_PRI
-                       if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
-                               /* T309 is not enabled : hangup calls when alarm occurs */
-                               if (p->call) {
-                                       if (p->pri && p->pri->pri) {
-                                               if (!pri_grab(p, p->pri)) {
-                                                       pri_hangup(p->pri->pri, p->call, -1);
-                                                       pri_destroycall(p->pri->pri, p->call);
-                                                       p->call = NULL;
-                                                       pri_rel(p->pri);
+                       if (p->sig == SIG_PRI) {
+                               if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
+                                       /* T309 is not enabled : hangup calls when alarm occurs */
+                                       if (p->call) {
+                                               if (p->pri && p->pri->pri) {
+                                                       if (!pri_grab(p, p->pri)) {
+                                                               pri_hangup(p->pri->pri, p->call, -1);
+                                                               pri_destroycall(p->pri->pri, p->call);
+                                                               p->call = NULL;
+                                                               pri_rel(p->pri);
+                                                       } else
+                                                               ast_log(LOG_WARNING, "Failed to grab PRI!\n");
                                                } else
-                                                       ast_log(LOG_WARNING, "Failed to grab PRI!\n");
-                                       } else
-                                               ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
+                                                       ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
+                                       }
+                                       if (p->owner)
+                                               p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
                                }
-                               if (p->owner)
-                                       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
                        }
                        if (p->bearer)
                                p->bearer->inalarm = 1;
@@ -4105,6 +4255,10 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                break;
                        }
 #endif
+#ifdef HAVE_SS7
+                       if (p->sig == SIG_SS7)
+                               break;
+#endif
                case ZT_EVENT_ONHOOK:
                        if (p->radio) {
                                p->subs[index].f.frametype = AST_FRAME_CONTROL;
@@ -4136,8 +4290,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                        if (p->subs[SUB_CALLWAIT].owner) {
                                                /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
                                                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
-                                               if (option_verbose > 2) 
-                                                       ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
+                                               ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel);
                                                unalloc_sub(p, SUB_CALLWAIT);   
 #if 0
                                                p->subs[index].needanswer = 0;
@@ -4154,15 +4307,15 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                unsigned int mssinceflash;
                                                /* Here we have to retain the lock on both the main channel, the 3-way channel, and
                                                   the private structure -- not especially easy or clean */
-                                               while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
+                                               while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) {
                                                        /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
                                                        ast_mutex_unlock(&p->lock);
-                                                       ast_mutex_unlock(&ast->lock);
+                                                       ast_channel_unlock(ast);
                                                        usleep(1);
                                                        /* We can grab ast and p in that order, without worry.  We should make sure
                                                           nothing seriously bad has happened though like some sort of bizarre double
                                                           masquerade! */
-                                                       ast_mutex_lock(&ast->lock);
+                                                       ast_channel_lock(ast);
                                                        ast_mutex_lock(&p->lock);
                                                        if (p->owner != ast) {
                                                                ast_log(LOG_WARNING, "This isn't good...\n");
@@ -4174,17 +4327,15 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                        return NULL;
                                                }
                                                mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
+                                               ast_debug(1, "Last flash was %d ms ago\n", mssinceflash);
                                                if (mssinceflash < MIN_MS_SINCE_FLASH) {
                                                        /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
                                                           hanging up.  Hangup both channels now */
                                                        if (p->subs[SUB_THREEWAY].owner)
                                                                ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
                                                        p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
-                                                       if (option_debug)
-                                                               ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
-                                                       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
+                                                       ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
+                                                       ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
                                                } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
                                                        if (p->transfer) {
                                                                /* In any case this isn't a threeway call anymore */
@@ -4192,7 +4343,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                                p->subs[SUB_THREEWAY].inthreeway = 0;
                                                                /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
                                                                if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
-                                                                       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
+                                                                       ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
                                                                        /* Swap subs and dis-own channel */
                                                                        swap_subs(p, SUB_THREEWAY, SUB_REAL);
                                                                        p->owner = NULL;
@@ -4202,21 +4353,21 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                                        if ((res = attempt_transfer(p)) < 0) {
                                                                                p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
                                                                                if (p->subs[SUB_THREEWAY].owner)
-                                                                                       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
+                                                                                       ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
                                                                        } else if (res) {
                                                                                /* Don't actually hang up at this point */
                                                                                if (p->subs[SUB_THREEWAY].owner)
-                                                                                       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
+                                                                                       ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
                                                                                break;
                                                                        }
                                                                }
                                                        } else {
                                                                p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
                                                                if (p->subs[SUB_THREEWAY].owner)
-                                                                       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
+                                                                       ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
                                                        }
                                                } else {
-                                                       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
+                                                       ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
                                                        /* Swap subs and dis-own channel */
                                                        swap_subs(p, SUB_THREEWAY, SUB_REAL);
                                                        p->owner = NULL;
@@ -4291,8 +4442,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                        p->subs[index].f.subclass = AST_CONTROL_ANSWER;
                                        /* Make sure it stops ringing */
                                        zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
+                                       ast_debug(1, "channel %d answered\n", p->channel);
                                        if (p->cidspill) {
                                                /* Cancel any running CallerID spill */
                                                ast_free(p->cidspill);
@@ -4312,8 +4462,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                        p->dop.dialstr[0] = '\0';
                                                        return NULL;
                                                } else {
-                                                       if (option_debug)
-                                                               ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
+                                                       ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
                                                        p->subs[index].f.frametype = AST_FRAME_NULL;
                                                        p->subs[index].f.subclass = 0;
                                                        p->dialing = 1;
@@ -4328,8 +4477,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                        ast->rings = 1;
                                        p->subs[index].f.frametype = AST_FRAME_CONTROL;
                                        p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
+                                       ast_debug(1, "channel %d picked up\n", p->channel);
                                        return &p->subs[index].f;
                                case AST_STATE_UP:
                                        /* Make sure it stops ringing */
@@ -4359,10 +4507,9 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
 
                                /* If we get a ring then we cannot be in 
                                 * reversed polarity. So we reset to idle */
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Setting IDLE polarity due "
-                                               "to ring. Old polarity was %d\n", 
-                                               p->polarity);
+                               ast_debug(1, "Setting IDLE polarity due "
+                                       "to ring. Old polarity was %d\n", 
+                                       p->polarity);
                                p->polarity = POLARITY_IDLE;
 
                                /* Fall through */
@@ -4384,13 +4531,11 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                if (ast->_state == AST_STATE_PRERING)
                                        ast_setstate(ast, AST_STATE_RING);
                                if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Ring detected\n");
+                                       ast_debug(1, "Ring detected\n");
                                        p->subs[index].f.frametype = AST_FRAME_CONTROL;
                                        p->subs[index].f.subclass = AST_CONTROL_RING;
                                } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Line answered\n");
+                                       ast_debug(1, "Line answered\n");
                                        if (p->confirmanswer) {
                                                p->subs[index].f.frametype = AST_FRAME_NULL;
                                                p->subs[index].f.subclass = 0;
@@ -4467,14 +4612,13 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                break;
                        }
                        /* Remember last time we got a flash-hook */
-                       gettimeofday(&p->flashtime, NULL);
+                       p->flashtime = ast_tvnow();
                        switch (mysig) {
                        case SIG_FXOLS:
                        case SIG_FXOGS:
                        case SIG_FXOKS:
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
-                                               index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
+                               ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
+                                       index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
                                p->callwaitcas = 0;
 
                                if (index != SUB_REAL) {
@@ -4487,8 +4631,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                        swap_subs(p, SUB_REAL, SUB_CALLWAIT);
                                        tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
                                        p->owner = p->subs[SUB_REAL].owner;
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
+                                       ast_debug(1, "Making %s the new owner\n", p->owner->name);
                                        if (p->owner->_state == AST_STATE_RINGING) {
                                                ast_setstate(p->owner, AST_STATE_UP);
                                                p->subs[SUB_REAL].needanswer = 1;
@@ -4528,8 +4671,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                if (!((ast->pbx) ||
                                                      (ast->_state == AST_STATE_UP) ||
                                                      (ast->_state == AST_STATE_RING))) {
-                                                       if (option_debug)
-                                                               ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
+                                                       ast_debug(1, "Flash when call not up or ringing\n");
                                                        goto winkflashdone;
                                                }
                                                if (alloc_sub(p, SUB_THREEWAY)) {
@@ -4562,8 +4704,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                        zt_enable_ec(p);
                                                        ast_hangup(chan);
                                                } else {
-                                                       if (option_verbose > 2) 
-                                                               ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
+                                                       ast_verb(3, "Started three way call on channel %d\n", p->channel);
                                                        /* Start music on hold if appropriate */
                                                        if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
                                                                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
@@ -4577,8 +4718,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                        /* Already have a 3 way call */
                                        if (p->subs[SUB_THREEWAY].inthreeway) {
                                                /* Call is already up, drop the last person */
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
+                                               ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel);
                                                /* If the primary call isn't answered yet, use it */
                                                if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
                                                        /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
@@ -4586,8 +4726,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                        p->owner = p->subs[SUB_REAL].owner;
                                                }
                                                /* Drop the last call and stop the conference */
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
+                                               ast_verb(3, "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
                                                p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
                                                p->subs[SUB_REAL].inthreeway = 0;
                                                p->subs[SUB_THREEWAY].inthreeway = 0;
@@ -4597,8 +4736,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                    (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
                                                        int otherindex = SUB_THREEWAY;
 
-                                                       if (option_verbose > 2)
-                                                               ast_verbose(VERBOSE_PREFIX_3 "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name);
+                                                       ast_verb(3, "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name);
                                                        /* Put them in the threeway, and flip */
                                                        p->subs[SUB_THREEWAY].inthreeway = 1;
                                                        p->subs[SUB_REAL].inthreeway = 1;
@@ -4611,14 +4749,12 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                        p->subs[otherindex].needunhold = 1;
                                                        p->owner = p->subs[SUB_REAL].owner;
                                                        if (ast->_state == AST_STATE_RINGING) {
-                                                               if (option_debug)
-                                                                       ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
+                                                               ast_debug(1, "Enabling ringtone on real and threeway\n");
                                                                res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
                                                                res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
                                                        }
                                                } else {
-                                                       if (option_verbose > 2)
-                                                               ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
+                                                       ast_verb(3, "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
                                                        swap_subs(p, SUB_THREEWAY, SUB_REAL);
                                                        p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
                                                        p->owner = p->subs[SUB_REAL].owner;
@@ -4644,16 +4780,15 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                        case SIG_FXSGS:
                                if (option_debug) {
                                        if (p->dialing)
-                                               ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
+                                               ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
                                        else
-                                               ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
+                                               ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
                                }
                                break;
                        case SIG_FEATDMF_TA:
                                switch (p->whichwink) {
                                case 0:
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
+                                       ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
                                        snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
                                        break;
                                case 1:
@@ -4679,10 +4814,9 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                        ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
                                        p->dop.dialstr[0] = '\0';
                                        return NULL;
-                               } else {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
-                               }
+                               } else
+                                       ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
+
                                p->dop.dialstr[0] = '\0';
                                break;
                        default:
@@ -4709,10 +4843,9 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                        ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
                                        p->dop.dialstr[0] = '\0';
                                        return NULL;
-                               } else {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
-                               }
+                               } else
+                                       ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
+
                                p->dop.dialstr[0] = '\0';
                                p->dop.op = ZT_DIAL_OP_REPLACE;
                                break;
@@ -4724,8 +4857,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                        case SIG_FEATB:
                        case SIG_SF_FEATDMF:
                        case SIG_SF_FEATB:
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
+                               ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
                                break;
                        default:
                                break;
@@ -4743,16 +4875,14 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                if (p->answeronpolarityswitch &&
                                    ((ast->_state == AST_STATE_DIALING) ||
                                         (ast->_state == AST_STATE_RINGING))) {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
+                                       ast_debug(1, "Answering on polarity switch!\n");
                                        ast_setstate(p->owner, AST_STATE_UP);
                                        if (p->hanguponpolarityswitch) {
-                                               gettimeofday(&p->polaritydelaytv, NULL);
+                                               p->polaritydelaytv = ast_tvnow();
                                        }
-                               } else {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
-                               }
+                               } else
+                                       ast_debug(1, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
+
                        } 
                        /* Removed else statement from here as it was preventing hangups from ever happening*/
                        /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
@@ -4761,30 +4891,24 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                               (p->polarity == POLARITY_REV) &&
                                ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
                                 /* Added log_debug information below to provide a better indication of what is going on */
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
+                               ast_debug(1, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
                        
                                if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
+                                       ast_debug(1, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
                                        ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
                                        p->polarity = POLARITY_IDLE;
-                               } else {
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state);
-                               }
+                               } else
+                                       ast_debug(1, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state);
+
                        } else {
                                p->polarity = POLARITY_IDLE;
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
+                               ast_debug(1, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
                        }
                        /* Added more log_debug information below to provide a better indication of what is going on */
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
+                       ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
                        break;
                default:
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
+                       ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
        }
        return &p->subs[index].f;
 }
@@ -4825,8 +4949,7 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
                /* Switch to real if there is one and this isn't something really silly... */
                if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
                        (res != ZT_EVENT_HOOKCOMPLETE)) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
+                       ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
                        p->owner = p->subs[SUB_REAL].owner;
                        if (p->owner && ast_bridged_channel(p->owner))
                                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
@@ -4836,8 +4959,7 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
                case ZT_EVENT_ONHOOK:
                        zt_disable_ec(p);
                        if (p->owner) {
-                               if (option_verbose > 2) 
-                                       ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
+                               ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name);
                                zt_ring_phone(p);
                                p->callwaitingrepeat = 0;
                                p->cidcwexpire = 0;
@@ -4858,10 +4980,9 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
                        /* Do nothing */
                        break;
                case ZT_EVENT_WINKFLASH:
-                       gettimeofday(&p->flashtime, NULL);
+                       p->flashtime = ast_tvnow();
                        if (p->owner) {
-                               if (option_verbose > 2) 
-                                       ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
+                               ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
                                if (p->owner->_state != AST_STATE_UP) {
                                        /* Answer if necessary */
                                        usedindex = zt_get_index(p->owner, p, 0);
@@ -4885,8 +5006,8 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
                f = &p->subs[index].f;
                return f;
        }
-       if (!(p->radio || (p->oprmode < 0)) && option_debug) 
-               ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
+       if (!(p->radio || (p->oprmode < 0))) 
+               ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
        /* If it's not us, return NULL immediately */
        if (ast != p->owner) {
                ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
@@ -5029,8 +5150,7 @@ static struct ast_frame  *zt_read(struct ast_channel *ast)
                p->subs[index].f.frametype = AST_FRAME_CONTROL;
                p->subs[index].f.subclass = AST_CONTROL_HOLD;
                ast_mutex_unlock(&p->lock);
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
+               ast_debug(1, "Sending hold on '%s'\n", ast->name);
                return &p->subs[index].f;
        }       
        
@@ -5040,8 +5160,7 @@ static struct ast_frame  *zt_read(struct ast_channel *ast)
                p->subs[index].f.frametype = AST_FRAME_CONTROL;
                p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
                ast_mutex_unlock(&p->lock);
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
+               ast_debug(1, "Sending unhold on '%s'\n", ast->name);
                return &p->subs[index].f;
        }       
        
@@ -5086,8 +5205,7 @@ static struct ast_frame  *zt_read(struct ast_channel *ast)
                return f;
        }
        if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
+               ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
                f = __zt_exception(ast);
                ast_mutex_unlock(&p->lock);
                return f;
@@ -5097,8 +5215,7 @@ static struct ast_frame  *zt_read(struct ast_channel *ast)
 
                c = tdd_feed(p->tdd,readbuf,READ_SIZE);
                if (c < 0) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG,"tdd_feed failed\n");
+                       ast_debug(1,"tdd_feed failed\n");
                        ast_mutex_unlock(&p->lock);
                        return NULL;
                }
@@ -5125,8 +5242,7 @@ static struct ast_frame  *zt_read(struct ast_channel *ast)
        }
        /* Expire CID/CW */
        if (p->cidcwexpire == 1) {
-               if (option_verbose > 2)
-                       ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
+               ast_verb(3, "CPE does not support Call Waiting Caller*ID.\n");
                restore_conference(p);
        }
        if (p->subs[index].linear) {
@@ -5146,8 +5262,7 @@ static struct ast_frame  *zt_read(struct ast_channel *ast)
        p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
        p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
 #if 0
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
+       ast_debug(1, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
 #endif 
        if (p->dialing || /* Transmitting something */
           (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
@@ -5214,8 +5329,7 @@ static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index,
                        size = (linear ? READ_SIZE * 2 : READ_SIZE);
                res = write(fd, buf, size);
                if (res != size) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
+                       ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
                        return sent;
                }
                len -= size;
@@ -5228,7 +5342,6 @@ static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
 {
        struct zt_pvt *p = ast->tech_pvt;
        int res;
-       unsigned char outbuf[4096];
        int index;
        index = zt_get_index(ast, p, 0);
        if (index < 0) {
@@ -5265,27 +5378,20 @@ static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
                return -1;
        }
        if (p->dialing) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
+               ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast->name);
                return 0;
        }
        if (!p->owner) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
+               ast_debug(1, "Dropping frame since there is no active owner on %s...\n",ast->name);
                return 0;
        }
        if (p->cidspill) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
+               ast_debug(1, "Dropping frame since I've still got a callerid spill\n");
                return 0;
        }
        /* Return if it's not valid data */
        if (!frame->data || !frame->datalen)
                return 0;
-       if (frame->datalen > sizeof(outbuf) * 2) {
-               ast_log(LOG_WARNING, "Frame too large\n");
-               return 0;
-       }
 
        if (frame->subclass == AST_FORMAT_SLINEAR) {
                if (!p->subs[index].linear) {
@@ -5320,8 +5426,7 @@ static int zt_indicate(struct ast_channel *chan, int condition, const void *data
        int func = ZT_FLASH;
        ast_mutex_lock(&p->lock);
        index = zt_get_index(chan, p, 0);
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
+       ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name);
        if (index == SUB_REAL) {
                switch (condition) {
                case AST_CONTROL_BUSY:
@@ -5381,8 +5486,7 @@ static int zt_indicate(struct ast_channel *chan, int condition, const void *data
                        }
                        break;
                case AST_CONTROL_PROCEEDING:
-                       if (option_debug)
-                               ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
+                       ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
 #ifdef HAVE_PRI
                        if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
                                if (p->pri->pri) {              
@@ -5411,8 +5515,7 @@ static int zt_indicate(struct ast_channel *chan, int condition, const void *data
                        res = 0;
                        break;
                case AST_CONTROL_PROGRESS:
-                       if (option_debug)
-                               ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
+                       ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
 #ifdef HAVE_PRI
                        p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */
                        if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
@@ -5527,6 +5630,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
        int x,y;
        int features;
        struct ast_str *chan_name;
+       struct ast_variable *v;
        ZT_PARAMS ps;
        if (i->subs[index].owner) {
                ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
@@ -5570,7 +5674,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
                else
                        deflaw = AST_FORMAT_ULAW;
        }
-       tmp->fds[0] = i->subs[index].zfd;
+       ast_channel_set_fd(tmp, 0, i->subs[index].zfd);
        tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
        /* Start out assuming ulaw since it's smaller :) */
        tmp->rawreadformat = deflaw;
@@ -5604,8 +5708,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
        }
        if (features) {
                if (i->dsp) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
+                       ast_debug(1, "Already have a dsp on %s?\n", tmp->name);
                } else {
                        if (i->channel != CHAN_PSEUDO)
                                i->dsp = ast_dsp_new();
@@ -5613,7 +5716,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
                                i->dsp = NULL;
                        if (i->dsp) {
                                i->dsp_features = features & ~DSP_PROGRESS_TALK;
-#ifdef HAVE_PRI
+#if defined(HAVE_PRI) || defined(HAVE_SS7)
                                /* We cannot do progress detection until receives PROGRESS message */
                                if (i->outgoing && ((i->sig == SIG_PRI) || (i->sig == SIG_SS7))) {
                                        /* Remember requested DSP features, don't treat
@@ -5665,19 +5768,16 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
        /* Don't use ast_set_callerid() here because it will
         * generate a needless NewCallerID event */
 #ifdef PRI_ANI
-       tmp->cid.cid_num = ast_strdup(i->cid_num);
-       tmp->cid.cid_name = ast_strdup(i->cid_name);
        if (!ast_strlen_zero(i->cid_ani))
                tmp->cid.cid_ani = ast_strdup(i->cid_ani);
        else    
                tmp->cid.cid_ani = ast_strdup(i->cid_num);
 #else
-       tmp->cid.cid_num = ast_strdup(i->cid_num);
        tmp->cid.cid_ani = ast_strdup(i->cid_num);
-       tmp->cid.cid_name = ast_strdup(i->cid_name);
 #endif
        tmp->cid.cid_pres = i->callingpres;
        tmp->cid.cid_ton = i->cid_ton;
+       tmp->cid.cid_ani2 = i->cid_ani2;
 #if defined(HAVE_PRI) || defined(HAVE_SS7)
        tmp->transfercapability = transfercapability;
        pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
@@ -5693,6 +5793,10 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
        zt_confmute(i, 0);
        /* Configure the new channel jb */
        ast_jb_configure(tmp, &global_jbconf);
+
+       for (v = i->vars ; v ; v = v->next)
+                pbx_builtin_setvar_helper(tmp, v->name, v->value);
+
        if (startpbx) {
                if (ast_pbx_start(tmp)) {
                        ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
@@ -5780,8 +5884,7 @@ static void *ss_thread(void *data)
                return NULL;
        }
 
-       if (option_verbose > 2) 
-               ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
+       ast_verb(3, "Starting simple switch on '%s'\n", chan->name);
        index = zt_get_index(chan, p, 1);
        if (index < 0) {
                ast_log(LOG_WARNING, "Huh?\n");
@@ -5808,8 +5911,7 @@ static void *ss_thread(void *data)
                                timeout = gendigittimeout;
                        res = ast_waitfordigit(chan, timeout);
                        if (res < 0) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
+                               ast_debug(1, "waitfordigit returned < 0...\n");
                                ast_hangup(chan);
                                return NULL;
                        } else if (res) {
@@ -5820,8 +5922,7 @@ static void *ss_thread(void *data)
                }
                /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
                if (ast_strlen_zero(exten)) {
-                       if (option_verbose > 2)
-                               ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
+                       ast_verb(3, "Going to extension s|1 because of empty extension received on overlap call\n");
                        exten[0] = 's';
                        exten[1] = '\0';
                }
@@ -5837,8 +5938,7 @@ static void *ss_thread(void *data)
                                ast_log(LOG_WARNING, "PBX exited non-zero!\n");
                        }
                } else {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
+                       ast_debug(1, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
                        chan->hangupcause = AST_CAUSE_UNALLOCATED;
                        ast_hangup(chan);
                        p->exten[0] = '\0';
@@ -5957,8 +6057,7 @@ static void *ss_thread(void *data)
                                        }
                                        res = ast_waitfordigit(chan, timeout);
                                        if (res < 0) {
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
+                                               ast_debug(1, "waitfordigit returned < 0...\n");
                                                ast_hangup(chan);
                                                return NULL;
                                        } else if (res) {
@@ -5976,8 +6075,7 @@ static void *ss_thread(void *data)
                        ast_hangup(chan);
                        return NULL;
                } else if (res < 0) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
+                       ast_debug(1, "Got hung up before digits finished\n");
                        ast_hangup(chan);
                        return NULL;
                }
@@ -6100,8 +6198,7 @@ static void *ss_thread(void *data)
                        }
                        return NULL;
                } else {
-                       if (option_verbose > 2)
-                               ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
+                       ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
                        sleep(2);
                        res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
                        if (res < 0)
@@ -6134,12 +6231,12 @@ static void *ss_thread(void *data)
                                res = ast_waitfordigit(chan, timeout);
                        timeout = 0;
                        if (res < 0) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
+                               ast_debug(1, "waitfordigit returned < 0...\n");
                                res = tone_zone_play_tone(p->subs[index].zfd, -1);
                                ast_hangup(chan);
                                return NULL;
                        } else if (res)  {
+                               ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
                                exten[len++]=res;
                                exten[len] = '\0';
                        }
@@ -6152,8 +6249,7 @@ static void *ss_thread(void *data)
                                        if (getforward) {
                                                /* Record this as the forwarding extension */
                                                ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
+                                               ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
                                                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
                                                if (res)
                                                        break;
@@ -6192,15 +6288,13 @@ static void *ss_thread(void *data)
                                        timeout = matchdigittimeout;
                                }
                        } else if (res == 0) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
+                               ast_debug(1, "not enough digits (and no ambiguous match)...\n");
                                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
                                zt_wait_event(p->subs[index].zfd);
                                ast_hangup(chan);
                                return NULL;
                        } else if (p->callwaiting && !strcmp(exten, "*70")) {
-                               if (option_verbose > 2) 
-                                       ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
+                               ast_verb(3, "Disabling call waiting on %s\n", chan->name);
                                /* Disable call waiting if enabled */
                                p->callwaiting = 0;
                                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
@@ -6229,8 +6323,7 @@ static void *ss_thread(void *data)
                                        }
                                        zt_enable_ec(p);
                                        if (ast_pickup_call(chan)) {
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "No call pickup possible...\n");
+                                               ast_debug(1, "No call pickup possible...\n");
                                                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
                                                zt_wait_event(p->subs[index].zfd);
                                        }
@@ -6243,8 +6336,7 @@ static void *ss_thread(void *data)
                                }
                                
                        } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
-                               if (option_verbose > 2) 
-                                       ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
+                               ast_verb(3, "Disabling Caller*ID on %s\n", chan->name);
                                /* Disable Caller*ID if enabled */
                                p->hidecallerid = 1;
                                if (chan->cid.cid_num)
@@ -6271,8 +6363,7 @@ static void *ss_thread(void *data)
                                break;
                        } else if (!strcmp(exten, "*78")) {
                                /* Do not disturb */
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
+                               ast_verb(3, "Enabled DND on channel %d\n", p->channel);
                                manager_event(EVENT_FLAG_SYSTEM, "DNDState",
                                                        "Channel: Zap/%d\r\n"
                                                        "Status: enabled\r\n", p->channel);
@@ -6283,8 +6374,7 @@ static void *ss_thread(void *data)
                                len = 0;
                        } else if (!strcmp(exten, "*79")) {
                                /* Do not disturb */
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
+                               ast_verb(3, "Disabled DND on channel %d\n", p->channel);
                                manager_event(EVENT_FLAG_SYSTEM, "DNDState",
                                                        "Channel: Zap/%d\r\n"
                                                        "Status: disabled\r\n", p->channel);
@@ -6299,8 +6389,7 @@ static void *ss_thread(void *data)
                                memset(exten, 0, sizeof(exten));
                                len = 0;
                        } else if (p->cancallforward && !strcmp(exten, "*73")) {
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
+                               ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel);
                                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
                                memset(p->call_forward, 0, sizeof(p->call_forward));
                                getforward = 0;
@@ -6312,12 +6401,10 @@ static void *ss_thread(void *data)
                                /* This is a three way call, the main call being a real channel, 
                                        and we're parking the first call. */
                                ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
+                               ast_verb(3, "Parking call to '%s'\n", chan->name);
                                break;
                        } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
+                               ast_verb(3, "Blacklisting number %s\n", p->lastcid_num);
                                res = ast_db_put("blacklist", p->lastcid_num, "1");
                                if (!res) {
                                        res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
@@ -6325,8 +6412,7 @@ static void *ss_thread(void *data)
                                        len = 0;
                                }
                        } else if (p->hidecallerid && !strcmp(exten, "*82")) {
-                               if (option_verbose > 2) 
-                                       ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
+                               ast_verb(3, "Enabling Caller*ID on %s\n", chan->name);
                                /* Enable Caller*ID if enabled */
                                p->hidecallerid = 0;
                                if (chan->cid.cid_num)
@@ -6382,8 +6468,7 @@ static void *ss_thread(void *data)
                                }                                       
                        } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
                                                        ((exten[0] != '*') || (strlen(exten) > 2))) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
+                               ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
                                break;
                        }
                        if (!timeout)
@@ -6418,8 +6503,7 @@ static void *ss_thread(void *data)
                                                res = 0;
                                        ast_frfree(f);
                                        if (res) {
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Got ring!\n");
+                                               ast_debug(1, "Got ring!\n");
                                                res = 0;
                                                break;
                                        }
@@ -6439,8 +6523,7 @@ static void *ss_thread(void *data)
                                else if (smdi_msg->type == 'N')
                                        pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
 
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
+                               ast_debug(1, "Recieved SMDI message on %s\n", chan->name);
                        } else {
                                ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
                        }
@@ -6452,14 +6535,13 @@ static void *ss_thread(void *data)
                /* If we want caller id, we're in a prering state due to a polarity reversal
                 * and we're set to use a polarity reversal to trigger the start of caller id,
                 * grab the caller id and wait for ringing to start... */
-               } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
+               } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN))) {
                        /* If set to use DTMF CID signalling, listen for DTMF */
                        if (p->cid_signalling == CID_SIG_DTMF) {
                                int i = 0;
                                cs = NULL;
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Receiving DTMF cid on "
-                                               "channel %s\n", chan->name);
+                               ast_debug(1, "Receiving DTMF cid on "
+                                       "channel %s\n", chan->name);
                                zt_setlinear(p->subs[index].zfd, 0);
                                res = 2000;
                                for (;;) {
@@ -6472,10 +6554,11 @@ static void *ss_thread(void *data)
                                                return NULL;
                                        } 
                                        f = ast_read(chan);
+                                       if (!f)
+                                               break;
                                        if (f->frametype == AST_FRAME_DTMF) {
                                                dtmfbuf[i++] = f->subclass;
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
+                                               ast_debug(1, "CID got digit '%c'\n", f->subclass);
                                                res = 2000;
                                        }
                                        ast_frfree(f);
@@ -6486,12 +6569,10 @@ static void *ss_thread(void *data)
                                dtmfbuf[i] = '\0';
                                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
                                /* Got cid and ring. */
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
+                               ast_debug(1, "CID got string '%s'\n", dtmfbuf);
                                callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
-                                               dtmfcid, flags);
+                               ast_debug(1, "CID is '%s', flags %d\n", 
+                                       dtmfcid, flags);
                                /* If first byte is NULL, we have no cid */
                                if (!ast_strlen_zero(dtmfcid)) 
                                        number = dtmfcid;
@@ -6652,23 +6733,22 @@ static void *ss_thread(void *data)
                                                                }
                                                        }
                                                }
-                                               if (option_verbose > 2)
                                                        /* this only shows up if you have n of the dring patterns filled in */
-                                                       ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
+                                               ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
                                                for (counter = 0; counter < 3; counter++) {
                                                        /* Check to see if the rings we received match any of the ones in zapata.conf for this
                                                        channel */
                                                        distMatches = 0;
                                                        for (counter1 = 0; counter1 < 3; counter1++) {
-                                                               ast_verbose( VERBOSE_PREFIX_3 "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
+                                                               ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
                                                                if (p->drings.ringnum[counter].ring[counter1] == -1) {
-                                                                       ast_verbose( VERBOSE_PREFIX_3 "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
+                                                                       ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
                                                                        curRingData[counter1]);
                                                                        distMatches++;
                                                                }
                                                                else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
                                                                    curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
-                                                                       ast_verbose( VERBOSE_PREFIX_3 "Ring pattern matched in range: %d to %d\n",
+                                                                       ast_verb(3, "Ring pattern matched in range: %d to %d\n",
                                                                        (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
                                                                        (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
                                                                        distMatches++;
@@ -6679,8 +6759,7 @@ static void *ss_thread(void *data)
                                                                /* The ring matches, set the context to whatever is for distinctive ring.. */
                                                                ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
                                                                ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
-                                                               if (option_verbose > 2)
-                                                                       ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
+                                                               ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
                                                                break;
                                                        }
                                                }
@@ -6702,6 +6781,45 @@ static void *ss_thread(void *data)
                                return NULL;
                        }
                } else if (p->use_callerid && p->cid_start == CID_START_RING) {
+                        if (p->cid_signalling == CID_SIG_DTMF) {
+                                int i = 0;
+                                cs = NULL;
+                                zt_setlinear(p->subs[index].zfd, 0);
+                                res = 2000;
+                                for (;;) {
+                                        struct ast_frame *f;
+                                        res = ast_waitfor(chan, res);
+                                        if (res <= 0) {
+                                                ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
+                                                                "Exiting simple switch\n");
+                                                ast_hangup(chan);
+                                                return NULL;
+                                        }
+                                        f = ast_read(chan);
+                                        if (f->frametype == AST_FRAME_DTMF) {
+                                                dtmfbuf[i++] = f->subclass;
+                                                ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
+                                                res = 2000;
+                                        }
+                                        ast_frfree(f);
+
+                                        if (p->ringt_base == p->ringt)
+                                                break;
+
+                                }
+                                dtmfbuf[i] = '\0';
+                                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
+                                /* Got cid and ring. */
+                                callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
+                                ast_log(LOG_DEBUG, "CID is '%s', flags %d\n",
+                                                dtmfcid, flags);
+                                /* If first byte is NULL, we have no cid */
+                                if (!ast_strlen_zero(dtmfcid))
+                                        number = dtmfcid;
+                                else
+                                        number = NULL;
+                                /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
+                        } else {
                        /* FSK Bell202 callerID */
                        cs = callerid_new(p->cid_signalling);
                        if (cs) {
@@ -6777,8 +6895,7 @@ static void *ss_thread(void *data)
                                }
                                if (res == 1) {
                                        callerid_get(cs, &name, &number, &flags);
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
+                                       ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
                                }
                                if (distinctiveringaftercid == 1) {
                                        /* Clear the current ring data array so we dont have old data in it. */
@@ -6786,8 +6903,7 @@ static void *ss_thread(void *data)
                                                curRingData[receivedRingT] = 0;
                                        }
                                        receivedRingT = 0;
-                                       if (option_verbose > 2)
-                                               ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
+                                       ast_verb(3, "Detecting post-CID distinctive ring\n");
                                        for (;;) {
                                                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
                                                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))    {
@@ -6831,30 +6947,28 @@ static void *ss_thread(void *data)
                                        }
                                }
                                if (p->usedistinctiveringdetection == 1) {
-                                       if (option_verbose > 2)
                                                /* this only shows up if you have n of the dring patterns filled in */
-                                               ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
+                                       ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
 
                                        for (counter = 0; counter < 3; counter++) {
                                                /* Check to see if the rings we received match any of the ones in zapata.conf for this
                                                channel */
-                                               if (option_verbose > 2)
                                                        /* this only shows up if you have n of the dring patterns filled in */
-                                                       ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
+                                               ast_verb(3, "Checking %d,%d,%d\n",
                                                                p->drings.ringnum[counter].ring[0],
                                                                p->drings.ringnum[counter].ring[1],
                                                                p->drings.ringnum[counter].ring[2]);
                                                distMatches = 0;
                                                for (counter1 = 0; counter1 < 3; counter1++) {
-                                                       ast_verbose( VERBOSE_PREFIX_3 "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
+                                                       ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
                                                        if (p->drings.ringnum[counter].ring[counter1] == -1) {
-                                                               ast_verbose( VERBOSE_PREFIX_3 "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
+                                                               ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
                                                                curRingData[counter1]);
                                                                distMatches++;
                                                        }
                                                        else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
                                                            curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
-                                                               ast_verbose( VERBOSE_PREFIX_3 "Ring pattern matched in range: %d to %d\n",
+                                                               ast_verb(3, "Ring pattern matched in range: %d to %d\n",
                                                                (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
                                                                (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
                                                                distMatches++;
@@ -6864,8 +6978,7 @@ static void *ss_thread(void *data)
                                                        /* The ring matches, set the context to whatever is for distinctive ring.. */
                                                        ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
                                                        ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
-                                                       if (option_verbose > 2)
-                                                               ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
+                                                       ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
                                                        break;
                                                }
                                        }
@@ -6881,6 +6994,7 @@ static void *ss_thread(void *data)
                        } else
                                ast_log(LOG_WARNING, "Unable to get caller ID space\n");
                }
+               }
                else
                        cs = NULL;
 
@@ -6982,7 +7096,7 @@ static int handle_init_event(struct zt_pvt *i, int event)
                                        else
                                                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
                                        if (res < 0) 
-                                               ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel);
+                                               ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
                                        if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
                                                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
                                                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
@@ -7015,7 +7129,11 @@ static int handle_init_event(struct zt_pvt *i, int event)
                case SIG_SF_FEATB:
                case SIG_SF:
                                /* Check for callerid, digits, etc */
-                               chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
+                               if (i->cid_start == CID_START_POLARITY_IN) {
+                                       chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
+                               } else {
+                                       chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
+                               }
                                if (chan && ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
                                        ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
                                        res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
@@ -7106,9 +7224,9 @@ static int handle_init_event(struct zt_pvt *i, int event)
                case SIG_FXSLS:
                case SIG_FXSKS:
                case SIG_FXSGS:
-                       if (i->cid_start == CID_START_POLARITY) {
+                       if (i->cid_start == CID_START_POLARITY || i->cid_start == CID_START_POLARITY_IN) {
                                i->polarity = POLARITY_REV;
-                               ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
+                               ast_verb(2, "Starting post polarity "
                                            "CID detection on channel %d\n",
                                            i->channel);
                                chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
@@ -7151,15 +7269,16 @@ static void *do_monitor(void *data)
                ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
                return NULL;
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Monitor starting...\n");
+       ast_debug(1, "Monitor starting...\n");
 #endif
        for (;;) {
                /* Lock the interface list */
                ast_mutex_lock(&iflock);
                if (!pfds || (lastalloc != ifcount)) {
-                       if (pfds)
+                       if (pfds) {
                                ast_free(pfds);
+                               pfds = NULL;
+                       }
                        if (ifcount) {
                                if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
                                        ast_mutex_unlock(&iflock);
@@ -7218,8 +7337,12 @@ static void *do_monitor(void *data)
                                                        res = has_voicemail(last);
                                                        if (last->msgstate != res) {
                                                                int x;
-                                                               if (option_debug)
-                                                                       ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
+                                                               ast_debug(1, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
+#ifdef ZT_VMWI
+                                                               res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_VMWI, res);
+                                                               if (res2)
+                                                                       ast_log(LOG_DEBUG, "Unable to control message waiting led on channel %d\n", last->channel);
+#endif
                                                                x = ZT_FLUSH_BOTH;
                                                                res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
                                                                if (res2)
@@ -7246,8 +7369,7 @@ static void *do_monitor(void *data)
                                        res = zt_get_event(i->subs[SUB_REAL].zfd);
                                        if (res)
                                        {
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
+                                               ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
                                                /* Don't hold iflock while handling init events */
                                                ast_mutex_unlock(&iflock);
                                                handle_init_event(i, res);
@@ -7292,8 +7414,7 @@ static void *do_monitor(void *data)
                                        } else {
                                                ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
                                        }
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
+                                       ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
                                        /* Don't hold iflock while handling init events -- race with chlock */
                                        ast_mutex_unlock(&iflock);
                                        handle_init_event(i, res);
@@ -7309,8 +7430,7 @@ static void *do_monitor(void *data)
                                                continue;
                                        }
                                        res = zt_get_event(i->subs[SUB_REAL].zfd);
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
+                                       ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
                                        /* Don't hold iflock while handling init events */
                                        ast_mutex_unlock(&iflock);
                                        handle_init_event(i, res);
@@ -7469,7 +7589,7 @@ static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
 
 #ifdef HAVE_SS7
 
-static unsigned int parse_pointcode(char *pcstring)
+static unsigned int parse_pointcode(const char *pcstring)
 {
        unsigned int code1, code2, code3;
        int numvals;
@@ -7615,6 +7735,14 @@ static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pr
                                tmp->ss7 = ss7;
                                tmp->ss7call = NULL;
                                ss7->pvts[ss7->numchans++] = tmp;
+
+                               ast_copy_string(linksets[span].internationalprefix, conf.ss7.internationalprefix, sizeof(linksets[span].internationalprefix));
+                               ast_copy_string(linksets[span].nationalprefix, conf.ss7.nationalprefix, sizeof(linksets[span].nationalprefix));
+                               ast_copy_string(linksets[span].subscriberprefix, conf.ss7.subscriberprefix, sizeof(linksets[span].subscriberprefix));
+                               ast_copy_string(linksets[span].unknownprefix, conf.ss7.unknownprefix, sizeof(linksets[span].unknownprefix));
+
+                               linksets[span].called_nai = conf.ss7.called_nai;
+                               linksets[span].calling_nai = conf.ss7.calling_nai;
                        }
 #endif
 #ifdef HAVE_PRI
@@ -7892,8 +8020,14 @@ static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pr
                ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name));
                ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox));
                if (!ast_strlen_zero(tmp->mailbox)) {
+                       char *mailbox, *context;
+                       mailbox = context = ast_strdupa(tmp->mailbox);
+                       strsep(&context, "@");
+                       if (ast_strlen_zero(context))
+                               context = "default";
                        tmp->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
-                               AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, tmp->mailbox,
+                               AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
+                               AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
                                AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
                                AST_EVENT_IE_END);
                }
@@ -7901,6 +8035,10 @@ static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pr
                tmp->group = conf.chan.group;
                tmp->callgroup = conf.chan.callgroup;
                tmp->pickupgroup= conf.chan.pickupgroup;
+               if (conf.chan.vars) {
+                       tmp->vars = conf.chan.vars;
+                       conf.chan.vars = NULL;
+               }
                tmp->cid_rxgain = conf.chan.cid_rxgain;
                tmp->rxgain = conf.chan.rxgain;
                tmp->txgain = conf.chan.txgain;
@@ -8073,8 +8211,7 @@ static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch,
                                        return 1;
 #endif
                        } else if (par.rxisoffhook) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
+                               ast_debug(1, "Channel %d off hook, can't use\n", p->channel);
                                /* Not available when the other end is off hook */
                                return 0;
                        }
@@ -8158,9 +8295,8 @@ static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
                if (!backwards && (x >= pri->numchans))
                        break;
                if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
-                                       pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
+                       ast_debug(1, "Found empty available channel %d/%d\n", 
+                               pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
                        return x;
                }
                if (backwards)
@@ -8289,10 +8425,9 @@ static struct ast_channel *zt_request(const char *type, int format, void *data,
 #endif
 
                if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
-                               if (p->inalarm) 
-                                       goto next;
+                       ast_debug(1, "Using channel %d\n", p->channel);
+                       if (p->inalarm) 
+                               goto next;
 
                        callwait = (p->owner != NULL);
 #ifdef HAVE_PRI
@@ -8312,10 +8447,9 @@ static struct ast_channel *zt_request(const char *type, int format, void *data,
                                                ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
                                                p = NULL;
                                                break;
-                                       } else {
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
-                                       }
+                                       } else
+                                               ast_debug(1, "Allocated placeholder pseudo channel\n");
+
                                        p->pri = pri;
                                }
                        }
@@ -8410,6 +8544,38 @@ static int ss7_find_cic(struct zt_ss7 *linkset, int cic)
        return winner;
 }
 
+static void ss7_handle_cqm(struct zt_ss7 *linkset, int startcic, int endcic)
+{
+       unsigned char status[32];
+       struct zt_pvt *p = NULL;
+       int i, offset;
+
+       for (i = 0; i < linkset->numchans; i++) {
+               if (linkset->pvts[i] && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic))) {
+                       p = linkset->pvts[i];
+                       offset = p->cic - startcic;
+                       status[offset] = 0;
+                       if (p->locallyblocked)
+                               status[offset] |= (1 << 0) | (1 << 4);
+                       if (p->remotelyblocked)
+                               status[offset] |= (1 << 1) | (1 << 5);
+                       if (p->ss7call) {
+                               if (p->outgoing)
+                                       status[offset] |= (1 << 3);
+                               else
+                                       status[offset] |= (1 << 2);
+                       } else
+                               status[offset] |= 0x3 << 2;
+               }
+       }
+
+       if (p)
+               isup_cqr(linkset->ss7, startcic, endcic, p->dpc, status);
+       else
+               ast_log(LOG_WARNING, "Could not find any equipped circuits within CQM CICs\n");
+       
+}
+
 static inline void ss7_block_cics(struct zt_ss7 *linkset, int startcic, int endcic, unsigned char state[], int block)
 {
        int i;
@@ -8465,9 +8631,12 @@ static void ss7_reset_linkset(struct zt_ss7 *linkset)
 
 static void zt_loopback(struct zt_pvt *p, int enable)
 {
-       if (ioctl(p->subs[SUB_REAL].zfd, ZT_LOOPBACK, &enable)) {
-               ast_log(LOG_WARNING, "Unable to set loopback on channel %d\n", p->channel);
-               return;
+       if (p->loopedback != enable) {
+               if (ioctl(p->subs[SUB_REAL].zfd, ZT_LOOPBACK, &enable)) {
+                       ast_log(LOG_WARNING, "Unable to set loopback on channel %d\n", p->channel);
+                       return;
+               }
+               p->loopedback = enable;
        }
 }
 
@@ -8497,11 +8666,47 @@ static void ss7_start_call(struct zt_pvt *p, struct zt_ss7 *linkset)
        c = zt_new(p, AST_STATE_RING, 1, SUB_REAL, law, 0);
        ast_mutex_lock(&linkset->lock);
        if (c)
-               ast_verbose(VERBOSE_PREFIX_3 "Accepting call to '%s' on CIC %d\n", p->exten, p->cic);
+               ast_verb(3, "Accepting call to '%s' on CIC %d\n", p->exten, p->cic);
        else
                ast_log(LOG_WARNING, "Unable to start PBX on CIC %d\n", p->cic);
+
+       if (!ast_strlen_zero(p->charge_number)) {
+               pbx_builtin_setvar_helper(c, "SS7_CHARGE_NUMBER", p->charge_number);
+               /* Clear this after we set it */
+               p->charge_number[0] = 0;
+       }
+       if (!ast_strlen_zero(p->gen_add_number)) {
+               pbx_builtin_setvar_helper(c, "SS7_GENERIC_ADDRESS", p->gen_add_number);
+               /* Clear this after we set it */
+               p->gen_add_number[0] = 0;
+       }
+
 }
 
+static void ss7_apply_plan_to_number(char *buf, size_t size, const struct zt_ss7 *ss7, const char *number, const unsigned nai)
+{
+       switch (nai) {
+       case SS7_NAI_INTERNATIONAL:
+               snprintf(buf, size, "%s%s", ss7->internationalprefix, number);
+               break;
+       case SS7_NAI_NATIONAL:
+               snprintf(buf, size, "%s%s", ss7->nationalprefix, number);
+               break;
+       case SS7_NAI_SUBSCRIBER:
+               snprintf(buf, size, "%s%s", ss7->subscriberprefix, number);
+               break;
+       case SS7_NAI_UNKNOWN:
+               snprintf(buf, size, "%s%s", ss7->unknownprefix, number);
+               break;
+       default:
+               snprintf(buf, size, "%s", number);
+               break;
+       }
+}
+static int ss7_pres_scr2cid_pres(char presentation_ind, char screening_ind)
+{
+    return ((presentation_ind & 0x3) << 5) | (screening_ind & 0x3);
+}
 
 static void *ss7_linkset(void *data)
 {
@@ -8522,7 +8727,7 @@ static void *ss7_linkset(void *data)
        while(1) {
                ast_mutex_lock(&linkset->lock);
                if ((next = ss7_schedule_next(ss7))) {
-                       gettimeofday(&tv, NULL);
+                       tv = ast_tvnow();
                        tv.tv_sec = next->tv_sec - tv.tv_sec;
                        tv.tv_usec = next->tv_usec - tv.tv_usec;
                        if (tv.tv_usec < 0) {
@@ -8563,13 +8768,13 @@ static void *ss7_linkset(void *data)
                                }
                                switch (x) {
                                case ZT_EVENT_OVERRUN:
-                                       ast_log(LOG_DEBUG, "Overrun detected!\n");
+                                       ast_debug(1, "Overrun detected!\n");
                                        break;
                                case ZT_EVENT_BADFCS:
-                                       ast_log(LOG_DEBUG, "Bad FCS\n");
+                                       ast_debug(1, "Bad FCS\n");
                                        break;
                                case ZT_EVENT_ABORT:
-                                       ast_log(LOG_DEBUG, "HDLC Abort\n");
+                                       ast_debug(1, "HDLC Abort\n");
                                        break;
                                case ZT_EVENT_ALARM:
                                        ast_log(LOG_ERROR, "Alarm on link!\n");
@@ -8589,10 +8794,15 @@ static void *ss7_linkset(void *data)
                                }
                        }
 
-                       if (pollers[i].revents & POLLIN)
+                       if (pollers[i].revents & POLLIN) {
+                               ast_mutex_lock(&linkset->lock);
                                res = ss7_read(ss7, pollers[i].fd);
+                               ast_mutex_unlock(&linkset->lock);
+                       }
                        if (pollers[i].revents & POLLOUT) {
+                               ast_mutex_lock(&linkset->lock);
                                res = ss7_write(ss7, pollers[i].fd);
+                               ast_mutex_unlock(&linkset->lock);
                                if (res < 0) {
                                        ast_log(LOG_ERROR, "Error in write %s", strerror(errno));
                                }
@@ -8623,7 +8833,7 @@ static void *ss7_linkset(void *data)
                                }
                                break;
                        case MTP2_LINK_UP:
-                               ast_log(LOG_DEBUG, "MTP2 link up\n");
+                               ast_debug(1, "MTP2 link up\n");
                                break;
                        case ISUP_EVENT_CPG:
                                chanpos = ss7_find_cic(linkset, e->cpg.cic);
@@ -8642,13 +8852,17 @@ static void *ss7_linkset(void *data)
                                case CPG_EVENT_INBANDINFO:
                                        {
                                                struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
-                                               ast_log(LOG_DEBUG, "Queuing frame PROGRESS on CIC %d\n", p->cic);
-                                               zap_queue_frame(p, &f, ss7);
+                                               ast_debug(1, "Queuing frame PROGRESS on CIC %d\n", p->cic);
+                                               zap_queue_frame(p, &f, linkset);
                                                p->progress = 1;
+                                               if (p->dsp && p->dsp_features) {
+                                                       ast_dsp_set_features(p->dsp, p->dsp_features);
+                                                       p->dsp_features = 0;
+                                               }
                                        }
                                        break;
                                default:
-                                       ast_log(LOG_DEBUG, "Do not handle CPG with event type 0x%x\n", e->cpg.event);
+                                       ast_debug(1, "Do not handle CPG with event type 0x%x\n", e->cpg.event);
                                }
 
                                ast_mutex_unlock(&p->lock);
@@ -8670,7 +8884,7 @@ static void *ss7_linkset(void *data)
                                isup_rlc(ss7, e->rsc.call);
                                break;
                        case ISUP_EVENT_GRS:
-                               ast_log(LOG_DEBUG, "Got Reset for CICs %d to %d: Acknowledging\n", e->grs.startcic, e->grs.endcic);
+                               ast_debug(1, "Got Reset for CICs %d to %d: Acknowledging\n", e->grs.startcic, e->grs.endcic);
                                chanpos = ss7_find_cic(linkset, e->grs.startcic);
                                if (chanpos < 0) {
                                        ast_log(LOG_WARNING, "GRS on unconfigured CIC %d\n", e->grs.startcic);
@@ -8680,13 +8894,17 @@ static void *ss7_linkset(void *data)
                                isup_gra(ss7, e->grs.startcic, e->grs.endcic, p->dpc);
                                ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, NULL, 0);
                                break;
+                       case ISUP_EVENT_CQM:
+                               ast_debug(1, "Got Circuit group query message from CICs %d to %d\n", e->cqm.startcic, e->cqm.endcic);
+                               ss7_handle_cqm(linkset, e->cqm.startcic, e->cqm.endcic);
+                               break;
                        case ISUP_EVENT_GRA:
                                ast_verbose("Got reset acknowledgement from CIC %d to %d.\n", e->gra.startcic, e->gra.endcic);
                                ss7_inservice(linkset, e->gra.startcic, e->gra.endcic);
                                ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.status, 1);
                                break;
                        case ISUP_EVENT_IAM:
-                               ast_log(LOG_DEBUG, "Got IAM for CIC %d and number %s\n", e->iam.cic, e->iam.called_party_num);
+                               ast_debug(1, "Got IAM for CIC %d and called number %s, calling number %s\n", e->iam.cic, e->iam.called_party_num, e->iam.calling_party_num);
                                chanpos = ss7_find_cic(linkset, e->iam.cic);
                                if (chanpos < 0) {
                                        ast_log(LOG_WARNING, "IAM on unconfigured CIC %d\n", e->iam.cic);
@@ -8711,8 +8929,11 @@ static void *ss7_linkset(void *data)
                                p->ss7call = e->iam.call;
                                isup_set_call_dpc(p->ss7call, dpc);
 
-                               if (p->use_callerid)
-                                       ast_copy_string(p->cid_num, e->iam.calling_party_num, sizeof(p->cid_num));
+                               if ( (p->use_callerid) && (!ast_strlen_zero(e->iam.calling_party_num)) )
+                               {
+                                       ss7_apply_plan_to_number(p->cid_num, sizeof(p->cid_num), linkset, e->iam.calling_party_num, e->iam.calling_nai);
+                                       p->callingpres = ss7_pres_scr2cid_pres(e->iam.presentation_ind, e->iam.screening_ind);
+                               }
                                else
                                        p->cid_num[0] = 0;
 
@@ -8721,21 +8942,29 @@ static void *ss7_linkset(void *data)
                                        p->exten[1] = '\0';
                                } else if (!ast_strlen_zero(e->iam.called_party_num)) {
                                        char *st;
-                                       ast_copy_string(p->exten, e->iam.called_party_num, sizeof(p->exten));
+                                       ss7_apply_plan_to_number(p->exten, sizeof(p->exten), linkset, e->iam.called_party_num, e->iam.called_nai);
                                        st = strchr(p->exten, '#');
                                        if (st)
                                                *st = '\0';
-                               } else
-                                       p->exten[0] = '\0';
+                                       } else
+                                               p->exten[0] = '\0';
 
-                               /* Need to fill these fields */
                                p->cid_ani[0] = '\0';
                                p->cid_name[0] = '\0';
+                               p->cid_ani2 = e->iam.oli_ani2;
                                p->cid_ton = 0;
+                               ast_copy_string(p->charge_number, e->iam.charge_number, sizeof(p->charge_number));
+
+                               ast_copy_string(p->gen_add_number, e->iam.gen_add_number, sizeof(p->gen_add_number));
+                               p->gen_add_type = e->iam.gen_add_type;
+                               p->gen_add_nai = e->iam.gen_add_nai;
+                               p->gen_add_pres_ind = e->iam.gen_add_pres_ind;
+                               p->gen_add_num_plan = e->iam.gen_add_num_plan;
+                                       
                                /* Set DNID */
                                if (!ast_strlen_zero(e->iam.called_party_num))
-                                       ast_copy_string(p->dnid, e->iam.called_party_num, sizeof(p->exten));
-
+                                       ss7_apply_plan_to_number(p->dnid, sizeof(p->dnid), linkset, e->iam.called_party_num, e->iam.called_nai);
+                               
                                if (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
 
                                        if (e->iam.cot_check_required) {
@@ -8743,7 +8972,7 @@ static void *ss7_linkset(void *data)
                                        } else
                                                ss7_start_call(p, linkset);
                                } else {
-                                       ast_log(LOG_DEBUG, "Call on CIC for unconfigured extension %s\n", p->exten);
+                                       ast_debug(1, "Call on CIC for unconfigured extension %s\n", p->exten);
                                        isup_rel(ss7, e->iam.call, -1);
                                }
                                ast_mutex_unlock(&p->lock);
@@ -8761,6 +8990,22 @@ static void *ss7_linkset(void *data)
                                
                                ss7_start_call(p, linkset);
                                break;
+                       case ISUP_EVENT_CCR:
+                               ast_debug(1, "Got CCR request on CIC %d\n", e->ccr.cic);
+                               chanpos = ss7_find_cic(linkset, e->ccr.cic);
+                               if (chanpos < 0) {
+                                       ast_log(LOG_WARNING, "CCR on unconfigured CIC %d\n", e->ccr.cic);
+                                       break;
+                               }
+
+                               p = linkset->pvts[chanpos];
+
+                               ast_mutex_lock(&p->lock);
+                               zt_loopback(p, 1);
+                               ast_mutex_unlock(&p->lock);
+
+                               isup_lpa(linkset->ss7, e->ccr.cic, p->dpc);
+                               break;
                        case ISUP_EVENT_REL:
                                chanpos = ss7_find_cic(linkset, e->rel.cic);
                                if (chanpos < 0) {
@@ -8771,10 +9016,13 @@ static void *ss7_linkset(void *data)
                                ast_mutex_lock(&p->lock);
                                if (p->owner) {
                                        p->owner->hangupcause = e->rel.cause;
-                                       ast_queue_hangup(p->owner);
+                                       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
                                } else
                                        ast_log(LOG_WARNING, "REL on channel (CIC %d) without owner!\n", p->cic);
 
+                               /* End the loopback if we have one */
+                               zt_loopback(p, 0);
+
                                isup_rlc(ss7, e->rel.call);
                                p->ss7call = NULL;
 
@@ -8791,7 +9039,7 @@ static void *ss7_linkset(void *data)
 
                                        p = linkset->pvts[chanpos];
 
-                                       ast_log(LOG_DEBUG, "Queueing frame from SS7_EVENT_ACM on CIC %d\n", p->cic);
+                                       ast_debug(1, "Queueing frame from SS7_EVENT_ACM on CIC %d\n", p->cic);
 
                                        ast_mutex_lock(&p->lock);
                                        zap_queue_frame(p, &f, linkset);
@@ -8820,6 +9068,19 @@ static void *ss7_linkset(void *data)
                                ss7_block_cics(linkset, e->cgu.startcic, e->cgu.endcic, e->cgu.status, 0);
                                isup_cgua(linkset->ss7, e->cgu.startcic, e->cgu.endcic, p->dpc, e->cgu.status, e->cgu.type);
                                break;
+                       case ISUP_EVENT_UCIC:
+                               chanpos = ss7_find_cic(linkset, e->ucic.cic);
+                               if (chanpos < 0) {
+                                       ast_log(LOG_WARNING, "UCIC on unconfigured CIC %d\n", e->ucic.cic);
+                                       break;
+                               }
+                               p = linkset->pvts[chanpos];
+                               ast_debug(1, "Unequiped Circuit Id Code on CIC %d\n", e->ucic.cic);
+                               ast_mutex_lock(&p->lock);
+                               p->remotelyblocked = 1;
+                               p->inservice = 0;
+                               ast_mutex_unlock(&p->lock);                     //doesn't require a SS7 acknowledgement
+                               break;
                        case ISUP_EVENT_BLO:
                                chanpos = ss7_find_cic(linkset, e->blo.cic);
                                if (chanpos < 0) {
@@ -8827,12 +9088,24 @@ static void *ss7_linkset(void *data)
                                        break;
                                }
                                p = linkset->pvts[chanpos];
-                               ast_log(LOG_DEBUG, "Blocking CIC %d\n", e->blo.cic);
+                               ast_debug(1, "Blocking CIC %d\n", e->blo.cic);
                                ast_mutex_lock(&p->lock);
                                p->remotelyblocked = 1;
                                ast_mutex_unlock(&p->lock);
                                isup_bla(linkset->ss7, e->blo.cic, p->dpc);
                                break;
+                       case ISUP_EVENT_BLA:
+                               chanpos = ss7_find_cic(linkset, e->bla.cic);
+                               if (chanpos < 0) {
+                                       ast_log(LOG_WARNING, "BLA on unconfigured CIC %d\n", e->bla.cic);
+                                       break;
+                               }
+                               ast_debug(1, "Blocking CIC %d\n", e->bla.cic);
+                               p = linkset->pvts[chanpos];
+                               ast_mutex_lock(&p->lock);
+                               p->locallyblocked = 1;
+                               ast_mutex_unlock(&p->lock);
+                               break;
                        case ISUP_EVENT_UBL:
                                chanpos = ss7_find_cic(linkset, e->ubl.cic);
                                if (chanpos < 0) {
@@ -8840,12 +9113,24 @@ static void *ss7_linkset(void *data)
                                        break;
                                }
                                p = linkset->pvts[chanpos];
-                               ast_log(LOG_DEBUG, "Unblocking CIC %d\n", e->ubl.cic);
+                               ast_debug(1, "Unblocking CIC %d\n", e->ubl.cic);
                                ast_mutex_lock(&p->lock);
                                p->remotelyblocked = 0;
                                ast_mutex_unlock(&p->lock);
                                isup_uba(linkset->ss7, e->ubl.cic, p->dpc);
                                break;
+                       case ISUP_EVENT_UBA:
+                               chanpos = ss7_find_cic(linkset, e->uba.cic);
+                               if (chanpos < 0) {
+                                       ast_log(LOG_WARNING, "UBA on unconfigured CIC %d\n", e->uba.cic);
+                                       break;
+                               }
+                               p = linkset->pvts[chanpos];
+                               ast_debug(1, "Unblocking CIC %d\n", e->uba.cic);
+                               ast_mutex_lock(&p->lock);
+                               p->locallyblocked = 0;
+                               ast_mutex_unlock(&p->lock);
+                               break;
                        case ISUP_EVENT_CON:
                        case ISUP_EVENT_ANM:
                                if (e->e == ISUP_EVENT_CON)
@@ -8862,6 +9147,10 @@ static void *ss7_linkset(void *data)
                                        p = linkset->pvts[chanpos];
                                        ast_mutex_lock(&p->lock);
                                        p->subs[SUB_REAL].needanswer = 1;
+                                       if (p->dsp && p->dsp_features) {
+                                               ast_dsp_set_features(p->dsp, p->dsp_features);
+                                               p->dsp_features = 0;
+                                       }
                                        zt_enable_ec(p);
                                        ast_mutex_unlock(&p->lock);
                                }
@@ -8874,12 +9163,15 @@ static void *ss7_linkset(void *data)
                                } else {
                                        p = linkset->pvts[chanpos];
                                        ast_mutex_lock(&p->lock);
-                                       p->ss7call = NULL;
+                                       if (p->alreadyhungup)
+                                               p->ss7call = NULL;
+                                       else
+                                               ast_log(LOG_NOTICE, "Received RLC out and we haven't sent REL.  Ignoring.\n");
                                        ast_mutex_unlock(&p->lock);
                                }
                                break;
                        default:
-                               ast_log(LOG_DEBUG, "Unknown event %s\n", ss7_event2str(e->e));
+                               ast_debug(1, "Unknown event %s\n", ss7_event2str(e->e));
                                break;
                        }
                }
@@ -8891,6 +9183,7 @@ static void *ss7_linkset(void *data)
 
 static void zt_ss7_message(struct ss7 *ss7, char *s)
 {
+#if 0
        int i;
 
        for (i = 0; i < NUM_SPANS; i++)
@@ -8898,18 +9191,25 @@ static void zt_ss7_message(struct ss7 *ss7, char *s)
                        break;
 
        ast_verbose("[%d] %s", i+1, s);
+#else
+       ast_verbose("%s", s);
+#endif
 }
 
 static void zt_ss7_error(struct ss7 *ss7, char *s)
 {
+#if 0
        int i;
 
        for (i = 0; i < NUM_SPANS; i++)
                if (linksets[i].ss7 == ss7)
                        break;
 
-       ast_log(LOG_ERROR, "[%d] %s", i+1, s);
+#else
+       ast_log(LOG_ERROR, "%s", s);
+#endif
 }
+
 #endif /* HAVE_SS7 */
 
 #ifdef HAVE_PRI
@@ -8974,8 +9274,7 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
                if (pri->pvts[x]->call == c) {
                        /* Found our call */
                        if (principle != x) {
-                               if (option_verbose > 2)
-                                       ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
+                               ast_verb(3, "Moving call from channel %d to channel %d\n",
                                                pri->pvts[x]->channel, pri->pvts[principle]->channel);
                                if (pri->pvts[principle]->owner) {
                                        ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
@@ -8989,7 +9288,7 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
                                                               "Zap/%d:%d-%d", pri->trunkgroup,
                                                               pri->pvts[principle]->channel, 1);
                                        pri->pvts[principle]->owner->tech_pvt = pri->pvts[principle];
-                                       pri->pvts[principle]->owner->fds[0] = pri->pvts[principle]->subs[SUB_REAL].zfd;
+                                       ast_channel_set_fd(pri->pvts[principle]->owner, 0, pri->pvts[principle]->subs[SUB_REAL].zfd);
                                        pri->pvts[principle]->subs[SUB_REAL].owner = pri->pvts[x]->subs[SUB_REAL].owner;
                                } else
                                        ast_log(LOG_WARNING, "Whoa, there's no  owner, and we're having to fix up channel %d to channel %d\n", pri->pvts[x]->channel, pri->pvts[principle]->channel);
@@ -9017,10 +9316,9 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
                                zt_close(crv->subs[SUB_REAL].zfd);
                                pri->pvts[principle]->call = crv->call;
                                pri_assign_bearer(crv, pri, pri->pvts[principle]);
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
-                                                                               pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
-                                                                               pri->trunkgroup, crv->channel);
+                               ast_debug(1, "Assigning bearer %d/%d to CRV %d:%d\n",
+                                       pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
+                                       pri->trunkgroup, crv->channel);
                                wakeup_sub(crv, SUB_REAL, pri);
                        }
                        return principle;
@@ -9039,8 +9337,7 @@ static void *do_idle_thread(void *vchan)
        char ex[80];
        /* Wait up to 30 seconds for an answer */
        int newms, ms = 30000;
-       if (option_verbose > 2) 
-               ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
+       ast_verb(3, "Initiating idle call on channel %s\n", chan->name);
        snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
        if (ast_call(chan, ex, 0)) {
                ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
@@ -9060,18 +9357,15 @@ static void *do_idle_thread(void *vchan)
                                ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
                                ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
                                chan->priority = 1;
-                               if (option_verbose > 3) 
-                                       ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
+                               ast_verb(4, "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
                                ast_pbx_run(chan);
                                /* It's already hungup, return immediately */
                                return NULL;
                        case AST_CONTROL_BUSY:
-                               if (option_verbose > 3) 
-                                       ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
+                               ast_verb(4, "Idle channel '%s' busy, waiting...\n", chan->name);
                                break;
                        case AST_CONTROL_CONGESTION:
-                               if (option_verbose > 3) 
-                                       ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
+                               ast_verb(4, "Idle channel '%s' congested, waiting...\n", chan->name);
                                break;
                        };
                }
@@ -9192,7 +9486,7 @@ static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
        do {
                redo = 0;
                for (x = 0; x < 3; x++) {
-                       while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
+                       while (p->subs[x].owner && ast_channel_trylock(p->subs[x].owner)) {
                                redo++;
                                ast_mutex_unlock(&p->lock);
                                usleep(1);
@@ -9200,7 +9494,7 @@ static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
                        }
                        if (p->subs[x].owner) {
                                ast_queue_hangup(p->subs[x].owner);
-                               ast_mutex_unlock(&p->subs[x].owner->lock);
+                               ast_channel_unlock(p->subs[x].owner);
                        }
                }
        } while (redo);
@@ -9275,7 +9569,7 @@ static void *pri_dchannel(void *vpri)
        int nextidle = -1;
        struct ast_channel *c;
        struct timeval tv, lowest, *next;
-       struct timeval lastidle = { 0, 0 };
+       struct timeval lastidle = ast_tvnow();
        int doidling=0;
        char *cc;
        char idlen[80];
@@ -9292,7 +9586,6 @@ static void *pri_dchannel(void *vpri)
        char plancallingani[256];
        char calledtonstr[10];
        
-       gettimeofday(&lastidle, NULL);
        if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
                /* Need to do idle dialing, check to be sure though */
                cc = strchr(pri->idleext, '@');
@@ -9362,7 +9655,7 @@ static void *pri_dchannel(void *vpri)
                                                }
                                        } else
                                                ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
-                                       gettimeofday(&lastidle, NULL);
+                                       lastidle = ast_tvnow();
                                }
                        } else if ((haveidles < pri->minunused) &&
                                   (activeidles > pri->minidle)) {
@@ -9449,8 +9742,7 @@ static void *pri_dchannel(void *vpri)
                                                pri_restart(pri->dchans[which]);
                                        }
                                
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
+                                       ast_debug(1, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
                                } else if (fds[which].revents & POLLIN) {
                                        e = pri_check_event(pri->dchans[which]);
                                }
@@ -9472,8 +9764,7 @@ static void *pri_dchannel(void *vpri)
 
                        switch (e->e) {
                        case PRI_EVENT_DCHAN_UP:
-                               if (option_verbose > 1) 
-                                       ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
+                               ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span);
                                pri->dchanavail[which] |= DCHAN_UP;
                                if (!pri->pri) pri_find_dchan(pri);
 
@@ -9493,8 +9784,7 @@ static void *pri_dchannel(void *vpri)
                                        }
                                break;
                        case PRI_EVENT_DCHAN_DOWN:
-                               if (option_verbose > 1) 
-                                       ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
+                               ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span);
                                pri->dchanavail[which] &= ~DCHAN_UP;
                                pri_find_dchan(pri);
                                if (!pri_is_up(pri)) {
@@ -9530,8 +9820,7 @@ static void *pri_dchannel(void *vpri)
                                                ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 
                                                        PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
                                        else {
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n", 
+                                               ast_verb(3, "B-channel %d/%d restarted on span %d\n",
                                                                PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
                                                ast_mutex_lock(&pri->pvts[chanpos]->lock);
                                                if (pri->pvts[chanpos]->call) {
@@ -9546,8 +9835,7 @@ static void *pri_dchannel(void *vpri)
                                                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
                                        }
                                } else {
-                                       if (option_verbose > 2)
-                                               ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
+                                       ast_verb(3, "Restart on requested on entire span %d\n", pri->span);
                                        for (x = 0; x < pri->numchans; x++)
                                                if (pri->pvts[x]) {
                                                        ast_mutex_lock(&pri->pvts[x]->lock);
@@ -9637,7 +9925,7 @@ static void *pri_dchannel(void *vpri)
                                                        break;
                                                } else {
                                                        /* This is where we handle initial glare */
-                                                       ast_log(LOG_DEBUG, "Ring requested on channel %d/%d already in use or previously requested on span %d.  Attempting to renegotiate channel.\n", 
+                                                       ast_debug(1, "Ring requested on channel %d/%d already in use or previously requested on span %d.  Attempting to renegotiate channel.\n", 
                                                        PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
                                                        ast_mutex_unlock(&pri->pvts[chanpos]->lock);
                                                        chanpos = -1;
@@ -9696,8 +9984,7 @@ static void *pri_dchannel(void *vpri)
                                                             e->ring.redirectingnum, e->ring.callingplanrdnis);
                                        /* If immediate=yes go to s|1 */
                                        if (pri->pvts[chanpos]->immediate) {
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
+                                               ast_verb(3, "Going to extension s|1 because of immediate=yes\n");
                                                pri->pvts[chanpos]->exten[0] = 's';
                                                pri->pvts[chanpos]->exten[1] = '\0';
                                        }
@@ -9712,8 +9999,7 @@ static void *pri_dchannel(void *vpri)
                                                ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
                                        /* No number yet, but received "sending complete"? */
                                        if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
+                                               ast_verb(3, "Going to extension s|1 because of Complete received\n");
                                                pri->pvts[chanpos]->exten[0] = 's';
                                                pri->pvts[chanpos]->exten[1] = '\0';
                                        }
@@ -9760,8 +10046,7 @@ static void *pri_dchannel(void *vpri)
                                                                pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
                                                                c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
                                                                pri->pvts[chanpos]->owner = &inuse;
-                                                               if (option_debug)
-                                                                       ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
+                                                               ast_debug(1, "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);
                                                        }
@@ -9771,6 +10056,7 @@ static void *pri_dchannel(void *vpri)
                                                        if (e->ring.ani2 >= 0) {
                                                                snprintf(ani2str, 5, "%.2d", e->ring.ani2);
                                                                pbx_builtin_setvar_helper(c, "ANI2", ani2str);
+                                                               pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
                                                        }
 
 #ifdef SUPPORT_USERUSER
@@ -9786,8 +10072,7 @@ static void *pri_dchannel(void *vpri)
                                                        
                                                        ast_mutex_lock(&pri->lock);
                                                        if (c && !ast_pthread_create_detached(&threadid, NULL, ss_thread, c)) {
-                                                               if (option_verbose > 2)
-                                                                       ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
+                                                               ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
                                                                                plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
                                                                                pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
                                                        } else {
@@ -9810,6 +10095,7 @@ static void *pri_dchannel(void *vpri)
                                                                if (e->ring.ani2 >= 0) {
                                                                        snprintf(ani2str, 5, "%d", e->ring.ani2);
                                                                        pbx_builtin_setvar_helper(c, "ANI2", ani2str);
+                                                                       pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
                                                                }
 
 #ifdef SUPPORT_USERUSER
@@ -9823,8 +10109,7 @@ static void *pri_dchannel(void *vpri)
                                                        
                                                                snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
                                                                pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
-                                                               if (option_verbose > 2)
-                                                                       ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
+                                                               ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
                                                                                plancallingnum, pri->pvts[chanpos]->exten, 
                                                                                        pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
                                                                zt_enable_ec(pri->pvts[chanpos]);
@@ -9836,8 +10121,7 @@ static void *pri_dchannel(void *vpri)
                                                        }
                                                }
                                        } else {
-                                               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",
+                                               ast_verb(3, "Extension '%s' in context '%s' from '%s' does not exist.  Rejecting call on channel %d/%d, span %d\n",
                                                                pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 
                                                                        pri->pvts[chanpos]->prioffset, pri->span);
                                                pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
@@ -9870,10 +10154,9 @@ static void *pri_dchannel(void *vpri)
                                                        zt_enable_ec(pri->pvts[chanpos]);
                                                        pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
                                                        pri->pvts[chanpos]->alerting = 1;
-                                               } else {
-                                                       if (option_debug)
-                                                               ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
-                                               }
+                                               } else
+                                                       ast_debug(1, "Deferring ringing notification because of extra digits to dial...\n");
+
 #ifdef PRI_PROGRESS_MASK
                                                if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
 #else
@@ -9909,14 +10192,12 @@ static void *pri_dchannel(void *vpri)
                                                struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
 
                                                if (e->proceeding.cause > -1) {
-                                                       if (option_verbose > 2)
-                                                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
+                                                       ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause);
 
                                                        /* Work around broken, out of spec USER_BUSY cause in a progress message */
                                                        if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
                                                                if (pri->pvts[chanpos]->owner) {
-                                                                       if (option_verbose > 2)
-                                                                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
+                                                                       ast_verb(3, "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
 
                                                                        pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
                                                                        f.subclass = AST_CONTROL_BUSY;
@@ -9925,9 +10206,8 @@ static void *pri_dchannel(void *vpri)
                                                }
                                                
                                                ast_mutex_lock(&pri->pvts[chanpos]->lock);
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
-                                                                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
+                                               ast_debug(1, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
+                                                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
                                                zap_queue_frame(pri->pvts[chanpos], &f, pri);
 #ifdef PRI_PROGRESS_MASK
                                                if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
@@ -9952,9 +10232,8 @@ static void *pri_dchannel(void *vpri)
                                                struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
                                                
                                                ast_mutex_lock(&pri->pvts[chanpos]->lock);
-                                               if (option_debug)
-                                                       ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
-                                                                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
+                                               ast_debug(1, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
+                                                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
                                                zap_queue_frame(pri->pvts[chanpos], &f, pri);
 #ifdef PRI_PROGRESS_MASK
                                                if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
@@ -10018,8 +10297,7 @@ static void *pri_dchannel(void *vpri)
                                                        pri->pvts[chanpos]->dsp_features = 0;
                                                }
                                                if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
-                                                       if (option_debug)
-                                                               ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
+                                                       ast_debug(1, "Starting up GR-303 trunk now that we got CONNECT...\n");
                                                        x = ZT_START;
                                                        res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
                                                        if (res < 0) {
@@ -10034,14 +10312,12 @@ static void *pri_dchannel(void *vpri)
                                                        if (res < 0) {
                                                                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
                                                                pri->pvts[chanpos]->dop.dialstr[0] = '\0';
-                                                       } else {
-                                                               if (option_debug)
-                                                                       ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
-                                                       }
+                                                       } else
+                                                               ast_debug(1, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
+
                                                        pri->pvts[chanpos]->dop.dialstr[0] = '\0';
                                                } else if (pri->pvts[chanpos]->confirmanswer) {
-                                                       if (option_debug)
-                                                               ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
+                                                       ast_debug(1, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
                                                } else {
                                                        pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
                                                        /* Enable echo cancellation if it's not on already */
@@ -10075,43 +10351,44 @@ static void *pri_dchannel(void *vpri)
                                                        else if (pri->pvts[chanpos]->owner) {
                                                                /* Queue a BUSY instead of a hangup if our cause is appropriate */
                                                                pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
-                                                               switch(e->hangup.cause) {
-                                                               case PRI_CAUSE_USER_BUSY:
-                                                                       pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
-                                                                       break;
-                                                               case PRI_CAUSE_CALL_REJECTED:
-                                                               case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
-                                                               case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
-                                                               case PRI_CAUSE_SWITCH_CONGESTION:
-                                                               case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
-                                                               case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
-                                                                       pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
-                                                                       break;
-                                                               default:
+                                                               if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
                                                                        pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+                                                               else {
+                                                                       switch (e->hangup.cause) {
+                                                                       case PRI_CAUSE_USER_BUSY:
+                                                                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
+                                                                               break;
+                                                                       case PRI_CAUSE_CALL_REJECTED:
+                                                                       case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
+                                                                       case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
+                                                                       case PRI_CAUSE_SWITCH_CONGESTION:
+                                                                       case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
+                                                                       case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
+                                                                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
+                                                                               break;
+                                                                       default:
+                                                                               pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+                                                                       }
                                                                }
                                                        }
-                                                       if (option_verbose > 2) 
-                                                               ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup\n", 
-                                                                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
+                                                       ast_verb(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->pvts[chanpos]->call = NULL;
                                                }
                                                if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
-                                                       if (option_verbose > 2)
-                                                               ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 
+                                                       ast_verb(3, "Forcing restart of channel %d/%d on span %d since channel reported in use\n",
                                                                        PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
                                                        pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
                                                        pri->pvts[chanpos]->resetting = 1;
                                                }
                                                if (e->hangup.aoc_units > -1)
-                                                       if (option_verbose > 2)
-                                                               ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
+                                                       ast_verb(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)) {
+                                               if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
                                                        pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
                                                }
 #endif
@@ -10139,34 +10416,35 @@ static void *pri_dchannel(void *vpri)
                                                        pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
                                                else if (pri->pvts[chanpos]->owner) {
                                                        pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
-                                                       switch(e->hangup.cause) {
-                                                       case PRI_CAUSE_USER_BUSY:
-                                                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
-                                                               break;
-                                                       case PRI_CAUSE_CALL_REJECTED:
-                                                       case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
-                                                       case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
-                                                       case PRI_CAUSE_SWITCH_CONGESTION:
-                                                       case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
-                                                       case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
-                                                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
-                                                               break;
-                                                       default:
+                                                       if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
                                                                pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+                                                       else {
+                                                               switch (e->hangup.cause) {
+                                                                       case PRI_CAUSE_USER_BUSY:
+                                                                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
+                                                                               break;
+                                                                       case PRI_CAUSE_CALL_REJECTED:
+                                                                       case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
+                                                                       case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
+                                                                       case PRI_CAUSE_SWITCH_CONGESTION:
+                                                                       case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
+                                                                       case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
+                                                                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
+                                                                               break;
+                                                                       default:
+                                                                               pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+                                                               }
                                                        }
-                                                       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);
+                                                       ast_verb(3, "Channel %d/%d, span %d got hangup request, cause %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause);
                                                        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",
+                                                               ast_verb(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");
                                                } else {
                                                        pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
                                                        pri->pvts[chanpos]->call = NULL;
                                                }
                                                if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
-                                                       if (option_verbose > 2)
-                                                               ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", 
+                                                       ast_verb(3, "Forcing restart of channel %d/%d span %d since channel reported in use\n",
                                                                        PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
                                                        pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
                                                        pri->pvts[chanpos]->resetting = 1;
@@ -10196,8 +10474,7 @@ static void *pri_dchannel(void *vpri)
                                                pri->pvts[chanpos]->call = NULL;
                                                pri->pvts[chanpos]->resetting = 0;
                                                if (pri->pvts[chanpos]->owner) {
-                                                       if (option_verbose > 2) 
-                                                               ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
+                                                       ast_verb(3, "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
                                                }
 
 #ifdef SUPPORT_USERUSER
@@ -10223,9 +10500,8 @@ static void *pri_dchannel(void *vpri)
                                                if (pri->pvts[x] && pri->pvts[x]->resetting) {
                                                        chanpos = x;
                                                        ast_mutex_lock(&pri->pvts[chanpos]->lock);
-                                                       if (option_debug)
-                                                               ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
-                                                                               pri->pvts[chanpos]->prioffset, pri->span);
+                                                       ast_debug(1, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
+                                                               pri->pvts[chanpos]->prioffset, pri->span);
                                                        if (pri->pvts[chanpos]->realcall) 
                                                                pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
                                                        else if (pri->pvts[chanpos]->owner) {
@@ -10234,8 +10510,7 @@ static void *pri_dchannel(void *vpri)
                                                                pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
                                                        }
                                                        pri->pvts[chanpos]->resetting = 0;
-                                                       if (option_verbose > 2)
-                                                               ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
+                                                       ast_verb(3, "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan,
                                                                        pri->pvts[chanpos]->prioffset, pri->span);
                                                        ast_mutex_unlock(&pri->pvts[chanpos]->lock);
                                                        if (pri->resetting)
@@ -10259,8 +10534,7 @@ static void *pri_dchannel(void *vpri)
                                                }
                                                pri->pvts[chanpos]->resetting = 0;
                                                pri->pvts[chanpos]->inservice = 1;
-                                               if (option_verbose > 2)
-                                                       ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
+                                               ast_verb(3, "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan,
                                                                        pri->pvts[chanpos]->prioffset, pri->span);
                                                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
                                                if (pri->resetting)
@@ -10280,8 +10554,7 @@ static void *pri_dchannel(void *vpri)
                                                pri->pvts[chanpos]->setup_ack = 1;
                                                /* Send any queued digits */
                                                for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
-                                                       if (option_debug)
-                                                               ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
+                                                       ast_debug(1, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
                                                        pri_information(pri->pri, pri->pvts[chanpos]->call, 
                                                                pri->pvts[chanpos]->dialdest[x]);
                                                }
@@ -10312,8 +10585,7 @@ static void *pri_dchannel(void *vpri)
                                }
                                break;
                        default:
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Event: %d\n", e->e);
+                               ast_debug(1, "Event: %d\n", e->e);
                        }
                }       
                ast_mutex_unlock(&pri->lock);
@@ -10439,61 +10711,88 @@ static char *complete_span_5(const char *line, const char *word, int pos, int st
        return complete_span_helper(line,word,pos,state,4);
 }
 
-static int handle_pri_set_debug_file(int fd, int argc, char **argv)
+static char *handle_pri_unset_debug_file(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       int myfd;
-
-       if (!strncasecmp(argv[1], "set", 3)) {
-               if (argc < 5) 
-                       return RESULT_SHOWUSAGE;
-
-               if (ast_strlen_zero(argv[4]))
-                       return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "pri unset debug file";
+               e->usage = "Usage: pri unset debug file\n"
+                          "       Stop sending debug output to the previously \n"
+                          "       specified file\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;    
+       }
+       /* Assume it is unset */
+       ast_mutex_lock(&pridebugfdlock);
+       close(pridebugfd);
+       pridebugfd = -1;
+       ast_cli(a->fd, "PRI debug output to file disabled\n");
+       ast_mutex_unlock(&pridebugfdlock);
+       return CLI_SUCCESS;
+}
 
-               myfd = open(argv[4], O_CREAT|O_WRONLY, AST_FILE_MODE);
-               if (myfd < 0) {
-                       ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
-                       return RESULT_SUCCESS;
-               }
+static char *handle_pri_set_debug_file(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+       int myfd;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "pri set debug file";
+               e->usage = "Usage: pri set debug file [output-file]\n"
+                          "       Sends PRI debug output to the specified output file\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;    
+       }
+       if (a->argc < 5)
+               return CLI_SHOWUSAGE;
 
-               ast_mutex_lock(&pridebugfdlock);
+       if (ast_strlen_zero(a->argv[4]))
+               return CLI_SHOWUSAGE;
 
-               if (pridebugfd >= 0)
-                       close(pridebugfd);
+       myfd = open(a->argv[4], O_CREAT|O_WRONLY, AST_FILE_MODE);
+       if (myfd < 0) {
+               ast_cli(a->fd, "Unable to open '%s' for writing\n", a->argv[4]);
+               return CLI_SUCCESS;
+       }
 
-               pridebugfd = myfd;
-               ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
-               
-               ast_mutex_unlock(&pridebugfdlock);
+       ast_mutex_lock(&pridebugfdlock);
 
-               ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
-       } else {
-               /* Assume it is unset */
-               ast_mutex_lock(&pridebugfdlock);
+       if (pridebugfd >= 0)
                close(pridebugfd);
-               pridebugfd = -1;
-               ast_cli(fd, "PRI debug output to file disabled\n");
-               ast_mutex_unlock(&pridebugfdlock);
-       }
 
-       return RESULT_SUCCESS;
+       pridebugfd = myfd;
+       ast_copy_string(pridebugfilename,a->argv[4],sizeof(pridebugfilename));
+       ast_mutex_unlock(&pridebugfdlock);
+       ast_cli(a->fd, "PRI debug output will be sent to '%s'\n", a->argv[4]);
+       return CLI_SUCCESS;
 }
 
-static int handle_pri_debug(int fd, int argc, char *argv[])
+static char *handle_pri_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int span;
        int x;
-       if (argc < 4) {
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:  
+               e->command = "pri debug span";
+               e->usage = 
+                       "Usage: pri debug span <span>\n"
+                       "       Enables debugging on a given PRI span\n";
+               return NULL;
+       case CLI_GENERATE:      
+               return complete_span_4(a->line, a->word, a->pos, a->n);
+       }
+       if (a->argc < 4) {
+               return CLI_SHOWUSAGE;
        }
-       span = atoi(argv[3]);
+       span = atoi(a->argv[3]);
        if ((span < 1) || (span > NUM_SPANS)) {
-               ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
-