include "logger.h" and errno.h from asterisk.h - usage shows that they
[asterisk/asterisk.git] / channels / chan_zap.c
index 20ae5a3..633d7b9 100644 (file)
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
-#include <stdio.h>
-#include <string.h>
 #ifdef __NetBSD__
 #include <pthread.h>
 #include <signal.h>
 #else
 #include <sys/signal.h>
 #endif
-#include <errno.h>
-#include <stdlib.h>
-#if !defined(SOLARIS) && !defined(__FreeBSD__)
-#include <stdint.h>
-#endif
-#include <unistd.h>
 #include <sys/ioctl.h>
 #include <math.h>
 #include <ctype.h>
@@ -80,7 +72,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/lock.h"
 #include "asterisk/channel.h"
 #include "asterisk/config.h"
-#include "asterisk/logger.h"
 #include "asterisk/module.h"
 #include "asterisk/pbx.h"
 #include "asterisk/options.h"
@@ -665,6 +656,11 @@ static struct zt_pvt {
        struct zt_ss7 *ss7;
        struct isup_call *ss7call;
        char charge_number[50];
+       char gen_add_number[50];
+       unsigned char gen_add_num_plan;
+       unsigned char gen_add_nai;
+       unsigned char gen_add_pres_ind;
+       unsigned char gen_add_type;
        int transcap;
        int cic;                                                        /*!< CIC associated with channel */
        unsigned int dpc;                                               /*!< CIC's DPC */
@@ -719,8 +715,7 @@ static struct zt_chan_conf zt_chan_conf_default(void) {
                        .localprefix = "",
                        .privateprefix = "",
                        .unknownprefix = "",
-
-                       .resetinterval = 3600
+                       .resetinterval = -1,
                },
 #endif
 #ifdef HAVE_SS7
@@ -1074,7 +1069,13 @@ static int zt_open(char *fn)
                }
        }
        bs = READ_SIZE;
-       if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) return -1;
+       if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) {
+               ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
+               x = errno;
+               close(fd);
+               errno = x;
+               return -1;
+       }
        return fd;
 }
 
@@ -2244,6 +2245,9 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                char ss7_calling_nai;
                int calling_nai_strip;
                const char *charge_str = NULL;
+#if 0
+               const char *gen_address = NULL;
+#endif
 
                c = strchr(dest, '/');
                if (c)
@@ -2311,8 +2315,14 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                charge_str = pbx_builtin_getvar_helper(ast, "SS7_CHARGE_NUMBER");
                if (charge_str)
                        isup_set_charge(p->ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
-
-
+               
+#if 0
+               /* Set the generic address if it is set */
+               gen_address = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_ADDRESS");
+               if (gen_address)
+                       isup_set_gen_address(p->ss7call, gen_address, p->gen_add_nai,p->gen_add_pres_ind, p->gen_add_num_plan,p->gen_add_type); /* need to add some types here for NAI,PRES,TYPE */
+#endif
+               
                isup_iam(p->ss7->ss7, p->ss7call);
                ast_setstate(ast, AST_STATE_DIALING);
                ss7_rel(p->ss7);
@@ -2337,17 +2347,17 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                        c++;
                else
                        c = dest;
-               if (!p->hidecalleridname)
-                       n = ast->cid.cid_name;
-               else
-                       n = NULL;
+
+               l = NULL;
+               n = NULL;
+
                if (!p->hidecallerid) {
                        l = ast->cid.cid_num;
-                       n = ast->cid.cid_name;
-               } else {
-                       l = NULL;
-                       n = NULL;
+                       if (!p->hidecalleridname) {
+                               n = ast->cid.cid_name;
+                       }
                }
+
                if (strlen(c) < p->stripmsd) {
                        ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
                        ast_mutex_unlock(&p->lock);
@@ -2428,6 +2438,56 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                                pridialplan = PRI_LOCAL_ISDN;
                        }
                }
