Merge in ast_strftime branch, which changes timestamps to be accurate to the microsec...
[asterisk/asterisk.git] / channels / chan_zap.c
index 0aa37a8..0e52a7b 100644 (file)
@@ -38,6 +38,7 @@
  */
 
 /*** MODULEINFO
+       <depend>res_smdi</depend>
        <depend>zaptel_vldtmf</depend>
        <depend>zaptel</depend>
        <depend>tonezone</depend>
@@ -106,6 +107,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/abstract_jb.h"
 #include "asterisk/smdi.h"
 #include "asterisk/astobj.h"
+#include "asterisk/event.h"
+
 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
 
 /*! Global jitterbuffer configuration - by default, jb is disabled */
@@ -163,7 +166,7 @@ static const char tdesc[] = "Zapata Telephony Driver"
 #ifdef HAVE_PRI
                " w/PRI"
 #endif
-#ifdef HAVEL_LIBSS7
+#ifdef HAVEL_SS7
               "w/SS7"
 #endif
 ;
@@ -208,10 +211,15 @@ static const char config[] = "zapata.conf";
 
 #define DCHAN_AVAILABLE        (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
 
+/* Overlap dialing option types */
+#define ZAP_OVERLAPDIAL_NONE 0
+#define ZAP_OVERLAPDIAL_OUTGOING 1
+#define ZAP_OVERLAPDIAL_INCOMING 2
+#define ZAP_OVERLAPDIAL_BOTH (ZAP_OVERLAPDIAL_INCOMING|ZAP_OVERLAPDIAL_OUTGOING)
+
 static char defaultcic[64] = "";
 static char defaultozz[64] = "";
 
-static char language[MAX_LANGUAGE] = "";
 static char progzone[10] = "";
 
 static int usedistinctiveringdetection = 0;
@@ -261,6 +269,14 @@ static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_chann
 
 static int zt_sendtext(struct ast_channel *c, const char *text);
 
+static void mwi_event_cb(const struct ast_event *event, void *userdata)
+{
+       /* This module does not handle MWI in an event-based manner.  However, it
+        * subscribes to MWI for each mailbox that is configured so that the core
+        * knows that we care about it.  Then, chan_zap will get the MWI from the
+        * event cache instead of checking the mailbox directly. */
+}
+
 /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
 static inline int zt_get_event(int fd)
 {
@@ -305,6 +321,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;
@@ -317,6 +335,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 */
 };
@@ -470,6 +494,7 @@ static struct zt_pvt {
        int outsigmod;                                  /*!< Outbound Signalling style (modifier) */
        int oprmode;                                    /*!< "Operator Services" mode */
        struct zt_pvt *oprpeer;                         /*!< "Operator Services" peer tech_pvt ptr */
+       float cid_rxgain;                                       /*!< "Gain to apply during caller id */
        float rxgain;
        float txgain;
        int tonezone;                                   /*!< tone zone for this chan, or -1 for default */
@@ -506,7 +531,7 @@ static struct zt_pvt {
        unsigned int inalarm:1;
        unsigned int mate:1;                            /*!< flag to say its in MATE mode */
        unsigned int outgoing:1;
-       unsigned int overlapdial:1;
+       /* unsigned int overlapdial:1;                  unused and potentially confusing */
        unsigned int permcallwaiting:1;
        unsigned int permhidecallerid:1;                /*!< Whether to hide our outgoing caller ID or not */
        unsigned int priindication_oob:1;
@@ -559,7 +584,7 @@ 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 */
@@ -600,6 +625,7 @@ static struct zt_pvt {
        struct tdd_state *tdd;                          /*!< TDD flag */
        char call_forward[AST_MAX_EXTENSION];
        char mailbox[AST_MAX_EXTENSION];
+       struct ast_event_sub *mwi_event_sub;
        char dialdest[256];
        int onhooktime;
        int msgstate;
@@ -645,6 +671,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];
@@ -676,6 +706,16 @@ static struct zt_chan_conf zt_chan_conf_default(void) {
                        .resetinterval = 3600
                },
 #endif
+#ifdef HAVE_SS7
+               .ss7 = {
+                       .called_nai = SS7_NAI_NATIONAL,
+                       .calling_nai = SS7_NAI_NATIONAL,
+                       .internationalprefix = "",
+                       .nationalprefix = "",
+                       .subscriberprefix = "",
+                       .unknownprefix = ""
+               },
+#endif
                .chan = {
                        .context = "default",
                        .cid_num = "",
@@ -691,6 +731,8 @@ static struct zt_chan_conf zt_chan_conf_default(void) {
                        .sig = -1,
                        .outsigmod = -1,
 
+                       .cid_rxgain = +5.0,
+
                        .tonezone = -1,
 
                        .echocancel = 1,
@@ -956,8 +998,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;
@@ -1060,8 +1101,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));
@@ -1077,8 +1117,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);
        }
@@ -1133,8 +1172,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';
@@ -1159,8 +1197,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;
        }
@@ -1195,8 +1232,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;
@@ -1370,8 +1406,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;
 }
 
@@ -1403,8 +1438,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;
 }
@@ -1518,8 +1552,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;
 }
 
@@ -1530,13 +1563,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) {
@@ -1552,13 +1583,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)
@@ -1570,14 +1598,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)
@@ -1589,10 +1613,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;
 }
@@ -1674,8 +1696,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;
        }
 
@@ -1693,8 +1714,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;
        }
 