+               while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
+                       switch (c[p->stripmsd]) {
+                       case 'U':
+                               pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'I':
+                               pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'N':
+                               pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'L':
+                               pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'S':
+                               pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'A':
+                               pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'R':
+                               pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
+                               break;
+                       case 'u':
+                               pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
+                               break;
+                       case 'e':
+                               pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
+                               break;
+                       case 'x':
+                               pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
+                               break;
+                       case 'f':
+                               pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
+                               break;
+                       case 'n':
+                               pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
+                               break;
+                       case 'p':
+                               pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
+                               break;
+                       case 'r':
+                               pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
+                               break;
+                       default:
+                               if (isalpha(*c))
+                                       ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", *c > 'Z' ? "NPI" : "TON", *c);
+                       }
+                       c++;
+               }
                pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
 
                ldp_strip = 0;
@@ -2447,6 +2507,58 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
                                prilocaldialplan = PRI_LOCAL_ISDN;
                        }
                }
+               if (l != NULL) {
+                       while (*l > '9' && *l != '*' && *l != '#') {
+                               switch (*l) {
+                               case 'U':
+                                       prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'I':
+                                       prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'N':
+                                       prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'L':
+                                       prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'S':
+                                       prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'A':
+                                       prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'R':
+                                       prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
+                                       break;
+                               case 'u':
+                                       prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'e':
+                                       prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'x':
+                                       prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'f':
+                                       prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'n':
+                                       prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'p':
+                                       prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
+                                       break;
+                               case 'r':
+                                       prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
+                                       break;
+                               default:
+                                       if (isalpha(*l))
+                                               ast_log(LOG_WARNING, "Unrecognized prilocaldialplan %s modifier: %c\n", *c > 'Z' ? "NPI" : "TON", *c);
+                               }
+                               l++;
+                       }
+               }
                pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
                        p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
                if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
@@ -5604,7 +5716,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
                                i->dsp = NULL;
                        if (i->dsp) {
                                i->dsp_features = features & ~DSP_PROGRESS_TALK;
-#ifdef HAVE_PRI
+#if defined(HAVE_PRI) || defined(HAVE_SS7)
                                /* We cannot do progress detection until receives PROGRESS message */
                                if (i->outgoing && ((i->sig == SIG_PRI) || (i->sig == SIG_SS7))) {
                                        /* Remember requested DSP features, don't treat
@@ -7163,8 +7275,10 @@ static void *do_monitor(void *data)
                /* Lock the interface list */
                ast_mutex_lock(&iflock);
                if (!pfds || (lastalloc != ifcount)) {
-                       if (pfds)
+                       if (pfds) {
                                ast_free(pfds);
+                               pfds = NULL;
+                       }
                        if (ifcount) {
                                if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
                                        ast_mutex_unlock(&iflock);
@@ -7475,7 +7589,7 @@ static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
 
 #ifdef HAVE_SS7
 
-static unsigned int parse_pointcode(char *pcstring)
+static unsigned int parse_pointcode(const char *pcstring)
 {
        unsigned int code1, code2, code3;
        int numvals;
@@ -8430,6 +8544,38 @@ static int ss7_find_cic(struct zt_ss7 *linkset, int cic)
        return winner;
 }
 
+static void ss7_handle_cqm(struct zt_ss7 *linkset, int startcic, int endcic)
+{
+       unsigned char status[32];
+       struct zt_pvt *p = NULL;
+       int i, offset;
+
+       for (i = 0; i < linkset->numchans; i++) {
+               if (linkset->pvts[i] && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic))) {
+                       p = linkset->pvts[i];
+                       offset = p->cic - startcic;
+                       status[offset] = 0;
+                       if (p->locallyblocked)
+                               status[offset] |= (1 << 0) | (1 << 4);
+                       if (p->remotelyblocked)
+                               status[offset] |= (1 << 1) | (1 << 5);
+                       if (p->ss7call) {
+                               if (p->outgoing)
+                                       status[offset] |= (1 << 3);
+                               else
+                                       status[offset] |= (1 << 2);
+                       } else
+                               status[offset] |= 0x3 << 2;
+               }
+       }
+
+       if (p)
+               isup_cqr(linkset->ss7, startcic, endcic, p->dpc, status);
+       else
+               ast_log(LOG_WARNING, "Could not find any equipped circuits within CQM CICs\n");
+       
+}
+
 static inline void ss7_block_cics(struct zt_ss7 *linkset, int startcic, int endcic, unsigned char state[], int block)
 {
        int i;
@@ -8529,6 +8675,11 @@ static void ss7_start_call(struct zt_pvt *p, struct zt_ss7 *linkset)
                /* Clear this after we set it */
                p->charge_number[0] = 0;
        }
+       if (!ast_strlen_zero(p->gen_add_number)) {
+               pbx_builtin_setvar_helper(c, "SS7_GENERIC_ADDRESS", p->gen_add_number);
+               /* Clear this after we set it */
+               p->gen_add_number[0] = 0;
+       }
 
 }
 
@@ -8643,10 +8794,15 @@ static void *ss7_linkset(void *data)
                                }
                        }
 