@@ -1712,8 +1732,8 @@ static int bump_gains(struct zt_pvt *p)
 {
        int res;
 
-       /* Bump receive gain by 5.0db */
-       res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
+       /* Bump receive gain by value stored in cid_rxgain */
+       res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + p->cid_rxgain, p->txgain, p->law);
        if (res) {
                ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
                return -1;
@@ -1737,14 +1757,23 @@ static int restore_gains(struct zt_pvt *p)
 
 static inline int zt_set_hook(int fd, int hs)
 {
-       int x, res;
+       int x, res, count = 0;
+
        x = hs;
        res = ioctl(fd, ZT_HOOK, &x);
-       if (res < 0) 
-       {
+
+       while (res < 0 && count < 20) {
+               usleep(100000); /* 1/10 sec. */
+               x = hs;
+               res = ioctl(fd, ZT_HOOK, &x);
+               count++;
+       }
+
+       if (res < 0) {
                if (errno == EINPROGRESS) return 0;
                ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
        }
+
        return res;
 }
 
@@ -1787,8 +1816,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;
 }
 
@@ -1803,8 +1831,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;
 }
 
@@ -1828,8 +1855,21 @@ static int send_cwcidspill(struct zt_pvt *p)
 
 static int has_voicemail(struct zt_pvt *p)
 {
+       int new_msgs;
+       struct ast_event *event;
+
+       event = ast_event_get_cached(AST_EVENT_MWI,
+               AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, p->mailbox,
+               AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
+               AST_EVENT_IE_END);
+
+       if (event) {
+               new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
+               ast_event_destroy(event);
+       } else
+               new_msgs = ast_app_has_voicemail(p->mailbox, NULL);
 
-       return ast_app_has_voicemail(p->mailbox, NULL);
+       return new_msgs;
 }
 
 static int send_callerid(struct zt_pvt *p)
@@ -1855,7 +1895,7 @@ static int send_callerid(struct zt_pvt *p)
                        return 0;
                p->cidpos += res;
        }
-       free(p->cidspill);
+       ast_free(p->cidspill);
        p->cidspill = NULL;
        if (p->callwaitcas) {
                /* Wait for CID/CW to expire */
@@ -1871,7 +1911,7 @@ static int zt_callwait(struct ast_channel *ast)
        p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
        if (p->cidspill) {
                ast_log(LOG_WARNING, "Spill already exists?!?\n");
-               free(p->cidspill);
+               ast_free(p->cidspill);
        }
        if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
                return -1;
@@ -1893,6 +1933,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;
@@ -1948,7 +2000,7 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                                /* Generate the Caller-ID spill if desired */
                                if (p->cidspill) {
                                        ast_log(LOG_WARNING, "cidspill already exists??\n");
-                                       free(p->cidspill);
+                                       ast_free(p->cidspill);
                                }
                                p->callwaitcas = 0;
                                if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
@@ -1979,8 +2031,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';
                        }
@@ -2072,8 +2123,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;
@@ -2148,10 +2198,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;
@@ -2167,13 +2216,17 @@ 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;
+
                c = strchr(dest, '/');
                if (c)
                        c++;
@@ -2186,7 +2239,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);
 
@@ -2197,9 +2254,42 @@ 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_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc);
 
                isup_iam(p->ss7->ss7, p->ss7call);
+               ast_setstate(ast, AST_STATE_DIALING);
                ss7_rel(p->ss7);
        }
 #endif /* HAVE_SS7 */
@@ -2269,13 +2359,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);
@@ -2387,8 +2475,10 @@ static void destroy_zt_pvt(struct zt_pvt **pvt)
                p->next->prev = p->prev;
        if (p->use_smdi)
                ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy);
+       if (p->mwi_event_sub)
+               ast_event_unsubscribe(p->mwi_event_sub);
        ast_mutex_destroy(&p->lock);
-       free(p);
+       ast_free(p);
        *pvt = NULL;
 }
 
@@ -2464,24 +2554,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;
        }
@@ -2490,8 +2577,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;
        }
@@ -2590,8 +2676,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;
@@ -2611,12 +2696,12 @@ static int zt_hangup(struct ast_channel *ast)
        restore_gains(p);
        if (p->origcid_num) {
                ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
-               free(p->origcid_num);
+               ast_free(p->origcid_num);
                p->origcid_num = NULL;
        }       
        if (p->origcid_name) {
                ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
-               free(p->origcid_name);
+               ast_free(p->origcid_name);
                p->origcid_name = NULL;
        }       
        if (p->dsp)
@@ -2624,9 +2709,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) {
@@ -2643,32 +2727,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;
@@ -2688,13 +2767,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;
@@ -2797,8 +2874,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);
@@ -2811,8 +2887,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);
@@ -2836,8 +2911,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;
                        }
@@ -2855,8 +2929,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))))
@@ -2879,7 +2952,7 @@ static int zt_hangup(struct ast_channel *ast)
                        tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
                }
                if (p->cidspill)
-                       free(p->cidspill);
+                       ast_free(p->cidspill);
                if (p->sig)
                        zt_disable_ec(p);
                x = 0;
@@ -2901,8 +2974,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);
@@ -2985,18 +3057,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;
@@ -3067,8 +3137,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;
@@ -3077,8 +3146,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)
@@ -3086,18 +3154,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;
                }
@@ -3107,16 +3172,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 */
@@ -3145,23 +3208,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;
@@ -3184,21 +3244,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)
@@ -3217,19 +3274,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;
@@ -3280,8 +3334,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;
@@ -3337,8 +3390,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)
@@ -3501,9 +3553,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
@@ -3513,13 +3564,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) && 
@@ -3527,13 +3576,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)) {
@@ -3606,9 +3653,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;
                }
@@ -3626,8 +3672,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);
@@ -3678,8 +3723,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;
        }
@@ -3798,9 +3842,8 @@ static int attempt_transfer(struct zt_pvt *p)
                /* 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;
        }
@@ -3848,9 +3891,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;
 
-       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) {
-               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;
@@ -3860,9 +3904,9 @@ 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')) {
-                       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)
-                               free(p->cidspill);
+                               ast_free(p->cidspill);
                        send_cwcidspill(p);
                }
                if ((f->subclass != 'm') && (f->subclass != 'u')) 
@@ -3887,9 +3931,9 @@ static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_fram
                                } else
                                        ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
                        } else
-                               ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
+                               ast_debug(1, "Already in a fax extension, not redirecting\n");
                } else
-                               ast_log(LOG_DEBUG, "Fax already handled\n");
+                       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;
@@ -3917,7 +3961,6 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
        char *c;
        struct zt_pvt *p = ast->tech_pvt;
        pthread_t threadid;
-       pthread_attr_t attr;
        struct ast_channel *chan;
        struct ast_frame *f;
 
@@ -3943,15 +3986,13 @@ 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) {
+               if (!p->proceeding && p->sig == SIG_PRI && p->pri && (p->pri->overlapdial & ZAP_OVERLAPDIAL_INCOMING)) {
                        /* absorb event */
                } else {
 #endif
@@ -3965,8 +4006,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;
@@ -3993,8 +4033,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 */
@@ -4021,8 +4060,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) {
@@ -4140,16 +4178,14 @@ 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_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
                                                        ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
                                                } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
                                                        if (p->transfer) {
@@ -4257,11 +4293,10 @@ 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 */
-                                               free(p->cidspill);
+                                               ast_free(p->cidspill);
                                                p->cidspill = NULL;
                                        }
                                        p->dialing = 0;
@@ -4278,8 +4313,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;
@@ -4294,8 +4328,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 */
@@ -4325,10 +4358,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 */
@@ -4350,13 +4382,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;
@@ -4391,7 +4421,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                        ast->rings++;
                        if ((ast->rings > p->cidrings) && (p->cidspill)) {
                                ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
-                               free(p->cidspill);
+                               ast_free(p->cidspill);
                                p->cidspill = NULL;
                                p->callwaitcas = 0;
                        }
@@ -4433,14 +4463,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) {
@@ -4453,8 +4482,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;
@@ -4494,8 +4522,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)) {
@@ -4520,11 +4547,9 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                if (res)
                                                        ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
                                                p->owner = chan;
-                                               pthread_attr_init(&attr);
-                                               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
                                                if (!chan) {
                                                        ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
-                                               } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
+                                               } else if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
                                                        ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
                                                        res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
                                                        zt_enable_ec(p);
@@ -4540,14 +4565,12 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
                                                        }
                                                        p->subs[SUB_THREEWAY].needhold = 1;
                                                }
-                                               pthread_attr_destroy(&attr);
                                        }
                                } else {
                                        /* 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*/
@@ -4580,8 +4603,7 @@ 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);
                                                        }
@@ -4613,16 +4635,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:
@@ -4648,10 +4669,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:
@@ -4678,10 +4698,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;
@@ -4693,8 +4712,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;
@@ -4712,16 +4730,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 */
@@ -4730,30 +4746,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;
 }
@@ -4794,8 +4804,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);
@@ -4827,7 +4836,7 @@ 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);
@@ -4854,10 +4863,8 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
                f = &p->subs[index].f;
                return f;
        }
-       if (!(p->radio || (p->oprmode < 0))) {
-               if (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);
@@ -5000,8 +5007,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;
        }       
        
@@ -5011,8 +5017,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;
        }       
        
@@ -5057,8 +5062,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;
@@ -5068,8 +5072,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;
                }