-                       if (pollers[i].revents & POLLIN)
+                       if (pollers[i].revents & POLLIN) {
+                               ast_mutex_lock(&linkset->lock);
                                res = ss7_read(ss7, pollers[i].fd);
+                               ast_mutex_unlock(&linkset->lock);
+                       }
                        if (pollers[i].revents & POLLOUT) {
+                               ast_mutex_lock(&linkset->lock);
                                res = ss7_write(ss7, pollers[i].fd);
+                               ast_mutex_unlock(&linkset->lock);
                                if (res < 0) {
                                        ast_log(LOG_ERROR, "Error in write %s", strerror(errno));
                                }
@@ -8699,6 +8855,10 @@ static void *ss7_linkset(void *data)
                                                ast_debug(1, "Queuing frame PROGRESS on CIC %d\n", p->cic);
                                                zap_queue_frame(p, &f, linkset);
                                                p->progress = 1;
+                                               if (p->dsp && p->dsp_features) {
+                                                       ast_dsp_set_features(p->dsp, p->dsp_features);
+                                                       p->dsp_features = 0;
+                                               }
                                        }
                                        break;
                                default:
@@ -8734,6 +8894,10 @@ static void *ss7_linkset(void *data)
                                isup_gra(ss7, e->grs.startcic, e->grs.endcic, p->dpc);
                                ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, NULL, 0);
                                break;
+                       case ISUP_EVENT_CQM:
+                               ast_debug(1, "Got Circuit group query message from CICs %d to %d\n", e->cqm.startcic, e->cqm.endcic);
+                               ss7_handle_cqm(linkset, e->cqm.startcic, e->cqm.endcic);
+                               break;
                        case ISUP_EVENT_GRA:
                                ast_verbose("Got reset acknowledgement from CIC %d to %d.\n", e->gra.startcic, e->gra.endcic);
                                ss7_inservice(linkset, e->gra.startcic, e->gra.endcic);
@@ -8782,17 +8946,21 @@ static void *ss7_linkset(void *data)
                                        st = strchr(p->exten, '#');
                                        if (st)
                                                *st = '\0';
-                               } else
-                                       p->exten[0] = '\0';
+                                       } else
+                                               p->exten[0] = '\0';
 
-                               /* Need to fill these fields */
                                p->cid_ani[0] = '\0';
                                p->cid_name[0] = '\0';
                                p->cid_ani2 = e->iam.oli_ani2;
                                p->cid_ton = 0;
-                               
                                ast_copy_string(p->charge_number, e->iam.charge_number, sizeof(p->charge_number));
 
+                               ast_copy_string(p->gen_add_number, e->iam.gen_add_number, sizeof(p->gen_add_number));
+                               p->gen_add_type = e->iam.gen_add_type;
+                               p->gen_add_nai = e->iam.gen_add_nai;
+                               p->gen_add_pres_ind = e->iam.gen_add_pres_ind;
+                               p->gen_add_num_plan = e->iam.gen_add_num_plan;
+                                       
                                /* Set DNID */
                                if (!ast_strlen_zero(e->iam.called_party_num))
                                        ss7_apply_plan_to_number(p->dnid, sizeof(p->dnid), linkset, e->iam.called_party_num, e->iam.called_nai);