@@ -5117,8 +5120,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 */
@@ -5146,7 +5148,9 @@ static struct ast_frame  *zt_read(struct ast_channel *ast)
                                }
                        } else if (f->frametype == AST_FRAME_DTMF) {
 #ifdef HAVE_PRI
-                               if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
+                               if (!p->proceeding && p->sig==SIG_PRI && p->pri && 
+                                   ((!p->outgoing && (p->pri->overlapdial & ZAP_OVERLAPDIAL_INCOMING)) ||
+                                    (p->outgoing && (p->pri->overlapdial & ZAP_OVERLAPDIAL_OUTGOING)))) {
                                        /* Don't accept in-band DTMF when in overlap dial mode */
                                        f->frametype = AST_FRAME_NULL;
                                        f->subclass = 0;
@@ -5183,8 +5187,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;
@@ -5234,18 +5237,15 @@ 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 */
@@ -5289,8 +5289,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:
@@ -5350,8 +5349,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) {              
@@ -5380,8 +5378,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) {
@@ -5495,34 +5492,31 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
        int res;
        int x,y;
        int features;
-       char *b2 = 0;
+       struct ast_str *chan_name;
        ZT_PARAMS ps;
        if (i->subs[index].owner) {
                ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
                return NULL;
        }
        y = 1;
+       chan_name = ast_str_alloca(32);
        do {
-               if (b2)
-                       free(b2);
 #ifdef HAVE_PRI
                if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
-                       asprintf(&b2, "Zap/%d:%d-%d", i->pri->trunkgroup, i->channel, y);
+                       ast_str_set(&chan_name, 0, "%d:%d-%d", i->pri->trunkgroup, i->channel, y);
                else
 #endif
                if (i->channel == CHAN_PSEUDO)
-                       asprintf(&b2, "Zap/pseudo-%ld", ast_random());
+                       ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random());
                else    
-                       asprintf(&b2, "Zap/%d-%d", i->channel, y);
+                       ast_str_set(&chan_name, 0, "%d-%d", i->channel, y);
                for (x = 0; x < 3; x++) {
-                       if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
+                       if ((index != x) && i->subs[x].owner && !strcasecmp(chan_name->str, i->subs[x].owner->name))
                                break;
                }
                y++;
        } while (x < 3);
-       tmp = ast_channel_alloc(0, state, 0, 0, i->accountcode, i->exten, i->context, i->amaflags, b2);
-       if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
-               free(b2);
+       tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", chan_name->str);
        if (!tmp)
                return NULL;
        tmp->tech = &zap_tech;
@@ -5552,30 +5546,31 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
        i->subs[index].linear = 0;
        zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
        features = 0;
-       if (i->busydetect && CANBUSYDETECT(i))
-               features |= DSP_FEATURE_BUSY_DETECT;
-       if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
-               features |= DSP_FEATURE_CALL_PROGRESS;
-       if ((!i->outgoing && (i->callprogress & 4)) || 
-           (i->outgoing && (i->callprogress & 2))) {
-               features |= DSP_FEATURE_FAX_DETECT;
-       }
+       if (index == SUB_REAL) {
+               if (i->busydetect && CANBUSYDETECT(i))
+                       features |= DSP_FEATURE_BUSY_DETECT;
+               if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
+                       features |= DSP_FEATURE_CALL_PROGRESS;
+               if ((!i->outgoing && (i->callprogress & 4)) || 
+                   (i->outgoing && (i->callprogress & 2))) {
+                       features |= DSP_FEATURE_FAX_DETECT;
+               }
 #ifdef ZT_TONEDETECT
-       x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
-       if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
+               x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
+               if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
 #endif         
-               i->hardwaredtmf = 0;
-               features |= DSP_FEATURE_DTMF_DETECT;
+                       i->hardwaredtmf = 0;
+                       features |= DSP_FEATURE_DTMF_DETECT;
 #ifdef ZT_TONEDETECT
-       } else if (NEED_MFDETECT(i)) {
-               i->hardwaredtmf = 1;
-               features |= DSP_FEATURE_DTMF_DETECT;
-       }
+               } else if (NEED_MFDETECT(i)) {
+                       i->hardwaredtmf = 1;
+                       features |= DSP_FEATURE_DTMF_DETECT;
+               }
 #endif
+       }
        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();
@@ -5638,7 +5633,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
        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_num);
+               tmp->cid.cid_ani = ast_strdup(i->cid_ani);
        else    
                tmp->cid.cid_ani = ast_strdup(i->cid_num);
 #else
@@ -5741,6 +5736,15 @@ static void *ss_thread(void *data)
        int res;
        int index;
 
+       /* in the bizarre case where the channel has become a zombie before we
+          even get started here, abort safely
+       */
+       if (!p) {
+               ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
+               ast_hangup(chan);
+               return NULL;
+       }
+
        if (option_verbose > 2) 
                ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
        index = zt_get_index(chan, p, 1);
@@ -5769,8 +5773,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) {
@@ -5798,8 +5801,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';
@@ -5918,8 +5920,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) {
@@ -5937,8 +5938,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;
                }
@@ -6095,8 +6095,7 @@ 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;
@@ -6153,8 +6152,7 @@ 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);
@@ -6190,8 +6188,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);
                                        }
@@ -6209,10 +6206,10 @@ static void *ss_thread(void *data)
                                /* Disable Caller*ID if enabled */
                                p->hidecallerid = 1;
                                if (chan->cid.cid_num)
-                                       free(chan->cid.cid_num);
+                                       ast_free(chan->cid.cid_num);
                                chan->cid.cid_num = NULL;
                                if (chan->cid.cid_name)
-                                       free(chan->cid.cid_name);
+                                       ast_free(chan->cid.cid_name);
                                chan->cid.cid_name = NULL;
                                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
                                if (res) {
@@ -6291,10 +6288,10 @@ static void *ss_thread(void *data)
                                /* Enable Caller*ID if enabled */
                                p->hidecallerid = 0;
                                if (chan->cid.cid_num)
-                                       free(chan->cid.cid_num);
+                                       ast_free(chan->cid.cid_num);
                                chan->cid.cid_num = NULL;
                                if (chan->cid.cid_name)
-                                       free(chan->cid.cid_name);
+                                       ast_free(chan->cid.cid_name);
                                chan->cid.cid_name = NULL;
                                ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
                                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
@@ -6343,8 +6340,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)
@@ -6379,8 +6375,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;
                                        }
@@ -6400,8 +6395,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");
                        }
@@ -6413,14 +6407,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 (;;) {
@@ -6435,8 +6428,7 @@ static void *ss_thread(void *data)
                                        f = ast_read(chan);
                                        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);
@@ -6447,12 +6439,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;
@@ -6663,6 +6653,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) {
@@ -6738,8 +6767,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. */
@@ -6842,6 +6870,7 @@ static void *ss_thread(void *data)
                        } else
                                ast_log(LOG_WARNING, "Unable to get caller ID space\n");
                }
+               }
                else
                        cs = NULL;
 
@@ -6899,10 +6928,8 @@ static int handle_init_event(struct zt_pvt *i, int event)
 {
        int res;
        pthread_t threadid;
-       pthread_attr_t attr;
        struct ast_channel *chan;
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
        /* Handle an event on a given channel for the monitor thread. */
        switch (event) {
        case ZT_EVENT_NONE:
@@ -6922,7 +6949,7 @@ static int handle_init_event(struct zt_pvt *i, int event)
                                break;
                        if (i->cidspill) {
                                /* Cancel VMWI spill */
-                               free(i->cidspill);
+                               ast_free(i->cidspill);
                                i->cidspill = NULL;
                        }
                        if (i->immediate) {
@@ -6946,7 +6973,7 @@ static int handle_init_event(struct zt_pvt *i, int event)
                                                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);
-                                       if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
+                                       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);
                                                if (res < 0)
@@ -6978,8 +7005,12 @@ 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 (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
+                               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);
                                        if (res < 0)
@@ -7069,13 +7100,13 @@ 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 "
                                            "CID detection on channel %d\n",
                                            i->channel);
                                chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
-                               if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
+                               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);
                                }
                        }
@@ -7093,7 +7124,6 @@ static int handle_init_event(struct zt_pvt *i, int event)
                zap_destroy_channel_bynum(i->channel);
                break;
        }
-       pthread_attr_destroy(&attr);
        return 0;
 }
 
@@ -7115,15 +7145,14 @@ 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)
-                               free(pfds);
+                               ast_free(pfds);
                        if (ifcount) {
                                if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
                                        ast_mutex_unlock(&iflock);
@@ -7179,11 +7208,10 @@ static void *do_monitor(void *data)
                                        if (last) {
                                                if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
                                                        (last->sig & __ZT_SIG_FXO)) {
-                                                       res = ast_app_has_voicemail(last->mailbox, NULL);
+                                                       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);
                                                                x = ZT_FLUSH_BOTH;
                                                                res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
                                                                if (res2)
@@ -7210,8 +7238,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);
@@ -7244,7 +7271,7 @@ static void *do_monitor(void *data)
                                                if (res2 > 0) {
                                                        i->cidpos += res2;
                                                        if (i->cidpos >= i->cidlen) {
-                                                               free(i->cidspill);
+                                                               ast_free(i->cidspill);
                                                                i->cidspill = 0;
                                                                i->cidpos = 0;
                                                                i->cidlen = 0;
@@ -7256,8 +7283,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);
@@ -7273,8 +7299,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);
@@ -7292,9 +7317,6 @@ static void *do_monitor(void *data)
 
 static int restart_monitor(void)
 {
-       pthread_attr_t attr;
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        /* If we're supposed to be stopped -- stay stopped */
        if (monitor_thread == AST_PTHREADT_STOP)
                return 0;
@@ -7305,25 +7327,17 @@ static int restart_monitor(void)
                return -1;
        }
        if (monitor_thread != AST_PTHREADT_NULL) {
-               /* Just signal it to be sure it wakes up */
-#if 0
-               pthread_cancel(monitor_thread);
-#endif
+               /* Wake up the thread */
                pthread_kill(monitor_thread, SIGURG);
-#if 0
-               pthread_join(monitor_thread, NULL);
-#endif
        } else {
                /* Start a new monitor */
-               if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
+               if (ast_pthread_create_detached_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
                        ast_mutex_unlock(&monlock);
                        ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
-                       pthread_attr_destroy(&attr);
                        return -1;
                }
        }
        ast_mutex_unlock(&monlock);
-       pthread_attr_destroy(&attr);
        return 0;
 }
 
@@ -7449,7 +7463,7 @@ static unsigned int parse_pointcode(char *pcstring)
        unsigned int code1, code2, code3;
        int numvals;
 
-       numvals = sscanf(pcstring, "%d.%d.%d", &code1, &code2, &code3);
+       numvals = sscanf(pcstring, "%d-%d-%d", &code1, &code2, &code3);
        if (numvals == 1)
                return code1;
        if (numvals == 3)
@@ -7590,6 +7604,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
@@ -7858,7 +7880,7 @@ static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pr
                tmp->canpark = conf.chan.canpark;
                tmp->transfer = conf.chan.transfer;
                ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext));
-               ast_copy_string(tmp->language, language, sizeof(tmp->language));
+               ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language));
                ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret));
                ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest));
                ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context));
@@ -7866,10 +7888,17 @@ static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pr
                tmp->cid_ton = 0;
                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)) {
+                       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_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
+                               AST_EVENT_IE_END);
+               }
                tmp->msgstate = -1;
                tmp->group = conf.chan.group;
                tmp->callgroup = conf.chan.callgroup;
                tmp->pickupgroup= conf.chan.pickupgroup;
+               tmp->cid_rxgain = conf.chan.cid_rxgain;
                tmp->rxgain = conf.chan.rxgain;
                tmp->txgain = conf.chan.txgain;
                tmp->tonezone = conf.chan.tonezone;
@@ -8041,8 +8070,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;
                        }
@@ -8126,9 +8154,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)
@@ -8257,10 +8284,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
@@ -8280,10 +8306,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;
                                }
                        }
@@ -8470,6 +8495,30 @@ static void ss7_start_call(struct zt_pvt *p, struct zt_ss7 *linkset)
                ast_log(LOG_WARNING, "Unable to start PBX on CIC %d\n", p->cic);
 }
 