@@ -8901,7 +9069,6 @@ static void *ss7_linkset(void *data)
                                isup_cgua(linkset->ss7, e->cgu.startcic, e->cgu.endcic, p->dpc, e->cgu.status, e->cgu.type);
                                break;
                        case ISUP_EVENT_UCIC:
-                               ast_verb(3,"Got UCIC message on CIC %d\n", e->ucic.cic);
                                chanpos = ss7_find_cic(linkset, e->ucic.cic);
                                if (chanpos < 0) {
                                        ast_log(LOG_WARNING, "UCIC on unconfigured CIC %d\n", e->ucic.cic);
@@ -8915,7 +9082,6 @@ static void *ss7_linkset(void *data)
                                ast_mutex_unlock(&p->lock);                     //doesn't require a SS7 acknowledgement
                                break;
                        case ISUP_EVENT_BLO:
-                               ast_verb(3,"Got BLO acknowledgement from CIC %d\n", e->ubl.cic);
                                chanpos = ss7_find_cic(linkset, e->blo.cic);
                                if (chanpos < 0) {
                                        ast_log(LOG_WARNING, "BLO on unconfigured CIC %d\n", e->blo.cic);
@@ -8925,12 +9091,22 @@ static void *ss7_linkset(void *data)
                                ast_debug(1, "Blocking CIC %d\n", e->blo.cic);
                                ast_mutex_lock(&p->lock);
                                p->remotelyblocked = 1;
-                               p->inservice = 0;
                                ast_mutex_unlock(&p->lock);
                                isup_bla(linkset->ss7, e->blo.cic, p->dpc);
                                break;
+                       case ISUP_EVENT_BLA:
+                               chanpos = ss7_find_cic(linkset, e->bla.cic);
+                               if (chanpos < 0) {
+                                       ast_log(LOG_WARNING, "BLA on unconfigured CIC %d\n", e->bla.cic);
+                                       break;
+                               }
+                               ast_debug(1, "Blocking CIC %d\n", e->bla.cic);
+                               p = linkset->pvts[chanpos];
+                               ast_mutex_lock(&p->lock);
+                               p->locallyblocked = 1;
+                               ast_mutex_unlock(&p->lock);
+                               break;
                        case ISUP_EVENT_UBL:
-                               ast_verb(3,"Got UBL acknowledgement from CIC %d\n", e->ubl.cic);
                                chanpos = ss7_find_cic(linkset, e->ubl.cic);
                                if (chanpos < 0) {
                                        ast_log(LOG_WARNING, "UBL on unconfigured CIC %d\n", e->ubl.cic);
@@ -8940,10 +9116,21 @@ static void *ss7_linkset(void *data)
                                ast_debug(1, "Unblocking CIC %d\n", e->ubl.cic);
                                ast_mutex_lock(&p->lock);
                                p->remotelyblocked = 0;
-                               p->inservice = 1;
                                ast_mutex_unlock(&p->lock);
                                isup_uba(linkset->ss7, e->ubl.cic, p->dpc);
                                break;
+                       case ISUP_EVENT_UBA:
+                               chanpos = ss7_find_cic(linkset, e->uba.cic);
+                               if (chanpos < 0) {
+                                       ast_log(LOG_WARNING, "UBA on unconfigured CIC %d\n", e->uba.cic);
+                                       break;
+                               }
+                               p = linkset->pvts[chanpos];
+                               ast_debug(1, "Unblocking CIC %d\n", e->uba.cic);
+                               ast_mutex_lock(&p->lock);
+                               p->locallyblocked = 0;
+                               ast_mutex_unlock(&p->lock);
+                               break;
                        case ISUP_EVENT_CON:
                        case ISUP_EVENT_ANM:
                                if (e->e == ISUP_EVENT_CON)
@@ -8960,6 +9147,10 @@ static void *ss7_linkset(void *data)
                                        p = linkset->pvts[chanpos];
                                        ast_mutex_lock(&p->lock);
                                        p->subs[SUB_REAL].needanswer = 1;
+                                       if (p->dsp && p->dsp_features) {
+                                               ast_dsp_set_features(p->dsp, p->dsp_features);
+                                               p->dsp_features = 0;
+                                       }
                                        zt_enable_ec(p);
                                        ast_mutex_unlock(&p->lock);
                                }
@@ -10828,14 +11019,14 @@ static char *handle_pri_show_debug(struct ast_cli_entry *e, int cmd, struct ast_
 }
 
 static struct ast_cli_entry zap_pri_cli[] = {
-       NEW_CLI(handle_pri_debug, "Enables PRI debugging on a span"),
-       NEW_CLI(handle_pri_no_debug, "Disables PRI debugging on a span"),
-       NEW_CLI(handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging"),
-       NEW_CLI(handle_pri_show_spans, "Displays PRI Information"),
-       NEW_CLI(handle_pri_show_span, "Displays PRI Information"),
-       NEW_CLI(handle_pri_show_debug, "Displays current PRI debug settings"),
-       NEW_CLI(handle_pri_set_debug_file, "Sends PRI debug output to the specified file"),
-       NEW_CLI(handle_pri_unset_debug_file, "Ends PRI debug output to file"),
+       AST_CLI_DEFINE(handle_pri_debug, "Enables PRI debugging on a span"),
+       AST_CLI_DEFINE(handle_pri_no_debug, "Disables PRI debugging on a span"),
+       AST_CLI_DEFINE(handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging"),
+       AST_CLI_DEFINE(handle_pri_show_spans, "Displays PRI Information"),
+       AST_CLI_DEFINE(handle_pri_show_span, "Displays PRI Information"),
+       AST_CLI_DEFINE(handle_pri_show_debug, "Displays current PRI debug settings"),
+       AST_CLI_DEFINE(handle_pri_set_debug_file, "Sends PRI debug output to the specified file"),
+       AST_CLI_DEFINE(handle_pri_unset_debug_file, "Ends PRI debug output to file"),
 };
 
 #endif /* HAVE_PRI */
@@ -11352,13 +11543,13 @@ static char *zap_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_a
 }
 
 static struct ast_cli_entry zap_cli[] = {
-       NEW_CLI(handle_zap_show_cadences, "List cadences"),
-       NEW_CLI(zap_show_channels, "Show active zapata channels"),
-       NEW_CLI(zap_show_channel, "Show information on a channel"),
-       NEW_CLI(zap_destroy_channel, "Destroy a channel"),
-       NEW_CLI(zap_restart_cmd, "Fully restart zaptel channels"),
-       NEW_CLI(zap_show_status, "Show all Zaptel cards status"),
-       NEW_CLI(zap_show_version, "Show the Zaptel version in use"),
+       AST_CLI_DEFINE(handle_zap_show_cadences, "List cadences"),
+       AST_CLI_DEFINE(zap_show_channels, "Show active zapata channels"),
+       AST_CLI_DEFINE(zap_show_channel, "Show information on a channel"),
+       AST_CLI_DEFINE(zap_destroy_channel, "Destroy a channel"),
+       AST_CLI_DEFINE(zap_restart_cmd, "Fully restart zaptel channels"),
+       AST_CLI_DEFINE(zap_show_status, "Show all Zaptel cards status"),
+       AST_CLI_DEFINE(zap_show_version, "Show the Zaptel version in use"),
 };
 
 #define TRANSFER       0
@@ -11701,7 +11892,7 @@ static int linkset_addsigchan(int sigchan)
                        return -1;
                }
 
-               ss7_add_link(link->ss7, link->fds[curfd]);
+               ss7_add_link(link->ss7, SS7_TRANSPORT_ZAP, link->fds[curfd]);
                link->numsigchans++;
 
                memset(&si, 0, sizeof(si));
@@ -11844,9 +12035,6 @@ static char *handle_ss7_block_cic(struct ast_cli_entry *e, int cmd, struct ast_c
                if (linksets[linkset-1].pvts[i]->cic == cic) {
                        blocked = linksets[linkset-1].pvts[i]->locallyblocked;
                        if (!blocked) {
-                               ast_mutex_lock(&linksets[linkset-1].pvts[i]->lock);
-                               linksets[linkset-1].pvts[i]->locallyblocked = 1;
-                               ast_mutex_unlock(&linksets[linkset-1].pvts[i]->lock);
                                ast_mutex_lock(&linksets[linkset-1].lock);
                                isup_blo(linksets[linkset-1].ss7, cic, linksets[linkset-1].pvts[i]->dpc);
                                ast_mutex_unlock(&linksets[linkset-1].lock);
@@ -11908,9 +12096,6 @@ static char *handle_ss7_unblock_cic(struct ast_cli_entry *e, int cmd, struct ast
                if (linksets[linkset-1].pvts[i]->cic == cic) {
                        blocked = linksets[linkset-1].pvts[i]->locallyblocked;
                        if (blocked) {
-                               ast_mutex_lock(&linksets[linkset-1].pvts[i]->lock);
-                               linksets[linkset-1].pvts[i]->locallyblocked = 0;
-                               ast_mutex_unlock(&linksets[linkset-1].pvts[i]->lock);
                                ast_mutex_lock(&linksets[linkset-1].lock);
                                isup_ubl(linksets[linkset-1].ss7, cic, linksets[linkset-1].pvts[i]->dpc);
                                ast_mutex_unlock(&linksets[linkset-1].lock);
@@ -11958,11 +12143,11 @@ static char *handle_ss7_show_linkset(struct ast_cli_entry *e, int cmd, struct as
 }
 
 static struct ast_cli_entry zap_ss7_cli[] = {
-       NEW_CLI(handle_ss7_debug, "Enables SS7 debugging on a linkset"), 
-       NEW_CLI(handle_ss7_no_debug, "Disables SS7 debugging on a linkset"), 
-       NEW_CLI(handle_ss7_block_cic, "Disables SS7 debugging on a linkset"),
-       NEW_CLI(handle_ss7_unblock_cic, "Disables SS7 debugging on a linkset"),
-       NEW_CLI(handle_ss7_show_linkset, "Shows the status of a linkset"),
+       AST_CLI_DEFINE(handle_ss7_debug, "Enables SS7 debugging on a linkset"), 
+       AST_CLI_DEFINE(handle_ss7_no_debug, "Disables SS7 debugging on a linkset"), 
+       AST_CLI_DEFINE(handle_ss7_block_cic, "Disables SS7 debugging on a linkset"),
+       AST_CLI_DEFINE(handle_ss7_unblock_cic, "Disables SS7 debugging on a linkset"),
+       AST_CLI_DEFINE(handle_ss7_show_linkset, "Shows the status of a linkset"),
 };
 #endif /* HAVE_SS7 */
 
@@ -12076,7 +12261,7 @@ static int build_channels(struct zt_chan_conf conf, int iscrv, const char *value
 static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
 {
        struct zt_pvt *tmp;
-       char *ringc; /* temporary string for parsing the dring number. */
+       const char *ringc; /* temporary string for parsing the dring number. */
        int y;
        int found_pseudo = 0;
         char zapchan[MAX_CHANLIST_LEN] = {};
@@ -12615,9 +12800,9 @@ static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int r
                                }
                        } else if (!strcasecmp(v->name, "pritimer")) {
 #ifdef PRI_GETSET_TIMERS
-                               char *timerc, *c;
+                               char tmp[20], *timerc, *c = tmp;
                                int timer, timeridx;
-                               c = v->value;
+                               ast_copy_string(tmp, v->value, sizeof(tmp));
                                timerc = strsep(&c, ",");
                                if (timerc) {
                                        timer = atoi(c);
@@ -13058,7 +13243,7 @@ static int load_module(void)
        if (ast_channel_register(&zap_tech)) {
                ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
                __unload_module();
-               return -1;
+               return AST_MODULE_LOAD_FAILURE;
        }
 #ifdef HAVE_PRI
        ast_string_field_init(&inuse, 16);
@@ -13158,8 +13343,10 @@ static int zt_sendtext(struct ast_channel *c, const char *text)
                        continue;
                }
                  /* if got exception */
-               if (fds[0].revents & POLLPRI)
+               if (fds[0].revents & POLLPRI) {
+                       ast_free(mybuf);
                        return -1;
+               }
                if (!(fds[0].revents & POLLOUT)) {
                        ast_debug(1, "write fd not ready on channel %d\n", p->channel);
                        continue;