+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)
 {
@@ -8480,21 +8529,17 @@ static void *ss7_linkset(void *data)
        ss7_event *e = NULL;
        struct zt_pvt *p;
        int chanpos;
-       pthread_attr_t attr;
        struct pollfd pollers[NUM_DCHANS];
        int cic;
        unsigned int dpc;
        int nextms = 0;
 
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
        ss7_start(ss7);
 
        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) {
@@ -8535,13 +8580,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");
@@ -8579,9 +8624,10 @@ static void *ss7_linkset(void *data)
                while ((e = ss7_check_event(ss7))) {
                        switch (e->e) {
                        case SS7_EVENT_UP:
-                               ast_verbose("--- SS7 Up ---\n");
-                               if (linkset->state != LINKSET_STATE_UP)
+                               if (linkset->state != LINKSET_STATE_UP) {
+                                       ast_verbose("--- SS7 Up ---\n");
                                        ss7_reset_linkset(linkset);
+                               }
                                linkset->state = LINKSET_STATE_UP;
                                break;
                        case SS7_EVENT_DOWN:
@@ -8594,7 +8640,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);
@@ -8613,13 +8659,13 @@ 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;
                                        }
                                        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);
@@ -8641,7 +8687,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);
@@ -8657,7 +8703,7 @@ static void *ss7_linkset(void *data)
                                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);
@@ -8682,8 +8728,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;
 
@@ -8692,7 +8741,7 @@ 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';
@@ -8705,8 +8754,8 @@ static void *ss7_linkset(void *data)
                                p->cid_ton = 0;
                                /* 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) {
@@ -8714,7 +8763,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);
@@ -8740,9 +8789,10 @@ static void *ss7_linkset(void *data)
                                }
                                p = linkset->pvts[chanpos];
                                ast_mutex_lock(&p->lock);
-                               if (p->owner)
-                                       ast_queue_hangup(p->owner);
-                               else
+                               if (p->owner) {
+                                       p->owner->hangupcause = e->rel.cause;
+                                       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+                               } else
                                        ast_log(LOG_WARNING, "REL on channel (CIC %d) without owner!\n", p->cic);
 
                                isup_rlc(ss7, e->rel.call);
@@ -8761,7 +8811,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);
@@ -8797,7 +8847,7 @@ 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);
@@ -8810,7 +8860,7 @@ 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);
@@ -8849,7 +8899,7 @@ static void *ss7_linkset(void *data)
                                }
                                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;
                        }
                }
@@ -8861,6 +8911,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++)
@@ -8868,18 +8919,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
@@ -8987,10 +9045,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;
@@ -9245,7 +9302,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];
@@ -9257,13 +9314,11 @@ static void *pri_dchannel(void *vpri)
        int cause=0;
        struct zt_pvt *crv;
        pthread_t threadid;
-       pthread_attr_t attr;
        char ani2str[6];
        char plancallingnum[256];
        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, '@');
@@ -9333,7 +9388,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)) {
@@ -9420,8 +9475,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]);
                                }
@@ -9544,7 +9598,7 @@ static void *pri_dchannel(void *vpri)
                                        if (chanpos > -1) {
                                                ast_mutex_lock(&pri->pvts[chanpos]->lock);
                                                /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
-                                               if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
+                                               if ((pri->overlapdial & ZAP_OVERLAPDIAL_INCOMING) && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
                                                        /* how to do that */
                                                        int digitlen = strlen(e->digit.digits);
                                                        char digit;
@@ -9572,7 +9626,7 @@ static void *pri_dchannel(void *vpri)
                                        if (chanpos > -1) {
                                                ast_mutex_lock(&pri->pvts[chanpos]->lock);
                                                /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
-                                               if (pri->overlapdial && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
+                                               if ((pri->overlapdial & ZAP_OVERLAPDIAL_INCOMING) && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
                                                        /* how to do that */
                                                        int digitlen = strlen(e->ring.callednum);
                                                        char digit;
@@ -9608,7 +9662,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;
@@ -9689,7 +9743,7 @@ static void *pri_dchannel(void *vpri)
                                                pri->pvts[chanpos]->exten[1] = '\0';
                                        }
                                        /* Make sure extension exists (or in overlap dial mode, can exist) */
-                                       if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
+                                       if (((pri->overlapdial & ZAP_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
                                                ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
                                                /* Setup law */
                                                int law;
@@ -9709,7 +9763,7 @@ static void *pri_dchannel(void *vpri)
                                                res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
                                                if (res < 0)
                                                        ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
-                                               if (e->ring.complete || !pri->overlapdial) {
+                                               if (e->ring.complete || !(pri->overlapdial & ZAP_OVERLAPDIAL_INCOMING)) {
                                                        /* Just announce proceeding */
                                                        pri->pvts[chanpos]->proceeding = 1;
                                                        pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
@@ -9723,7 +9777,7 @@ static void *pri_dchannel(void *vpri)
                                                pri->pvts[chanpos]->callingpres = e->ring.callingpres;
                                        
                                                /* Start PBX */
-                                               if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
+                                               if ((pri->overlapdial & ZAP_OVERLAPDIAL_INCOMING) && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
                                                        /* Release the PRI lock while we create the channel */
                                                        ast_mutex_unlock(&pri->lock);
                                                        if (crv) {
@@ -9731,8 +9785,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);
                                                        }
@@ -9756,9 +9809,7 @@ static void *pri_dchannel(void *vpri)
                                                                pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
                                                        
                                                        ast_mutex_lock(&pri->lock);
-                                                       pthread_attr_init(&attr);
-                                                       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-                                                       if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
+                                                       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",
                                                                                plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
@@ -9773,7 +9824,6 @@ static void *pri_dchannel(void *vpri)
                                                                        pri->pvts[chanpos]->call = NULL;
                                                                }
                                                        }
-                                                       pthread_attr_destroy(&attr);
                                                } else  {
                                                        ast_mutex_unlock(&pri->lock);
                                                        /* Release PRI lock while we create the channel */
@@ -9844,10 +9894,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
@@ -9899,9 +9948,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) {
@@ -9926,9 +9974,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) {
@@ -9992,8 +10039,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) {
@@ -10008,14 +10054,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 */
@@ -10049,25 +10093,29 @@ 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_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", 
+                                                                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
                                                } else {
                                                        pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
                                                        pri->pvts[chanpos]->call = NULL;
@@ -10113,23 +10161,27 @@ 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_verbose(VERBOSE_PREFIX_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",
@@ -10197,9 +10249,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) {
@@ -10254,8 +10305,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]);
                                                }
@@ -10286,8 +10336,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);
@@ -10350,8 +10399,8 @@ static int start_pri(struct zt_pri *pri)
                pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
                /* Force overlap dial if we're doing GR-303! */
                if (pri->switchtype == PRI_SWITCH_GR303_TMC)
-                       pri->overlapdial = 1;
-               pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
+                       pri->overlapdial |= ZAP_OVERLAPDIAL_BOTH;
+               pri_set_overlapdial(pri->dchans[i],(pri->overlapdial & ZAP_OVERLAPDIAL_OUTGOING)?1:0);
                /* Enslave to master if appropriate */
                if (i)
                        pri_enslave(pri->dchans[0], pri->dchans[i]);
@@ -10599,12 +10648,12 @@ static int handle_pri_show_span(int fd, int argc, char *argv[])
                        info_str = pri_dump_info_str(pris[span-1].pri);
                        if (info_str) {
                                ast_cli(fd, "%s", info_str);
-                               free(info_str);
+                               ast_free(info_str);
                        }
 #else
                        pri_dump_info(pris[span-1].pri);
 #endif
-                       ast_cli(fd, "\n");
+                       ast_cli(fd, "Overlap Recv: %s\n\n", (pris[span-1].overlapdial & ZAP_OVERLAPDIAL_INCOMING)?"Yes":"No");
                }
        }
        return RESULT_SUCCESS;
@@ -10711,13 +10760,11 @@ static int zap_restart(void)
        if (option_verbose > 0)
                ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
        while (iflist) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
+               ast_debug(1, "Destroying zaptel channel no. %d\n", iflist->channel);
                /* Also updates iflist: */
                destroy_channel(NULL, iflist, 1);
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
+       ast_debug(1, "Channels destroyed. Now re-reading config.\n");
        if (setup_zap(1) != 0) {
                ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
                return 1;
@@ -10932,6 +10979,7 @@ static int zap_show_channel(int fd, int argc, char **argv)
                        ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
                        ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
                        ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
+                       ast_cli(fd, "TDD: %s\n", tmp->tdd ? "yes" : "no");
                        ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
                        ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
                        ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
@@ -11395,7 +11443,7 @@ static int __unload_module(void)
        while (p) {
                /* Free any callerid */
                if (p->cidspill)
-                       free(p->cidspill);
+                       ast_free(p->cidspill);
                /* Close the zapata thingy */
                if (p->subs[SUB_REAL].zfd > -1)
                        zt_close(p->subs[SUB_REAL].zfd);
@@ -11536,8 +11584,6 @@ static int linkset_addsigchan(int sigchan)
        if (cur_defaultdpc < 0) {
                ast_log(LOG_ERROR, "Unspecified defaultdpc!\n");
                return -1;
-       } else {
-               ss7_set_default_dpc(link->ss7, cur_defaultdpc);
        }
 
        if (cur_networkindicator < 0) {
@@ -11933,6 +11979,8 @@ static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int r
                } else if (!strcasecmp(v->name, "cidstart")) {
                        if (!strcasecmp(v->value, "ring"))
                                confp->chan.cid_start = CID_START_RING;
+                       else if (!strcasecmp(v->value, "polarity_in"))
+                               confp->chan.cid_start = CID_START_POLARITY_IN;
                        else if (!strcasecmp(v->value, "polarity"))
                                confp->chan.cid_start = CID_START_POLARITY;
                        else if (ast_true(v->value))
@@ -12050,6 +12098,10 @@ static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int r
                        confp->chan.immediate = ast_true(v->value);
                } else if (!strcasecmp(v->name, "transfertobusy")) {
                        confp->chan.transfertobusy = ast_true(v->value);
+               } else if (!strcasecmp(v->name, "cid_rxgain")) {
+                       if (sscanf(v->value, "%f", &confp->chan.cid_rxgain) != 1) {
+                               ast_log(LOG_WARNING, "Invalid cid_rxgain: %s\n", v->value);
+                       }
                } else if (!strcasecmp(v->name, "rxgain")) {
                        if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
                                ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
@@ -12087,6 +12139,14 @@ static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int r
                                ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
                        else
                                confp->chan.amaflags = y;
+               } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
+                       confp->chan.polarityonanswerdelay = atoi(v->value);
+               } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
+                       confp->chan.answeronpolarityswitch = ast_true(v->value);
+               } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
+                       confp->chan.hanguponpolarityswitch = ast_true(v->value);
+               } else if (!strcasecmp(v->name, "sendcalleridafter")) {
+                       confp->chan.sendcalleridafter = atoi(v->value);
                } else if (!reload){ 
                         if (!strcasecmp(v->name, "signalling")) {
                                confp->chan.outsigmod = -1;
@@ -12287,7 +12347,7 @@ static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int r
                                } else if (!strcasecmp(v->value, "redundant")) {
                                        confp->pri.localdialplan = -2;
                                } else {
-                                       ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
+                                       ast_log(LOG_WARNING, "Unknown PRI localdialplan '%s' at line %d.\n", v->value, v->lineno);
                                }
                        } else if (!strcasecmp(v->name, "switchtype")) {
                                if (!strcasecmp(v->value, "national")) 
@@ -12360,7 +12420,17 @@ static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int r
                        } else if (!strcasecmp(v->name, "idledial")) {
                                ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
                        } else if (!strcasecmp(v->name, "overlapdial")) {
-                               confp->pri.overlapdial = ast_true(v->value);
+                               if (ast_true(v->value)) {
+                                       confp->pri.overlapdial = ZAP_OVERLAPDIAL_BOTH;
+                               } else if (!strcasecmp(v->value, "incoming")) {
+                                       confp->pri.overlapdial = ZAP_OVERLAPDIAL_INCOMING;
+                               } else if (!strcasecmp(v->value, "outgoing")) {
+                                       confp->pri.overlapdial = ZAP_OVERLAPDIAL_OUTGOING;
+                               } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) {
+                                       confp->pri.overlapdial = ZAP_OVERLAPDIAL_BOTH;
+                               } else {
+                                       confp->pri.overlapdial = ZAP_OVERLAPDIAL_NONE;
+                               }
                        } else if (!strcasecmp(v->name, "pritimer")) {
 #ifdef PRI_GETSET_TIMERS
                                char *timerc, *c;
@@ -12413,6 +12483,38 @@ static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int r
                                        cur_networkindicator = SS7_NI_INT_SPARE;
                                else
                                        cur_networkindicator = -1;
+                       } else if (!strcasecmp(v->name, "ss7_internationalprefix")) {
+                               ast_copy_string(confp->ss7.internationalprefix, v->value, sizeof(confp->ss7.internationalprefix));
+                       } else if (!strcasecmp(v->name, "ss7_nationalprefix")) {
+                               ast_copy_string(confp->ss7.nationalprefix, v->value, sizeof(confp->ss7.nationalprefix));
+                       } else if (!strcasecmp(v->name, "ss7_subscriberprefix")) {
+                               ast_copy_string(confp->ss7.subscriberprefix, v->value, sizeof(confp->ss7.subscriberprefix));
+                       } else if (!strcasecmp(v->name, "ss7_unknownprefix")) {
+                               ast_copy_string(confp->ss7.unknownprefix, v->value, sizeof(confp->ss7.unknownprefix));
+                       } else if (!strcasecmp(v->name, "ss7_called_nai")) {
+                               if (!strcasecmp(v->value, "national")) {
+                                       confp->ss7.called_nai = SS7_NAI_NATIONAL;
+                               } else if (!strcasecmp(v->value, "international")) {
+                                       confp->ss7.called_nai = SS7_NAI_INTERNATIONAL;
+                               } else if (!strcasecmp(v->value, "subscriber")) {
+                                       confp->ss7.called_nai = SS7_NAI_SUBSCRIBER;
+                               } else if (!strcasecmp(v->value, "dynamic")) {
+                                       confp->ss7.called_nai = SS7_NAI_DYNAMIC;
+                               } else {
+                                       ast_log(LOG_WARNING, "Unknown SS7 called_nai '%s' at line %d.\n", v->value, v->lineno);
+                               }
+                       } else if (!strcasecmp(v->name, "ss7_calling_nai")) {
+                               if (!strcasecmp(v->value, "national")) {
+                                       confp->ss7.calling_nai = SS7_NAI_NATIONAL;
+                               } else if (!strcasecmp(v->value, "international")) {
+                                       confp->ss7.calling_nai = SS7_NAI_INTERNATIONAL;
+                               } else if (!strcasecmp(v->value, "subscriber")) {
+                                       confp->ss7.calling_nai = SS7_NAI_SUBSCRIBER;
+                               } else if (!strcasecmp(v->value, "dynamic")) {
+                                       confp->ss7.calling_nai = SS7_NAI_DYNAMIC;
+                               } else {
+                                       ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno);
+                               }
                        } else if (!strcasecmp(v->name, "sigchan")) {
                                int sigchan, res;
                                sigchan = atoi(v->value);
@@ -12541,14 +12643,6 @@ static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int r
                                        }
                                }
                                close(ctlfd);
-                       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
-                               confp->chan.polarityonanswerdelay = atoi(v->value);
-                       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
-                               confp->chan.answeronpolarityswitch = ast_true(v->value);
-                       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
-                               confp->chan.hanguponpolarityswitch = ast_true(v->value);
-                       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
-                               confp->chan.sendcalleridafter = atoi(v->value);
                        } else if (!strcasecmp(v->name, "defaultcic")) {
                                ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
                        } else if (!strcasecmp(v->name, "defaultozz")) {
@@ -12849,7 +12943,7 @@ static int zt_sendtext(struct ast_channel *c, const char *text)
                len = tdd_generate(p->tdd, buf, text);
                if (len < 1) {
                        ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
-                       free(mybuf);
+                       ast_free(mybuf);
                        return -1;
                }
        }
@@ -12858,7 +12952,7 @@ static int zt_sendtext(struct ast_channel *c, const char *text)
        fd = p->subs[index].zfd;
        while (len) {
                if (ast_check_hangup(c)) {
-                       free(mybuf);
+                       ast_free(mybuf);
                        return -1;
                }
                size = len;
@@ -12869,32 +12963,29 @@ static int zt_sendtext(struct ast_channel *c, const char *text)
                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) {
-                               free(mybuf);
+                               ast_free(mybuf);
                                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;
                buf += size;
        }
-       free(mybuf);
+       ast_free(mybuf);
        return(0);
 }