Thu Oct 8 21:55:59 2009

Asterisk developer's documentation


chan_zap.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * Copyright (C) 2003-2006 Junghanns.NET GmbH
00015  * Klaus-Peter Junghanns <kpj@junghanns.net>
00016  *
00017  *
00018  * This program is free software, distributed under the terms of
00019  * the GNU General Public License Version 2. See the LICENSE file
00020  * at the top of the source tree.
00021  */
00022 
00023 /*! \file
00024  *
00025  * \brief Zaptel Pseudo TDM interface 
00026  *
00027  * \author Mark Spencer <markster@digium.com>
00028  * 
00029  * Connects to the zaptel telephony library as well as 
00030  * libpri. Libpri is optional and needed only if you are
00031  * going to use ISDN connections.
00032  *
00033  * You need to install libraries before you attempt to compile
00034  * and install the zaptel channel.
00035  *
00036  * \par See also
00037  * \arg \ref Config_zap
00038  *
00039  * \ingroup channel_drivers
00040  *
00041  * \todo Deprecate the "musiconhold" configuration option post 1.4
00042  */
00043 
00044 /*** MODULEINFO
00045    <depend>res_smdi</depend>
00046    <depend>zaptel_vldtmf</depend>
00047    <depend>zaptel</depend>
00048    <depend>tonezone</depend>
00049    <depend>res_features</depend>
00050    <use>pri</use>
00051  ***/
00052 
00053 #include "asterisk.h"
00054 
00055 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 120425 $")
00056 
00057 #include <stdio.h>
00058 #include <string.h>
00059 #ifdef __NetBSD__
00060 #include <pthread.h>
00061 #include <signal.h>
00062 #else
00063 #include <sys/signal.h>
00064 #endif
00065 #include <errno.h>
00066 #include <stdlib.h>
00067 #if !defined(SOLARIS) && !defined(__FreeBSD__)
00068 #include <stdint.h>
00069 #endif
00070 #include <unistd.h>
00071 #include <sys/ioctl.h>
00072 #include <math.h>
00073 #include <ctype.h>
00074 #include <zaptel/zaptel.h>
00075 #include <zaptel/tonezone.h>
00076 
00077 #ifdef HAVE_PRI
00078 #include <bristuffed/libpri.h>
00079 #endif
00080 #ifdef HAVE_GSMAT
00081 #include <libgsmat.h>
00082 #endif
00083 
00084 #include "asterisk/lock.h"
00085 #include "asterisk/channel.h"
00086 #include "asterisk/config.h"
00087 #include "asterisk/logger.h"
00088 #include "asterisk/module.h"
00089 #include "asterisk/pbx.h"
00090 #include "asterisk/options.h"
00091 #include "asterisk/file.h"
00092 #include "asterisk/ulaw.h"
00093 #include "asterisk/alaw.h"
00094 #include "asterisk/callerid.h"
00095 #include "asterisk/adsi.h"
00096 #include "asterisk/cli.h"
00097 #include "asterisk/cdr.h"
00098 #include "asterisk/features.h"
00099 #include "asterisk/musiconhold.h"
00100 #include "asterisk/say.h"
00101 #include "asterisk/tdd.h"
00102 #include "asterisk/app.h"
00103 #include "asterisk/dsp.h"
00104 #include "asterisk/astdb.h"
00105 #include "asterisk/manager.h"
00106 #include "asterisk/causes.h"
00107 #include "asterisk/term.h"
00108 #include "asterisk/utils.h"
00109 #include "asterisk/transcap.h"
00110 #include "asterisk/stringfields.h"
00111 #include "asterisk/abstract_jb.h"
00112 #include "asterisk/smdi.h"
00113 #include "asterisk/astobj.h"
00114 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00115 
00116 /*! Global jitterbuffer configuration - by default, jb is disabled */
00117 static struct ast_jb_conf default_jbconf =
00118 {
00119    .flags = 0,
00120    .max_size = -1,
00121    .resync_threshold = -1,
00122    .impl = ""
00123 };
00124 static struct ast_jb_conf global_jbconf;
00125 
00126 #if !defined(ZT_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(ZT_SIG_HARDHDLC))
00127 #error "Your zaptel is too old.  Please update"
00128 #endif
00129 
00130 #ifndef ZT_TONEDETECT
00131 /* Work around older code with no tone detect */
00132 #define ZT_EVENT_DTMFDOWN 0
00133 #define ZT_EVENT_DTMFUP 0
00134 #endif
00135 
00136 /* define this to send PRI user-user information elements */
00137 #undef SUPPORT_USERUSER
00138 
00139 /*! 
00140  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00141  * the user hangs up to reset the state machine so ring works properly.
00142  * This is used to be able to support kewlstart by putting the zhone in
00143  * groundstart mode since their forward disconnect supervision is entirely
00144  * broken even though their documentation says it isn't and their support
00145  * is entirely unwilling to provide any assistance with their channel banks
00146  * even though their web site says they support their products for life.
00147  */
00148 /* #define ZHONE_HACK */
00149 
00150 /*! \note
00151  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00152  * before dialing on it.  Certain FXO interfaces always think they're out of
00153  * service with this method however.
00154  */
00155 /* #define ZAP_CHECK_HOOKSTATE */
00156 
00157 /*! \brief Typically, how many rings before we should send Caller*ID */
00158 #define DEFAULT_CIDRINGS 1
00159 
00160 #define CHANNEL_PSEUDO -12
00161 
00162 #define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
00163 
00164 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
00165 #define NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) 
00166 
00167 static const char tdesc[] = "Zapata Telephony Driver"
00168 #ifdef HAVE_PRI
00169                " w/PRI"
00170 #endif
00171 ;
00172 
00173 static const char config[] = "zapata.conf";
00174 
00175 #define SIG_EM    ZT_SIG_EM
00176 #define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
00177 #define SIG_FEATD (0x0200000 | ZT_SIG_EM)
00178 #define  SIG_FEATDMF (0x0400000 | ZT_SIG_EM)
00179 #define  SIG_FEATB   (0x0800000 | ZT_SIG_EM)
00180 #define  SIG_E911 (0x1000000 | ZT_SIG_EM)
00181 #define  SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)
00182 #define  SIG_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
00183 #define  SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM)
00184 #define SIG_FXSLS ZT_SIG_FXSLS
00185 #define SIG_FXSGS ZT_SIG_FXSGS
00186 #define SIG_FXSKS ZT_SIG_FXSKS
00187 #define SIG_FXOLS ZT_SIG_FXOLS
00188 #define SIG_FXOGS ZT_SIG_FXOGS
00189 #define SIG_FXOKS ZT_SIG_FXOKS
00190 #define SIG_PRI      ZT_SIG_CLEAR
00191 #define SIG_GSM      (0x100000 | ZT_SIG_CLEAR)
00192 #define  SIG_SF      ZT_SIG_SF
00193 #define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
00194 #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)
00195 #define  SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)
00196 #define  SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
00197 #define SIG_EM_E1 ZT_SIG_EM_E1
00198 #define SIG_GR303FXOKS  (0x0100000 | ZT_SIG_FXOKS)
00199 #define SIG_GR303FXSKS  (0x0100000 | ZT_SIG_FXSKS)
00200 
00201 #define NUM_SPANS       ZT_MAX_SPANS
00202 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00203 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00204 
00205 #define CHAN_PSEUDO  -2
00206 
00207 #define DCHAN_PROVISIONED (1 << 0)
00208 #define DCHAN_NOTINALARM  (1 << 1)
00209 #define DCHAN_UP          (1 << 2)
00210 
00211 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00212 
00213 static char defaultcic[64] = "";
00214 static char defaultozz[64] = "";
00215 
00216 static char progzone[10] = "";
00217 
00218 static int distinctiveringaftercid = 0;
00219 
00220 static int numbufs = 4;
00221 
00222 #ifdef HAVE_PRI
00223 static struct ast_channel inuse;
00224 #ifdef PRI_GETSET_TIMERS
00225 static int pritimers[PRI_MAX_TIMERS];
00226 #endif
00227 #endif
00228 
00229 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
00230 static int firstdigittimeout = 16000;
00231 
00232 /*! \brief How long to wait for following digits (FXO logic) */
00233 static int gendigittimeout = 8000;
00234 
00235 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
00236 static int matchdigittimeout = 3000;
00237 
00238 /*! \brief Protect the interface list (of zt_pvt's) */
00239 AST_MUTEX_DEFINE_STATIC(iflock);
00240 
00241 static char gsm_modem_pin[20];
00242 static char gsm_modem_exten[AST_MAX_EXTENSION];
00243 
00244 static int ifcount = 0;
00245 
00246 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
00247    when it's doing something critical. */
00248 AST_MUTEX_DEFINE_STATIC(monlock);
00249 
00250 /*! \brief This is the thread for the monitor which checks for input on the channels
00251    which are not currently in use. */
00252 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00253 
00254 static int restart_monitor(void);
00255 
00256 static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
00257 
00258 static int zt_sendtext(struct ast_channel *c, const char *text);
00259 
00260 static int zt_sendmessage(struct ast_channel *c, const char *dest, const char *text, int ispdu);
00261 
00262 /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
00263 static inline int zt_get_event(int fd)
00264 {
00265    int j;
00266    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00267       return -1;
00268    return j;
00269 }
00270 
00271 /*! \brief Avoid the silly zt_waitevent which ignores a bunch of events */
00272 static inline int zt_wait_event(int fd)
00273 {
00274    int i, j = 0;
00275    i = ZT_IOMUX_SIGEVENT;
00276    if (ioctl(fd, ZT_IOMUX, &i) == -1)
00277       return -1;
00278    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00279       return -1;
00280    return j;
00281 }
00282 
00283 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
00284 #define READ_SIZE 160
00285 
00286 #define MASK_AVAIL      (1 << 0) /*!< Channel available for PRI use */
00287 #define MASK_INUSE      (1 << 1) /*!< Channel currently in use */
00288 
00289 #define CALLWAITING_SILENT_SAMPLES  ( (300 * 8) / READ_SIZE) /*!< 300 ms */
00290 #define CALLWAITING_REPEAT_SAMPLES  ( (10000 * 8) / READ_SIZE) /*!< 10,000 ms */
00291 #define CIDCW_EXPIRE_SAMPLES     ( (500 * 8) / READ_SIZE) /*!< 500 ms */
00292 #define MIN_MS_SINCE_FLASH       ( (2000) )  /*!< 2000 ms */
00293 #define DEFAULT_RINGT            ( (8000 * 8) / READ_SIZE) /*!< 8,000 ms */
00294 
00295 struct zt_pvt;
00296 
00297 static int ringt_base = DEFAULT_RINGT;
00298 
00299 #ifdef HAVE_PRI
00300 
00301 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
00302 #define PRI_CHANNEL(p) ((p) & 0xff)
00303 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00304 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
00305 
00306 struct zt_suspended_call {
00307    ast_mutex_t lock;    /* Mutex */
00308    char msn[AST_MAX_EXTENSION];  /* the MSN to which this parked call belongs */
00309    char callid[10];        /* the callID provided by the user */
00310    int parked_at;       /* extension in the call parking context */
00311    struct zt_suspended_call *next;
00312 };
00313 
00314 struct zt_pri {
00315    pthread_t master;                /*!< Thread of master */
00316    ast_mutex_t lock;                /*!< Mutex */
00317    char idleext[AST_MAX_EXTENSION];          /*!< Where to idle extra calls */
00318    char idlecontext[AST_MAX_CONTEXT];           /*!< What context to use for idle */
00319    char idledial[AST_MAX_EXTENSION];            /*!< What to dial before dumping */
00320    int minunused;                   /*!< Min # of channels to keep empty */
00321    int minidle;                     /*!< Min # of "idling" calls to keep active */
00322    int nodetype;                    /*!< Node type */
00323    int switchtype;                     /*!< Type of switch to emulate */
00324    int nsf;                   /*!< Network-Specific Facilities */
00325    int dialplan;                    /*!< Dialing plan */
00326    int localdialplan;                  /*!< Local dialing plan */
00327    char nocid[AST_MAX_EXTENSION];               /*!< CallerID string to use if none provided */
00328    char withheldcid[AST_MAX_EXTENSION];            /*!< CallerID string to use if CallerID is withheld */
00329    char internationalprefix[10];             /*!< country access code ('00' for european dialplans) */
00330    char nationalprefix[10];               /*!< area access code ('0' for european dialplans) */
00331    char localprefix[20];                  /*!< area access code + area code ('0'+area code for european dialplans) */
00332    char privateprefix[20];                /*!< for private dialplans */
00333    char unknownprefix[20];                /*!< for unknown dialplans */
00334    int dchannels[NUM_DCHANS];             /*!< What channel are the dchannels on */
00335    int trunkgroup;                     /*!< What our trunkgroup is */
00336    int mastertrunkgroup;                  /*!< What trunk group is our master */
00337    int prilogicalspan;                 /*!< Logical span number within trunk group */
00338    int numchans;                    /*!< Num of channels we represent */
00339    int overlapdial;                 /*!< In overlap dialing mode */
00340    int usercid;
00341    int facilityenable;                 /*!< Enable facility IEs */
00342    struct pri *dchans[NUM_DCHANS];              /*!< Actual d-channels */
00343    int dchanavail[NUM_DCHANS];               /*!< Whether each channel is available */
00344    struct pri *pri;                 /*!< Currently active D-channel */
00345    int debug;
00346    int fds[NUM_DCHANS];                /*!< FD's for d-channels */
00347    int offset;
00348    int span;
00349    int resetting;
00350    int resetpos;
00351    time_t lastreset;                /*!< time when unused channels were last reset */
00352    long resetinterval;                 /*!< Interval (in seconds) for resetting unused channels */
00353    struct zt_pvt *pvts[MAX_CHANNELS];           /*!< Member channel pvt structs */
00354    struct zt_pvt *crvs;                /*!< Member CRV structs */
00355    struct zt_pvt *crvend;                 /*!< Pointer to end of CRV structs */
00356    struct zt_suspended_call *suspended_calls; /* Calls parked with SUSPEND messages */
00357    int debugfd;
00358 };
00359 
00360 #ifdef HAVE_GSMAT
00361 struct zt_gsm {
00362    pthread_t master;
00363    ast_mutex_t lock;    /* Mutex */
00364    int fd;
00365    int span;
00366    struct gsm_modul *modul;
00367    char pin[256];
00368    int available;
00369    char exten[AST_MAX_EXTENSION];      /* Where to idle extra calls */
00370    struct zt_pvt *pvt;
00371 };
00372 #endif
00373 
00374 static struct zt_pri pris[NUM_SPANS];
00375 
00376 #if 0
00377 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
00378 #else
00379 #define DEFAULT_PRI_DEBUG 0
00380 #endif
00381 
00382 static inline void pri_rel(struct zt_pri *pri)
00383 {
00384    ast_mutex_unlock(&pri->lock);
00385 }
00386 
00387 #else
00388 /*! Shut up the compiler */
00389 struct zt_pri;
00390 #endif
00391 
00392 #define SUB_REAL  0        /*!< Active call */
00393 #define SUB_CALLWAIT 1        /*!< Call-Waiting call on hold */
00394 #define SUB_THREEWAY 2        /*!< Three-way call */
00395 
00396 /* Polarity states */
00397 #define POLARITY_IDLE   0
00398 #define POLARITY_REV    1
00399 
00400 
00401 
00402 static struct zt_distRings drings;
00403 
00404 struct distRingData {
00405    int ring[3];
00406 };
00407 struct ringContextData {
00408    char contextData[AST_MAX_CONTEXT];
00409 };
00410 struct zt_distRings {
00411    struct distRingData ringnum[3];
00412    struct ringContextData ringContext[3];
00413 };
00414 
00415 static char *subnames[] = {
00416    "Real",
00417    "Callwait",
00418    "Threeway"
00419 };
00420 
00421 struct zt_subchannel {
00422    int zfd;
00423    struct ast_channel *owner;
00424    int chan;
00425    short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
00426    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00427    unsigned int needringing:1;
00428    unsigned int needbusy:1;
00429    unsigned int needcongestion:1;
00430    unsigned int needcallerid:1;
00431    unsigned int needanswer:1;
00432    unsigned int needflash:1;
00433    unsigned int needhold:1;
00434    unsigned int needunhold:1;
00435    unsigned int linear:1;
00436    unsigned int inthreeway:1;
00437    ZT_CONFINFO curconf;
00438 };
00439 
00440 #define CONF_USER_REAL     (1 << 0)
00441 #define CONF_USER_THIRDCALL   (1 << 1)
00442 
00443 #define MAX_SLAVES   4
00444 
00445 static struct zt_pvt {
00446    ast_mutex_t lock;
00447    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00448                      /*!< Up to three channels can be associated with this call */
00449       
00450    struct zt_subchannel sub_unused;    /*!< Just a safety precaution */
00451    struct zt_subchannel subs[3];       /*!< Sub-channels */
00452    struct zt_confinfo saveconf;        /*!< Saved conference info */
00453 
00454    struct zt_pvt *slaves[MAX_SLAVES];     /*!< Slave to us (follows our conferencing) */
00455    struct zt_pvt *master;           /*!< Master to us (we follow their conferencing) */
00456    int inconference;          /*!< If our real should be in the conference */
00457    
00458    int sig;             /*!< Signalling style */
00459    int radio;              /*!< radio type */
00460    int outsigmod;             /*!< Outbound Signalling style (modifier) */
00461    int oprmode;               /*!< "Operator Services" mode */
00462    struct zt_pvt *oprpeer;          /*!< "Operator Services" peer tech_pvt ptr */
00463    float rxgain;
00464    float txgain;
00465    int tonezone;              /*!< tone zone for this chan, or -1 for default */
00466    struct zt_pvt *next;          /*!< Next channel in list */
00467    struct zt_pvt *prev;          /*!< Prev channel in list */
00468 
00469    /* flags */
00470    unsigned int adsi:1;
00471    unsigned int answeronpolarityswitch:1;
00472    unsigned int busydetect:1;
00473    unsigned int callreturn:1;
00474    unsigned int callwaiting:1;
00475    unsigned int callwaitingcallerid:1;
00476    unsigned int cancallforward:1;
00477    unsigned int canpark:1;
00478    unsigned int confirmanswer:1;       /*!< Wait for '#' to confirm answer */
00479    unsigned int destroy:1;
00480    unsigned int didtdd:1;           /*!< flag to say its done it once */
00481    unsigned int dialednone:1;
00482    unsigned int dialing:1;
00483    unsigned int digital:1;
00484    unsigned int dnd:1;
00485    unsigned int echobreak:1;
00486    unsigned int echocanbridged:1;
00487    unsigned int echocanon:1;
00488    unsigned int faxhandled:1;       /*!< Has a fax tone already been handled? */
00489                      /*!< KPJ: i will abuse this flag to implement a zapata option for dialing out
00490                          on a zap channel with EC to be off no matter what happens. */
00491    unsigned int firstradio:1;
00492    unsigned int hanguponpolarityswitch:1;
00493    unsigned int hardwaredtmf:1;
00494    unsigned int hidecallerid:1;
00495    unsigned int hidecalleridname:1;      /*!< Hide just the name not the number for legacy PBX use */
00496    unsigned int ignoredtmf:1;
00497    unsigned int immediate:1;        /*!< Answer before getting digits? */
00498    unsigned int inalarm:1;
00499    unsigned int unknown_alarm:1;
00500    unsigned int mate:1;          /*!< flag to say its in MATE mode */
00501    unsigned int outgoing:1;
00502    unsigned int overlapdial:1;
00503    unsigned int permcallwaiting:1;
00504    unsigned int permhidecallerid:1;    /*!< Whether to hide our outgoing caller ID or not */
00505    unsigned int priindication_oob:2;
00506    unsigned int pritransfer:2;
00507    unsigned int priexclusive:1;
00508    unsigned int pulse:1;
00509    unsigned int pulsedial:1;        /*!< whether a pulse dial phone is detected */
00510    unsigned int restrictcid:1;         /*!< Whether restrict the callerid -> only send ANI */
00511    unsigned int threewaycalling:1;
00512    unsigned int transfer:1;
00513    unsigned int use_callerid:1;        /*!< Whether or not to use caller id on this channel */
00514    unsigned int use_callingpres:1;        /*!< Whether to use the callingpres the calling switch sends */
00515    unsigned int usedistinctiveringdetection:1;
00516    unsigned int zaptrcallerid:1;       /*!< should we use the callerid from incoming call on zap transfer or not */
00517    unsigned int transfertobusy:1;         /*!< allow flash-transfers to busy channels */
00518 #if defined(HAVE_PRI)
00519    unsigned int alerting:1;
00520    unsigned int alreadyhungup:1;
00521    unsigned int isidlecall:1;
00522    unsigned int proceeding:1;
00523    unsigned int progress:1;
00524    unsigned int resetting:1;
00525    unsigned int setup_ack:1;
00526 #endif
00527    unsigned int use_smdi:1;      /* Whether to use SMDI on this channel */
00528    struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */
00529 
00530    struct zt_distRings drings;
00531 
00532    char context[AST_MAX_CONTEXT];
00533    char defcontext[AST_MAX_CONTEXT];
00534    char exten[AST_MAX_EXTENSION];
00535    char language[MAX_LANGUAGE];
00536    char mohinterpret[MAX_MUSICCLASS];
00537    char mohsuggest[MAX_MUSICCLASS];
00538 #ifdef PRI_ANI
00539    char cid_ani[AST_MAX_EXTENSION];
00540 #endif
00541    char cid_num[AST_MAX_EXTENSION];
00542    int cid_ton;               /*!< Type Of Number (TON) */
00543    int cid_pres;              /*!< Calling Presentation */
00544    char cid_name[AST_MAX_EXTENSION];
00545    char lastcid_num[AST_MAX_EXTENSION];
00546    char lastcid_name[AST_MAX_EXTENSION];
00547    char *origcid_num;            /*!< malloced original callerid */
00548    char *origcid_name;           /*!< malloced original callerid */
00549    char callwait_num[AST_MAX_EXTENSION];
00550    char callwait_name[AST_MAX_EXTENSION];
00551    char rdnis[AST_MAX_EXTENSION];
00552    char dnid[AST_MAX_EXTENSION];
00553    ast_group_t group;
00554    int law;
00555    int confno;             /*!< Our conference */
00556    int confusers;             /*!< Who is using our conference */
00557    int propconfno;               /*!< Propagated conference number */
00558    ast_group_t callgroup;
00559    ast_group_t pickupgroup;
00560    int channel;               /*!< Channel Number or CRV */
00561    int span;               /*!< Span number */
00562    time_t guardtime;          /*!< Must wait this much time before using for new call */
00563    int cid_signalling;           /*!< CID signalling type bell202 or v23 */
00564    int cid_start;             /*!< CID start indicator, polarity or ring */
00565    int callingpres;           /*!< The value of callling presentation that we're going to use when placing a PRI call */
00566    int callwaitingrepeat;           /*!< How many samples to wait before repeating call waiting */
00567    int cidcwexpire;           /*!< When to expire our muting for CID/CW */
00568    unsigned char *cidspill;
00569    int cidpos;
00570    int cidlen;
00571    int ringt;
00572    int ringt_base;
00573    int stripmsd;
00574    int callwaitcas;
00575    int callwaitrings;
00576    int echocancel;
00577    int echotraining;
00578    char echorest[20];
00579    int busycount;
00580    int busy_tonelength;
00581    int busy_quietlength;
00582    int callprogress;
00583    struct timeval flashtime;        /*!< Last flash-hook time */
00584    struct ast_dsp *dsp;
00585    int cref;               /*!< Call reference number */
00586    ZT_DIAL_OPERATION dop;
00587    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00588    char finaldial[64];
00589    char accountcode[AST_MAX_ACCOUNT_CODE];      /*!< Account code */
00590    int amaflags;              /*!< AMA Flags */
00591    struct tdd_state *tdd;           /*!< TDD flag */
00592    char call_forward[AST_MAX_EXTENSION];
00593    char mailbox[AST_MAX_EXTENSION];
00594    char dialdest[256];
00595    int onhooktime;
00596    int msgstate;
00597    int distinctivering;          /*!< Which distinctivering to use */
00598    int cidrings;              /*!< Which ring to deliver CID on */
00599    int dtmfrelax;             /*!< whether to run in relaxed DTMF mode */
00600    int fake_event;
00601    int polarityonanswerdelay;
00602    struct timeval polaritydelaytv;
00603    int sendcalleridafter;
00604 #ifdef HAVE_PRI
00605    struct zt_pri *pri;
00606    struct zt_pvt *bearer;
00607    struct zt_pvt *realcall;
00608    q931_call *call;
00609    int tei;             /* channel in use by this tei */
00610    q931_call *holdedcall;
00611    int prioffset;
00612    int logicalspan;
00613 #endif   
00614 #ifdef HAVE_GSMAT
00615    struct zt_gsm gsm;
00616 #endif
00617    int polarity;
00618    int dsp_features;
00619    char begindigit;
00620 } *iflist = NULL, *ifend = NULL;
00621 
00622 /*! \brief Channel configuration from zapata.conf .
00623  * This struct is used for parsing the [channels] section of zapata.conf.
00624  * Generally there is a field here for every possible configuration item.
00625  *
00626  * The state of fields is saved along the parsing and whenever a 'channel'
00627  * statement is reached, the current zt_chan_conf is used to configure the 
00628  * channel (struct zt_pvt)
00629  *
00630  * @seealso zt_chan_init for the default values.
00631  */
00632 struct zt_chan_conf {
00633    struct zt_pvt chan;
00634 #ifdef HAVE_PRI
00635    struct zt_pri pri;
00636 #endif
00637    ZT_PARAMS timing;
00638 
00639    char smdi_port[SMDI_MAX_FILENAME_LEN];
00640 };
00641 
00642 /** returns a new zt_chan_conf with default values (by-value) */
00643 static struct zt_chan_conf zt_chan_conf_default(void) {
00644    /* recall that if a field is not included here it is initialized
00645     * to 0 or equivalent
00646     */
00647    struct zt_chan_conf conf = {
00648 #ifdef HAVE_PRI
00649       .pri = {
00650          .nsf = PRI_NSF_NONE,
00651          .switchtype = PRI_SWITCH_NI2,
00652          .dialplan = PRI_NATIONAL_ISDN + 1,
00653          .localdialplan = PRI_NATIONAL_ISDN + 1,
00654          .nodetype = PRI_CPE,
00655 
00656          .minunused = 2,
00657          .idleext = "",
00658          .idledial = "",
00659          .nocid = "No CID available",
00660          .withheldcid = "CID withheld",
00661          .internationalprefix = "",
00662          .nationalprefix = "",
00663          .localprefix = "",
00664          .privateprefix = "",
00665          .unknownprefix = "",
00666          .usercid = 0,
00667 
00668          .resetinterval = 3600
00669       },
00670 #endif
00671       .chan = {
00672          .context = "default",
00673          .cid_num = "",
00674          .cid_name = "",
00675          .mohinterpret = "default",
00676          .mohsuggest = "",
00677          .transfertobusy = 1,
00678          .priindication_oob = 0,
00679          .pritransfer = 0,
00680 
00681          .cid_signalling = CID_SIG_BELL,
00682          .cid_start = CID_START_RING,
00683          .zaptrcallerid = 0,
00684          .use_callerid = 1,
00685          .sig = -1,
00686          .outsigmod = -1,
00687 
00688          .tonezone = -1,
00689 
00690          .echocancel = 1,
00691 
00692          .busycount = 3,
00693 
00694          .accountcode = "",
00695 
00696          .mailbox = "",
00697 
00698 
00699          .polarityonanswerdelay = 600,
00700 
00701          .sendcalleridafter = DEFAULT_CIDRINGS
00702       },
00703       .timing = {
00704          .prewinktime = -1,
00705          .preflashtime = -1,
00706          .winktime = -1,
00707          .flashtime = -1,
00708          .starttime = -1,
00709          .rxwinktime = -1,
00710          .rxflashtime = -1,
00711          .debouncetime = -1
00712       },
00713       .smdi_port = "/dev/ttyS0",
00714    };
00715 
00716    return conf;
00717 }
00718 
00719 
00720 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
00721 static int zt_digit_begin(struct ast_channel *ast, char digit);
00722 static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00723 static int zt_sendmessage(struct ast_channel *c, const char *dest, const char *text, int ispdu);
00724 static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
00725 static int zt_hangup(struct ast_channel *ast);
00726 static int zt_answer(struct ast_channel *ast);
00727 static struct ast_frame *zt_read(struct ast_channel *ast);
00728 static int zt_write(struct ast_channel *ast, struct ast_frame *frame);
00729 static struct ast_frame *zt_exception(struct ast_channel *ast);
00730 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
00731 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00732 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
00733 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
00734 static void enable_dtmf_detect(struct zt_pvt *p);
00735 static void disable_dtmf_detect(struct zt_pvt *p);
00736 
00737 static const struct ast_channel_tech zap_tech = {
00738    .type = "Zap",
00739    .description = tdesc,
00740    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
00741    .requester = zt_request,
00742    .send_digit_begin = zt_digit_begin,
00743    .send_digit_end = zt_digit_end,
00744    .send_text = zt_sendtext,
00745 #if 0 /* we (Debian) disable that addition because of ABI breakage */
00746    .send_message = zt_sendmessage,
00747 #endif
00748    .call = zt_call,
00749    .hangup = zt_hangup,
00750    .answer = zt_answer,
00751    .read = zt_read,
00752    .write = zt_write,
00753    .bridge = zt_bridge,
00754    .exception = zt_exception,
00755    .indicate = zt_indicate,
00756    .fixup = zt_fixup,
00757    .setoption = zt_setoption,
00758    .func_channel_read = zt_func_read,
00759 };
00760 
00761 #ifdef HAVE_PRI
00762 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
00763 #else
00764 #define GET_CHANNEL(p) ((p)->channel)
00765 #endif
00766 
00767 struct zt_pvt *round_robin[32];
00768 
00769 #ifdef HAVE_PRI
00770 struct app_tmp {
00771    char app[256];
00772    char data[256];
00773    struct ast_channel *chan;
00774    pthread_t t;
00775 };
00776 
00777 static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
00778 {
00779    int res;
00780    /* Grab the lock first */
00781    do {
00782       res = ast_mutex_trylock(&pri->lock);
00783       if (res) {
00784          DEADLOCK_AVOIDANCE(&pvt->lock);
00785       }
00786    } while (res);
00787    /* Then break the poll */
00788    pthread_kill(pri->master, SIGURG);
00789    return 0;
00790 }
00791 #endif
00792 
00793 #define NUM_CADENCE_MAX 25
00794 static int num_cadence = 4;
00795 static int user_has_defined_cadences = 0;
00796 
00797 static struct zt_ring_cadence cadences[NUM_CADENCE_MAX] = {
00798    { { 125, 125, 2000, 4000 } },       /*!< Quick chirp followed by normal ring */
00799    { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
00800    { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
00801    { { 1000, 500, 2500, 5000 } },   /*!< Long ring */
00802 };
00803 
00804 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
00805  * is 1, the second pause is 2 and so on.
00806  */
00807 
00808 static int cidrings[NUM_CADENCE_MAX] = {
00809    2,                            /*!< Right after first long ring */
00810    4,                            /*!< Right after long part */
00811    3,                            /*!< After third chirp */
00812    2,                            /*!< Second spell */
00813 };
00814 
00815 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
00816          (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
00817 
00818 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00819 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00820 
00821 static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok)
00822 {
00823    int res;
00824    if (p->subs[0].owner == ast)
00825       res = 0;
00826    else if (p->subs[1].owner == ast)
00827       res = 1;
00828    else if (p->subs[2].owner == ast)
00829       res = 2;
00830    else {
00831       res = -1;
00832       if (!nullok)
00833          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
00834    }
00835    return res;
00836 }
00837 
00838 #ifdef HAVE_PRI
00839 static void wakeup_sub(struct zt_pvt *p, int a, struct zt_pri *pri)
00840 #else
00841 static void wakeup_sub(struct zt_pvt *p, int a, void *pri)
00842 #endif
00843 {
00844 #ifdef HAVE_PRI
00845    if (pri)
00846       ast_mutex_unlock(&pri->lock);
00847 #endif         
00848    for (;;) {
00849       if (p->subs[a].owner) {
00850          if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
00851             DEADLOCK_AVOIDANCE(&p->lock);
00852          } else {
00853             ast_queue_frame(p->subs[a].owner, &ast_null_frame);
00854             ast_mutex_unlock(&p->subs[a].owner->lock);
00855             break;
00856          }
00857       } else
00858          break;
00859    }
00860 #ifdef HAVE_PRI
00861    if (pri)
00862       ast_mutex_lock(&pri->lock);
00863 #endif         
00864 }
00865 
00866 #ifdef HAVE_PRI
00867 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, struct zt_pri *pri)
00868 #else
00869 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *pri)
00870 #endif
00871 {
00872    /* We must unlock the PRI to avoid the possibility of a deadlock */
00873 #ifdef HAVE_PRI
00874    if (pri)
00875       ast_mutex_unlock(&pri->lock);
00876 #endif      
00877    for (;;) {
00878       if (p->owner) {
00879          if (ast_mutex_trylock(&p->owner->lock)) {
00880             DEADLOCK_AVOIDANCE(&p->lock);
00881          } else {
00882             ast_queue_frame(p->owner, f);
00883             ast_mutex_unlock(&p->owner->lock);
00884             break;
00885          }
00886       } else
00887          break;
00888    }
00889 #ifdef HAVE_PRI
00890    if (pri)
00891       ast_mutex_lock(&pri->lock);
00892 #endif      
00893 }
00894 
00895 static int restore_gains(struct zt_pvt *p);
00896 
00897 static void swap_subs(struct zt_pvt *p, int a, int b)
00898 {
00899    int tchan;
00900    int tinthreeway;
00901    struct ast_channel *towner;
00902 
00903    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
00904 
00905    tchan = p->subs[a].chan;
00906    towner = p->subs[a].owner;
00907    tinthreeway = p->subs[a].inthreeway;
00908 
00909    p->subs[a].chan = p->subs[b].chan;
00910    p->subs[a].owner = p->subs[b].owner;
00911    p->subs[a].inthreeway = p->subs[b].inthreeway;
00912 
00913    p->subs[b].chan = tchan;
00914    p->subs[b].owner = towner;
00915    p->subs[b].inthreeway = tinthreeway;
00916 
00917    if (p->subs[a].owner) 
00918       p->subs[a].owner->fds[0] = p->subs[a].zfd;
00919    if (p->subs[b].owner) 
00920       p->subs[b].owner->fds[0] = p->subs[b].zfd;
00921    wakeup_sub(p, a, NULL);
00922    wakeup_sub(p, b, NULL);
00923 }
00924 
00925 static int zt_open(char *fn)
00926 {
00927    int fd;
00928    int isnum;
00929    int chan = 0;
00930    int bs;
00931    int x;
00932    isnum = 1;
00933    for (x = 0; x < strlen(fn); x++) {
00934       if (!isdigit(fn[x])) {
00935          isnum = 0;
00936          break;
00937       }
00938    }
00939    if (isnum) {
00940       chan = atoi(fn);
00941       if (chan < 1) {
00942          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
00943          return -1;
00944       }
00945       fn = "/dev/zap/channel";
00946    }
00947    fd = open(fn, O_RDWR | O_NONBLOCK);
00948    if (fd < 0) {
00949       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
00950       return -1;
00951    }
00952    if (chan) {
00953       if (ioctl(fd, ZT_SPECIFY, &chan)) {
00954          x = errno;
00955          close(fd);
00956          errno = x;
00957          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
00958          return -1;
00959       }
00960    }
00961    bs = READ_SIZE;
00962    if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) {
00963       ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
00964       x = errno;
00965       close(fd);
00966       errno = x;
00967       return -1;
00968    }
00969    return fd;
00970 }
00971 
00972 static void zt_close(int fd)
00973 {
00974    if (fd > 0)
00975       close(fd);
00976 }
00977 
00978 static int zt_setlinear(int zfd, int linear)
00979 {
00980    int res;
00981    res = ioctl(zfd, ZT_SETLINEAR, &linear);
00982    if (res)
00983       return res;
00984    return 0;
00985 }
00986 
00987 
00988 static int alloc_sub(struct zt_pvt *p, int x)
00989 {
00990    ZT_BUFFERINFO bi;
00991    int res;
00992    if (p->subs[x].zfd < 0) {
00993       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
00994       if (p->subs[x].zfd > -1) {
00995          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
00996          if (!res) {
00997             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
00998             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
00999             bi.numbufs = numbufs;
01000             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
01001             if (res < 0) {
01002                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
01003             }
01004          } else 
01005             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
01006          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
01007             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd);
01008             zt_close(p->subs[x].zfd);
01009             p->subs[x].zfd = -1;
01010             return -1;
01011          }
01012          if (option_debug)
01013             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
01014          return 0;
01015       } else
01016          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
01017       return -1;
01018    }
01019    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
01020    return -1;
01021 }
01022 
01023 static int unalloc_sub(struct zt_pvt *p, int x)
01024 {
01025    if (!x) {
01026       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
01027       return -1;
01028    }
01029    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
01030    if (p->subs[x].zfd > -1) {
01031       zt_close(p->subs[x].zfd);
01032    }
01033    p->subs[x].zfd = -1;
01034    p->subs[x].linear = 0;
01035    p->subs[x].chan = 0;
01036    p->subs[x].owner = NULL;
01037    p->subs[x].inthreeway = 0;
01038    p->polarity = POLARITY_IDLE;
01039    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
01040    return 0;
01041 }
01042 
01043 static int digit_to_dtmfindex(char digit)
01044 {
01045    if (isdigit(digit))
01046       return ZT_TONE_DTMF_BASE + (digit - '0');
01047    else if (digit >= 'A' && digit <= 'D')
01048       return ZT_TONE_DTMF_A + (digit - 'A');
01049    else if (digit >= 'a' && digit <= 'd')
01050       return ZT_TONE_DTMF_A + (digit - 'a');
01051    else if (digit == '*')
01052       return ZT_TONE_DTMF_s;
01053    else if (digit == '#')
01054       return ZT_TONE_DTMF_p;
01055    else
01056       return -1;
01057 }
01058 
01059 static int zt_digit_begin(struct ast_channel *chan, char digit)
01060 {
01061    struct zt_pvt *pvt;
01062    int index;
01063    int dtmf = -1;
01064    
01065    pvt = chan->tech_pvt;
01066 
01067    ast_mutex_lock(&pvt->lock);
01068 
01069    index = zt_get_index(chan, pvt, 0);
01070 
01071    if ((index != SUB_REAL) || !pvt->owner)
01072       goto out;
01073 
01074 #ifdef HAVE_PRI
01075    if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
01076       if (pvt->setup_ack) {
01077          if (!pri_grab(pvt, pvt->pri)) {
01078             pri_information(pvt->pri->pri, pvt->call, digit);
01079             pri_rel(pvt->pri);
01080          } else
01081             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
01082       } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
01083          int res;
01084          ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
01085          res = strlen(pvt->dialdest);
01086          pvt->dialdest[res++] = digit;
01087          pvt->dialdest[res] = '\0';
01088       }
01089       goto out;
01090    }
01091 #endif
01092    if ((dtmf = digit_to_dtmfindex(digit)) == -1)
01093       goto out;
01094 
01095    if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) {
01096       int res;
01097       ZT_DIAL_OPERATION zo = {
01098          .op = ZT_DIAL_OP_APPEND,
01099          .dialstr[0] = 'T',
01100          .dialstr[1] = digit,
01101          .dialstr[2] = 0,
01102       };
01103       if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
01104          ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
01105       else
01106          pvt->dialing = 1;
01107    } else {
01108       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
01109       pvt->dialing = 1;
01110       pvt->begindigit = digit;
01111    }
01112 
01113 out:
01114    ast_mutex_unlock(&pvt->lock);
01115 
01116    return 0;
01117 }
01118 
01119 static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
01120 {
01121    struct zt_pvt *pvt;
01122    int res = 0;
01123    int index;
01124    int x;
01125    
01126    pvt = chan->tech_pvt;
01127 
01128    ast_mutex_lock(&pvt->lock);
01129    
01130    index = zt_get_index(chan, pvt, 0);
01131 
01132    if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)
01133       goto out;
01134 
01135 #ifdef HAVE_PRI
01136    /* This means that the digit was already sent via PRI signalling */
01137    if (pvt->sig == SIG_PRI && !pvt->begindigit)
01138       goto out;
01139 #endif
01140 
01141    if (pvt->begindigit) {
01142       x = -1;
01143       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
01144       res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x);
01145       pvt->dialing = 0;
01146       pvt->begindigit = 0;
01147    }
01148 
01149 out:
01150    ast_mutex_unlock(&pvt->lock);
01151 
01152    return res;
01153 }
01154 
01155 static char *events[] = {
01156    "No event",
01157    "On hook",
01158    "Ring/Answered",
01159    "Wink/Flash",
01160    "Alarm",
01161    "No more alarm",
01162    "HDLC Abort",
01163    "HDLC Overrun",
01164    "HDLC Bad FCS",
01165    "Dial Complete",
01166    "Ringer On",
01167    "Ringer Off",
01168    "Hook Transition Complete",
01169    "Bits Changed",
01170    "Pulse Start",
01171    "Timer Expired",
01172    "Timer Ping",
01173    "Polarity Reversal",
01174    "Ring Begin",
01175 };
01176 
01177 static struct {
01178    int alarm;
01179    char *name;
01180 } alarms[] = {
01181    { ZT_ALARM_RED, "Red Alarm" },
01182    { ZT_ALARM_YELLOW, "Yellow Alarm" },
01183    { ZT_ALARM_BLUE, "Blue Alarm" },
01184    { ZT_ALARM_RECOVER, "Recovering" },
01185    { ZT_ALARM_LOOPBACK, "Loopback" },
01186    { ZT_ALARM_NOTOPEN, "Not Open" },
01187    { ZT_ALARM_NONE, "None" },
01188 };
01189 
01190 static char *alarm2str(int alarm)
01191 {
01192    int x;
01193    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
01194       if (alarms[x].alarm & alarm)
01195          return alarms[x].name;
01196    }
01197    return alarm ? "Unknown Alarm" : "No Alarm";
01198 }
01199 
01200 static char *event2str(int event)
01201 {
01202    static char buf[256];
01203    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01204       return events[event];
01205    sprintf(buf, "Event %d", event); /* safe */
01206    return buf;
01207 }
01208 
01209 #ifdef HAVE_PRI
01210 static char *dialplan2str(int dialplan)
01211 {
01212    if (dialplan == -1) {
01213       return("Dynamically set dialplan in ISDN");
01214    }
01215    return (pri_plan2str(dialplan));
01216 }
01217 #endif
01218 
01219 static char *zap_sig2str(int sig)
01220 {
01221    static char buf[256];
01222    switch (sig) {
01223    case SIG_EM:
01224       return "E & M Immediate";
01225    case SIG_EMWINK:
01226       return "E & M Wink";
01227    case SIG_EM_E1:
01228       return "E & M E1";
01229    case SIG_FEATD:
01230       return "Feature Group D (DTMF)";
01231    case SIG_FEATDMF:
01232       return "Feature Group D (MF)";
01233    case SIG_FEATDMF_TA:
01234       return "Feature Groud D (MF) Tandem Access";
01235    case SIG_FEATB:
01236       return "Feature Group B (MF)";
01237    case SIG_E911:
01238       return "E911 (MF)";
01239    case SIG_FGC_CAMA:
01240       return "FGC/CAMA (Dialpulse)";
01241    case SIG_FGC_CAMAMF:
01242       return "FGC/CAMA (MF)";
01243    case SIG_FXSLS:
01244       return "FXS Loopstart";
01245    case SIG_FXSGS:
01246       return "FXS Groundstart";
01247    case SIG_FXSKS:
01248       return "FXS Kewlstart";
01249    case SIG_FXOLS:
01250       return "FXO Loopstart";
01251    case SIG_FXOGS:
01252       return "FXO Groundstart";
01253    case SIG_FXOKS:
01254       return "FXO Kewlstart";
01255    case SIG_PRI:
01256       return "ISDN PRI";
01257    case SIG_SF:
01258       return "SF (Tone) Immediate";
01259    case SIG_SFWINK:
01260       return "SF (Tone) Wink";
01261    case SIG_SF_FEATD:
01262       return "SF (Tone) with Feature Group D (DTMF)";
01263    case SIG_SF_FEATDMF:
01264       return "SF (Tone) with Feature Group D (MF)";
01265    case SIG_SF_FEATB:
01266       return "SF (Tone) with Feature Group B (MF)";
01267    case SIG_GR303FXOKS:
01268       return "GR-303 with FXOKS";
01269    case SIG_GR303FXSKS:
01270       return "GR-303 with FXSKS";
01271    case SIG_GSM:
01272       return "GSM";
01273    case 0:
01274       return "Pseudo";
01275    default:
01276       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
01277       return buf;
01278    }
01279 }
01280 
01281 #define sig2str zap_sig2str
01282 
01283 static int conf_add(struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
01284 {
01285    /* If the conference already exists, and we're already in it
01286       don't bother doing anything */
01287    ZT_CONFINFO zi;
01288    
01289    memset(&zi, 0, sizeof(zi));
01290    zi.chan = 0;
01291 
01292    if (slavechannel > 0) {
01293       /* If we have only one slave, do a digital mon */
01294       zi.confmode = ZT_CONF_DIGITALMON;
01295       zi.confno = slavechannel;
01296    } else {
01297       if (!index) {
01298          /* Real-side and pseudo-side both participate in conference */
01299          zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
01300             ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
01301       } else
01302          zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
01303       zi.confno = p->confno;
01304    }
01305    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01306       return 0;
01307    if (c->zfd < 0)
01308       return 0;
01309    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01310       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
01311       return -1;
01312    }
01313    if (slavechannel < 1) {
01314       p->confno = zi.confno;
01315    }
01316    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01317    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01318    return 0;
01319 }
01320 
01321 static int isourconf(struct zt_pvt *p, struct zt_subchannel *c)
01322 {
01323    /* If they're listening to our channel, they're ours */  
01324    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01325       return 1;
01326    /* If they're a talker on our (allocated) conference, they're ours */
01327    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01328       return 1;
01329    return 0;
01330 }
01331 
01332 static int conf_del(struct zt_pvt *p, struct zt_subchannel *c, int index)
01333 {
01334    ZT_CONFINFO zi;
01335    if (/* Can't delete if there's no zfd */
01336       (c->zfd < 0) ||
01337       /* Don't delete from the conference if it's not our conference */
01338       !isourconf(p, c)
01339       /* Don't delete if we don't think it's conferenced at all (implied) */
01340       ) return 0;
01341    memset(&zi, 0, sizeof(zi));
01342    zi.chan = 0;
01343    zi.confno = 0;
01344    zi.confmode = 0;
01345    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01346       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01347       return -1;
01348    }
01349    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01350    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01351    return 0;
01352 }
01353 
01354 static int isslavenative(struct zt_pvt *p, struct zt_pvt **out)
01355 {
01356    int x;
01357    int useslavenative;
01358    struct zt_pvt *slave = NULL;
01359    /* Start out optimistic */
01360    useslavenative = 1;
01361    /* Update conference state in a stateless fashion */
01362    for (x = 0; x < 3; x++) {
01363       /* Any three-way calling makes slave native mode *definitely* out
01364          of the question */
01365       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
01366          useslavenative = 0;
01367    }
01368    /* If we don't have any 3-way calls, check to see if we have
01369       precisely one slave */
01370    if (useslavenative) {
01371       for (x = 0; x < MAX_SLAVES; x++) {
01372          if (p->slaves[x]) {
01373             if (slave) {
01374                /* Whoops already have a slave!  No 
01375                   slave native and stop right away */
01376                slave = NULL;
01377                useslavenative = 0;
01378                break;
01379             } else {
01380                /* We have one slave so far */
01381                slave = p->slaves[x];
01382             }
01383          }
01384       }
01385    }
01386    /* If no slave, slave native definitely out */
01387    if (!slave)
01388       useslavenative = 0;
01389    else if (slave->law != p->law) {
01390       useslavenative = 0;
01391       slave = NULL;
01392    }
01393    if (out)
01394       *out = slave;
01395    return useslavenative;
01396 }
01397 
01398 static int reset_conf(struct zt_pvt *p)
01399 {
01400    ZT_CONFINFO zi;
01401    memset(&zi, 0, sizeof(zi));
01402    p->confno = -1;
01403    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01404    if (p->subs[SUB_REAL].zfd > -1) {
01405       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
01406          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
01407    }
01408    return 0;
01409 }
01410 
01411 static int update_conf(struct zt_pvt *p)
01412 {
01413    int needconf = 0;
01414    int x;
01415    int useslavenative;
01416    struct zt_pvt *slave = NULL;
01417 
01418    useslavenative = isslavenative(p, &slave);
01419    /* Start with the obvious, general stuff */
01420    for (x = 0; x < 3; x++) {
01421       /* Look for three way calls */
01422       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
01423          conf_add(p, &p->subs[x], x, 0);
01424          needconf++;
01425       } else {
01426          conf_del(p, &p->subs[x], x);
01427       }
01428    }
01429    /* If we have a slave, add him to our conference now. or DAX
01430       if this is slave native */
01431    for (x = 0; x < MAX_SLAVES; x++) {
01432       if (p->slaves[x]) {
01433          if (useslavenative)
01434             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
01435          else {
01436             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
01437             needconf++;
01438          }
01439       }
01440    }
01441    /* If we're supposed to be in there, do so now */
01442    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
01443       if (useslavenative)
01444          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
01445       else {
01446          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
01447          needconf++;
01448       }
01449    }
01450    /* If we have a master, add ourselves to his conference */
01451    if (p->master) {
01452       if (isslavenative(p->master, NULL)) {
01453          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
01454       } else {
01455          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
01456       }
01457    }
01458    if (!needconf) {
01459       /* Nobody is left (or should be left) in our conference.
01460          Kill it. */
01461       p->confno = -1;
01462    }
01463    if (option_debug)
01464       ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
01465    return 0;
01466 }
01467 
01468 static void zt_enable_ec(struct zt_pvt *p)
01469 {
01470    int x;
01471    int res;
01472    if (!p)
01473       return;
01474    if (p->faxhandled)  {
01475       ast_log(LOG_DEBUG, "Not enabling echo cancellation on a fax/modem call\n");
01476       return;
01477    }
01478    if (p->echocanon) {
01479       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01480       return;
01481    }
01482    if (p->digital) {
01483       ast_log(LOG_DEBUG, "Echo cancellation does not make any sense on digital connections!\n");
01484       return;
01485    }
01486    if (p->echocancel) {
01487       if (p->sig == SIG_PRI) {
01488          x = 1;
01489          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
01490          if (res)
01491             ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
01492       }
01493       x = p->echocancel;
01494       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01495       if (res) 
01496          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
01497       else {
01498          p->echocanon = 1;
01499          if (option_debug)
01500             ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01501       }
01502    } else if (option_debug)
01503       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01504 }
01505 
01506 static void zt_train_ec(struct zt_pvt *p)
01507 {
01508    int x;
01509    int res;
01510    if (p && p->echocancel && p->echotraining && (!p->digital) && (!p->faxhandled)) {
01511       x = p->echotraining;
01512       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01513       if (res)
01514          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01515       else {
01516          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01517       }
01518    } else
01519       ast_log(LOG_DEBUG, "No echo training requested\n");
01520 }
01521 
01522 static void zt_disable_ec(struct zt_pvt *p)
01523 {
01524    int x;
01525    int res;
01526    if (p->echocancel) {
01527       x = 0;
01528       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01529       if (res)
01530          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01531       else if (option_debug)
01532          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01533    }
01534    p->echocanon = 0;
01535 }
01536 
01537 static void fill_txgain(struct zt_gains *g, float gain, int law)
01538 {
01539    int j;
01540    int k;
01541    float linear_gain = pow(10.0, gain / 20.0);
01542 
01543    switch (law) {
01544    case ZT_LAW_ALAW:
01545       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01546          if (gain) {
01547             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01548             if (k > 32767) k = 32767;
01549             if (k < -32767) k = -32767;
01550             g->txgain[j] = AST_LIN2A(k);
01551          } else {
01552             g->txgain[j] = j;
01553          }
01554       }
01555       break;
01556    case ZT_LAW_MULAW:
01557       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01558          if (gain) {
01559             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01560             if (k > 32767) k = 32767;
01561             if (k < -32767) k = -32767;
01562             g->txgain[j] = AST_LIN2MU(k);
01563          } else {
01564             g->txgain[j] = j;
01565          }
01566       }
01567       break;
01568    }
01569 }
01570 
01571 static void fill_rxgain(struct zt_gains *g, float gain, int law)
01572 {
01573    int j;
01574    int k;
01575    float linear_gain = pow(10.0, gain / 20.0);
01576 
01577    switch (law) {
01578    case ZT_LAW_ALAW:
01579       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01580          if (gain) {
01581             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01582             if (k > 32767) k = 32767;
01583             if (k < -32767) k = -32767;
01584             g->rxgain[j] = AST_LIN2A(k);
01585          } else {
01586             g->rxgain[j] = j;
01587          }
01588       }
01589       break;
01590    case ZT_LAW_MULAW:
01591       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01592          if (gain) {
01593             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01594             if (k > 32767) k = 32767;
01595             if (k < -32767) k = -32767;
01596             g->rxgain[j] = AST_LIN2MU(k);
01597          } else {
01598             g->rxgain[j] = j;
01599          }
01600       }
01601       break;
01602    }
01603 }
01604 
01605 static int set_actual_txgain(int fd, int chan, float gain, int law)
01606 {
01607    struct zt_gains g;
01608    int res;
01609 
01610    memset(&g, 0, sizeof(g));
01611    g.chan = chan;
01612    res = ioctl(fd, ZT_GETGAINS, &g);
01613    if (res) {
01614       if (option_debug)
01615          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01616       return res;
01617    }
01618 
01619    fill_txgain(&g, gain, law);
01620 
01621    return ioctl(fd, ZT_SETGAINS, &g);
01622 }
01623 
01624 static int set_actual_rxgain(int fd, int chan, float gain, int law)
01625 {
01626    struct zt_gains g;
01627    int res;
01628 
01629    memset(&g, 0, sizeof(g));
01630    g.chan = chan;
01631    res = ioctl(fd, ZT_GETGAINS, &g);
01632    if (res) {
01633       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01634       return res;
01635    }
01636 
01637    fill_rxgain(&g, gain, law);
01638 
01639    return ioctl(fd, ZT_SETGAINS, &g);
01640 }
01641 
01642 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
01643 {
01644    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01645 }
01646 
01647 static int bump_gains(struct zt_pvt *p)
01648 {
01649    int res;
01650 
01651    /* Bump receive gain by 5.0db */
01652    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01653    if (res) {
01654       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01655       return -1;
01656    }
01657 
01658    return 0;
01659 }
01660 
01661 static int restore_gains(struct zt_pvt *p)
01662 {
01663    int res;
01664 
01665    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01666    if (res) {
01667       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01668       return -1;
01669    }
01670 
01671    return 0;
01672 }
01673 
01674 static inline int zt_set_hook(int fd, int hs)
01675 {
01676    int x, res;
01677 
01678    x = hs;
01679    res = ioctl(fd, ZT_HOOK, &x);
01680 
01681    if (res < 0) {
01682       if (errno == EINPROGRESS)
01683          return 0;
01684       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01685    }
01686 
01687    return res;
01688 }
01689 
01690 static inline int zt_confmute(struct zt_pvt *p, int muted)
01691 {
01692    int x, y, res;
01693    x = muted;
01694    if ((p->sig == SIG_PRI) || (p->sig == SIG_GSM)) {
01695       y = 1;
01696       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01697       if (res)
01698          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01699    }
01700    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01701    if (res < 0)
01702       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01703    return res;
01704 }
01705 
01706 static int save_conference(struct zt_pvt *p)
01707 {
01708    struct zt_confinfo c;
01709    int res;
01710    if (p->saveconf.confmode) {
01711       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01712       return -1;
01713    }
01714    p->saveconf.chan = 0;
01715    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01716    if (res) {
01717       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01718       p->saveconf.confmode = 0;
01719       return -1;
01720    }
01721    c.chan = 0;
01722    c.confno = 0;
01723    c.confmode = ZT_CONF_NORMAL;
01724    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01725    if (res) {
01726       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01727       return -1;
01728    }
01729    if (option_debug)
01730       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01731    return 0;
01732 }
01733 
01734 static int restore_conference(struct zt_pvt *p)
01735 {
01736    int res;
01737    if (p->saveconf.confmode) {
01738       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01739       p->saveconf.confmode = 0;
01740       if (res) {
01741          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01742          return -1;
01743       }
01744    }
01745    if (option_debug)
01746       ast_log(LOG_DEBUG, "Restored conferencing\n");
01747    return 0;
01748 }
01749 
01750 static int send_callerid(struct zt_pvt *p);
01751 
01752 static int send_cwcidspill(struct zt_pvt *p)
01753 {
01754    p->callwaitcas = 0;
01755    p->cidcwexpire = 0;
01756    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
01757       return -1;
01758    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01759    /* Make sure we account for the end */
01760    p->cidlen += READ_SIZE * 4;
01761    p->cidpos = 0;
01762    send_callerid(p);
01763    if (option_verbose > 2)
01764       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01765    return 0;
01766 }
01767 
01768 static int has_voicemail(struct zt_pvt *p)
01769 {
01770 
01771    return ast_app_has_voicemail(p->mailbox, NULL);
01772 }
01773 
01774 static int send_callerid(struct zt_pvt *p)
01775 {
01776    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
01777    int res;
01778    /* Take out of linear mode if necessary */
01779    if (p->subs[SUB_REAL].linear) {
01780       p->subs[SUB_REAL].linear = 0;
01781       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
01782    }
01783    while (p->cidpos < p->cidlen) {
01784       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
01785       if (res < 0) {
01786          if (errno == EAGAIN)
01787             return 0;
01788          else {
01789             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
01790             return -1;
01791          }
01792       }
01793       if (!res)
01794          return 0;
01795       p->cidpos += res;
01796    }
01797    free(p->cidspill);
01798    p->cidspill = NULL;
01799    if (p->callwaitcas) {
01800       /* Wait for CID/CW to expire */
01801       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
01802    } else
01803       restore_conference(p);
01804    return 0;
01805 }
01806 
01807 static int zt_callwait(struct ast_channel *ast)
01808 {
01809    struct zt_pvt *p = ast->tech_pvt;
01810    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
01811    if (p->cidspill) {
01812       ast_log(LOG_WARNING, "Spill already exists?!?\n");
01813       free(p->cidspill);
01814    }
01815    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
01816       return -1;
01817    save_conference(p);
01818    /* Silence */
01819    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
01820    if (!p->callwaitrings && p->callwaitingcallerid) {
01821       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
01822       p->callwaitcas = 1;
01823       p->cidlen = 2400 + 680 + READ_SIZE * 4;
01824    } else {
01825       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
01826       p->callwaitcas = 0;
01827       p->cidlen = 2400 + READ_SIZE * 4;
01828    }
01829    p->cidpos = 0;
01830    send_callerid(p);
01831    
01832    return 0;
01833 }
01834 
01835 static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
01836 {
01837    struct zt_pvt *p = ast->tech_pvt;
01838    int x, res, index,mysig;
01839    char *c, *n, *l;
01840 #ifdef HAVE_PRI
01841    char *s = NULL;
01842 #endif
01843    char dest[256]; /* must be same length as p->dialdest */
01844    ast_mutex_lock(&p->lock);
01845    ast_copy_string(dest, rdest, sizeof(dest));
01846    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01847    if ((ast->_state == AST_STATE_BUSY)) {
01848       p->subs[SUB_REAL].needbusy = 1;
01849       ast_mutex_unlock(&p->lock);
01850       return 0;
01851    }
01852    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01853       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
01854       ast_mutex_unlock(&p->lock);
01855       return -1;
01856    }
01857    p->dialednone = 0;
01858    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
01859    {
01860       /* Special pseudo -- automatically up */
01861       ast_setstate(ast, AST_STATE_UP); 
01862       ast_mutex_unlock(&p->lock);
01863       return 0;
01864    }
01865    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
01866    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
01867    if (res)
01868       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
01869    p->outgoing = 1;
01870 
01871    if (IS_DIGITAL(ast->transfercapability)) {
01872        set_actual_gain(p->subs[SUB_REAL].zfd, 0, 0, 0, p->law);
01873    } else {
01874        set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01875    }
01876 
01877 
01878    mysig = p->sig;
01879    if (p->outsigmod > -1)
01880       mysig = p->outsigmod;
01881 
01882    switch (mysig) {
01883    case SIG_FXOLS:
01884    case SIG_FXOGS:
01885    case SIG_FXOKS:
01886       if (p->owner == ast) {
01887          /* Normal ring, on hook */
01888          
01889          /* Don't send audio while on hook, until the call is answered */
01890          p->dialing = 1;
01891          if (p->use_callerid) {
01892             /* Generate the Caller-ID spill if desired */
01893             if (p->cidspill) {
01894                ast_log(LOG_WARNING, "cidspill already exists??\n");
01895                free(p->cidspill);
01896             }
01897             p->callwaitcas = 0;
01898             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
01899                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
01900                p->cidpos = 0;
01901                send_callerid(p);
01902             }
01903          }
01904          /* Choose proper cadence */
01905          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
01906             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1]))
01907                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
01908             p->cidrings = cidrings[p->distinctivering - 1];
01909          } else {
01910             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
01911                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
01912             p->cidrings = p->sendcalleridafter;
01913          }
01914 
01915          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
01916          c = strchr(dest, '/');
01917          if (c)
01918             c++;
01919          if (c && (strlen(c) < p->stripmsd)) {
01920             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01921             c = NULL;
01922          }
01923          if (c) {
01924             p->dop.op = ZT_DIAL_OP_REPLACE;
01925             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
01926             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
01927          } else {
01928             p->dop.dialstr[0] = '\0';
01929          }
01930          x = ZT_RING;
01931          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
01932             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
01933             ast_mutex_unlock(&p->lock);
01934             return -1;
01935          }
01936          p->dialing = 1;
01937       } else {
01938          /* Call waiting call */
01939          p->callwaitrings = 0;
01940          if (ast->cid.cid_num)
01941             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
01942          else
01943             p->callwait_num[0] = '\0';
01944          if (ast->cid.cid_name)
01945             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
01946          else
01947             p->callwait_name[0] = '\0';
01948          /* Call waiting tone instead */
01949          if (zt_callwait(ast)) {
01950             ast_mutex_unlock(&p->lock);
01951             return -1;
01952          }
01953          /* Make ring-back */
01954          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
01955             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
01956             
01957       }
01958       n = ast->cid.cid_name;
01959       l = ast->cid.cid_num;
01960       if (l)
01961          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
01962       else
01963          p->lastcid_num[0] = '\0';
01964       if (n)
01965          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
01966       else
01967          p->lastcid_name[0] = '\0';
01968       ast_setstate(ast, AST_STATE_RINGING);
01969       index = zt_get_index(ast, p, 0);
01970       if (index > -1) {
01971          p->subs[index].needringing = 1;
01972       }
01973       break;
01974    case SIG_FXSLS:
01975    case SIG_FXSGS:
01976    case SIG_FXSKS:
01977    case SIG_EMWINK:
01978    case SIG_EM:
01979    case SIG_EM_E1:
01980    case SIG_FEATD:
01981    case SIG_FEATDMF:
01982    case SIG_E911:
01983    case SIG_FGC_CAMA:
01984    case SIG_FGC_CAMAMF:
01985    case SIG_FEATB:
01986    case SIG_SFWINK:
01987    case SIG_SF:
01988    case SIG_SF_FEATD:
01989    case SIG_SF_FEATDMF:
01990    case SIG_FEATDMF_TA:
01991    case SIG_SF_FEATB:
01992       c = strchr(dest, '/');
01993       if (c)
01994          c++;
01995       else
01996          c = "";
01997       if (strlen(c) < p->stripmsd) {
01998          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01999          ast_mutex_unlock(&p->lock);
02000          return -1;
02001       }
02002 #ifdef HAVE_PRI
02003       /* Start the trunk, if not GR-303 */
02004       if (!p->pri) {
02005 #endif
02006          x = ZT_START;
02007          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02008          if (res < 0) {
02009             if (errno != EINPROGRESS) {
02010                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
02011                ast_mutex_unlock(&p->lock);
02012                return -1;
02013             }
02014          }
02015 #ifdef HAVE_PRI
02016       }
02017 #endif
02018       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
02019       p->dop.op = ZT_DIAL_OP_REPLACE;
02020 
02021       c += p->stripmsd;
02022 
02023       switch (mysig) {
02024       case SIG_FEATD:
02025          l = ast->cid.cid_num;
02026          if (l) 
02027             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
02028          else
02029             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
02030          break;
02031       case SIG_FEATDMF:
02032          l = ast->cid.cid_num;
02033          if (l) 
02034             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
02035          else
02036             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
02037          break;
02038       case SIG_FEATDMF_TA:
02039       {
02040          const char *cic, *ozz;
02041 
02042          /* If you have to go through a Tandem Access point you need to use this */
02043          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
02044          if (!ozz)
02045             ozz = defaultozz;
02046          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
02047          if (!cic)
02048             cic = defaultcic;
02049          if (!ozz || !cic) {
02050             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
02051             ast_mutex_unlock(&p->lock);
02052             return -1;
02053          }
02054          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
02055          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
02056          p->whichwink = 0;
02057       }
02058          break;
02059       case SIG_E911:
02060          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
02061          break;
02062       case SIG_FGC_CAMA:
02063          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
02064          break;
02065       case SIG_FGC_CAMAMF:
02066       case SIG_FEATB:
02067          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
02068          break;
02069       default:
02070          if (p->pulse)
02071             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
02072          else
02073             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
02074          break;
02075       }
02076 
02077       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
02078          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02079          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02080          p->echorest[sizeof(p->echorest) - 1] = '\0';
02081          p->echobreak = 1;
02082          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02083       } else
02084          p->echobreak = 0;
02085       if (!res) {
02086          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
02087             x = ZT_ONHOOK;
02088             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02089             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
02090             ast_mutex_unlock(&p->lock);
02091             return -1;
02092          }
02093       } else
02094          ast_log(LOG_DEBUG, "Deferring dialing...\n");
02095       p->dialing = 1;
02096       if (ast_strlen_zero(c))
02097          p->dialednone = 1;
02098       ast_setstate(ast, AST_STATE_DIALING);
02099       break;
02100    case 0:
02101       /* Special pseudo -- automatically up*/
02102       ast_setstate(ast, AST_STATE_UP);
02103       break;      
02104    case SIG_PRI:
02105       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02106       p->dialdest[0] = '\0';
02107       disable_dtmf_detect(p);
02108       break;
02109    case SIG_GSM:
02110 #ifdef HAVE_GSMAT
02111       if (p->gsm.modul) {
02112           c = strchr(dest, '/');
02113           if (c)
02114          c++;
02115           else
02116          c = dest;
02117           ast_mutex_lock(&p->gsm.lock);
02118           if (gsm_dial(p->gsm.modul, p->use_callingpres ? ast->cid.cid_pres : 0, c)) {
02119          ast_log(LOG_WARNING, "dialing failed on channel %d\n", p->channel);
02120          ast_mutex_unlock(&p->gsm.lock);
02121          ast_mutex_unlock(&p->lock);
02122          return -1;
02123           }
02124           ast_mutex_unlock(&p->gsm.lock);
02125       }
02126 #endif
02127       break;
02128    default:
02129       ast_log(LOG_DEBUG, "not yet implemented\n");
02130       ast_mutex_unlock(&p->lock);
02131       return -1;
02132    }
02133 #ifdef HAVE_PRI
02134    if (p->pri) {
02135       struct pri_sr *sr;
02136 #ifdef SUPPORT_USERUSER
02137       const char *useruser;
02138 #endif
02139       int pridialplan;
02140       int dp_strip;
02141       int prilocaldialplan;
02142       int ldp_strip;
02143       int exclusive;
02144       const char *rr_str;
02145       int redirect_reason;
02146 
02147       if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) {
02148           // pass NO audio when ringing an isdn phone
02149           p->dialing = 1;
02150           // maybe we could allow passing audio when calling a p2p PBX, but well... ;-)
02151       }
02152 
02153       c = strchr(dest, '/');
02154       if (c)
02155          c++;
02156       else
02157          c = dest;
02158 
02159       l = NULL;
02160       n = NULL;
02161 
02162       if (!p->hidecallerid) {
02163          l = ast->cid.cid_num;
02164          if (!p->hidecalleridname) {
02165             n = ast->cid.cid_name;
02166          }
02167       }
02168 
02169 
02170       if (strlen(c) < p->stripmsd) {
02171          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02172          ast_mutex_unlock(&p->lock);
02173          return -1;
02174       }
02175       strncpy(p->dnid, (c + p->stripmsd), sizeof(p->dnid)-1);
02176       if (mysig != SIG_FXSKS) {
02177          p->dop.op = ZT_DIAL_OP_REPLACE;
02178          s = strchr(c + p->stripmsd, 'w');
02179          if (s) {
02180             if (strlen(s) > 1)
02181                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02182             else
02183                p->dop.dialstr[0] = '\0';
02184             *s = '\0';
02185          } else {
02186             p->dop.dialstr[0] = '\0';
02187          }
02188       }
02189       if (pri_grab(p, p->pri)) {
02190          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02191          ast_mutex_unlock(&p->lock);
02192          return -1;
02193       }
02194       if (!(p->call = pri_new_call(p->pri->pri))) {
02195          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02196          pri_rel(p->pri);
02197          ast_mutex_unlock(&p->lock);
02198          return -1;
02199       } else {
02200       // ast_log(LOG_NOTICE, "call %d\n", p->call);
02201       }
02202       if (!(sr = pri_sr_new())) {
02203          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02204          pri_destroycall(p->pri->pri, p->call);
02205          p->call = NULL;
02206          pri_rel(p->pri);
02207          ast_mutex_unlock(&p->lock);
02208          return -1;
02209       }
02210       if (p->bearer || (mysig == SIG_FXSKS)) {
02211          if (p->bearer) {
02212             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);
02213             p->bearer->call = p->call;
02214          } else
02215             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02216          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02217       }
02218       p->digital = IS_DIGITAL(ast->transfercapability);
02219       /* Add support for exclusive override */
02220       if (p->priexclusive)
02221          exclusive = 1;
02222       else {
02223       /* otherwise, traditional behavior */
02224          if (p->pri->nodetype == PRI_NETWORK)
02225             exclusive = 0;
02226          else
02227             exclusive = 1;
02228       }
02229       
02230       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02231       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02232                (p->digital ? -1 : 
02233                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)), ast->lowlayercompat);
02234       if (p->pri->facilityenable)
02235          pri_facility_enable(p->pri->pri);
02236 
02237       if (option_verbose > 2)
02238          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02239       dp_strip = 0;
02240       pridialplan = p->pri->dialplan - 1;
02241       if (pridialplan == -2) { /* compute dynamically */
02242          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02243             dp_strip = strlen(p->pri->internationalprefix);
02244             pridialplan = PRI_INTERNATIONAL_ISDN;
02245          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02246             dp_strip = strlen(p->pri->nationalprefix);
02247             pridialplan = PRI_NATIONAL_ISDN;
02248          } else {
02249             pridialplan = PRI_LOCAL_ISDN;
02250          }
02251       }
02252       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
02253 
02254       ldp_strip = 0;
02255       prilocaldialplan = p->pri->localdialplan - 1;
02256       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02257          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02258             ldp_strip = strlen(p->pri->internationalprefix);
02259             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02260          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02261             ldp_strip = strlen(p->pri->nationalprefix);
02262             prilocaldialplan = PRI_NATIONAL_ISDN;
02263          } else {
02264             prilocaldialplan = PRI_LOCAL_ISDN;
02265          }
02266       }
02267       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
02268          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02269       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
02270          if (!strcasecmp(rr_str, "UNKNOWN"))
02271             redirect_reason = 0;
02272          else if (!strcasecmp(rr_str, "BUSY"))
02273             redirect_reason = 1;
02274          else if (!strcasecmp(rr_str, "NO_REPLY"))
02275             redirect_reason = 2;
02276          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
02277             redirect_reason = 15;
02278          else
02279             redirect_reason = PRI_REDIR_UNCONDITIONAL;
02280       } else
02281          redirect_reason = PRI_REDIR_UNCONDITIONAL;
02282       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
02283 
02284 #ifdef SUPPORT_USERUSER
02285       /* User-user info */
02286       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02287 
02288       if (useruser)
02289          pri_sr_set_useruser(sr, useruser);
02290 #endif
02291 
02292       if (pri_setup(p->pri->pri, p->call, sr)) {
02293          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02294             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02295          pri_rel(p->pri);
02296          ast_mutex_unlock(&p->lock);
02297          pri_sr_free(sr);
02298          return -1;
02299       }
02300       pri_sr_free(sr);
02301       ast_setstate(ast, AST_STATE_DIALING);
02302       pri_rel(p->pri);
02303    }
02304 #endif      
02305    ast_mutex_unlock(&p->lock);
02306    return 0;
02307 }
02308 
02309 static void destroy_zt_pvt(struct zt_pvt **pvt)
02310 {
02311    struct zt_pvt *p = *pvt;
02312    /* Remove channel from the list */
02313    if (p->prev)
02314       p->prev->next = p->next;
02315    if (p->next)
02316       p->next->prev = p->prev;
02317    if (p->use_smdi)
02318       ast_smdi_interface_unref(p->smdi_iface);
02319    ast_mutex_destroy(&p->lock);
02320    free(p);
02321    *pvt = NULL;
02322 }
02323 
02324 static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
02325 {
02326    int owned = 0;
02327    int i = 0;
02328 
02329    if (!now) {
02330       if (cur->owner) {
02331          owned = 1;
02332       }
02333 
02334       for (i = 0; i < 3; i++) {
02335          if (cur->subs[i].owner) {
02336             owned = 1;
02337          }
02338       }
02339       if (!owned) {
02340          if (prev) {
02341             prev->next = cur->next;
02342             if (prev->next)
02343                prev->next->prev = prev;
02344             else
02345                ifend = prev;
02346          } else {
02347             iflist = cur->next;
02348             if (iflist)
02349                iflist->prev = NULL;
02350             else
02351                ifend = NULL;
02352          }
02353          if (cur->subs[SUB_REAL].zfd > -1) {
02354             zt_close(cur->subs[SUB_REAL].zfd);
02355          }
02356          destroy_zt_pvt(&cur);
02357       }
02358    } else {
02359       if (prev) {
02360          prev->next = cur->next;
02361          if (prev->next)
02362             prev->next->prev = prev;
02363          else
02364             ifend = prev;
02365       } else {
02366          iflist = cur->next;
02367          if (iflist)
02368             iflist->prev = NULL;
02369          else
02370             ifend = NULL;
02371       }
02372       if (cur->subs[SUB_REAL].zfd > -1) {
02373          zt_close(cur->subs[SUB_REAL].zfd);
02374       }
02375       destroy_zt_pvt(&cur);
02376    }
02377    return 0;
02378 }
02379 
02380 #ifdef HAVE_PRI
02381 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
02382 
02383 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02384 
02385 static char *zap_send_keypad_facility_descrip = 
02386 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02387 "  IE over the current channel.\n";
02388 
02389 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02390 {
02391    /* Data will be our digit string */
02392    struct zt_pvt *p;
02393    char *digits = (char *) data;
02394 
02395    if (ast_strlen_zero(digits)) {
02396       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
02397       return -1;
02398    }
02399 
02400    p = (struct zt_pvt *)chan->tech_pvt;
02401 
02402    if (!p) {
02403       ast_log(LOG_DEBUG, "Unable to find technology private\n");
02404       return -1;
02405    }
02406 
02407    ast_mutex_lock(&p->lock);
02408 
02409    if (!p->pri || !p->call) {
02410       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
02411       ast_mutex_unlock(&p->lock);
02412       return -1;
02413    }
02414 
02415    if (!pri_grab(p, p->pri)) {
02416       pri_keypad_facility(p->pri->pri, p->call, digits);
02417       pri_rel(p->pri);
02418    } else {
02419       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
02420       ast_mutex_unlock(&p->lock);
02421       return -1;
02422    }
02423 
02424    ast_mutex_unlock(&p->lock);
02425 
02426    return 0;
02427 }
02428 
02429 static int pri_is_up(struct zt_pri *pri)
02430 {
02431    int x;
02432    for (x = 0; x < NUM_DCHANS; x++) {
02433       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
02434          return 1;
02435    }
02436    return 0;
02437 }
02438 
02439 static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer)
02440 {
02441    bearer->owner = &inuse;
02442    bearer->realcall = crv;
02443    crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
02444    if (crv->subs[SUB_REAL].owner)
02445       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
02446    crv->bearer = bearer;
02447    crv->call = bearer->call;
02448    crv->pri = pri;
02449    return 0;
02450 }
02451 
02452 static char *pri_order(int level)
02453 {
02454    switch (level) {
02455    case 0:
02456       return "Primary";
02457    case 1:
02458       return "Secondary";
02459    case 2:
02460       return "Tertiary";
02461    case 3:
02462       return "Quaternary";
02463    default:
02464       return "<Unknown>";
02465    }     
02466 }
02467 
02468 /* Returns fd of the active dchan */
02469 static int pri_active_dchan_fd(struct zt_pri *pri)
02470 {
02471    int x = -1;
02472 
02473    for (x = 0; x < NUM_DCHANS; x++) {
02474       if ((pri->dchans[x] == pri->pri))
02475          break;
02476    }
02477 
02478    return pri->fds[x];
02479 }
02480 
02481 static int pri_find_dchan(struct zt_pri *pri)
02482 {
02483    int oldslot = -1;
02484    struct pri *old;
02485    int newslot = -1;
02486    int x;
02487    old = pri->pri;
02488    for (x = 0; x < NUM_DCHANS; x++) {
02489       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
02490          newslot = x;
02491       if (pri->dchans[x] == old) {
02492          oldslot = x;
02493       }
02494    }
02495    if (newslot < 0) {
02496       newslot = 0;
02497       if (pri->nodetype != BRI_CPE_PTMP) {
02498           ast_log(LOG_WARNING, "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
02499          pri->dchannels[newslot]);
02500       }
02501    }
02502    if (old && (oldslot != newslot))
02503       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
02504          pri->dchannels[oldslot], pri->dchannels[newslot]);
02505    pri->pri = pri->dchans[newslot];
02506    return 0;
02507 }
02508 #endif
02509 
02510 static int zt_setlaw(int zfd, int law)
02511 {
02512    int res;
02513    res = ioctl(zfd, ZT_SETLAW, &law);
02514    if (res)
02515       return res;
02516    return 0;
02517 }
02518 
02519 
02520 static int zt_hangup(struct ast_channel *ast)
02521 {
02522    int res;
02523    int index,x, law;
02524    /*static int restore_gains(struct zt_pvt *p);*/
02525    struct zt_pvt *p = ast->tech_pvt;
02526    struct zt_pvt *tmp = NULL;
02527    struct zt_pvt *prev = NULL;
02528    ZT_PARAMS par;
02529 
02530    if (option_debug)
02531       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
02532    if (!ast->tech_pvt) {
02533       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02534       return 0;
02535    }
02536    
02537    ast_mutex_lock(&p->lock);
02538    
02539    index = zt_get_index(ast, p, 1);
02540 
02541    if (p->sig == SIG_PRI) {
02542       x = 1;
02543       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02544    }
02545 
02546    x = 0;
02547    zt_confmute(p, 0);
02548    restore_gains(p);
02549    if (p->origcid_num) {
02550       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02551       free(p->origcid_num);
02552       p->origcid_num = NULL;
02553    }  
02554    if (p->origcid_name) {
02555       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02556       free(p->origcid_name);
02557       p->origcid_name = NULL;
02558    }  
02559    if (p->dsp)
02560       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02561    if (p->exten)
02562       p->exten[0] = '\0';
02563 
02564    if (option_debug)
02565       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02566       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
02567 
02568    if (index > -1) {
02569       /* Real channel, do some fixup */
02570       p->subs[index].owner = NULL;
02571       p->subs[index].needanswer = 0;
02572       p->subs[index].needflash = 0;
02573       p->subs[index].needringing = 0;
02574       p->subs[index].needbusy = 0;
02575       p->subs[index].needcongestion = 0;
02576       p->subs[index].linear = 0;
02577       p->subs[index].needcallerid = 0;
02578       p->polarity = POLARITY_IDLE;
02579       zt_setlinear(p->subs[index].zfd, 0);
02580       if (index == SUB_REAL) {
02581          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
02582             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02583             if (p->subs[SUB_CALLWAIT].inthreeway) {
02584                /* We had flipped over to answer a callwait and now it's gone */
02585                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02586                /* Move to the call-wait, but un-own us until they flip back. */
02587                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02588                unalloc_sub(p, SUB_CALLWAIT);
02589                p->owner = NULL;
02590             } else {
02591                /* The three way hung up, but we still have a call wait */
02592                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02593                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02594                unalloc_sub(p, SUB_THREEWAY);
02595                if (p->subs[SUB_REAL].inthreeway) {
02596                   /* This was part of a three way call.  Immediately make way for
02597                      another call */
02598                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02599                   p->owner = p->subs[SUB_REAL].owner;
02600                } else {
02601                   /* This call hasn't been completed yet...  Set owner to NULL */
02602                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02603                   p->owner = NULL;
02604                }
02605                p->subs[SUB_REAL].inthreeway = 0;
02606             }
02607          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
02608             /* Move to the call-wait and switch back to them. */
02609             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02610             unalloc_sub(p, SUB_CALLWAIT);
02611             p->owner = p->subs[SUB_REAL].owner;
02612             if (p->owner->_state != AST_STATE_UP)
02613                p->subs[SUB_REAL].needanswer = 1;
02614             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
02615                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
02616          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
02617             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02618             unalloc_sub(p, SUB_THREEWAY);
02619             if (p->subs[SUB_REAL].inthreeway) {
02620                /* This was part of a three way call.  Immediately make way for
02621                   another call */
02622                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02623                p->owner = p->subs[SUB_REAL].owner;
02624             } else {
02625                /* This call hasn't been completed yet...  Set owner to NULL */
02626                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02627                p->owner = NULL;
02628             }
02629             p->subs[SUB_REAL].inthreeway = 0;
02630          }
02631       } else if (index == SUB_CALLWAIT) {
02632          /* Ditch the holding callwait call, and immediately make it availabe */
02633          if (p->subs[SUB_CALLWAIT].inthreeway) {
02634             /* This is actually part of a three way, placed on hold.  Place the third part
02635                on music on hold now */
02636             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
02637                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
02638                   S_OR(p->mohsuggest, NULL),
02639                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02640             }
02641             p->subs[SUB_THREEWAY].inthreeway = 0;
02642             /* Make it the call wait now */
02643             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
02644             unalloc_sub(p, SUB_THREEWAY);
02645          } else
02646             unalloc_sub(p, SUB_CALLWAIT);
02647       } else if (index == SUB_THREEWAY) {
02648          if (p->subs[SUB_CALLWAIT].inthreeway) {
02649             /* The other party of the three way call is currently in a call-wait state.
02650                Start music on hold for them, and take the main guy out of the third call */
02651             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
02652                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
02653                   S_OR(p->mohsuggest, NULL),
02654                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02655             }
02656             p->subs[SUB_CALLWAIT].inthreeway = 0;
02657          }
02658          p->subs[SUB_REAL].inthreeway = 0;
02659          /* If this was part of a three way call index, let us make
02660             another three way call */
02661          unalloc_sub(p, SUB_THREEWAY);
02662       } else {
02663          /* This wasn't any sort of call, but how are we an index? */
02664          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
02665       }
02666    }
02667 
02668    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
02669       int outgoing = p->outgoing;
02670       p->owner = NULL;
02671       p->ringt = 0;
02672       p->distinctivering = 0;
02673       p->confirmanswer = 0;
02674       p->cidrings = 1;
02675       p->outgoing = 0;
02676       p->digital = 0;
02677       p->faxhandled = 0;
02678       p->pulsedial = 0;
02679       p->onhooktime = time(NULL);
02680 #ifdef HAVE_PRI
02681       p->proceeding = 0;
02682       p->progress = 0;
02683       p->alerting = 0;
02684       p->setup_ack = 0;
02685 #endif      
02686       if (p->dsp) {
02687          ast_dsp_free(p->dsp);
02688          p->dsp = NULL;
02689       }
02690 
02691       law = ZT_LAW_DEFAULT;
02692       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
02693       if (res < 0) 
02694          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
02695       /* Perform low level hangup if no owner left */
02696 #ifdef HAVE_PRI
02697       if (p->pri) {
02698 #ifdef SUPPORT_USERUSER
02699          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
02700 #endif
02701 
02702          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
02703          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
02704             if (!pri_grab(p, p->pri)) {
02705                if (p->alreadyhungup) {
02706                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
02707 
02708 #ifdef SUPPORT_USERUSER
02709                   pri_call_set_useruser(p->call, useruser);
02710 #endif
02711 
02712                   pri_hangup(p->pri->pri, p->call, -1, -1);
02713                   p->call = NULL;
02714                   if (p->bearer) 
02715                      p->bearer->call = NULL;
02716                } else {
02717                   const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
02718                   int icause = ast->hangupcause ? ast->hangupcause : -1;
02719                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
02720 
02721 #ifdef SUPPORT_USERUSER
02722                   pri_call_set_useruser(p->call, useruser);
02723 #endif
02724 
02725                   p->alreadyhungup = 1;
02726                   if (p->bearer)
02727                      p->bearer->alreadyhungup = 1;
02728                   if (cause) {
02729                      if (atoi(cause))
02730                         icause = atoi(cause);
02731                   }
02732 
02733                   pri_hangup(p->pri->pri, p->call, icause, -1);
02734 
02735                   /* if we send a rel9999ease complete we wont ge no hangup event, so clear the call here */
02736                   if (icause == 34 || icause == 44 || icause == 82 || icause == 1 || icause == 81 || icause == 17) {
02737                       if ((ast->_state == AST_STATE_RING) || (ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING) || (ast->_state == AST_STATE_RESERVED)) {
02738                      p->call = NULL;
02739                       } else {
02740                      ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state);
02741                      icause = 16; /* Note, in pri_hangup() libpri will already override the cause */
02742                       }
02743                   }
02744 
02745                   if (p->pri->nodetype == BRI_NETWORK_PTMP) {
02746                       if ((icause == 16 || icause == -1) && (ast->_state != AST_STATE_UP)) {
02747                      if (outgoing) {
02748                          p->call = NULL;
02749                      }
02750                       }
02751                   }
02752 
02753 
02754                }
02755                if (res < 0) 
02756                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
02757                pri_rel(p->pri);        
02758             } else {
02759                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02760                res = -1;
02761             }
02762          } else {
02763             if (p->bearer)
02764                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
02765             p->call = NULL;
02766             res = 0;
02767          }
02768       }
02769 #endif
02770 #ifdef HAVE_GSMAT
02771       if (p->gsm.modul) {
02772           if (!p->alreadyhungup)
02773          gsm_hangup(p->gsm.modul);
02774       }
02775 #endif
02776       if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_GSM))
02777          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
02778       if (res < 0) {
02779          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
02780       }
02781       switch (p->sig) {
02782       case SIG_FXOGS:
02783       case SIG_FXOLS:
02784       case SIG_FXOKS:
02785          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
02786          if (!res) {
02787 #if 0
02788             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
02789 #endif
02790             /* If they're off hook, try playing congestion */
02791             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
02792                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
02793             else
02794                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02795          }
02796          break;
02797       case SIG_FXSGS:
02798       case SIG_FXSLS:
02799       case SIG_FXSKS:
02800          /* Make sure we're not made available for at least two seconds assuming
02801             we were actually used for an inbound or outbound call. */
02802          if (ast->_state != AST_STATE_RESERVED) {
02803             time(&p->guardtime);
02804             p->guardtime += 2;
02805          }
02806          break;
02807       default:
02808          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02809       }
02810       if (p->cidspill)
02811          free(p->cidspill);
02812       if (p->sig)
02813          zt_disable_ec(p);
02814       x = 0;
02815       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
02816       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
02817       p->didtdd = 0;
02818       p->cidspill = NULL;
02819       p->callwaitcas = 0;
02820       p->callwaiting = p->permcallwaiting;
02821       p->hidecallerid = p->permhidecallerid;
02822       p->dialing = 0;
02823       p->rdnis[0] = '\0';
02824       update_conf(p);
02825       reset_conf(p);
02826       /* Restore data mode */
02827       if (p->sig == SIG_PRI) {
02828          x = 0;
02829          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02830       }
02831 #ifdef HAVE_PRI
02832       if (p->bearer) {
02833          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
02834          /* Free up the bearer channel as well, and
02835             don't use its file descriptor anymore */
02836          update_conf(p->bearer);
02837          reset_conf(p->bearer);
02838          p->bearer->owner = NULL;
02839          p->bearer->realcall = NULL;
02840          p->bearer = NULL;
02841          p->subs[SUB_REAL].zfd = -1;
02842          p->pri = NULL;
02843       }
02844 #endif
02845       restart_monitor();
02846    }
02847 
02848    p->callwaitingrepeat = 0;
02849    p->cidcwexpire = 0;
02850    p->oprmode = 0;
02851    ast->tech_pvt = NULL;
02852    ast_mutex_unlock(&p->lock);
02853    ast_module_unref(ast_module_info->self);
02854    if (option_verbose > 2) 
02855       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
02856 
02857    ast_mutex_lock(&iflock);
02858    tmp = iflist;
02859    prev = NULL;
02860    if (p->destroy) {
02861       while (tmp) {
02862          if (tmp == p) {
02863             destroy_channel(prev, tmp, 0);
02864             break;
02865          } else {
02866             prev = tmp;
02867             tmp = tmp->next;
02868          }
02869       }
02870    }
02871    ast_mutex_unlock(&iflock);
02872    return 0;
02873 }
02874 
02875 static int zt_answer(struct ast_channel *ast)
02876 {
02877    struct zt_pvt *p = ast->tech_pvt;
02878    int res = 0;
02879    int index;
02880    int oldstate = ast->_state;
02881    ast_setstate(ast, AST_STATE_UP);
02882    ast_mutex_lock(&p->lock);
02883    index = zt_get_index(ast, p, 0);
02884    if (index < 0)
02885       index = SUB_REAL;
02886    /* nothing to do if a radio channel */
02887    if ((p->radio || (p->oprmode < 0))) {
02888       ast_mutex_unlock(&p->lock);
02889       return 0;
02890    }
02891    switch (p->sig) {
02892    case SIG_FXSLS:
02893    case SIG_FXSGS:
02894    case SIG_FXSKS:
02895       p->ringt = 0;
02896       /* Fall through */
02897    case SIG_EM:
02898    case SIG_EM_E1:
02899    case SIG_EMWINK:
02900    case SIG_FEATD:
02901    case SIG_FEATDMF:
02902    case SIG_FEATDMF_TA:
02903    case SIG_E911:
02904    case SIG_FGC_CAMA:
02905    case SIG_FGC_CAMAMF:
02906    case SIG_FEATB:
02907    case SIG_SF:
02908    case SIG_SFWINK:
02909    case SIG_SF_FEATD:
02910    case SIG_SF_FEATDMF:
02911    case SIG_SF_FEATB:
02912    case SIG_FXOLS:
02913    case SIG_FXOGS:
02914    case SIG_FXOKS:
02915       /* Pick up the line */
02916       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
02917       if (p->hanguponpolarityswitch) {
02918          gettimeofday(&p->polaritydelaytv, NULL);
02919       }
02920       res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
02921       tone_zone_play_tone(p->subs[index].zfd, -1);
02922       p->dialing = 0;
02923       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
02924          if (oldstate == AST_STATE_RINGING) {
02925             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
02926             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
02927             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02928             p->owner = p->subs[SUB_REAL].owner;
02929          }
02930       }
02931       if (p->sig & __ZT_SIG_FXS) {
02932          zt_enable_ec(p);
02933          zt_train_ec(p);
02934       }
02935       break;
02936 #ifdef HAVE_PRI
02937    case SIG_PRI:
02938       /* Send a pri acknowledge */
02939       if (!pri_grab(p, p->pri)) {
02940          p->proceeding = 1;
02941          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
02942          pri_rel(p->pri);
02943          /* stop ignoring inband dtmf */
02944          enable_dtmf_detect(p);
02945       } else {
02946          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02947          res = -1;
02948       }
02949       /* the audio path is complete now, train the echo canceler */
02950       zt_train_ec(p);
02951       break;
02952 #endif
02953 #ifdef HAVE_GSMAT
02954    case SIG_GSM:
02955       if (p->gsm.modul) {
02956           gsm_answer(p->gsm.modul);
02957       }
02958       break;
02959 #endif
02960    case 0:
02961       ast_mutex_unlock(&p->lock);
02962       return 0;
02963    default:
02964       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
02965       res = -1;
02966    }
02967    ast_mutex_unlock(&p->lock);
02968    return res;
02969 }
02970 
02971 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
02972 {
02973    char *cp;
02974    signed char *scp;
02975    int x;
02976    int index;
02977    struct zt_pvt *p = chan->tech_pvt, *pp;
02978    struct oprmode *oprmode;
02979    
02980 
02981    /* all supported options require data */
02982    if (!data || (datalen < 1)) {
02983       errno = EINVAL;
02984       return -1;
02985    }
02986 
02987    switch (option) {
02988    case AST_OPTION_TXGAIN:
02989       scp = (signed char *) data;
02990       index = zt_get_index(chan, p, 0);
02991       if (index < 0) {
02992          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
02993          return -1;
02994       }
02995       if (option_debug)
02996          ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
02997       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
02998    case AST_OPTION_RXGAIN:
02999       scp = (signed char *) data;
03000       index = zt_get_index(chan, p, 0);
03001       if (index < 0) {
03002          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
03003          return -1;
03004       }
03005       if (option_debug)
03006          ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
03007       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
03008    case AST_OPTION_TONE_VERIFY:
03009       if (!p->dsp)
03010          break;
03011       cp = (char *) data;
03012       switch (*cp) {
03013       case 1:
03014          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
03015          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
03016          break;
03017       case 2:
03018          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
03019          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
03020          break;
03021       default:
03022          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
03023          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
03024          break;
03025       }
03026       break;
03027    case AST_OPTION_TDD:
03028       /* turn on or off TDD */
03029       cp = (char *) data;
03030       p->mate = 0;
03031       if (!*cp) { /* turn it off */
03032          if (option_debug)
03033             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
03034          if (p->tdd)
03035             tdd_free(p->tdd);
03036          p->tdd = 0;
03037          break;
03038       }
03039       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
03040          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
03041       zt_disable_ec(p);
03042       /* otherwise, turn it on */
03043       if (!p->didtdd) { /* if havent done it yet */
03044          unsigned char mybuf[41000], *buf;
03045          int size, res, fd, len;
03046          struct pollfd fds[1];
03047 
03048          buf = mybuf;
03049          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
03050          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
03051          len = 40000;
03052          index = zt_get_index(chan, p, 0);
03053          if (index < 0) {
03054             ast_log(LOG_WARNING, "No index in TDD?\n");
03055             return -1;
03056          }
03057          fd = p->subs[index].zfd;
03058          while (len) {
03059             if (ast_check_hangup(chan))
03060                return -1;
03061             size = len;
03062             if (size > READ_SIZE)
03063                size = READ_SIZE;
03064             fds[0].fd = fd;
03065             fds[0].events = POLLPRI | POLLOUT;
03066             fds[0].revents = 0;
03067             res = poll(fds, 1, -1);
03068             if (!res) {
03069                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
03070                continue;
03071             }
03072             /* if got exception */
03073             if (fds[0].revents & POLLPRI)
03074                return -1;
03075             if (!(fds[0].revents & POLLOUT)) {
03076                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
03077                continue;
03078             }
03079             res = write(fd, buf, size);
03080             if (res != size) {
03081                if (res == -1) return -1;
03082                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
03083                break;
03084             }
03085             len -= size;
03086             buf += size;
03087          }
03088          p->didtdd = 1; /* set to have done it now */    
03089       }
03090       if (*cp == 2) { /* Mate mode */
03091          if (p->tdd)
03092             tdd_free(p->tdd);
03093          p->tdd = 0;
03094          p->mate = 1;
03095          break;
03096       }     
03097       if (!p->tdd) { /* if we dont have one yet */
03098          p->tdd = tdd_new(); /* allocate one */
03099       }     
03100       break;
03101    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
03102       if (!p->dsp)
03103          break;
03104       cp = (char *) data;
03105       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
03106          *cp ? "ON" : "OFF", (int) *cp, chan->name);
03107                 p->dtmfrelax = 0;
03108                 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
03109                 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
03110       break;
03111    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
03112       cp = (char *) data;
03113       if (!*cp) {    
03114          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
03115          x = 0;
03116          zt_disable_ec(p);
03117       } else {    
03118          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
03119          x = 1;
03120       }
03121       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
03122          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
03123       break;
03124    case AST_OPTION_OPRMODE:  /* Operator services mode */
03125       oprmode = (struct oprmode *) data;
03126       pp = oprmode->peer->tech_pvt;
03127       p->oprmode = pp->oprmode = 0;
03128       /* setup peers */
03129       p->oprpeer = pp;
03130       pp->oprpeer = p;
03131       /* setup modes, if any */
03132       if (oprmode->mode) 
03133       {
03134          pp->oprmode = oprmode->mode;
03135          p->oprmode = -oprmode->mode;
03136       }
03137       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
03138          oprmode->mode, chan->name,oprmode->peer->name);;
03139       break;
03140    case AST_OPTION_ECHOCAN:
03141       cp = (char *) data;
03142       if (*cp) {
03143          ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
03144          zt_enable_ec(p);
03145       } else {
03146          ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
03147          zt_disable_ec(p);
03148       }
03149       break;
03150    }
03151    errno = 0;
03152 
03153    return 0;
03154 }
03155 
03156 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
03157 {
03158    struct zt_pvt *p = chan->tech_pvt;
03159    
03160    if (!strcasecmp(data, "rxgain")) {
03161       ast_mutex_lock(&p->lock);
03162       snprintf(buf, len, "%f", p->rxgain);
03163       ast_mutex_unlock(&p->lock);   
03164    } else if (!strcasecmp(data, "txgain")) {
03165       ast_mutex_lock(&p->lock);
03166       snprintf(buf, len, "%f", p->txgain);
03167       ast_mutex_unlock(&p->lock);   
03168    } else {
03169       ast_copy_string(buf, "", len);
03170    }
03171    return 0;
03172 }
03173 
03174 
03175 static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
03176 {
03177    /* Unlink a specific slave or all slaves/masters from a given master */
03178    int x;
03179    int hasslaves;
03180    if (!master)
03181       return;
03182    if (needlock) {
03183       ast_mutex_lock(&master->lock);
03184       if (slave) {
03185          while (ast_mutex_trylock(&slave->lock)) {
03186             DEADLOCK_AVOIDANCE(&master->lock);
03187          }
03188       }
03189    }
03190    hasslaves = 0;
03191    for (x = 0; x < MAX_SLAVES; x++) {
03192       if (master->slaves[x]) {
03193          if (!slave || (master->slaves[x] == slave)) {
03194             /* Take slave out of the conference */
03195             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
03196             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
03197             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
03198             master->slaves[x]->master = NULL;
03199             master->slaves[x] = NULL;
03200          } else
03201             hasslaves = 1;
03202       }
03203       if (!hasslaves)
03204          master->inconference = 0;
03205    }
03206    if (!slave) {
03207       if (master->master) {
03208          /* Take master out of the conference */
03209          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
03210          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
03211          hasslaves = 0;
03212          for (x = 0; x < MAX_SLAVES; x++) {
03213             if (master->master->slaves[x] == master)
03214                master->master->slaves[x] = NULL;
03215             else if (master->master->slaves[x])
03216                hasslaves = 1;
03217          }
03218          if (!hasslaves)
03219             master->master->inconference = 0;
03220       }
03221       master->master = NULL;
03222    }
03223    update_conf(master);
03224    if (needlock) {
03225       if (slave)
03226          ast_mutex_unlock(&slave->lock);
03227       ast_mutex_unlock(&master->lock);
03228    }
03229 }
03230 
03231 static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
03232    int x;
03233    if (!slave || !master) {
03234       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
03235       return;
03236    }
03237    for (x = 0; x < MAX_SLAVES; x++) {
03238       if (!master->slaves[x]) {
03239          master->slaves[x] = slave;
03240          break;
03241       }
03242    }
03243    if (x >= MAX_SLAVES) {
03244       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
03245       master->slaves[MAX_SLAVES - 1] = slave;
03246    }
03247    if (slave->master) 
03248       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
03249    slave->master = master;
03250    
03251    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
03252 }
03253 
03254 static void disable_dtmf_detect(struct zt_pvt *p)
03255 {
03256 #ifdef ZT_TONEDETECT
03257    int val;
03258 #endif
03259 
03260    p->ignoredtmf = 1;
03261 
03262 #ifdef ZT_TONEDETECT
03263    val = 0;
03264    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03265 #endif      
03266    if (!p->hardwaredtmf && p->dsp) {
03267       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03268       ast_dsp_set_features(p->dsp, p->dsp_features);
03269    }
03270 }
03271 
03272 static void enable_dtmf_detect(struct zt_pvt *p)
03273 {
03274 #ifdef ZT_TONEDETECT
03275    int val;
03276 #endif
03277 
03278    if (p->channel == CHAN_PSEUDO)
03279       return;
03280 
03281    p->ignoredtmf = 0;
03282 
03283 #ifdef ZT_TONEDETECT
03284    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
03285    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03286 #endif      
03287    if (!p->hardwaredtmf && p->dsp) {
03288       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03289       ast_dsp_set_features(p->dsp, p->dsp_features);
03290    }
03291 }
03292 
03293 static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
03294 {
03295    struct ast_channel *who;
03296    struct zt_pvt *p0, *p1, *op0, *op1;
03297    struct zt_pvt *master = NULL, *slave = NULL;
03298    struct ast_frame *f;
03299    int inconf = 0;
03300    int nothingok = 1;
03301    int ofd0, ofd1;
03302    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03303    int os0 = -1, os1 = -1;
03304    int priority = 0;
03305    struct ast_channel *oc0, *oc1;
03306    enum ast_bridge_result res;
03307 
03308 #ifdef PRI_2BCT
03309    int triedtopribridge = 0;
03310    q931_call *q931c0 = NULL, *q931c1 = NULL;
03311 #endif
03312 
03313    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03314       There is code below to handle it properly until DTMF is actually seen,
03315       but due to currently unresolved issues it's ignored...
03316    */
03317 
03318    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03319       return AST_BRIDGE_FAILED_NOWARN;
03320 
03321    ast_mutex_lock(&c0->lock);
03322    while (ast_mutex_trylock(&c1->lock)) {
03323       DEADLOCK_AVOIDANCE(&c0->lock);
03324    }
03325 
03326    p0 = c0->tech_pvt;
03327    p1 = c1->tech_pvt;
03328    /* cant do pseudo-channels here */
03329    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03330       ast_mutex_unlock(&c0->lock);
03331       ast_mutex_unlock(&c1->lock);
03332       return AST_BRIDGE_FAILED_NOWARN;
03333    }
03334 
03335    oi0 = zt_get_index(c0, p0, 0);
03336    oi1 = zt_get_index(c1, p1, 0);
03337    if ((oi0 < 0) || (oi1 < 0)) {
03338       ast_mutex_unlock(&c0->lock);
03339       ast_mutex_unlock(&c1->lock);
03340       return AST_BRIDGE_FAILED;
03341    }
03342 
03343    op0 = p0 = c0->tech_pvt;
03344    op1 = p1 = c1->tech_pvt;
03345    ofd0 = c0->fds[0];
03346    ofd1 = c1->fds[0];
03347    oc0 = p0->owner;
03348    oc1 = p1->owner;
03349 
03350    if (ast_mutex_trylock(&p0->lock)) {
03351       /* Don't block, due to potential for deadlock */
03352       ast_mutex_unlock(&c0->lock);
03353       ast_mutex_unlock(&c1->lock);
03354       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03355       return AST_BRIDGE_RETRY;
03356    }
03357    if (ast_mutex_trylock(&p1->lock)) {
03358       /* Don't block, due to potential for deadlock */
03359       ast_mutex_unlock(&p0->lock);
03360       ast_mutex_unlock(&c0->lock);
03361       ast_mutex_unlock(&c1->lock);
03362       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03363       return AST_BRIDGE_RETRY;
03364    }
03365 
03366    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03367       if (p0->owner && p1->owner) {
03368          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03369          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03370             master = p0;
03371             slave = p1;
03372             inconf = 1;
03373          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03374             master = p1;
03375             slave = p0;
03376             inconf = 1;
03377          } else {
03378             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03379             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03380                p0->channel,
03381                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03382                p0->subs[SUB_REAL].inthreeway, p0->channel,
03383                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03384                p1->subs[SUB_REAL].inthreeway);
03385          }
03386          nothingok = 0;
03387       }
03388    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03389       if (p1->subs[SUB_THREEWAY].inthreeway) {
03390          master = p1;
03391          slave = p0;
03392          nothingok = 0;
03393       }
03394    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03395       if (p0->subs[SUB_THREEWAY].inthreeway) {
03396          master = p0;
03397          slave = p1;
03398          nothingok = 0;
03399       }
03400    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03401       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03402          don't put us in anything */
03403       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03404          master = p1;
03405          slave = p0;
03406          nothingok = 0;
03407       }
03408    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03409       /* Same as previous */
03410       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03411          master = p0;
03412          slave = p1;
03413          nothingok = 0;
03414       }
03415    }
03416    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03417       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03418    if (master && slave) {
03419       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03420          in an active threeway call with a channel that is ringing, we should
03421          indicate ringing. */
03422       if ((oi1 == SUB_THREEWAY) && 
03423           p1->subs[SUB_THREEWAY].inthreeway && 
03424           p1->subs[SUB_REAL].owner && 
03425           p1->subs[SUB_REAL].inthreeway && 
03426           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03427          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
03428          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
03429          os1 = p1->subs[SUB_REAL].owner->_state;
03430       } else {
03431          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
03432          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
03433       }
03434       if ((oi0 == SUB_THREEWAY) && 
03435           p0->subs[SUB_THREEWAY].inthreeway && 
03436           p0->subs[SUB_REAL].owner && 
03437           p0->subs[SUB_REAL].inthreeway && 
03438           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03439          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
03440          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
03441          os0 = p0->subs[SUB_REAL].owner->_state;
03442       } else {
03443          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
03444          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
03445       }
03446       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03447          if (!p0->echocanbridged || !p1->echocanbridged) {
03448             /* Disable echo cancellation if appropriate */
03449             zt_disable_ec(p0);
03450             zt_disable_ec(p1);
03451          }
03452       }
03453       zt_link(slave, master);
03454       master->inconference = inconf;
03455    } else if (!nothingok)
03456       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03457 
03458    update_conf(p0);
03459    update_conf(p1);
03460    t0 = p0->subs[SUB_REAL].inthreeway;
03461    t1 = p1->subs[SUB_REAL].inthreeway;
03462 
03463    ast_mutex_unlock(&p0->lock);
03464    ast_mutex_unlock(&p1->lock);
03465 
03466    ast_mutex_unlock(&c0->lock);
03467    ast_mutex_unlock(&c1->lock);
03468 
03469    /* Native bridge failed */
03470    if ((!master || !slave) && !nothingok) {
03471       zt_enable_ec(p0);
03472       zt_enable_ec(p1);
03473       return AST_BRIDGE_FAILED;
03474    }
03475    
03476    if (option_verbose > 2) 
03477       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
03478 
03479    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03480       disable_dtmf_detect(op0);
03481 
03482    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03483       disable_dtmf_detect(op1);
03484 
03485    for (;;) {
03486       struct ast_channel *c0_priority[2] = {c0, c1};
03487       struct ast_channel *c1_priority[2] = {c1, c0};
03488 
03489       /* Here's our main loop...  Start by locking things, looking for private parts, 
03490          and then balking if anything is wrong */
03491       ast_mutex_lock(&c0->lock);
03492       while (ast_mutex_trylock(&c1->lock)) {
03493          DEADLOCK_AVOIDANCE(&c0->lock);
03494       }
03495 
03496       p0 = c0->tech_pvt;
03497       p1 = c1->tech_pvt;
03498 
03499       if (op0 == p0)
03500          i0 = zt_get_index(c0, p0, 1);
03501       if (op1 == p1)
03502          i1 = zt_get_index(c1, p1, 1);
03503       ast_mutex_unlock(&c0->lock);
03504       ast_mutex_unlock(&c1->lock);
03505 
03506       if (!timeoutms || 
03507           (op0 != p0) ||
03508           (op1 != p1) || 
03509           (ofd0 != c0->fds[0]) || 
03510           (ofd1 != c1->fds[0]) ||
03511           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
03512           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
03513           (oc0 != p0->owner) || 
03514           (oc1 != p1->owner) ||
03515           (t0 != p0->subs[SUB_REAL].inthreeway) ||
03516           (t1 != p1->subs[SUB_REAL].inthreeway) ||
03517           (oi0 != i0) ||
03518           (oi1 != i1)) {
03519          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
03520             op0->channel, oi0, op1->channel, oi1);
03521          res = AST_BRIDGE_RETRY;
03522          goto return_from_bridge;
03523       }
03524 
03525 #ifdef PRI_2BCT
03526       q931c0 = p0->call;
03527       q931c1 = p1->call;
03528       if (p0->transfer && p1->transfer 
03529           && q931c0 && q931c1 
03530           && !triedtopribridge) {
03531          pri_channel_bridge(q931c0, q931c1);
03532          triedtopribridge = 1;
03533       }
03534 #endif
03535 
03536       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
03537       if (!who) {
03538          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
03539          continue;
03540       }
03541       f = ast_read(who);
03542       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
03543          *fo = f;
03544          *rc = who;
03545          res = AST_BRIDGE_COMPLETE;
03546          goto return_from_bridge;
03547       }
03548       if (f->frametype == AST_FRAME_DTMF) {
03549          if ((who == c0) && p0->pulsedial) {
03550             ast_write(c1, f);
03551          } else if ((who == c1) && p1->pulsedial) {
03552             ast_write(c0, f);
03553          } else {
03554             *fo = f;
03555             *rc = who;
03556             res = AST_BRIDGE_COMPLETE;
03557             goto return_from_bridge;
03558          }
03559       }
03560       ast_frfree(f);
03561       
03562       /* Swap who gets priority */
03563       priority = !priority;
03564    }
03565 
03566 return_from_bridge:
03567    if (op0 == p0)
03568       zt_enable_ec(p0);
03569 
03570    if (op1 == p1)
03571       zt_enable_ec(p1);
03572 
03573    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03574       enable_dtmf_detect(op0);
03575 
03576    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03577       enable_dtmf_detect(op1);
03578 
03579    zt_unlink(slave, master, 1);
03580 
03581    return res;
03582 }
03583 
03584 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
03585 {
03586    struct zt_pvt *p = newchan->tech_pvt;
03587    int x;
03588    if (newchan && newchan->tech_pvt) {
03589        p = newchan->tech_pvt;
03590    }
03591    if (!p) {
03592        if (newchan) {
03593       ast_log(LOG_ERROR, "channel %s has no tech_pvt structure\n", newchan->name);
03594        }
03595        return 0;
03596    }
03597    ast_mutex_lock(&p->lock);
03598    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
03599    if (p->owner == oldchan) {
03600       p->owner = newchan;
03601    }
03602    for (x = 0; x < 3; x++)
03603       if (p->subs[x].owner == oldchan) {
03604          if (!x)
03605             zt_unlink(NULL, p, 0);
03606          p->subs[x].owner = newchan;
03607       }
03608    if (newchan->_state == AST_STATE_RINGING) 
03609       zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
03610    update_conf(p);
03611    ast_mutex_unlock(&p->lock);
03612    return 0;
03613 }
03614 
03615 static int zt_ring_phone(struct zt_pvt *p)
03616 {
03617    int x;
03618    int res;
03619    /* Make sure our transmit state is on hook */
03620    x = 0;
03621    x = ZT_ONHOOK;
03622    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03623    do {
03624       x = ZT_RING;
03625       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03626       if (res) {
03627          switch (errno) {
03628          case EBUSY:
03629          case EINTR:
03630             /* Wait just in case */
03631             usleep(10000);
03632             continue;
03633          case EINPROGRESS:
03634             res = 0;
03635             break;
03636          default:
03637             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
03638             res = 0;
03639          }
03640       }
03641    } while (res);
03642    return res;
03643 }
03644 
03645 static void *ss_thread(void *data);
03646 
03647 static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int);
03648 
03649 static int attempt_transfer(struct zt_pvt *p)
03650 {
03651    /* In order to transfer, we need at least one of the channels to
03652       actually be in a call bridge.  We can't conference two applications
03653       together (but then, why would we want to?) */
03654    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03655       /* The three-way person we're about to transfer to could still be in MOH, so
03656          stop if now if appropriate */
03657       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03658          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
03659       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03660          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03661       }
03662       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
03663          tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
03664       }
03665       if (p->subs[SUB_REAL].owner->cdr) {
03666          /* Move CDR from second channel to current one */
03667          p->subs[SUB_THREEWAY].owner->cdr =
03668             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03669          p->subs[SUB_REAL].owner->cdr = NULL;
03670       }
03671       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03672          /* Move CDR from second channel's bridge to current one */
03673          p->subs[SUB_THREEWAY].owner->cdr =
03674             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03675          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03676       }
03677        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03678          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03679                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03680          return -1;
03681       }
03682       /* Orphan the channel after releasing the lock */
03683       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03684       unalloc_sub(p, SUB_THREEWAY);
03685    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03686       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03687       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03688          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03689       }
03690       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
03691          tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03692       }
03693       if (p->subs[SUB_THREEWAY].owner->cdr) {
03694          /* Move CDR from second channel to current one */
03695          p->subs[SUB_REAL].owner->cdr = 
03696             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03697          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03698       }
03699       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03700          /* Move CDR from second channel's bridge to current one */
03701          p->subs[SUB_REAL].owner->cdr = 
03702             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03703          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03704       }
03705       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03706          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03707                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03708          return -1;
03709       }
03710       /* Three-way is now the REAL */
03711       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03712       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03713       unalloc_sub(p, SUB_THREEWAY);
03714       /* Tell the caller not to hangup */
03715       return 1;
03716    } else {
03717       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03718                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03719       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03720       return -1;
03721    }
03722    return 0;
03723 }
03724 
03725 static int check_for_conference(struct zt_pvt *p)
03726 {
03727    ZT_CONFINFO ci;
03728    /* Fine if we already have a master, etc */
03729    if (p->master || (p->confno > -1))
03730       return 0;
03731    memset(&ci, 0, sizeof(ci));
03732    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03733       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03734       return 0;
03735    }
03736    /* If we have no master and don't have a confno, then 
03737       if we're in a conference, it's probably a MeetMe room or
03738       some such, so don't let us 3-way out! */
03739    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03740       if (option_verbose > 2) 
03741          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03742       return 1;
03743    }
03744    return 0;
03745 }
03746 
03747 static int get_alarms(struct zt_pvt *p)
03748 {
03749    int res;
03750    ZT_SPANINFO zi;
03751    memset(&zi, 0, sizeof(zi));
03752    zi.spanno = p->span;
03753    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03754    if (res < 0) {
03755       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03756       return 0;
03757    }
03758    return zi.alarms;
03759 }
03760 
03761 static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_frame **dest)
03762 {
03763    struct zt_pvt *p = ast->tech_pvt;
03764    struct ast_frame *f = *dest;
03765 
03766    if (option_debug)
03767       ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
03768 
03769    if (p->confirmanswer) {
03770       if (option_debug)
03771          ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
03772       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
03773          of a DTMF digit */
03774       p->subs[index].f.frametype = AST_FRAME_CONTROL;
03775       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03776       *dest = &p->subs[index].f;
03777       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
03778       p->confirmanswer = 0;
03779    } else if (p->callwaitcas) {
03780       if ((f->subclass == 'A') || (f->subclass == 'D')) {
03781          if (option_debug)
03782             ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
03783          if (p->cidspill)
03784             free(p->cidspill);
03785          send_cwcidspill(p);
03786       }
03787       if ((f->subclass != 'm') && (f->subclass != 'u')) 
03788          p->callwaitcas = 0;
03789       p->subs[index].f.frametype = AST_FRAME_NULL;
03790       p->subs[index].f.subclass = 0;
03791       *dest = &p->subs[index].f;
03792    } else if (f->subclass == 'f') {
03793       /* Fax tone -- Handle and return NULL */
03794       if ((p->callprogress & 0x6) && !p->faxhandled) {
03795          p->faxhandled++;
03796          if (strcmp(ast->exten, "fax")) {
03797             const char *target_context = S_OR(ast->macrocontext, ast->context);
03798 
03799             if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
03800                if (option_verbose > 2)
03801                   ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
03802                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
03803                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
03804                if (ast_async_goto(ast, target_context, "fax", 1))
03805                   ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
03806             } else {
03807                 if (option_verbose > 2)
03808                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
03809             }
03810          } else if (option_debug)
03811             ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
03812       } else if (option_debug)
03813             ast_log(LOG_DEBUG, "Fax already handled\n");
03814       zt_confmute(p, 0);
03815       p->subs[index].f.frametype = AST_FRAME_NULL;
03816       p->subs[index].f.subclass = 0;
03817       *dest = &p->subs[index].f;
03818    } else if (f->subclass == 'm') {
03819       /* Confmute request */
03820       zt_confmute(p, 1);
03821       p->subs[index].f.frametype = AST_FRAME_NULL;
03822       p->subs[index].f.subclass = 0;
03823       *dest = &p->subs[index].f;    
03824    } else if (f->subclass == 'u') {
03825       /* Unmute */
03826       zt_confmute(p, 0);
03827       p->subs[index].f.frametype = AST_FRAME_NULL;
03828       p->subs[index].f.subclass = 0;
03829       *dest = &p->subs[index].f;    
03830    } else
03831       zt_confmute(p, 0);
03832 }
03833          
03834 static struct ast_frame *zt_handle_event(struct ast_channel *ast)
03835 {
03836    int res, x;
03837    int index, mysig;
03838    char *c;
03839    struct zt_pvt *p = ast->tech_pvt;
03840    pthread_t threadid;
03841    pthread_attr_t attr;
03842    struct ast_channel *chan;
03843    struct ast_frame *f;
03844 
03845    index = zt_get_index(ast, p, 0);
03846    mysig = p->sig;
03847    if (p->outsigmod > -1)
03848       mysig = p->outsigmod;
03849    p->subs[index].f.frametype = AST_FRAME_NULL;
03850    p->subs[index].f.subclass = 0;
03851    p->subs[index].f.datalen = 0;
03852    p->subs[index].f.samples = 0;
03853    p->subs[index].f.mallocd = 0;
03854    p->subs[index].f.offset = 0;
03855    p->subs[index].f.src = "zt_handle_event";
03856    p->subs[index].f.data = NULL;
03857    f = &p->subs[index].f;
03858 
03859    if (index < 0)
03860       return &p->subs[index].f;
03861    if (p->fake_event) {
03862       res = p->fake_event;
03863       p->fake_event = 0;
03864    } else
03865       res = zt_get_event(p->subs[index].zfd);
03866 
03867    if (option_debug)
03868       ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
03869 
03870    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
03871       p->pulsedial =  (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
03872 
03873       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
03874 #ifdef HAVE_PRI
03875       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
03876          /* absorb event */
03877       } else {
03878 #endif
03879          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
03880          p->subs[index].f.subclass = res & 0xff;
03881 #ifdef HAVE_PRI
03882       }
03883 #endif
03884       zt_handle_dtmfup(ast, index, &f);
03885       return f;
03886    }
03887 
03888    if (res & ZT_EVENT_DTMFDOWN) {
03889       if (option_debug)
03890          ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
03891       /* Mute conference */
03892       zt_confmute(p, 1);
03893       p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
03894       p->subs[index].f.subclass = res & 0xff;
03895       return &p->subs[index].f;
03896    }
03897 
03898    switch (res) {
03899 #ifdef ZT_EVENT_EC_DISABLED
03900       case ZT_EVENT_EC_DISABLED:
03901          if (option_verbose > 2) 
03902             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
03903          p->echocanon = 0;
03904          break;
03905 #endif
03906       case ZT_EVENT_BITSCHANGED:
03907          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
03908       case ZT_EVENT_PULSE_START:
03909          /* Stop tone if there's a pulse start and the PBX isn't started */
03910          if (!ast->pbx)
03911             tone_zone_play_tone(p->subs[index].zfd, -1);
03912          break;   
03913       case ZT_EVENT_DIALCOMPLETE:
03914          if (p->inalarm) break;
03915          if ((p->radio || (p->oprmode < 0))) break;
03916          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
03917             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
03918             return NULL;
03919          }
03920          if (!x) { /* if not still dialing in driver */
03921             zt_enable_ec(p);
03922             if (p->echobreak) {
03923                zt_train_ec(p);
03924                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
03925                p->dop.op = ZT_DIAL_OP_REPLACE;
03926                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
03927                p->echobreak = 0;
03928             } else {
03929                p->dialing = 0;
03930                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
03931                   /* if thru with dialing after offhook */
03932                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
03933                      ast_setstate(ast, AST_STATE_UP);
03934                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03935                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03936                      break;
03937                   } else { /* if to state wait for offhook to dial rest */
03938                      /* we now wait for off hook */
03939                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
03940                   }
03941                }
03942                if (ast->_state == AST_STATE_DIALING) {
03943                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
03944                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
03945                   } 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)))) {
03946                      ast_setstate(ast, AST_STATE_RINGING);
03947                   } else if (!p->answeronpolarityswitch) {
03948                      ast_setstate(ast, AST_STATE_UP);
03949                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03950                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03951                      /* If aops=0 and hops=1, this is necessary */
03952                      p->polarity = POLARITY_REV;
03953                   } else {
03954                      /* Start clean, so we can catch the change to REV polarity when party answers */
03955                      p->polarity = POLARITY_IDLE;
03956                   }
03957                }
03958             }
03959          }
03960          break;
03961       case ZT_EVENT_ALARM:
03962 #ifdef HAVE_PRI
03963          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
03964             /* T309 is not enabled : hangup calls when alarm occurs */
03965             if (p->call) {
03966                if (p->pri && p->pri->pri) {
03967                   if (!pri_grab(p, p->pri)) {
03968                      pri_hangup(p->pri->pri, p->call, -1, -1);
03969                      pri_destroycall(p->pri->pri, p->call);
03970                      p->call = NULL;
03971                      pri_rel(p->pri);
03972                   } else
03973                      ast_log(LOG_WARNING, "Failed to grab PRI!\n");
03974                } else
03975                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
03976             }
03977             if (p->owner)
03978                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03979          }
03980          if (p->bearer)
03981             p->bearer->inalarm = 1;
03982          else
03983 #endif
03984          p->inalarm = 1;
03985          res = get_alarms(p);
03986          do {
03987             const char *alarm_str = alarm2str(res);
03988 
03989             /* hack alert!  Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
03990              * doesn't know what to do with it.  Don't confuse users with log messages. */
03991             if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
03992                p->unknown_alarm = 1;
03993                break;
03994             } else {
03995                p->unknown_alarm = 0;
03996             }
03997                
03998             ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
03999             manager_event(EVENT_FLAG_SYSTEM, "Alarm",
04000                "Alarm: %s\r\n"
04001                "Channel: %d\r\n",
04002                alarm_str, p->channel);
04003          } while (0);
04004 #ifdef HAVE_LIBPRI
04005          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
04006             /* fall through intentionally */
04007          } else {
04008             break;
04009          }
04010 #endif
04011       case ZT_EVENT_ONHOOK:
04012          if (p->radio) {
04013             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04014             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04015             break;
04016          }
04017          if (p->oprmode < 0)
04018          {
04019             if (p->oprmode != -1) break;
04020             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
04021             {
04022                /* Make sure it starts ringing */
04023                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
04024                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
04025                save_conference(p->oprpeer);
04026                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04027             }
04028             break;
04029          }
04030          switch (p->sig) {
04031          case SIG_FXOLS:
04032          case SIG_FXOGS:
04033          case SIG_FXOKS:
04034             p->onhooktime = time(NULL);
04035             p->msgstate = -1;
04036             /* Check for some special conditions regarding call waiting */
04037             if (index == SUB_REAL) {
04038                /* The normal line was hung up */
04039                if (p->subs[SUB_CALLWAIT].owner) {
04040                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
04041                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
04042                   if (option_verbose > 2) 
04043                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
04044                   unalloc_sub(p, SUB_CALLWAIT); 
04045 #if 0
04046                   p->subs[index].needanswer = 0;
04047                   p->subs[index].needringing = 0;
04048 #endif                  
04049                   p->callwaitingrepeat = 0;
04050                   p->cidcwexpire = 0;
04051                   p->owner = NULL;
04052                   /* Don't start streaming audio yet if the incoming call isn't up yet */
04053                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
04054                      p->dialing = 1;
04055                   zt_ring_phone(p);
04056                } else if (p->subs[SUB_THREEWAY].owner) {
04057                   unsigned int mssinceflash;
04058                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
04059                      the private structure -- not especially easy or clean */
04060                   while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
04061                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
04062                      ast_mutex_unlock(&p->lock);
04063                      DEADLOCK_AVOIDANCE(&ast->lock);
04064                      /* We can grab ast and p in that order, without worry.  We should make sure
04065                         nothing seriously bad has happened though like some sort of bizarre double
04066                         masquerade! */
04067                      ast_mutex_lock(&p->lock);
04068                      if (p->owner != ast) {
04069                         ast_log(LOG_WARNING, "This isn't good...\n");
04070                         return NULL;
04071                      }
04072                   }
04073                   if (!p->subs[SUB_THREEWAY].owner) {
04074                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
04075                      return NULL;
04076                   }
04077                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
04078                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
04079                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
04080                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
04081                         hanging up.  Hangup both channels now */
04082                      if (p->subs[SUB_THREEWAY].owner)
04083                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
04084                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04085                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
04086                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04087                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
04088                      if (p->transfer) {
04089                         /* In any case this isn't a threeway call anymore */
04090                         p->subs[SUB_REAL].inthreeway = 0;
04091                         p->subs[SUB_THREEWAY].inthreeway = 0;
04092                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
04093                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
04094                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04095                            /* Swap subs and dis-own channel */
04096                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
04097                            p->owner = NULL;
04098                            /* Ring the phone */
04099                            zt_ring_phone(p);
04100                         } else {
04101                            if ((res = attempt_transfer(p)) < 0) {
04102                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04103                               if (p->subs[SUB_THREEWAY].owner)
04104                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04105                            } else if (res) {
04106                               /* Don't actually hang up at this point */
04107                               if (p->subs[SUB_THREEWAY].owner)
04108                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04109                               break;
04110                            }
04111                         }
04112                      } else {
04113                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04114                         if (p->subs[SUB_THREEWAY].owner)
04115                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04116                      }
04117                   } else {
04118                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04119                      /* Swap subs and dis-own channel */
04120                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04121                      p->owner = NULL;
04122                      /* Ring the phone */
04123                      zt_ring_phone(p);
04124                   }
04125                }
04126             } else {
04127                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
04128             }
04129             /* Fall through */
04130          default:
04131             zt_disable_ec(p);
04132             return NULL;
04133          }
04134          break;
04135       case ZT_EVENT_RINGOFFHOOK:
04136          if (p->inalarm) break;
04137          if (p->oprmode < 0)
04138          {
04139             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
04140             {
04141                /* Make sure it stops ringing */
04142                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
04143                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
04144                restore_conference(p->oprpeer);
04145             }
04146             break;
04147          }
04148          if (p->radio)
04149          {
04150             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04151             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04152             break;
04153          }
04154          /* for E911, its supposed to wait for offhook then dial
04155             the second half of the dial string */
04156          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
04157             c = strchr(p->dialdest, '/');
04158             if (c)
04159                c++;
04160             else
04161                c = p->dialdest;
04162             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
04163             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
04164             if (strlen(p->dop.dialstr) > 4) {
04165                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
04166                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
04167                p->echorest[sizeof(p->echorest) - 1] = '\0';
04168                p->echobreak = 1;
04169                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
04170             } else
04171                p->echobreak = 0;
04172             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
04173                x = ZT_ONHOOK;
04174                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
04175                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
04176                return NULL;
04177                }
04178             p->dialing = 1;
04179             return &p->subs[index].f;
04180          }
04181          switch (p->sig) {
04182          case SIG_FXOLS:
04183          case SIG_FXOGS:
04184          case SIG_FXOKS:
04185             switch (ast->_state) {
04186             case AST_STATE_RINGING:
04187                zt_enable_ec(p);
04188                zt_train_ec(p);
04189                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04190                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04191                /* Make sure it stops ringing */
04192                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04193                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
04194                if (p->cidspill) {
04195                   /* Cancel any running CallerID spill */
04196                   free(p->cidspill);
04197                   p->cidspill = NULL;
04198                }
04199                p->dialing = 0;
04200                p->callwaitcas = 0;
04201                if (p->confirmanswer) {
04202                   /* Ignore answer if "confirm answer" is enabled */
04203                   p->subs[index].f.frametype = AST_FRAME_NULL;
04204                   p->subs[index].f.subclass = 0;
04205                } else if (!ast_strlen_zero(p->dop.dialstr)) {
04206                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
04207                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04208                   if (res < 0) {
04209                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04210                      p->dop.dialstr[0] = '\0';
04211                      return NULL;
04212                   } else {
04213                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
04214                      p->subs[index].f.frametype = AST_FRAME_NULL;
04215                      p->subs[index].f.subclass = 0;
04216                      p->dialing = 1;
04217                   }
04218                   p->dop.dialstr[0] = '\0';
04219                   ast_setstate(ast, AST_STATE_DIALING);
04220                } else
04221                   ast_setstate(ast, AST_STATE_UP);
04222                return &p->subs[index].f;
04223             case AST_STATE_DOWN:
04224                ast_setstate(ast, AST_STATE_RING);
04225                ast->rings = 1;
04226                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04227                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
04228                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
04229                return &p->subs[index].f;
04230             case AST_STATE_UP:
04231                /* Make sure it stops ringing */
04232                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04233                /* Okay -- probably call waiting*/
04234                if (ast_bridged_channel(p->owner))
04235                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04236                p->subs[index].needunhold = 1;
04237                break;
04238             case AST_STATE_RESERVED:
04239                /* Start up dialtone */
04240                if (has_voicemail(p))
04241                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
04242                else
04243                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
04244                break;
04245             default:
04246                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
04247             }
04248             break;
04249          case SIG_FXSLS:
04250          case SIG_FXSGS:
04251          case SIG_FXSKS:
04252             if (ast->_state == AST_STATE_RING) {
04253                p->ringt = p->ringt_base;
04254             }
04255 
04256             /* Fall through */
04257          case SIG_EM:
04258          case SIG_EM_E1:
04259          case SIG_EMWINK:
04260          case SIG_FEATD:
04261          case SIG_FEATDMF:
04262          case SIG_FEATDMF_TA:
04263          case SIG_E911:
04264          case SIG_FGC_CAMA:
04265          case SIG_FGC_CAMAMF:
04266          case SIG_FEATB:
04267          case SIG_SF:
04268          case SIG_SFWINK:
04269          case SIG_SF_FEATD:
04270          case SIG_SF_FEATDMF:
04271          case SIG_SF_FEATB:
04272             if (ast->_state == AST_STATE_PRERING)
04273                ast_setstate(ast, AST_STATE_RING);
04274             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
04275                if (option_debug)
04276                   ast_log(LOG_DEBUG, "Ring detected\n");
04277                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04278                p->subs[index].f.subclass = AST_CONTROL_RING;
04279             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
04280                if (option_debug)
04281                   ast_log(LOG_DEBUG, "Line answered\n");
04282                if (p->confirmanswer) {
04283                   p->subs[index].f.frametype = AST_FRAME_NULL;
04284                   p->subs[index].f.subclass = 0;
04285                } else {
04286                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
04287                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04288                   ast_setstate(ast, AST_STATE_UP);
04289                }
04290             } else if (ast->_state != AST_STATE_RING)
04291                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
04292             break;
04293          default:
04294             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
04295          }
04296          break;
04297 #ifdef ZT_EVENT_RINGBEGIN
04298       case ZT_EVENT_RINGBEGIN:
04299          switch (p->sig) {
04300          case SIG_FXSLS:
04301          case SIG_FXSGS:
04302          case SIG_FXSKS:
04303             if (ast->_state == AST_STATE_RING) {
04304                p->ringt = p->ringt_base;
04305             }
04306             break;
04307          }
04308          break;
04309 #endif         
04310       case ZT_EVENT_RINGEROFF:
04311          if (p->inalarm) break;
04312          if ((p->radio || (p->oprmode < 0))) break;
04313          ast->rings++;
04314          if ((ast->rings > p->cidrings) && (p->cidspill)) {
04315             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
04316             free(p->cidspill);
04317             p->cidspill = NULL;
04318             p->callwaitcas = 0;
04319          }
04320          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04321          p->subs[index].f.subclass = AST_CONTROL_RINGING;
04322          break;
04323       case ZT_EVENT_RINGERON:
04324          break;
04325       case ZT_EVENT_NOALARM:
04326          p->inalarm = 0;
04327 #ifdef HAVE_PRI
04328          /* Extremely unlikely but just in case */
04329          if (p->bearer)
04330             p->bearer->inalarm = 0;
04331 #endif            
04332          if (!p->unknown_alarm) {
04333             ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
04334             manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
04335                "Channel: %d\r\n", p->channel);
04336          } else {
04337             p->unknown_alarm = 0;
04338          }
04339          break;
04340       case ZT_EVENT_WINKFLASH:
04341          if (p->inalarm) break;
04342          if (p->radio) break;
04343          if (p->oprmode < 0) break;
04344          if (p->oprmode > 1)
04345          {
04346             struct zt_params par;
04347 
04348             if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
04349             {
04350                if (!par.rxisoffhook)
04351                {
04352                   /* Make sure it stops ringing */
04353                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
04354                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
04355                   save_conference(p);
04356                   tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04357                }
04358             }
04359             break;
04360          }
04361          /* Remember last time we got a flash-hook */
04362          gettimeofday(&p->flashtime, NULL);
04363          switch (mysig) {
04364          case SIG_FXOLS:
04365          case SIG_FXOGS:
04366          case SIG_FXOKS:
04367             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
04368                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
04369             p->callwaitcas = 0;
04370 
04371             if (index != SUB_REAL) {
04372                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
04373                goto winkflashdone;
04374             }
04375             
04376             if (p->subs[SUB_CALLWAIT].owner) {
04377                /* Swap to call-wait */
04378                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04379                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
04380                p->owner = p->subs[SUB_REAL].owner;
04381                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04382                if (p->owner->_state == AST_STATE_RINGING) {
04383                   ast_setstate(p->owner, AST_STATE_UP);
04384                   p->subs[SUB_REAL].needanswer = 1;
04385                }
04386                p->callwaitingrepeat = 0;
04387                p->cidcwexpire = 0;
04388                /* Start music on hold if appropriate */
04389                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
04390                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
04391                      S_OR(p->mohsuggest, NULL),
04392                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04393                }
04394                p->subs[SUB_CALLWAIT].needhold = 1;
04395                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04396                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
04397                      S_OR(p->mohsuggest, NULL),
04398                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04399                }
04400                p->subs[SUB_REAL].needunhold = 1;
04401             } else if (!p->subs[SUB_THREEWAY].owner) {
04402                char cid_num[256];
04403                char cid_name[256];
04404 
04405                if (!p->threewaycalling) {
04406                   /* Just send a flash if no 3-way calling */
04407                   p->subs[SUB_REAL].needflash = 1;
04408                   goto winkflashdone;
04409                } else if (!check_for_conference(p)) {
04410                   if (p->zaptrcallerid && p->owner) {
04411                      if (p->owner->cid.cid_num)
04412                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
04413                      if (p->owner->cid.cid_name)
04414                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
04415                   }
04416                   /* XXX This section needs much more error checking!!! XXX */
04417                   /* Start a 3-way call if feasible */
04418                   if (!((ast->pbx) ||
04419                         (ast->_state == AST_STATE_UP) ||
04420                         (ast->_state == AST_STATE_RING))) {
04421                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
04422                         goto winkflashdone;
04423                   }
04424                   if (alloc_sub(p, SUB_THREEWAY)) {
04425                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
04426                      goto winkflashdone;
04427                   }
04428                   /* Make new channel */
04429                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
04430                   if (p->zaptrcallerid) {
04431                      if (!p->origcid_num)
04432                         p->origcid_num = ast_strdup(p->cid_num);
04433                      if (!p->origcid_name)
04434                         p->origcid_name = ast_strdup(p->cid_name);
04435                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
04436                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
04437                   }
04438                   /* Swap things around between the three-way and real call */
04439                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
04440                   /* Disable echo canceller for better dialing */
04441                   zt_disable_ec(p);
04442                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
04443                   if (res)
04444                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
04445                   p->owner = chan;
04446                   pthread_attr_init(&attr);
04447                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04448                   if (!chan) {
04449                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
04450                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
04451                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
04452                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
04453                      zt_enable_ec(p);
04454                      ast_hangup(chan);
04455                   } else {
04456                      if (option_verbose > 2) 
04457                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
04458                      /* Start music on hold if appropriate */
04459                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
04460                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
04461                            S_OR(p->mohsuggest, NULL),
04462                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04463                      }
04464                      p->subs[SUB_THREEWAY].needhold = 1;
04465                   }
04466                   pthread_attr_destroy(&attr);
04467                }
04468             } else {
04469                /* Already have a 3 way call */
04470                if (p->subs[SUB_THREEWAY].inthreeway) {
04471                   /* Call is already up, drop the last person */
04472                   if (option_debug)
04473                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
04474                   /* If the primary call isn't answered yet, use it */
04475                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
04476                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
04477                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04478                      p->owner = p->subs[SUB_REAL].owner;
04479                   }
04480                   /* Drop the last call and stop the conference */
04481                   if (option_verbose > 2)
04482                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
04483                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04484                   p->subs[SUB_REAL].inthreeway = 0;
04485                   p->subs[SUB_THREEWAY].inthreeway = 0;
04486                } else {
04487                   /* Lets see what we're up to */
04488                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
04489                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
04490                      int otherindex = SUB_THREEWAY;
04491 
04492                      if (option_verbose > 2)
04493                         ast_verbose(VERBOSE_PREFIX_3 "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name);
04494                      /* Put them in the threeway, and flip */
04495                      p->subs[SUB_THREEWAY].inthreeway = 1;
04496                      p->subs[SUB_REAL].inthreeway = 1;
04497                      if (ast->_state == AST_STATE_UP) {
04498                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
04499                         otherindex = SUB_REAL;
04500                      }
04501                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
04502                         ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
04503                      p->subs[otherindex].needunhold = 1;
04504                      p->owner = p->subs[SUB_REAL].owner;
04505                      if (ast->_state == AST_STATE_RINGING) {
04506                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
04507                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04508                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
04509                      }
04510                   } else {
04511                      if (option_verbose > 2)
04512                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
04513                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04514                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04515                      p->owner = p->subs[SUB_REAL].owner;
04516                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
04517                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
04518                      p->subs[SUB_REAL].needunhold = 1;
04519                      zt_enable_ec(p);
04520                   }
04521                      
04522                }
04523             }
04524          winkflashdone:              
04525             update_conf(p);
04526             break;
04527          case SIG_EM:
04528          case SIG_EM_E1:
04529          case SIG_EMWINK:
04530          case SIG_FEATD:
04531          case SIG_SF:
04532          case SIG_SFWINK:
04533          case SIG_SF_FEATD:
04534          case SIG_FXSLS:
04535          case SIG_FXSGS:
04536             if (p->dialing)
04537                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
04538             else
04539                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
04540             break;
04541          case SIG_FEATDMF_TA:
04542             switch (p->whichwink) {
04543             case 0:
04544                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04545                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04546                break;
04547             case 1:
04548                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
04549                break;
04550             case 2:
04551                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
04552                return NULL;
04553             }
04554             p->whichwink++;
04555             /* Fall through */
04556          case SIG_FEATDMF:
04557          case SIG_E911:
04558          case SIG_FGC_CAMAMF:
04559          case SIG_FGC_CAMA:
04560          case SIG_FEATB:
04561          case SIG_SF_FEATDMF:
04562          case SIG_SF_FEATB:
04563             /* FGD MF *Must* wait for wink */
04564             if (!ast_strlen_zero(p->dop.dialstr)) {
04565                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04566                if (res < 0) {
04567                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04568                   p->dop.dialstr[0] = '\0';
04569                   return NULL;
04570                } else 
04571                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04572             }
04573             p->dop.dialstr[0] = '\0';
04574             break;
04575          default:
04576             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
04577          }
04578          break;
04579       case ZT_EVENT_HOOKCOMPLETE:
04580          if (p->inalarm) break;
04581          if ((p->radio || (p->oprmode < 0))) break;
04582          switch (mysig) {
04583          case SIG_FXSLS:  /* only interesting for FXS */
04584          case SIG_FXSGS:
04585          case SIG_FXSKS:
04586          case SIG_EM:
04587          case SIG_EM_E1:
04588          case SIG_EMWINK:
04589          case SIG_FEATD:
04590          case SIG_SF:
04591          case SIG_SFWINK:
04592          case SIG_SF_FEATD:
04593             if (!ast_strlen_zero(p->dop.dialstr)) {
04594                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04595                if (res < 0) {
04596                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04597                   p->dop.dialstr[0] = '\0';
04598                   return NULL;
04599                } else 
04600                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04601             }
04602             p->dop.dialstr[0] = '\0';
04603             p->dop.op = ZT_DIAL_OP_REPLACE;
04604             break;
04605          case SIG_FEATDMF:
04606          case SIG_FEATDMF_TA:
04607          case SIG_E911:
04608          case SIG_FGC_CAMA:
04609          case SIG_FGC_CAMAMF:
04610          case SIG_FEATB:
04611          case SIG_SF_FEATDMF:
04612          case SIG_SF_FEATB:
04613             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
04614             break;
04615          default:
04616             break;
04617          }
04618          break;
04619       case ZT_EVENT_POLARITY:
04620          /*
04621           * If we get a Polarity Switch event, check to see
04622           * if we should change the polarity state and
04623           * mark the channel as UP or if this is an indication
04624           * of remote end disconnect.
04625           */
04626          if (p->polarity == POLARITY_IDLE) {
04627             p->polarity = POLARITY_REV;
04628             if (p->answeronpolarityswitch &&
04629                 ((ast->_state == AST_STATE_DIALING) ||
04630                 (ast->_state == AST_STATE_RINGING))) {
04631                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
04632                ast_setstate(p->owner, AST_STATE_UP);
04633                if (p->hanguponpolarityswitch) {
04634                   gettimeofday(&p->polaritydelaytv, NULL);
04635                }
04636             } else
04637                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
04638          } 
04639          /* Removed else statement from here as it was preventing hangups from ever happening*/
04640          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
04641          if (p->hanguponpolarityswitch &&
04642             (p->polarityonanswerdelay > 0) &&
04643                 (p->polarity == POLARITY_REV) &&
04644             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
04645                                 /* Added log_debug information below to provide a better indication of what is going on */
04646             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) );
04647          
04648             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
04649                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
04650                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
04651                p->polarity = POLARITY_IDLE;
04652             } else {
04653                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);
04654             }
04655          } else {
04656             p->polarity = POLARITY_IDLE;
04657             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
04658          }
04659                         /* Added more log_debug information below to provide a better indication of what is going on */
04660          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) );
04661          break;
04662       default:
04663          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
04664    }
04665    return &p->subs[index].f;
04666 }
04667 
04668 static struct ast_frame *__zt_exception(struct ast_channel *ast)
04669 {
04670    struct zt_pvt *p = ast->tech_pvt;
04671    int res;
04672    int usedindex=-1;
04673    int index;
04674    struct ast_frame *f;
04675 
04676 
04677    index = zt_get_index(ast, p, 1);
04678    
04679    p->subs[index].f.frametype = AST_FRAME_NULL;
04680    p->subs[index].f.datalen = 0;
04681    p->subs[index].f.samples = 0;
04682    p->subs[index].f.mallocd = 0;
04683    p->subs[index].f.offset = 0;
04684    p->subs[index].f.subclass = 0;
04685    p->subs[index].f.delivery = ast_tv(0,0);
04686    p->subs[index].f.src = "zt_exception";
04687    p->subs[index].f.data = NULL;
04688    
04689    
04690    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
04691       /* If nobody owns us, absorb the event appropriately, otherwise
04692          we loop indefinitely.  This occurs when, during call waiting, the
04693          other end hangs up our channel so that it no longer exists, but we
04694          have neither FLASH'd nor ONHOOK'd to signify our desire to
04695          change to the other channel. */
04696       if (p->fake_event) {
04697          res = p->fake_event;
04698          p->fake_event = 0;
04699       } else
04700          res = zt_get_event(p->subs[SUB_REAL].zfd);
04701       /* Switch to real if there is one and this isn't something really silly... */
04702       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04703          (res != ZT_EVENT_HOOKCOMPLETE)) {
04704          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04705          p->owner = p->subs[SUB_REAL].owner;
04706          if (p->owner && ast_bridged_channel(p->owner))
04707             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04708          p->subs[SUB_REAL].needunhold = 1;
04709       }
04710       switch (res) {
04711       case ZT_EVENT_ONHOOK:
04712          zt_disable_ec(p);
04713          if (p->owner) {
04714             if (option_verbose > 2) 
04715                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04716             zt_ring_phone(p);
04717             p->callwaitingrepeat = 0;
04718             p->cidcwexpire = 0;
04719          } else
04720             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04721          update_conf(p);
04722          break;
04723       case ZT_EVENT_RINGOFFHOOK:
04724          zt_enable_ec(p);
04725          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04726          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04727             p->subs[SUB_REAL].needanswer = 1;
04728             p->dialing = 0;
04729          }
04730          break;
04731       case ZT_EVENT_HOOKCOMPLETE:
04732       case ZT_EVENT_RINGERON:
04733       case ZT_EVENT_RINGEROFF:
04734          /* Do nothing */
04735          break;
04736       case ZT_EVENT_WINKFLASH:
04737          gettimeofday(&p->flashtime, NULL);
04738          if (p->owner) {
04739             if (option_verbose > 2) 
04740                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04741             if (p->owner->_state != AST_STATE_UP) {
04742                /* Answer if necessary */
04743                usedindex = zt_get_index(p->owner, p, 0);
04744                if (usedindex > -1) {
04745                   p->subs[usedindex].needanswer = 1;
04746                }
04747                ast_setstate(p->owner, AST_STATE_UP);
04748             }
04749             p->callwaitingrepeat = 0;
04750             p->cidcwexpire = 0;
04751             if (ast_bridged_channel(p->owner))
04752                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04753             p->subs[SUB_REAL].needunhold = 1;
04754          } else
04755             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04756          update_conf(p);
04757          break;
04758       default:
04759          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04760       }
04761       f = &p->subs[index].f;
04762       return f;
04763    }
04764    if (!(p->radio || (p->oprmode < 0)) && option_debug) 
04765       ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04766    /* If it's not us, return NULL immediately */
04767    if (ast != p->owner) {
04768       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04769       f = &p->subs[index].f;
04770       return f;
04771    }
04772    f = zt_handle_event(ast);
04773    return f;
04774 }
04775 
04776 static struct ast_frame *zt_exception(struct ast_channel *ast)
04777 {
04778    struct zt_pvt *p = ast->tech_pvt;
04779    struct ast_frame *f;
04780    ast_mutex_lock(&p->lock);
04781    f = __zt_exception(ast);
04782    ast_mutex_unlock(&p->lock);
04783    return f;
04784 }
04785 
04786 static struct ast_frame  *zt_read(struct ast_channel *ast)
04787 {
04788    struct zt_pvt *p = ast->tech_pvt;
04789    int res;
04790    int index;
04791    void *readbuf;
04792    struct ast_frame *f;
04793    
04794 
04795    ast_mutex_lock(&p->lock);
04796    
04797    index = zt_get_index(ast, p, 0);
04798    
04799    /* Hang up if we don't really exist */
04800    if (index < 0) {
04801       ast_log(LOG_WARNING, "We dont exist?\n");
04802       ast_mutex_unlock(&p->lock);
04803       return NULL;
04804    }
04805    
04806    if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
04807 
04808    p->subs[index].f.frametype = AST_FRAME_NULL;
04809    p->subs[index].f.datalen = 0;
04810    p->subs[index].f.samples = 0;
04811    p->subs[index].f.mallocd = 0;
04812    p->subs[index].f.offset = 0;
04813    p->subs[index].f.subclass = 0;
04814    p->subs[index].f.delivery = ast_tv(0,0);
04815    p->subs[index].f.src = "zt_read";
04816    p->subs[index].f.data = NULL;
04817    
04818    /* make sure it sends initial key state as first frame */
04819    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
04820    {
04821       ZT_PARAMS ps;
04822 
04823       ps.channo = p->channel;
04824       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
04825          ast_mutex_unlock(&p->lock);
04826          return NULL;
04827       }
04828       p->firstradio = 1;
04829       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04830       if (ps.rxisoffhook)
04831       {
04832          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04833       }
04834       else
04835       {
04836          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04837       }
04838       ast_mutex_unlock(&p->lock);
04839       return &p->subs[index].f;
04840    }
04841    if (p->ringt == 1) {
04842       ast_mutex_unlock(&p->lock);
04843       return NULL;
04844    }
04845    else if (p->ringt > 0) 
04846       p->ringt--;
04847 
04848    if (p->subs[index].needringing) {
04849       /* Send ringing frame if requested */
04850       p->subs[index].needringing = 0;
04851       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04852       p->subs[index].f.subclass = AST_CONTROL_RINGING;
04853       ast_setstate(ast, AST_STATE_RINGING);
04854       ast_mutex_unlock(&p->lock);
04855       return &p->subs[index].f;
04856    }
04857 
04858    if (p->subs[index].needbusy) {
04859       /* Send busy frame if requested */
04860       p->subs[index].needbusy = 0;
04861       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04862       p->subs[index].f.subclass = AST_CONTROL_BUSY;
04863       ast_mutex_unlock(&p->lock);
04864       return &p->subs[index].f;
04865    }
04866 
04867    if (p->subs[index].needcongestion) {
04868       /* Send congestion frame if requested */
04869       p->subs[index].needcongestion = 0;
04870       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04871       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
04872       ast_mutex_unlock(&p->lock);
04873       return &p->subs[index].f;
04874    }
04875 
04876    if (p->subs[index].needcallerid) {
04877       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
04878                      S_OR(p->lastcid_name, NULL),
04879                      S_OR(p->lastcid_num, NULL)
04880                      );
04881       p->subs[index].needcallerid = 0;
04882    }
04883    
04884    if (p->subs[index].needanswer) {
04885       /* Send answer frame if requested */
04886       p->subs[index].needanswer = 0;
04887       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04888       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04889       ast_mutex_unlock(&p->lock);
04890       return &p->subs[index].f;
04891    }  
04892    
04893    if (p->subs[index].needflash) {
04894       /* Send answer frame if requested */
04895       p->subs[index].needflash = 0;
04896       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04897       p->subs[index].f.subclass = AST_CONTROL_FLASH;
04898       ast_mutex_unlock(&p->lock);
04899       return &p->subs[index].f;
04900    }  
04901    
04902    if (p->subs[index].needhold) {
04903       /* Send answer frame if requested */
04904       p->subs[index].needhold = 0;
04905       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04906       p->subs[index].f.subclass = AST_CONTROL_HOLD;
04907       ast_mutex_unlock(&p->lock);
04908       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
04909       return &p->subs[index].f;
04910    }  
04911    
04912    if (p->subs[index].needunhold) {
04913       /* Send answer frame if requested */
04914       p->subs[index].needunhold = 0;
04915       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04916       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
04917       ast_mutex_unlock(&p->lock);
04918       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
04919       return &p->subs[index].f;
04920    }  
04921    
04922    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
04923       if (!p->subs[index].linear) {
04924          p->subs[index].linear = 1;
04925          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04926          if (res) 
04927             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
04928       }
04929    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
04930          (ast->rawreadformat == AST_FORMAT_ALAW)) {
04931       if (p->subs[index].linear) {
04932          p->subs[index].linear = 0;
04933          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04934          if (res) 
04935             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
04936       }
04937    } else {
04938       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
04939       ast_mutex_unlock(&p->lock);
04940       return NULL;
04941    }
04942    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
04943    CHECK_BLOCKING(ast);
04944    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04945    ast_clear_flag(ast, AST_FLAG_BLOCKING);
04946    /* Check for hangup */
04947    if (res < 0) {
04948       f = NULL;
04949       if (res == -1)  {
04950          if (errno == EAGAIN) {
04951             /* Return "NULL" frame if there is nobody there */
04952             ast_mutex_unlock(&p->lock);
04953             return &p->subs[index].f;
04954          } else if (errno == ELAST) {
04955             f = __zt_exception(ast);
04956          } else
04957             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
04958       }
04959       ast_mutex_unlock(&p->lock);
04960       return f;
04961    }
04962    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
04963       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04964       f = __zt_exception(ast);
04965       ast_mutex_unlock(&p->lock);
04966       return f;
04967    }
04968    if (p->tdd) { /* if in TDD mode, see if we receive that */
04969       int c;
04970 
04971       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
04972       if (c < 0) {
04973          ast_log(LOG_DEBUG,"tdd_feed failed\n");
04974          ast_mutex_unlock(&p->lock);
04975          return NULL;
04976       }
04977       if (c) { /* if a char to return */
04978          p->subs[index].f.subclass = 0;
04979          p->subs[index].f.frametype = AST_FRAME_TEXT;
04980          p->subs[index].f.mallocd = 0;
04981          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04982          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
04983          p->subs[index].f.datalen = 1;
04984          *((char *) p->subs[index].f.data) = c;
04985          ast_mutex_unlock(&p->lock);
04986          return &p->subs[index].f;
04987       }
04988    }
04989    /* Ensure the CW timer decrements only on a single subchannel */
04990    if (p->callwaitingrepeat && zt_get_index(ast, p, 1) == SUB_REAL) {
04991       p->callwaitingrepeat--;
04992    }
04993    if (p->cidcwexpire)
04994       p->cidcwexpire--;
04995    /* Repeat callwaiting */
04996    if (p->callwaitingrepeat == 1) {
04997       p->callwaitrings++;
04998       zt_callwait(ast);
04999    }
05000    /* Expire CID/CW */
05001    if (p->cidcwexpire == 1) {
05002       if (option_verbose > 2)
05003          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
05004       restore_conference(p);
05005    }
05006    if (p->subs[index].linear) {
05007       p->subs[index].f.datalen = READ_SIZE * 2;
05008    } else 
05009       p->subs[index].f.datalen = READ_SIZE;
05010 
05011    /* Handle CallerID Transmission */
05012    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
05013       send_callerid(p);
05014    }
05015 
05016    p->subs[index].f.frametype = AST_FRAME_VOICE;
05017    p->subs[index].f.subclass = ast->rawreadformat;
05018    p->subs[index].f.samples = READ_SIZE;
05019    p->subs[index].f.mallocd = 0;
05020    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
05021    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
05022 #if 0
05023    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
05024 #endif   
05025    if (p->dialing || /* Transmitting something */
05026       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
05027       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
05028       ) {
05029       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
05030          don't send anything */
05031       p->subs[index].f.frametype = AST_FRAME_NULL;
05032       p->subs[index].f.subclass = 0;
05033       p->subs[index].f.samples = 0;
05034       p->subs[index].f.mallocd = 0;
05035       p->subs[index].f.offset = 0;
05036       p->subs[index].f.data = NULL;
05037       p->subs[index].f.datalen= 0;
05038    }
05039    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) {
05040       /* Perform busy detection. etc on the zap line */
05041       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
05042       if (f) {
05043          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
05044             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
05045                /* Treat this as a "hangup" instead of a "busy" on the assumption that
05046                   a busy  */
05047                f = NULL;
05048             }
05049          } else if (f->frametype == AST_FRAME_DTMF) {
05050 #ifdef HAVE_PRI
05051             if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) {
05052                /* Don't accept in-band DTMF when in overlap dial mode
05053                   or when in non-overlap overlapdialing mode ... */
05054                f->frametype = AST_FRAME_NULL;
05055                f->subclass = 0;
05056             }
05057 #endif            
05058             /* DSP clears us of being pulse */
05059             p->pulsedial = 0;
05060          }
05061       }
05062    } else 
05063       f = &p->subs[index].f; 
05064 
05065    if (f && (f->frametype == AST_FRAME_DTMF))
05066       zt_handle_dtmfup(ast, index, &f);
05067 
05068    /* If we have a fake_event, trigger exception to handle it */
05069    if (p->fake_event)
05070       ast_set_flag(ast, AST_FLAG_EXCEPTION);
05071 
05072    ast_mutex_unlock(&p->lock);
05073    return f;
05074 }
05075 
05076 static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
05077 {
05078    int sent=0;
05079    int size;
05080    int res;
05081    int fd;
05082    fd = p->subs[index].zfd;
05083    while (len) {
05084       size = len;
05085       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
05086          size = (linear ? READ_SIZE * 2 : READ_SIZE);
05087       res = write(fd, buf, size);
05088       if (res != size) {
05089          if (option_debug)
05090             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
05091          return sent;
05092       }
05093       len -= size;
05094       buf += size;
05095    }
05096    return sent;
05097 }
05098 
05099 static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
05100 {
05101    struct zt_pvt *p = ast->tech_pvt;
05102    int res;
05103    int index;
05104    index = zt_get_index(ast, p, 0);
05105    if (index < 0) {
05106       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
05107       return -1;
05108    }
05109 
05110 #if 0
05111 #ifdef HAVE_PRI
05112    ast_mutex_lock(&p->lock);
05113    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05114       if (p->pri->pri) {      
05115          if (!pri_grab(p, p->pri)) {
05116                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05117                pri_rel(p->pri);
05118          } else
05119                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05120       }
05121       p->proceeding=1;
05122    }
05123    ast_mutex_unlock(&p->lock);
05124 #endif
05125 #endif
05126    /* Write a frame of (presumably voice) data */
05127    if (frame->frametype != AST_FRAME_VOICE) {
05128       if (frame->frametype == AST_FRAME_TEXT) {
05129          ast_log(LOG_NOTICE, "text\n");
05130       } else if (frame->frametype != AST_FRAME_IMAGE)
05131          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
05132       return 0;
05133    }
05134    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
05135        (frame->subclass != AST_FORMAT_ULAW) &&
05136        (frame->subclass != AST_FORMAT_ALAW)) {
05137       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
05138       return -1;
05139    }
05140    if (p->dialing) {
05141       if (option_debug)
05142          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
05143       return 0;
05144    }
05145    if (!p->owner) {
05146       if (option_debug)
05147          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
05148       return 0;
05149    }
05150    if (p->cidspill) {
05151       if (option_debug)
05152          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
05153       return 0;
05154    }
05155    /* Return if it's not valid data */
05156    if (!frame->data || !frame->datalen)
05157       return 0;
05158 
05159    if (frame->subclass == AST_FORMAT_SLINEAR) {
05160       if (!p->subs[index].linear) {
05161          p->subs[index].linear = 1;
05162          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05163          if (res)
05164             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
05165       }
05166       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
05167    } else {
05168       /* x-law already */
05169       if (p->subs[index].linear) {
05170          p->subs[index].linear = 0;
05171          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05172          if (res)
05173             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
05174       }
05175       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
05176    }
05177    if (res < 0) {
05178       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
05179       return -1;
05180    } 
05181    return 0;
05182 }
05183 
05184 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
05185 {
05186    struct zt_pvt *p = chan->tech_pvt;
05187    int res=-1;
05188    int index;
05189    int func = ZT_FLASH;
05190    ast_mutex_lock(&p->lock);
05191    index = zt_get_index(chan, p, 0);
05192    if (option_debug)
05193       ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
05194    if (index == SUB_REAL) {
05195       switch (condition) {
05196       case AST_CONTROL_BUSY:
05197 #ifdef HAVE_PRI
05198          if ((p->priindication_oob == 1) && p->sig == SIG_PRI) {
05199             chan->hangupcause = AST_CAUSE_USER_BUSY;
05200             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05201             res = 0;
05202          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05203             if (p->pri->pri) {      
05204                if (!pri_grab(p, p->pri)) {
05205                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05206                   pri_rel(p->pri);
05207                }
05208                else
05209                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05210             }
05211             p->progress = 1;
05212             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05213          } else
05214 #endif
05215             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05216          break;
05217       case AST_CONTROL_RINGING:
05218 #ifdef HAVE_PRI
05219          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
05220             if (p->pri->pri) {      
05221                if (!pri_grab(p, p->pri)) {
05222                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05223                   pri_rel(p->pri);
05224                }
05225                else
05226                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05227             }
05228             p->alerting = 1;
05229          }
05230 #endif
05231          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
05232          if (chan->_state != AST_STATE_UP) {
05233             if ((chan->_state != AST_STATE_RING) ||
05234                ((p->sig != SIG_FXSKS) &&
05235                 (p->sig != SIG_FXSLS) &&
05236                 (p->sig != SIG_FXSGS)))
05237                ast_setstate(chan, AST_STATE_RINGING);
05238          }
05239          break;
05240       case AST_CONTROL_PROCEEDING:
05241          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
05242 #ifdef HAVE_PRI
05243          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05244             if (p->pri->pri) {      
05245                if (!pri_grab(p, p->pri)) {
05246                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05247                   pri_rel(p->pri);
05248                }
05249                else
05250                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05251             }
05252             p->proceeding = 1;
05253          }
05254 #endif
05255          /* don't continue in ast_indicate */
05256          res = 0;
05257          break;
05258       case AST_CONTROL_PROGRESS:
05259          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
05260 #ifdef HAVE_PRI
05261          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
05262          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05263             if (p->pri->pri) {      
05264                if (!pri_grab(p, p->pri)) {
05265                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05266                   pri_rel(p->pri);
05267                }
05268                else
05269                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05270             }
05271             p->progress = 1;
05272          }
05273 #endif
05274          /* don't continue in ast_indicate */
05275          res = 0;
05276          break;
05277       case AST_CONTROL_CONGESTION:
05278          chan->hangupcause = AST_CAUSE_CONGESTION;
05279 #ifdef HAVE_PRI
05280          if ((p->priindication_oob == 1) && p->sig == SIG_PRI) {
05281             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05282             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05283             res = 0;
05284          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05285             if (p->pri) {     
05286                if (!pri_grab(p, p->pri)) {
05287                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05288                   pri_rel(p->pri);
05289                } else
05290                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05291             }
05292             p->progress = 1;
05293             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05294          } else
05295 #endif
05296             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05297          break;
05298       case AST_CONTROL_HOLD:
05299 #ifdef HAVE_PRI
05300          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05301             if (!pri_grab(p, p->pri)) {
05302                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
05303                pri_rel(p->pri);
05304             } else
05305                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05306          } else
05307 #endif
05308             ast_moh_start(chan, data, p->mohinterpret);
05309          break;
05310       case AST_CONTROL_UNHOLD:
05311 #ifdef HAVE_PRI
05312          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05313             if (!pri_grab(p, p->pri)) {
05314                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
05315                pri_rel(p->pri);
05316             } else
05317                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05318          } else
05319 #endif
05320             ast_moh_stop(chan);
05321          break;
05322       case AST_CONTROL_RADIO_KEY:
05323          if (p->radio) 
05324              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
05325          res = 0;
05326          break;
05327       case AST_CONTROL_RADIO_UNKEY:
05328          if (p->radio)
05329              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
05330          res = 0;
05331          break;
05332       case AST_CONTROL_FLASH:
05333          /* flash hookswitch */
05334          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
05335             /* Clear out the dial buffer */
05336             p->dop.dialstr[0] = '\0';
05337             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05338                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05339                   chan->name, strerror(errno));
05340             } else
05341                res = 0;
05342          } else
05343             res = 0;
05344          break;
05345       case AST_CONTROL_SRCUPDATE:
05346          res = 0;
05347          break;
05348       case -1:
05349          res = tone_zone_play_tone(p->subs[index].zfd, -1);
05350          break;
05351       }
05352    } else
05353       res = 0;
05354    ast_mutex_unlock(&p->lock);
05355    return res;
05356 }
05357 
05358 static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
05359 {
05360    struct ast_channel *tmp;
05361    int deflaw;
05362    int res;
05363    int x,y;
05364    int features;
05365    char *b2 = NULL;
05366    ZT_PARAMS ps;
05367    if (i->subs[index].owner) {
05368       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
05369       return NULL;
05370    }
05371    y = 1;
05372    do {
05373       if (b2)
05374          free(b2);
05375 #ifdef HAVE_PRI
05376       if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
05377          b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y);
05378       else
05379 #endif
05380       if (i->channel == CHAN_PSEUDO)
05381          b2 = ast_safe_string_alloc("pseudo-%ld", ast_random());
05382       else  
05383          b2 = ast_safe_string_alloc("%d-%d", i->channel, y);
05384       for (x = 0; x < 3; x++) {
05385          if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
05386             break;
05387       }
05388       y++;
05389    } while (x < 3);
05390    tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2);
05391    if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
05392       free(b2);
05393    if (!tmp)
05394       return NULL;
05395    tmp->tech = &zap_tech;
05396    ps.channo = i->channel;
05397    res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
05398    if (res) {
05399       ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
05400       ps.curlaw = ZT_LAW_MULAW;
05401    }
05402    if (ps.curlaw == ZT_LAW_ALAW)
05403       deflaw = AST_FORMAT_ALAW;
05404    else
05405       deflaw = AST_FORMAT_ULAW;
05406    if (law) {
05407       if (law == ZT_LAW_ALAW)
05408          deflaw = AST_FORMAT_ALAW;
05409       else
05410          deflaw = AST_FORMAT_ULAW;
05411    }
05412    tmp->fds[0] = i->subs[index].zfd;
05413    tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
05414    /* Start out assuming ulaw since it's smaller :) */
05415    tmp->rawreadformat = deflaw;
05416    tmp->readformat = deflaw;
05417    tmp->rawwriteformat = deflaw;
05418    tmp->writeformat = deflaw;
05419    i->subs[index].linear = 0;
05420    zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
05421    features = 0;
05422    if (index == SUB_REAL) {
05423       if (i->busydetect && CANBUSYDETECT(i))
05424          features |= DSP_FEATURE_BUSY_DETECT;
05425       if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
05426          features |= DSP_FEATURE_CALL_PROGRESS;
05427       if ((!i->outgoing && (i->callprogress & 4)) || 
05428           (i->outgoing && (i->callprogress & 2))) {
05429          features |= DSP_FEATURE_FAX_DETECT;
05430       }
05431 #ifdef ZT_TONEDETECT
05432       x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
05433       if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
05434 #endif      
05435          i->hardwaredtmf = 0;
05436          features |= DSP_FEATURE_DTMF_DETECT;
05437 #ifdef ZT_TONEDETECT
05438       } else if (NEED_MFDETECT(i)) {
05439          i->hardwaredtmf = 1;
05440          features |= DSP_FEATURE_DTMF_DETECT;
05441       }
05442 #endif
05443    }
05444    if (features) {
05445       if (i->dsp) {
05446          ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
05447       } else {
05448          if (i->channel != CHAN_PSEUDO)
05449             i->dsp = ast_dsp_new();
05450          else
05451             i->dsp = NULL;
05452          if (i->dsp) {
05453             i->dsp_features = features & ~DSP_PROGRESS_TALK;
05454 #ifdef HAVE_PRI
05455             /* We cannot do progress detection until receives PROGRESS message */
05456             if (i->outgoing && (i->sig == SIG_PRI)) {
05457                /* Remember requested DSP features, don't treat
05458                   talking as ANSWER */
05459                features = 0;
05460             }
05461 #endif
05462             ast_dsp_set_features(i->dsp, features);
05463             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
05464             if (!ast_strlen_zero(progzone))
05465                ast_dsp_set_call_progress_zone(i->dsp, progzone);
05466             if (i->busydetect && CANBUSYDETECT(i)) {
05467                ast_dsp_set_busy_count(i->dsp, i->busycount);
05468                ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
05469             }
05470          }
05471       }
05472    }
05473       
05474    if (state == AST_STATE_RING)
05475       tmp->rings = 1;
05476    tmp->tech_pvt = i;
05477 #ifdef HAVE_PRI
05478    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS) || (i->sig == SIG_PRI)) {
05479 #else
05480    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
05481 #endif
05482       /* Only FXO signalled stuff can be picked up */ /* i dont think so, mr. ulaw! we alaws like to pick up BRIs/PRIs */
05483       tmp->callgroup = i->callgroup;
05484       tmp->pickupgroup = i->pickupgroup;
05485    }
05486    if (!ast_strlen_zero(i->language))
05487       ast_string_field_set(tmp, language, i->language);
05488    if (!i->owner)
05489       i->owner = tmp;
05490    if (!ast_strlen_zero(i->accountcode))
05491       ast_string_field_set(tmp, accountcode, i->accountcode);
05492    if (i->amaflags)
05493       tmp->amaflags = i->amaflags;
05494    i->subs[index].owner = tmp;
05495    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05496    ast_string_field_set(tmp, call_forward, i->call_forward);
05497    /* If we've been told "no ADSI" then enforce it */
05498    if (!i->adsi)
05499       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05500    if (!ast_strlen_zero(i->exten))
05501       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05502    if (!ast_strlen_zero(i->rdnis))
05503       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05504    if (!ast_strlen_zero(i->dnid))
05505       tmp->cid.cid_dnid = ast_strdup(i->dnid);
05506 
05507    /* Don't use ast_set_callerid() here because it will
05508     * generate a needless NewCallerID event */
05509 #ifdef PRI_ANI
05510    if (!ast_strlen_zero(i->cid_ani))
05511       tmp->cid.cid_ani = ast_strdup(i->cid_ani);
05512    else  
05513       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05514 #else
05515    tmp->cid.cid_ani = ast_strdup(i->cid_num);
05516 #endif
05517    tmp->cid.cid_pres = i->callingpres;
05518    tmp->cid.cid_ton = i->cid_ton;
05519 #ifdef HAVE_PRI
05520    tmp->transfercapability = transfercapability;
05521    pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
05522    if (transfercapability & PRI_TRANS_CAP_DIGITAL)
05523       i->digital = 1;
05524    /* Assume calls are not idle calls unless we're told differently */
05525    i->isidlecall = 0;
05526    i->alreadyhungup = 0;
05527 #endif
05528    /* clear the fake event in case we posted one before we had ast_channel */
05529    i->fake_event = 0;
05530    /* Assure there is no confmute on this channel */
05531    zt_confmute(i, 0);
05532    /* Configure the new channel jb */
05533    ast_jb_configure(tmp, &global_jbconf);
05534    if (startpbx) {
05535       if (ast_pbx_start(tmp)) {
05536          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05537          ast_hangup(tmp);
05538          i->owner = NULL;
05539          return NULL;
05540       }
05541    }
05542 
05543    ast_module_ref(ast_module_info->self);
05544    
05545    return tmp;
05546 }
05547 
05548 
05549 static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
05550 {
05551    char c;
05552 
05553    *str = 0; /* start with empty output buffer */
05554    for (;;)
05555    {
05556       /* Wait for the first digit (up to specified ms). */
05557       c = ast_waitfordigit(chan, ms);
05558       /* if timeout, hangup or error, return as such */
05559       if (c < 1)
05560          return c;
05561       *str++ = c;
05562       *str = 0;
05563       if (strchr(term, c))
05564          return 1;
05565    }
05566 }
05567 
05568 static int zt_wink(struct zt_pvt *p, int index)
05569 {
05570    int j;
05571    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05572    for (;;)
05573    {
05574          /* set bits of interest */
05575       j = ZT_IOMUX_SIGEVENT;
05576           /* wait for some happening */
05577       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05578          /* exit loop if we have it */
05579       if (j & ZT_IOMUX_SIGEVENT) break;
05580    }
05581      /* get the event info */
05582    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05583    return 0;
05584 }
05585 
05586 static void *ss_thread(void *data)
05587 {
05588    struct ast_channel *chan = data;
05589    struct zt_pvt *p = chan->tech_pvt;
05590    char exten[AST_MAX_EXTENSION] = "";
05591    char exten2[AST_MAX_EXTENSION] = "";
05592    unsigned char buf[256];
05593    char dtmfcid[300];
05594    char dtmfbuf[300];
05595    struct callerid_state *cs = NULL;
05596    char *name = NULL, *number = NULL;
05597    int distMatches;
05598    int curRingData[3];
05599    int receivedRingT;
05600    int counter1;
05601    int counter;
05602    int samples = 0;
05603    struct ast_smdi_md_message *smdi_msg = NULL;
05604    int flags;
05605    int i;
05606    int timeout;
05607    int getforward = 0;
05608    char *s1, *s2;
05609    int len = 0;
05610    int res;
05611    int index;
05612    int network;
05613 
05614    /* in the bizarre case where the channel has become a zombie before we
05615       even get started here, abort safely
05616    */
05617    if (!p) {
05618       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
05619       ast_hangup(chan);
05620       return NULL;
05621    }
05622 
05623    if (option_verbose > 2) 
05624       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
05625    index = zt_get_index(chan, p, 1);
05626    if (index < 0) {
05627       ast_log(LOG_WARNING, "Huh?\n");
05628       ast_hangup(chan);
05629       return NULL;
05630    }
05631    if (p->dsp)
05632       ast_dsp_digitreset(p->dsp);
05633    switch (p->sig) {
05634 #ifdef HAVE_PRI
05635    case SIG_PRI:
05636       /* Now loop looking for an extension */
05637       ast_copy_string(exten, p->exten, sizeof(exten));
05638       len = strlen(exten);
05639       res = 0;
05640       while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05641          if (len && !ast_ignore_pattern(chan->context, exten)) {
05642             tone_zone_play_tone(p->subs[index].zfd, -1);
05643          } else {
05644             network = p->pri->nodetype == PRI_NETWORK || p->pri->nodetype == BRI_NETWORK || p->pri->nodetype == BRI_NETWORK_PTMP;
05645             if (network) {
05646                 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05647             } else {
05648                 /* cpe be quiet */
05649                 tone_zone_play_tone(p->subs[index].zfd, -1);
05650             }
05651          }
05652          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
05653             timeout = matchdigittimeout;
05654          else
05655             timeout = gendigittimeout;
05656          res = ast_waitfordigit(chan, timeout);
05657          if (res < 0) {
05658             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05659             ast_hangup(chan);
05660             return NULL;
05661          } else if (res) {
05662             exten[len++] = res;
05663             exten[len] = '\0';
05664          } else
05665             break;
05666       }
05667       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
05668       if (ast_strlen_zero(exten)) {
05669          if (option_verbose > 2)
05670             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
05671          exten[0] = 's';
05672          exten[1] = '\0';
05673       }
05674       tone_zone_play_tone(p->subs[index].zfd, -1);
05675       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
05676          /* Start the real PBX */
05677          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05678          if (p->dsp) ast_dsp_digitreset(p->dsp);
05679          zt_enable_ec(p);
05680          ast_setstate(chan, AST_STATE_RING);
05681          res = ast_pbx_run(chan);
05682          if (res) {
05683             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
05684          }
05685       } else {
05686          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
05687          chan->hangupcause = AST_CAUSE_UNALLOCATED;
05688          ast_hangup(chan);
05689          p->exten[0] = '\0';
05690          /* Since we send release complete here, we won't get one */
05691          p->call = NULL;
05692       }
05693       return NULL;
05694       break;
05695 #endif
05696    case SIG_FEATD:
05697    case SIG_FEATDMF:
05698    case SIG_FEATDMF_TA:
05699    case SIG_E911:
05700    case SIG_FGC_CAMAMF:
05701    case SIG_FEATB:
05702    case SIG_EMWINK:
05703    case SIG_SF_FEATD:
05704    case SIG_SF_FEATDMF:
05705    case SIG_SF_FEATB:
05706    case SIG_SFWINK:
05707       if (zt_wink(p, index))  
05708          return NULL;
05709       /* Fall through */
05710    case SIG_EM:
05711    case SIG_EM_E1:
05712    case SIG_SF:
05713    case SIG_FGC_CAMA:
05714       res = tone_zone_play_tone(p->subs[index].zfd, -1);
05715       if (p->dsp)
05716          ast_dsp_digitreset(p->dsp);
05717       /* set digit mode appropriately */
05718       if (p->dsp) {
05719          if (NEED_MFDETECT(p))
05720             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
05721          else 
05722             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05723       }
05724       memset(dtmfbuf, 0, sizeof(dtmfbuf));
05725       /* Wait for the first digit only if immediate=no */
05726       if (!p->immediate)
05727          /* Wait for the first digit (up to 5 seconds). */
05728          res = ast_waitfordigit(chan, 5000);
05729       else
05730          res = 0;
05731       if (res > 0) {
05732          /* save first char */
05733          dtmfbuf[0] = res;
05734          switch (p->sig) {
05735          case SIG_FEATD:
05736          case SIG_SF_FEATD:
05737             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05738             if (res > 0)
05739                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05740             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05741             break;
05742          case SIG_FEATDMF_TA:
05743             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05744             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05745             if (zt_wink(p, index)) return NULL;
05746             dtmfbuf[0] = 0;
05747             /* Wait for the first digit (up to 5 seconds). */
05748             res = ast_waitfordigit(chan, 5000);
05749             if (res <= 0) break;
05750             dtmfbuf[0] = res;
05751             /* fall through intentionally */
05752          case SIG_FEATDMF:
05753          case SIG_E911:
05754          case SIG_FGC_CAMAMF:
05755          case SIG_SF_FEATDMF:
05756             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05757             /* if international caca, do it again to get real ANO */
05758             if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
05759             {
05760                if (zt_wink(p, index)) return NULL;
05761                dtmfbuf[0] = 0;
05762                /* Wait for the first digit (up to 5 seconds). */
05763                res = ast_waitfordigit(chan, 5000);
05764                if (res <= 0) break;
05765                dtmfbuf[0] = res;
05766                res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05767             }
05768             if (res > 0) {
05769                /* if E911, take off hook */
05770                if (p->sig == SIG_E911)
05771                   zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05772                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
05773             }
05774             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05775             break;
05776          case SIG_FEATB:
05777          case SIG_SF_FEATB:
05778             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05779             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05780             break;
05781          case SIG_EMWINK:
05782             /* if we received a '*', we are actually receiving Feature Group D
05783                dial syntax, so use that mode; otherwise, fall through to normal
05784                mode
05785             */
05786             if (res == '*') {
05787                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05788                if (res > 0)
05789                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05790                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05791                break;
05792             }
05793          default:
05794             /* If we got the first digit, get the rest */
05795             len = 1;
05796             dtmfbuf[len] = '\0';
05797             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05798                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05799                   timeout = matchdigittimeout;
05800                } else {
05801                   timeout = gendigittimeout;
05802                }
05803                res = ast_waitfordigit(chan, timeout);
05804                if (res < 0) {
05805                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05806                   ast_hangup(chan);
05807                   return NULL;
05808                } else if (res) {
05809                   dtmfbuf[len++] = res;
05810                   dtmfbuf[len] = '\0';
05811                } else {
05812                   break;
05813                }
05814             }
05815             break;
05816          }
05817       }
05818       if (res == -1) {
05819          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
05820          ast_hangup(chan);
05821          return NULL;
05822       } else if (res < 0) {
05823          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
05824          ast_hangup(chan);
05825          return NULL;
05826       }
05827 
05828       if (p->sig == SIG_FGC_CAMA) {
05829          char anibuf[100];
05830 
05831          if (ast_safe_sleep(chan,1000) == -1) {
05832                            ast_hangup(chan);
05833                            return NULL;
05834          }
05835                         zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05836                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
05837                         res = my_getsigstr(chan, anibuf, "#", 10000);
05838                         if ((res > 0) && (strlen(anibuf) > 2)) {
05839             if (anibuf[strlen(anibuf) - 1] == '#')
05840                anibuf[strlen(anibuf) - 1] = 0;
05841             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
05842          }
05843                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05844       }
05845 
05846       ast_copy_string(exten, dtmfbuf, sizeof(exten));
05847       if (ast_strlen_zero(exten))
05848          ast_copy_string(exten, "s", sizeof(exten));
05849       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
05850          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
05851          if (exten[0] == '*') {
05852             char *stringp=NULL;
05853             ast_copy_string(exten2, exten, sizeof(exten2));
05854             /* Parse out extension and callerid */
05855             stringp=exten2 +1;
05856             s1 = strsep(&stringp, "*");
05857             s2 = strsep(&stringp, "*");
05858             if (s2) {
05859                if (!ast_strlen_zero(p->cid_num))
05860                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05861                else
05862                   ast_set_callerid(chan, s1, NULL, s1);
05863                ast_copy_string(exten, s2, sizeof(exten));
05864             } else
05865                ast_copy_string(exten, s1, sizeof(exten));
05866          } else if (p->sig == SIG_FEATD)
05867             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05868       }
05869       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05870          if (exten[0] == '*') {
05871             char *stringp=NULL;
05872             ast_copy_string(exten2, exten, sizeof(exten2));
05873             /* Parse out extension and callerid */
05874             stringp=exten2 +1;
05875             s1 = strsep(&stringp, "#");
05876             s2 = strsep(&stringp, "#");
05877             if (s2) {
05878                if (!ast_strlen_zero(p->cid_num))
05879                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05880                else
05881                   if (*(s1 + 2))
05882                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
05883                ast_copy_string(exten, s2 + 1, sizeof(exten));
05884             } else
05885                ast_copy_string(exten, s1 + 2, sizeof(exten));
05886          } else
05887             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05888       }
05889       if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
05890          if (exten[0] == '*') {
05891             char *stringp=NULL;
05892             ast_copy_string(exten2, exten, sizeof(exten2));
05893             /* Parse out extension and callerid */
05894             stringp=exten2 +1;
05895             s1 = strsep(&stringp, "#");
05896             s2 = strsep(&stringp, "#");
05897             if (s2 && (*(s2 + 1) == '0')) {
05898                if (*(s2 + 2))
05899                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
05900             }
05901             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
05902             else ast_copy_string(exten, "911", sizeof(exten));
05903          } else
05904             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05905       }
05906       if (p->sig == SIG_FEATB) {
05907          if (exten[0] == '*') {
05908             char *stringp=NULL;
05909             ast_copy_string(exten2, exten, sizeof(exten2));
05910             /* Parse out extension and callerid */
05911             stringp=exten2 +1;
05912             s1 = strsep(&stringp, "#");
05913             ast_copy_string(exten, exten2 + 1, sizeof(exten));
05914          } else
05915             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05916       }
05917       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05918          zt_wink(p, index);
05919                         /* some switches require a minimum guard time between
05920                            the last FGD wink and something that answers
05921                            immediately. This ensures it */
05922                         if (ast_safe_sleep(chan,100)) return NULL;
05923       }
05924       zt_enable_ec(p);
05925       if (NEED_MFDETECT(p)) {
05926          if (p->dsp) {
05927             if (!p->hardwaredtmf)
05928                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
05929             else {
05930                ast_dsp_free(p->dsp);
05931                p->dsp = NULL;
05932             }
05933          }
05934       }
05935 
05936       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
05937          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05938          if (p->dsp) ast_dsp_digitreset(p->dsp);
05939          res = ast_pbx_run(chan);
05940          if (res) {
05941             ast_log(LOG_WARNING, "PBX exited non-zero\n");
05942             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05943          }
05944          return NULL;
05945       } else {
05946          if (option_verbose > 2)
05947             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
05948          sleep(2);
05949          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
05950          if (res < 0)
05951             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
05952          else
05953             sleep(1);
05954          res = ast_streamfile(chan, "ss-noservice", chan->language);
05955          if (res >= 0)
05956             ast_waitstream(chan, "");
05957          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05958          ast_hangup(chan);
05959          return NULL;
05960       }
05961       break;
05962    case SIG_FXOLS:
05963    case SIG_FXOGS:
05964    case SIG_FXOKS:
05965       /* Read the first digit */
05966       timeout = firstdigittimeout;
05967       /* If starting a threeway call, never timeout on the first digit so someone
05968          can use flash-hook as a "hold" feature */
05969       if (p->subs[SUB_THREEWAY].owner) 
05970          timeout = 999999;
05971       while (len < AST_MAX_EXTENSION-1) {
05972          /* Read digit unless it's supposed to be immediate, in which case the
05973             only answer is 's' */
05974          if (p->immediate) 
05975             res = 's';
05976          else
05977             res = ast_waitfordigit(chan, timeout);
05978          timeout = 0;
05979          if (res < 0) {
05980             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05981             res = tone_zone_play_tone(p->subs[index].zfd, -1);
05982             ast_hangup(chan);
05983             return NULL;
05984          } else if (res)  {
05985             exten[len++]=res;
05986             exten[len] = '\0';
05987          }
05988          if (!ast_ignore_pattern(chan->context, exten))
05989             tone_zone_play_tone(p->subs[index].zfd, -1);
05990          else
05991             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05992          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
05993             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05994                if (getforward) {
05995                   /* Record this as the forwarding extension */
05996                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
05997                   if (option_verbose > 2)
05998                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
05999                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06000                   if (res)
06001                      break;
06002                   usleep(500000);
06003                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
06004                   sleep(1);
06005                   memset(exten, 0, sizeof(exten));
06006                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
06007                   len = 0;
06008                   getforward = 0;
06009                } else  {
06010                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
06011                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06012                   if (!ast_strlen_zero(p->cid_num)) {
06013                      if (!p->hidecallerid)
06014                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
06015                      else
06016                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
06017                   }
06018                   if (!ast_strlen_zero(p->cid_name)) {
06019                      if (!p->hidecallerid)
06020                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
06021                   }
06022                   ast_setstate(chan, AST_STATE_RING);
06023                   zt_enable_ec(p);
06024                   res = ast_pbx_run(chan);
06025                   if (res) {
06026                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
06027                      res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06028                   }
06029                   return NULL;
06030                }
06031             } else {
06032                /* It's a match, but they just typed a digit, and there is an ambiguous match,
06033                   so just set the timeout to matchdigittimeout and wait some more */
06034                timeout = matchdigittimeout;
06035             }
06036          } else if (res == 0) {
06037             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
06038             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06039             zt_wait_event(p->subs[index].zfd);
06040             ast_hangup(chan);
06041             return NULL;
06042          } else if (p->callwaiting && !strcmp(exten, "*70")) {
06043             if (option_verbose > 2) 
06044                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
06045             /* Disable call waiting if enabled */
06046             p->callwaiting = 0;
06047             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06048             if (res) {
06049                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06050                   chan->name, strerror(errno));
06051             }
06052             len = 0;
06053             ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
06054             memset(exten, 0, sizeof(exten));
06055             timeout = firstdigittimeout;
06056                
06057          } else if (!strcmp(exten,ast_pickup_ext())) {
06058             /* Scan all channels and see if there are any
06059              * ringing channels that have call groups
06060              * that equal this channels pickup group  
06061              */
06062             if (index == SUB_REAL) {
06063                /* Switch us from Third call to Call Wait */
06064                if (p->subs[SUB_THREEWAY].owner) {
06065                   /* If you make a threeway call and the *8# a call, it should actually 
06066                      look like a callwait */
06067                   alloc_sub(p, SUB_CALLWAIT);   
06068                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
06069                   unalloc_sub(p, SUB_THREEWAY);
06070                }
06071                zt_enable_ec(p);
06072                if (ast_pickup_call(chan)) {
06073                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
06074                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06075                   zt_wait_event(p->subs[index].zfd);
06076                }
06077                ast_hangup(chan);
06078                return NULL;
06079             } else {
06080                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
06081                ast_hangup(chan);
06082                return NULL;
06083             }
06084             
06085          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
06086             if (option_verbose > 2) 
06087                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
06088             /* Disable Caller*ID if enabled */
06089             p->hidecallerid = 1;
06090             if (chan->cid.cid_num)
06091                free(chan->cid.cid_num);
06092             chan->cid.cid_num = NULL;
06093             if (chan->cid.cid_name)
06094                free(chan->cid.cid_name);
06095             chan->cid.cid_name = NULL;
06096             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06097             if (res) {
06098                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06099                   chan->name, strerror(errno));
06100             }
06101             len = 0;
06102             memset(exten, 0, sizeof(exten));
06103             timeout = firstdigittimeout;
06104          } else if (p->callreturn && !strcmp(exten, "*69")) {
06105             res = 0;
06106             if (!ast_strlen_zero(p->lastcid_num)) {
06107                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
06108             }
06109             if (!res)
06110                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06111             break;
06112          } else if (!strcmp(exten, "*78")) {
06113             /* Do not disturb */
06114             if (option_verbose > 2)
06115                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
06116             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
06117                      "Channel: Zap/%d\r\n"
06118                      "Status: enabled\r\n", p->channel);
06119             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06120             p->dnd = 1;
06121             getforward = 0;
06122             memset(exten, 0, sizeof(exten));
06123             len = 0;
06124          } else if (!strcmp(exten, "*79")) {
06125             /* Do not disturb */
06126             if (option_verbose > 2)
06127                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
06128             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
06129                      "Channel: Zap/%d\r\n"
06130                      "Status: disabled\r\n", p->channel);
06131             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06132             p->dnd = 0;
06133             getforward = 0;
06134             memset(exten, 0, sizeof(exten));
06135             len = 0;
06136          } else if (p->cancallforward && !strcmp(exten, "*72")) {
06137             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06138             getforward = 1;
06139             memset(exten, 0, sizeof(exten));
06140             len = 0;
06141          } else if (p->cancallforward && !strcmp(exten, "*73")) {
06142             if (option_verbose > 2)
06143                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
06144             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06145             memset(p->call_forward, 0, sizeof(p->call_forward));
06146             getforward = 0;
06147             memset(exten, 0, sizeof(exten));
06148             len = 0;
06149          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
06150                   p->subs[SUB_THREEWAY].owner &&
06151                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
06152             /* This is a three way call, the main call being a real channel, 
06153                and we're parking the first call. */
06154             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
06155             if (option_verbose > 2)
06156                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
06157             break;
06158          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
06159             if (option_verbose > 2)
06160                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
06161             res = ast_db_put("blacklist", p->lastcid_num, "1");
06162             if (!res) {
06163                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06164                memset(exten, 0, sizeof(exten));
06165                len = 0;
06166             }
06167          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
06168             if (option_verbose > 2) 
06169                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
06170             /* Enable Caller*ID if enabled */
06171             p->hidecallerid = 0;
06172             if (chan->cid.cid_num)
06173                free(chan->cid.cid_num);
06174             chan->cid.cid_num = NULL;
06175             if (chan->cid.cid_name)
06176                free(chan->cid.cid_name);
06177             chan->cid.cid_name = NULL;
06178             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
06179             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06180             if (res) {
06181                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06182                   chan->name, strerror(errno));
06183             }
06184             len = 0;
06185             memset(exten, 0, sizeof(exten));
06186             timeout = firstdigittimeout;
06187          } else if (!strcmp(exten, "*0")) {
06188             struct ast_channel *nbridge = 
06189                p->subs[SUB_THREEWAY].owner;
06190             struct zt_pvt *pbridge = NULL;
06191               /* set up the private struct of the bridged one, if any */
06192             if (nbridge && ast_bridged_channel(nbridge)) 
06193                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
06194             if (nbridge && pbridge && 
06195                 (nbridge->tech == &zap_tech) && 
06196                 (ast_bridged_channel(nbridge)->tech == &zap_tech) &&
06197                 ISTRUNK(pbridge)) {
06198                int func = ZT_FLASH;
06199                /* Clear out the dial buffer */
06200                p->dop.dialstr[0] = '\0';
06201                /* flash hookswitch */
06202                if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
06203                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
06204                      nbridge->name, strerror(errno));
06205                }
06206                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06207                unalloc_sub(p, SUB_THREEWAY);
06208                p->owner = p->subs[SUB_REAL].owner;
06209                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
06210                   ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
06211                ast_hangup(chan);
06212                return NULL;
06213             } else {
06214                tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06215                zt_wait_event(p->subs[index].zfd);
06216                tone_zone_play_tone(p->subs[index].zfd, -1);
06217                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06218                unalloc_sub(p, SUB_THREEWAY);
06219                p->owner = p->subs[SUB_REAL].owner;
06220                ast_hangup(chan);
06221                return NULL;
06222             }              
06223          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
06224                      ((exten[0] != '*') || (strlen(exten) > 2))) {
06225             if (option_debug)
06226                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);
06227             break;
06228          }
06229          if (!timeout)
06230             timeout = gendigittimeout;
06231          if (len && !ast_ignore_pattern(chan->context, exten))
06232             tone_zone_play_tone(p->subs[index].zfd, -1);
06233       }
06234       break;
06235    case SIG_FXSLS:
06236    case SIG_FXSGS:
06237    case SIG_FXSKS:
06238 #ifdef HAVE_PRI
06239       if (p->pri) {
06240          /* This is a GR-303 trunk actually.  Wait for the first ring... */
06241          struct ast_frame *f;
06242          int res;
06243          time_t start;
06244 
06245          time(&start);
06246          ast_setstate(chan, AST_STATE_RING);
06247          while (time(NULL) < start + 3) {
06248             res = ast_waitfor(chan, 1000);
06249             if (res) {
06250                f = ast_read(chan);
06251                if (!f) {
06252                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
06253                   ast_hangup(chan);
06254                   return NULL;
06255                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
06256                   res = 1;
06257                } else
06258                   res = 0;
06259                ast_frfree(f);
06260                if (res) {
06261                   ast_log(LOG_DEBUG, "Got ring!\n");
06262                   res = 0;
06263                   break;
06264                }
06265             }
06266          }
06267       }
06268 #endif
06269       /* check for SMDI messages */
06270       if (p->use_smdi && p->smdi_iface) {
06271          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
06272 
06273          if (smdi_msg != NULL) {
06274             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
06275 
06276             if (smdi_msg->type == 'B')
06277                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
06278             else if (smdi_msg->type == 'N')
06279                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
06280 
06281             ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
06282          } else {
06283             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
06284          }
06285       }
06286 
06287       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
06288             number = smdi_msg->calling_st;
06289 
06290       /* If we want caller id, we're in a prering state due to a polarity reversal
06291        * and we're set to use a polarity reversal to trigger the start of caller id,
06292        * grab the caller id and wait for ringing to start... */
06293       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
06294          /* If set to use DTMF CID signalling, listen for DTMF */
06295          if (p->cid_signalling == CID_SIG_DTMF) {
06296             int i = 0;
06297             cs = NULL;
06298             ast_log(LOG_DEBUG, "Receiving DTMF cid on "
06299                "channel %s\n", chan->name);
06300             zt_setlinear(p->subs[index].zfd, 0);
06301             res = 2000;
06302             for (;;) {
06303                struct ast_frame *f;
06304                res = ast_waitfor(chan, res);
06305                if (res <= 0) {
06306                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
06307                      "Exiting simple switch\n");
06308                   ast_hangup(chan);
06309                   return NULL;
06310                } 
06311                f = ast_read(chan);
06312                if (!f)
06313                   break;
06314                if (f->frametype == AST_FRAME_DTMF) {
06315                   dtmfbuf[i++] = f->subclass;
06316                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
06317                   res = 2000;
06318                }
06319                ast_frfree(f);
06320                if (chan->_state == AST_STATE_RING ||
06321                    chan->_state == AST_STATE_RINGING) 
06322                   break; /* Got ring */
06323             }
06324             dtmfbuf[i] = '\0';
06325             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06326             /* Got cid and ring. */
06327             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
06328             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
06329             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
06330                dtmfcid, flags);
06331             /* If first byte is NULL, we have no cid */
06332             if (!ast_strlen_zero(dtmfcid)) 
06333                number = dtmfcid;
06334             else
06335                number = NULL;
06336          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
06337          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
06338             cs = callerid_new(p->cid_signalling);
06339             if (cs) {
06340                samples = 0;
06341 #if 1
06342                bump_gains(p);
06343 #endif            
06344                /* Take out of linear mode for Caller*ID processing */
06345                zt_setlinear(p->subs[index].zfd, 0);
06346                
06347                /* First we wait and listen for the Caller*ID */
06348                for (;;) {  
06349                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06350                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06351                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06352                      callerid_free(cs);
06353                      ast_hangup(chan);
06354                      return NULL;
06355                   }
06356                   if (i & ZT_IOMUX_SIGEVENT) {
06357                      res = zt_get_event(p->subs[index].zfd);
06358                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06359 
06360                      if (p->cid_signalling == CID_SIG_V23_JP) {
06361 #ifdef ZT_EVENT_RINGBEGIN
06362                         if (res == ZT_EVENT_RINGBEGIN) {
06363                            res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06364                            usleep(1);
06365                         }
06366 #endif
06367                      } else {
06368                         res = 0;
06369                         break;
06370                      }
06371                   } else if (i & ZT_IOMUX_READ) {
06372                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06373                      if (res < 0) {
06374                         if (errno != ELAST) {
06375                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06376                            callerid_free(cs);
06377                            ast_hangup(chan);
06378                            return NULL;
06379                         }
06380                         break;
06381                      }
06382                      samples += res;
06383 
06384                      if  (p->cid_signalling == CID_SIG_V23_JP) {
06385                         res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
06386                      } else {
06387                         res = callerid_feed(cs, buf, res, AST_LAW(p));
06388                      }
06389 
06390                      if (res < 0) {
06391                         ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name);
06392                         break;
06393                      } else if (res)
06394                         break;
06395                      else if (samples > (8000 * 10))
06396                         break;
06397                   }
06398                }
06399                if (res == 1) {
06400                   callerid_get(cs, &name, &number, &flags);
06401                   ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06402                }
06403 
06404                if (p->cid_signalling == CID_SIG_V23_JP) {
06405                   res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
06406                   usleep(1);
06407                   res = 4000;
06408                } else {
06409 
06410                   /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
06411                   res = 2000;
06412                }
06413 
06414                for (;;) {
06415                   struct ast_frame *f;
06416                   res = ast_waitfor(chan, res);
06417                   if (res <= 0) {
06418                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
06419                         "Exiting simple switch\n");
06420                      ast_hangup(chan);
06421                      return NULL;
06422                   } 
06423                   f = ast_read(chan);
06424                   ast_frfree(f);
06425                   if (chan->_state == AST_STATE_RING ||
06426                       chan->_state == AST_STATE_RINGING) 
06427                      break; /* Got ring */
06428                }
06429    
06430                /* We must have a ring by now, so, if configured, lets try to listen for
06431                 * distinctive ringing */ 
06432                if (p->usedistinctiveringdetection == 1) {
06433                   len = 0;
06434                   distMatches = 0;
06435                   /* Clear the current ring data array so we dont have old data in it. */
06436                   for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06437                      curRingData[receivedRingT] = 0;
06438                   receivedRingT = 0;
06439                   counter = 0;
06440                   counter1 = 0;
06441                   /* Check to see if context is what it should be, if not set to be. */
06442                   if (strcmp(p->context,p->defcontext) != 0) {
06443                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06444                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06445                   }
06446       
06447                   for (;;) {  
06448                      i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06449                      if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06450                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06451                         callerid_free(cs);
06452                         ast_hangup(chan);
06453                         return NULL;
06454                      }
06455                      if (i & ZT_IOMUX_SIGEVENT) {
06456                         res = zt_get_event(p->subs[index].zfd);
06457                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06458                         res = 0;
06459                         /* Let us detect distinctive ring */
06460       
06461                         curRingData[receivedRingT] = p->ringt;
06462       
06463                         if (p->ringt < p->ringt_base/2)
06464                            break;
06465                         /* Increment the ringT counter so we can match it against
06466                            values in zapata.conf for distinctive ring */
06467                         if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06468                            break;
06469                      } else if (i & ZT_IOMUX_READ) {
06470                         res = read(p->subs[index].zfd, buf, sizeof(buf));
06471                         if (res < 0) {
06472                            if (errno != ELAST) {
06473                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06474                               callerid_free(cs);
06475                               ast_hangup(chan);
06476                               return NULL;
06477                            }
06478                            break;
06479                         }
06480                         if (p->ringt) 
06481                            p->ringt--;
06482                         if (p->ringt == 1) {
06483                            res = -1;
06484                            break;
06485                         }
06486                      }
06487                   }
06488                   if (option_verbose > 2)
06489                      /* this only shows up if you have n of the dring patterns filled in */
06490                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06491    
06492                   for (counter = 0; counter < 3; counter++) {
06493                      /* Check to see if the rings we received match any of the ones in zapata.conf for this
06494                      channel */
06495                      distMatches = 0;
06496                      for (counter1 = 0; counter1 < 3; counter1++) {
06497                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06498                         (p->drings.ringnum[counter].ring[counter1]-10)) {
06499                            distMatches++;
06500                         }
06501                      }
06502                      if (distMatches == 3) {
06503                         /* The ring matches, set the context to whatever is for distinctive ring.. */
06504                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06505                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06506                         if (option_verbose > 2)
06507                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06508                         break;
06509                      }
06510                   }
06511                }
06512                /* Restore linear mode (if appropriate) for Caller*ID processing */
06513                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06514 #if 1
06515                restore_gains(p);
06516 #endif            
06517             } else
06518                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
06519          } else {
06520             ast_log(LOG_WARNING, "Channel %s in prering "
06521                "state, but I have nothing to do. "
06522                "Terminating simple switch, should be "
06523                "restarted by the actual ring.\n", 
06524                chan->name);
06525             ast_hangup(chan);
06526             return NULL;
06527          }
06528       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
06529          /* FSK Bell202 callerID */
06530          cs = callerid_new(p->cid_signalling);
06531          if (cs) {
06532 #if 1
06533             bump_gains(p);
06534 #endif            
06535             samples = 0;
06536             len = 0;
06537             distMatches = 0;
06538             /* Clear the current ring data array so we dont have old data in it. */
06539             for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06540                curRingData[receivedRingT] = 0;
06541             receivedRingT = 0;
06542             counter = 0;
06543             counter1 = 0;
06544             /* Check to see if context is what it should be, if not set to be. */
06545             if (strcmp(p->context,p->defcontext) != 0) {
06546                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06547                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06548             }
06549 
06550             /* Take out of linear mode for Caller*ID processing */
06551             zt_setlinear(p->subs[index].zfd, 0);
06552             for (;;) {  
06553                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06554                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06555                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06556                   callerid_free(cs);
06557                   ast_hangup(chan);
06558                   return NULL;
06559                }
06560                if (i & ZT_IOMUX_SIGEVENT) {
06561                   res = zt_get_event(p->subs[index].zfd);
06562                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06563                   /* If we get a PR event, they hung up while processing calerid */
06564                   if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
06565                      ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
06566                      p->polarity = POLARITY_IDLE;
06567                      callerid_free(cs);
06568                      ast_hangup(chan);
06569                      return NULL;
06570                   }
06571                   res = 0;
06572                   /* Let us detect callerid when the telco uses distinctive ring */
06573 
06574                   curRingData[receivedRingT] = p->ringt;
06575 
06576                   if (p->ringt < p->ringt_base/2)
06577                      break;
06578                   /* Increment the ringT counter so we can match it against
06579                      values in zapata.conf for distinctive ring */
06580                   if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06581                      break;
06582                } else if (i & ZT_IOMUX_READ) {
06583                   res = read(p->subs[index].zfd, buf, sizeof(buf));
06584                   if (res < 0) {
06585                      if (errno != ELAST) {
06586                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06587                         callerid_free(cs);
06588                         ast_hangup(chan);
06589                         return NULL;
06590                      }
06591                      break;
06592                   }
06593                   if (p->ringt) 
06594                      p->ringt--;
06595                   if (p->ringt == 1) {
06596                      res = -1;
06597                      break;
06598                   }
06599                   samples += res;
06600                   res = callerid_feed(cs, buf, res, AST_LAW(p));
06601                   if (res < 0) {
06602                      ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06603                      break;
06604                   } else if (res)
06605                      break;
06606                   else if (samples > (8000 * 10))
06607                      break;
06608                }
06609             }
06610             if (res == 1) {
06611                callerid_get(cs, &name, &number, &flags);
06612                if (option_debug)
06613                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06614             }
06615             if (distinctiveringaftercid == 1) {
06616                /* Clear the current ring data array so we dont have old data in it. */
06617                for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
06618                   curRingData[receivedRingT] = 0;
06619                }
06620                receivedRingT = 0;
06621                if (option_verbose > 2)
06622                   ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
06623                for (;;) {
06624                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06625                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))    {
06626                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06627                      callerid_free(cs);
06628                      ast_hangup(chan);
06629                      return NULL;
06630                   }
06631                   if (i & ZT_IOMUX_SIGEVENT) {
06632                      res = zt_get_event(p->subs[index].zfd);
06633                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06634                      res = 0;
06635                      /* Let us detect callerid when the telco uses distinctive ring */
06636 
06637                      curRingData[receivedRingT] = p->ringt;
06638 
06639                      if (p->ringt < p->ringt_base/2)
06640                         break;
06641                      /* Increment the ringT counter so we can match it against
06642                         values in zapata.conf for distinctive ring */
06643                      if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06644                         break;
06645                   } else if (i & ZT_IOMUX_READ) {
06646                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06647                      if (res < 0) {
06648                         if (errno != ELAST) {
06649                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06650                            callerid_free(cs);
06651                            ast_hangup(chan);
06652                            return NULL;
06653                         }
06654                         break;
06655                      }
06656                   if (p->ringt)
06657                      p->ringt--;
06658                      if (p->ringt == 1) {
06659                         res = -1;
06660                         break;
06661                      }
06662                   }
06663                }
06664             }
06665             if (p->usedistinctiveringdetection == 1) {
06666                if (option_verbose > 2)
06667                   /* this only shows up if you have n of the dring patterns filled in */
06668                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06669 
06670                for (counter = 0; counter < 3; counter++) {
06671                   /* Check to see if the rings we received match any of the ones in zapata.conf for this
06672                   channel */
06673                   if (option_verbose > 2)
06674                      /* this only shows up if you have n of the dring patterns filled in */
06675                      ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
06676                         p->drings.ringnum[counter].ring[0],
06677                         p->drings.ringnum[counter].ring[1],
06678                         p->drings.ringnum[counter].ring[2]);
06679                   distMatches = 0;
06680                   for (counter1 = 0; counter1 < 3; counter1++) {
06681                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06682                      (p->drings.ringnum[counter].ring[counter1]-10)) {
06683                         distMatches++;
06684                      }
06685                   }
06686                   if (distMatches == 3) {
06687                      /* The ring matches, set the context to whatever is for distinctive ring.. */
06688                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06689                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06690                      if (option_verbose > 2)
06691                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06692                      break;
06693                   }
06694                }
06695             }
06696             /* Restore linear mode (if appropriate) for Caller*ID processing */
06697             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06698 #if 1
06699             restore_gains(p);
06700 #endif            
06701             if (res < 0) {
06702                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06703             }
06704          } else
06705             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
06706       }
06707       else
06708          cs = NULL;
06709 
06710       if (number)
06711          ast_shrink_phone_number(number);
06712       ast_set_callerid(chan, number, name, number);
06713 
06714       if (smdi_msg)
06715          ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
06716 
06717       if (cs)
06718          callerid_free(cs);
06719 
06720       ast_setstate(chan, AST_STATE_RING);
06721       chan->rings = 1;
06722       p->ringt = p->ringt_base;
06723       res = ast_pbx_run(chan);
06724       if (res) {
06725          ast_hangup(chan);
06726          ast_log(LOG_WARNING, "PBX exited non-zero\n");
06727       }
06728       return NULL;
06729    default:
06730       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
06731       res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06732       if (res < 0)
06733             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06734    }
06735    res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06736    if (res < 0)
06737          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06738    ast_hangup(chan);
06739    return NULL;
06740 }
06741 
06742 /* destroy a zaptel channel, identified by its number */
06743 static int zap_destroy_channel_bynum(int channel)
06744 {
06745    struct zt_pvt *tmp = NULL;
06746    struct zt_pvt *prev = NULL;
06747 
06748    tmp = iflist;
06749    while (tmp) {
06750       if (tmp->channel == channel) {
06751          destroy_channel(prev, tmp, 1);
06752          return RESULT_SUCCESS;
06753       }
06754       prev = tmp;
06755       tmp = tmp->next;
06756    }
06757    return RESULT_FAILURE;
06758 }
06759 
06760 static int handle_init_event(struct zt_pvt *i, int event)
06761 {
06762    int res;
06763    pthread_t threadid;
06764    pthread_attr_t attr;
06765    struct ast_channel *chan;
06766    pthread_attr_init(&attr);
06767    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06768    /* Handle an event on a given channel for the monitor thread. */
06769    switch (event) {
06770    case ZT_EVENT_NONE:
06771    case ZT_EVENT_BITSCHANGED:
06772       break;
06773    case ZT_EVENT_WINKFLASH:
06774    case ZT_EVENT_RINGOFFHOOK:
06775       if (i->inalarm) break;
06776       if (i->radio) break;
06777       /* Got a ring/answer.  What kind of channel are we? */
06778       switch (i->sig) {
06779       case SIG_FXOLS:
06780       case SIG_FXOGS:
06781       case SIG_FXOKS:
06782          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06783          if (res && (errno == EBUSY))
06784             break;
06785          if (i->cidspill) {
06786             /* Cancel VMWI spill */
06787             free(i->cidspill);
06788             i->cidspill = NULL;
06789          }
06790          if (i->immediate) {
06791             zt_enable_ec(i);
06792             /* The channel is immediately up.  Start right away */
06793             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06794             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06795             if (!chan) {
06796                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06797                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06798                if (res < 0)
06799                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06800             }
06801          } else {
06802             /* Check for callerid, digits, etc */
06803             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06804             if (chan) {
06805                if (has_voicemail(i))
06806                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06807                else
06808                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06809                if (res < 0) 
06810                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
06811                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06812                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06813                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06814                   if (res < 0)
06815                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06816                   ast_hangup(chan);
06817                }
06818             } else
06819                ast_log(LOG_WARNING, "Unable to create channel\n");
06820          }
06821          break;
06822       case SIG_FXSLS:
06823       case SIG_FXSGS:
06824       case SIG_FXSKS:
06825             i->ringt = i->ringt_base;
06826             /* Fall through */
06827       case SIG_EMWINK:
06828       case SIG_FEATD:
06829       case SIG_FEATDMF:
06830       case SIG_FEATDMF_TA:
06831       case SIG_E911:
06832       case SIG_FGC_CAMA:
06833       case SIG_FGC_CAMAMF:
06834       case SIG_FEATB:
06835       case SIG_EM:
06836       case SIG_EM_E1:
06837       case SIG_SFWINK:
06838       case SIG_SF_FEATD:
06839       case SIG_SF_FEATDMF:
06840       case SIG_SF_FEATB:
06841       case SIG_SF:
06842             /* Check for callerid, digits, etc */
06843             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06844             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06845                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06846                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06847                if (res < 0)
06848                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06849                ast_hangup(chan);
06850             } else if (!chan) {
06851                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06852             }
06853             break;
06854       default:
06855          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06856          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06857          if (res < 0)
06858                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06859          return -1;
06860       }
06861       break;
06862    case ZT_EVENT_NOALARM:
06863       i->inalarm = 0;
06864       if (!i->unknown_alarm) {
06865 #ifdef HAVE_PRI
06866           if (i->pri) {
06867          if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) {
06868              /* dont annoy BRI TE mode users with layer2layer alarms */
06869          } else {
06870 #endif
06871          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06872          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06873             "Channel: %d\r\n", i->channel);
06874 #ifdef HAVE_PRI
06875          }
06876           }
06877 #endif
06878 
06879       } else {
06880          i->unknown_alarm = 0;
06881       }
06882       break;
06883    case ZT_EVENT_ALARM:
06884       i->inalarm = 1;
06885       res = get_alarms(i);
06886       do {
06887 #ifdef HAVE_PRI
06888           if (i->pri) {
06889          if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) {
06890              /* dont annoy BRI TE mode users with layer2layer alarms */
06891          } else {
06892 #endif
06893              const char *alarm_str = alarm2str(res);
06894 
06895          /* hack alert!  Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
06896           * doesn't know what to do with it.  Don't confuse users with log messages. */
06897          if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
06898             i->unknown_alarm = 1;
06899             break;
06900          } else {
06901             i->unknown_alarm = 0;
06902          }
06903 
06904          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm_str);
06905          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06906             "Alarm: %s\r\n"
06907             "Channel: %d\r\n",
06908             alarm_str, i->channel);
06909 #ifdef HAVE_PRI
06910          }
06911           }
06912 #endif
06913       } while (0);
06914       /* fall thru intentionally */
06915    case ZT_EVENT_ONHOOK:
06916       if (i->radio)
06917          break;
06918       /* Back on hook.  Hang up. */
06919       switch (i->sig) {
06920       case SIG_FXOLS:
06921       case SIG_FXOGS:
06922       case SIG_FEATD:
06923       case SIG_FEATDMF:
06924       case SIG_FEATDMF_TA:
06925       case SIG_E911:
06926       case SIG_FGC_CAMA:
06927       case SIG_FGC_CAMAMF:
06928       case SIG_FEATB:
06929       case SIG_EM:
06930       case SIG_EM_E1:
06931       case SIG_EMWINK:
06932       case SIG_SF_FEATD:
06933       case SIG_SF_FEATDMF:
06934       case SIG_SF_FEATB:
06935       case SIG_SF:
06936       case SIG_SFWINK:
06937       case SIG_FXSLS:
06938       case SIG_FXSGS:
06939       case SIG_FXSKS:
06940       case SIG_GR303FXSKS:
06941          zt_disable_ec(i);
06942          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06943          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06944          break;
06945       case SIG_GR303FXOKS:
06946       case SIG_FXOKS:
06947          zt_disable_ec(i);
06948          /* Diddle the battery for the zhone */
06949 #ifdef ZHONE_HACK
06950          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06951          usleep(1);
06952 #endif         
06953          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06954          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06955          break;
06956       case SIG_PRI:
06957          if (event != ZT_EVENT_ALARM) {
06958              zt_disable_ec(i);
06959              res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06960          }
06961          break;
06962       default:
06963          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06964          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06965          return -1;
06966       }
06967       break;
06968    case ZT_EVENT_POLARITY:
06969       switch (i->sig) {
06970       case SIG_FXSLS:
06971       case SIG_FXSKS:
06972       case SIG_FXSGS:
06973          /* We have already got a PR before the channel was 
06974             created, but it wasn't handled. We need polarity 
06975             to be REV for remote hangup detection to work. 
06976             At least in Spain */
06977          if (i->hanguponpolarityswitch)
06978             i->polarity = POLARITY_REV;
06979 
06980          if (i->cid_start == CID_START_POLARITY) {
06981             i->polarity = POLARITY_REV;
06982             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
06983                    "CID detection on channel %d\n",
06984                    i->channel);
06985             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
06986             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06987                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06988             }
06989          }
06990          break;
06991       default:
06992          ast_log(LOG_WARNING, "handle_init_event detected "
06993             "polarity reversal on non-FXO (SIG_FXS) "
06994             "interface %d\n", i->channel);
06995       }
06996       break;
06997    case ZT_EVENT_REMOVED: /* destroy channel */
06998       ast_log(LOG_NOTICE, 
06999             "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 
07000             i->channel);
07001       zap_destroy_channel_bynum(i->channel);
07002       break;
07003    }
07004    pthread_attr_destroy(&attr);
07005    return 0;
07006 }
07007 
07008 static void *do_monitor(void *data)
07009 {
07010    int count, res, res2, spoint, pollres=0;
07011    struct zt_pvt *i;
07012    struct zt_pvt *last = NULL;
07013    time_t thispass = 0, lastpass = 0;
07014    int found;
07015    char buf[1024];
07016    struct pollfd *pfds=NULL;
07017    int lastalloc = -1;
07018    /* This thread monitors all the frame relay interfaces which are not yet in use
07019       (and thus do not have a separate thread) indefinitely */
07020    /* From here on out, we die whenever asked */
07021 #if 0
07022    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
07023       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
07024       return NULL;
07025    }
07026    ast_log(LOG_DEBUG, "Monitor starting...\n");
07027 #endif
07028    for (;;) {
07029       /* Lock the interface list */
07030       ast_mutex_lock(&iflock);
07031       if (!pfds || (lastalloc != ifcount)) {
07032          if (pfds) {
07033             free(pfds);
07034             pfds = NULL;
07035          }
07036          if (ifcount) {
07037             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
07038                ast_mutex_unlock(&iflock);
07039                return NULL;
07040             }
07041          }
07042          lastalloc = ifcount;
07043       }
07044       /* Build the stuff we're going to poll on, that is the socket of every
07045          zt_pvt that does not have an associated owner channel */
07046       count = 0;
07047       i = iflist;
07048       while (i) {
07049          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
07050             if (!i->owner && !i->subs[SUB_REAL].owner) {
07051                /* This needs to be watched, as it lacks an owner */
07052                pfds[count].fd = i->subs[SUB_REAL].zfd;
07053                pfds[count].events = POLLPRI;
07054                pfds[count].revents = 0;
07055                /* Message waiting or r2 channels also get watched for reading */
07056                if (i->cidspill)
07057                   pfds[count].events |= POLLIN;
07058                count++;
07059             }
07060          }
07061          i = i->next;
07062       }
07063       /* Okay, now that we know what to do, release the interface lock */
07064       ast_mutex_unlock(&iflock);
07065       
07066       pthread_testcancel();
07067       /* Wait at least a second for something to happen */
07068       res = poll(pfds, count, 1000);
07069       pthread_testcancel();
07070       /* Okay, poll has finished.  Let's see what happened.  */
07071       if (res < 0) {
07072          if ((errno != EAGAIN) && (errno != EINTR))
07073             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
07074          continue;
07075       }
07076       /* Alright, lock the interface list again, and let's look and see what has
07077          happened */
07078       ast_mutex_lock(&iflock);
07079       found = 0;
07080       spoint = 0;
07081       lastpass = thispass;
07082       thispass = time(NULL);
07083       i = iflist;
07084       while (i) {
07085          if (thispass != lastpass) {
07086             if (!found && ((i == last) || ((i == iflist) && !last))) {
07087                last = i;
07088                if (last) {
07089                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
07090                      (last->sig & __ZT_SIG_FXO)) {
07091                      res = ast_app_has_voicemail(last->mailbox, NULL);
07092                      if (last->msgstate != res) {
07093                         int x;
07094                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
07095                         x = ZT_FLUSH_BOTH;
07096                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
07097                         if (res2)
07098                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
07099                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
07100                            /* Turn on on hook transfer for 4 seconds */
07101                            x = 4000;
07102                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
07103                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
07104                            last->cidpos = 0;
07105                            last->msgstate = res;
07106                            last->onhooktime = thispass;
07107                         }
07108                         found ++;
07109                      }
07110                   }
07111                   last = last->next;
07112                }
07113             }
07114          }
07115          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
07116             if (i->radio && !i->owner)
07117             {
07118                res = zt_get_event(i->subs[SUB_REAL].zfd);
07119                if (res)
07120                {
07121                   if (option_debug)
07122                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
07123                   /* Don't hold iflock while handling init events */
07124                   ast_mutex_unlock(&iflock);
07125                   handle_init_event(i, res);
07126                   ast_mutex_lock(&iflock);   
07127                }
07128                i = i->next;
07129                continue;
07130             }              
07131             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
07132             if (pollres & POLLIN) {
07133                if (i->owner || i->subs[SUB_REAL].owner) {
07134 #ifdef HAVE_PRI
07135                   if (!i->pri)
07136 #endif                  
07137                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
07138                   i = i->next;
07139                   continue;
07140                }
07141                if (!i->cidspill) {
07142                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
07143                   i = i->next;
07144                   continue;
07145                }
07146                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
07147                if (res > 0) {
07148                   /* We read some number of bytes.  Write an equal amount of data */
07149                   if (res > i->cidlen - i->cidpos) 
07150                      res = i->cidlen - i->cidpos;
07151                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
07152                   if (res2 > 0) {
07153                      i->cidpos += res2;
07154                      if (i->cidpos >= i->cidlen) {
07155                         free(i->cidspill);
07156                         i->cidspill = 0;
07157                         i->cidpos = 0;
07158                         i->cidlen = 0;
07159                      }
07160                   } else {
07161                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
07162                      i->msgstate = -1;
07163                   }
07164                } else {
07165                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
07166                }
07167             }
07168             if (pollres & POLLPRI) {
07169                if (i->owner || i->subs[SUB_REAL].owner) {
07170 #ifdef HAVE_PRI
07171                   if (!i->pri)
07172 #endif                  
07173                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
07174                   i = i->next;
07175                   continue;
07176                }
07177                res = zt_get_event(i->subs[SUB_REAL].zfd);
07178                if (option_debug)
07179                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
07180                /* Don't hold iflock while handling init events */
07181                ast_mutex_unlock(&iflock);
07182                handle_init_event(i, res);
07183                ast_mutex_lock(&iflock);   
07184             }
07185          }
07186          i=i->next;
07187       }
07188       ast_mutex_unlock(&iflock);
07189    }
07190    /* Never reached */
07191    return NULL;
07192    
07193 }
07194 
07195 static int restart_monitor(void)
07196 {
07197    pthread_attr_t attr;
07198    pthread_attr_init(&attr);
07199    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
07200    /* If we're supposed to be stopped -- stay stopped */
07201    if (monitor_thread == AST_PTHREADT_STOP)
07202       return 0;
07203    ast_mutex_lock(&monlock);
07204    if (monitor_thread == pthread_self()) {
07205       ast_mutex_unlock(&monlock);
07206       ast_log(LOG_WARNING, "Cannot kill myself\n");
07207       return -1;
07208    }
07209    if (monitor_thread != AST_PTHREADT_NULL) {
07210       /* Wake up the thread */
07211       pthread_kill(monitor_thread, SIGURG);
07212    } else {
07213       /* Start a new monitor */
07214       if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
07215          ast_mutex_unlock(&monlock);
07216          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
07217          pthread_attr_destroy(&attr);
07218          return -1;
07219       }
07220    }
07221    ast_mutex_unlock(&monlock);
07222    pthread_attr_destroy(&attr);
07223    return 0;
07224 }
07225 
07226 #ifdef HAVE_PRI
07227 static int pri_resolve_span(int *span, int channel, int offset, struct zt_spaninfo *si)
07228 {
07229    int x;
07230    int trunkgroup;
07231    /* Get appropriate trunk group if there is one */
07232    trunkgroup = pris[*span].mastertrunkgroup;
07233    if (trunkgroup) {
07234       /* Select a specific trunk group */
07235       for (x = 0; x < NUM_SPANS; x++) {
07236          if (pris[x].trunkgroup == trunkgroup) {
07237             *span = x;
07238             return 0;
07239          }
07240       }
07241       ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
07242       *span = -1;
07243    } else {
07244       if (pris[*span].trunkgroup) {
07245          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
07246          *span = -1;
07247       } else if (pris[*span].mastertrunkgroup) {
07248          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
07249          *span = -1;
07250       } else {
07251          if (si->totalchans == 31) { /* if it's an E1 */
07252             pris[*span].dchannels[0] = 16 + offset;
07253          } else if (si->totalchans == 3) { /* if it's an S0 ZAPBRI */
07254             pris[*span].dchannels[0] = 3 + offset;
07255          } else {
07256             pris[*span].dchannels[0] = 24 + offset;
07257          }
07258          pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
07259          pris[*span].offset = offset;
07260          pris[*span].span = *span + 1;
07261       }
07262    }
07263    return 0;
07264 }
07265 
07266 static int pri_create_trunkgroup(int trunkgroup, int *channels)
07267 {
07268    struct zt_spaninfo si;
07269    ZT_PARAMS p;
07270    int fd;
07271    int span;
07272    int ospan=0;
07273    int x,y;
07274    for (x = 0; x < NUM_SPANS; x++) {
07275       if (pris[x].trunkgroup == trunkgroup) {
07276          ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
07277          return -1;
07278       }
07279    }
07280    for (y = 0; y < NUM_DCHANS; y++) {
07281       if (!channels[y]) 
07282          break;
07283       memset(&si, 0, sizeof(si));
07284       memset(&p, 0, sizeof(p));
07285       fd = open("/dev/zap/channel", O_RDWR);
07286       if (fd < 0) {
07287          ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
07288          return -1;
07289       }
07290       x = channels[y];
07291       if (ioctl(fd, ZT_SPECIFY, &x)) {
07292          ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
07293          zt_close(fd);
07294          return -1;
07295       }
07296       if (ioctl(fd, ZT_GET_PARAMS, &p)) {
07297          ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
07298          return -1;
07299       }
07300       if (ioctl(fd, ZT_SPANSTAT, &si)) {
07301          ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
07302          zt_close(fd);
07303          return -1;
07304       }
07305       span = p.spanno - 1;
07306       if (pris[span].trunkgroup) {
07307          ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
07308          zt_close(fd);
07309          return -1;
07310       }
07311       if (pris[span].pvts[0]) {
07312          ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
07313          zt_close(fd);
07314          return -1;
07315       }
07316       if (!y) {
07317          pris[span].trunkgroup = trunkgroup;
07318          pris[span].offset = channels[y] - p.chanpos;
07319          ospan = span;
07320       }
07321       pris[ospan].dchannels[y] = channels[y];
07322       pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
07323       pris[span].span = span + 1;
07324       zt_close(fd);
07325    }
07326    return 0;   
07327 }
07328 
07329 static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
07330 {
07331    if (pris[span].mastertrunkgroup) {
07332       ast_log(LOG_WARNING, "Span %d is already part of trunk group %d, cannot add to trunk group %d\n", span + 1, pris[span].mastertrunkgroup, trunkgroup);
07333       return -1;
07334    }
07335    pris[span].mastertrunkgroup = trunkgroup;
07336    pris[span].prilogicalspan = logicalspan;
07337    return 0;
07338 }
07339 
07340 #endif
07341 
07342 #ifdef HAVE_GSMAT
07343 static void *gsm_dchannel(void *vgsm);
07344 #endif
07345 
07346 static struct zt_pvt *mkintf(int channel, const struct zt_chan_conf *conf, struct zt_pri *pri, int reloading)
07347 {
07348    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
07349    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
07350    char fn[80];
07351 #if 1
07352    struct zt_bufferinfo bi;
07353 #endif
07354    struct zt_spaninfo si;
07355    int res;
07356    int span=0;
07357    int here = 0;
07358    int x;
07359    struct zt_pvt **wlist;
07360    struct zt_pvt **wend;
07361    ZT_PARAMS p;
07362 
07363    wlist = &iflist;
07364    wend = &ifend;
07365 
07366 #ifdef HAVE_PRI
07367    if (pri) {
07368       wlist = &pri->crvs;
07369       wend = &pri->crvend;
07370    }
07371 #endif
07372 
07373    tmp2 = *wlist;
07374    prev = NULL;
07375 
07376    while (tmp2) {
07377       if (!tmp2->destroy) {
07378          if (tmp2->channel == channel) {
07379             tmp = tmp2;
07380             here = 1;
07381             break;
07382          }
07383          if (tmp2->channel > channel) {
07384             break;
07385          }
07386       }
07387       prev = tmp2;
07388       tmp2 = tmp2->next;
07389    }
07390 
07391    if (!here && !reloading) {
07392       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
07393          destroy_zt_pvt(&tmp);
07394          return NULL;
07395       }
07396       ast_mutex_init(&tmp->lock);
07397       ifcount++;
07398       for (x = 0; x < 3; x++)
07399          tmp->subs[x].zfd = -1;
07400       tmp->channel = channel;
07401    }
07402 
07403    if (tmp) {
07404       int chan_sig = conf->chan.sig;
07405       if (!here) {
07406          if ((channel != CHAN_PSEUDO) && !pri) {
07407             snprintf(fn, sizeof(fn), "%d", channel);
07408             /* Open non-blocking */
07409             if (!here)
07410                tmp->subs[SUB_REAL].zfd = zt_open(fn);
07411             /* Allocate a zapata structure */
07412             if (tmp->subs[SUB_REAL].zfd < 0) {
07413                ast_log(LOG_ERROR, "Unable to open channel %d: %s\nhere = %d, tmp->channel = %d, channel = %d\n", channel, strerror(errno), here, tmp->channel, channel);
07414                destroy_zt_pvt(&tmp);
07415                return NULL;
07416             }
07417             memset(&p, 0, sizeof(p));
07418             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07419             if (res < 0) {
07420                ast_log(LOG_ERROR, "Unable to get parameters\n");
07421                destroy_zt_pvt(&tmp);
07422                return NULL;
07423             }
07424             if (p.sigtype != (conf->chan.sig & 0x3ffff)) {
07425                ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(conf->chan.sig), sig2str(p.sigtype));
07426                destroy_zt_pvt(&tmp);
07427                return NULL;
07428             }
07429             tmp->law = p.curlaw;
07430             tmp->span = p.spanno;
07431             span = p.spanno - 1;
07432          } else {
07433             if (channel == CHAN_PSEUDO)
07434                chan_sig = 0;
07435             else if ((chan_sig != SIG_FXOKS) && (chan_sig != SIG_FXSKS)) {
07436                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07437                return NULL;
07438             }
07439          }
07440 #ifdef HAVE_PRI
07441          if ((chan_sig == SIG_PRI) || (chan_sig == SIG_GR303FXOKS) || (chan_sig == SIG_GR303FXSKS)) {
07442             int offset;
07443             int myswitchtype;
07444             int matchesdchan;
07445             int x,y;
07446             offset = 0;
07447             if ((chan_sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07448                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07449                destroy_zt_pvt(&tmp);
07450                return NULL;
07451             }
07452             if (span >= NUM_SPANS) {
07453                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07454                destroy_zt_pvt(&tmp);
07455                return NULL;
07456             } else {
07457                si.spanno = 0;
07458                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07459                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07460                   destroy_zt_pvt(&tmp);
07461                   return NULL;
07462                }
07463                /* Store the logical span first based upon the real span */
07464                tmp->logicalspan = pris[span].prilogicalspan;
07465                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07466                if (span < 0) {
07467                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07468                   destroy_zt_pvt(&tmp);
07469                   return NULL;
07470                }
07471                if (chan_sig == SIG_PRI)
07472                   myswitchtype = conf->pri.switchtype;
07473                else
07474                   myswitchtype = PRI_SWITCH_GR303_TMC;
07475                /* Make sure this isn't a d-channel */
07476                matchesdchan=0;
07477                for (x = 0; x < NUM_SPANS; x++) {
07478                   for (y = 0; y < NUM_DCHANS; y++) {
07479                      if (pris[x].dchannels[y] == tmp->channel) {
07480                         matchesdchan = 1;
07481                         break;
07482                      }
07483                   }
07484                }
07485                offset = p.chanpos;
07486                if (!matchesdchan) {
07487                   if (pris[span].nodetype && (pris[span].nodetype != conf->pri.nodetype)) {
07488                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07489                      destroy_zt_pvt(&tmp);
07490                      return NULL;
07491                   }
07492                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07493                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07494                      destroy_zt_pvt(&tmp);
07495                      return NULL;
07496                   }
07497                   if ((pris[span].dialplan) && (pris[span].dialplan != conf->pri.dialplan)) {
07498                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07499                      destroy_zt_pvt(&tmp);
07500                      return NULL;
07501                   }
07502                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf->pri.idledial)) {
07503                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.idledial);
07504                      destroy_zt_pvt(&tmp);
07505                      return NULL;
07506                   }
07507                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf->pri.idleext)) {
07508                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.idleext);
07509                      destroy_zt_pvt(&tmp);
07510                      return NULL;
07511                   }
07512                                              if ((pris[span].localdialplan) && (pris[span].localdialplan != conf->pri.localdialplan)) {
07513                      ast_log(LOG_ERROR, "Span %d is already a %s local dialing plan\n", span + 1, dialplan2str(pris[span].localdialplan));
07514                      destroy_zt_pvt(&tmp);
07515                                                    return NULL;
07516                      }
07517                   if (pris[span].minunused && (pris[span].minunused != conf->pri.minunused)) {
07518                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.minunused);
07519                      destroy_zt_pvt(&tmp);
07520                      return NULL;
07521                   }
07522                   if (pris[span].minidle && (pris[span].minidle != conf->pri.minidle)) {
07523                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.minidle);
07524                      destroy_zt_pvt(&tmp);
07525                      return NULL;
07526                   }
07527                   if (pris[span].numchans >= MAX_CHANNELS) {
07528                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07529                         pris[span].trunkgroup);
07530                      destroy_zt_pvt(&tmp);
07531                      return NULL;
07532                   }
07533                   pris[span].nodetype = conf->pri.nodetype;
07534 
07535                   if (conf->pri.nodetype == BRI_NETWORK_PTMP) {
07536                       pris[span].dchanavail[0] =  DCHAN_AVAILABLE;
07537                       pri_find_dchan(&pris[span]);
07538                   }
07539                   pris[span].switchtype = myswitchtype;
07540                   pris[span].nsf = conf->pri.nsf;
07541                   pris[span].dialplan = conf->pri.dialplan;
07542                   pris[span].localdialplan = conf->pri.localdialplan;
07543                   pris[span].pvts[pris[span].numchans++] = tmp;
07544                   pris[span].minunused = conf->pri.minunused;
07545                   pris[span].minidle = conf->pri.minidle;
07546                   pris[span].overlapdial = conf->pri.overlapdial;
07547                   pris[span].usercid = conf->pri.usercid;
07548                   pris[span].suspended_calls = NULL;
07549                   pris[span].facilityenable = conf->pri.facilityenable;
07550                   ast_copy_string(pris[span].idledial, conf->pri.idledial, sizeof(pris[span].idledial));
07551                   ast_copy_string(pris[span].idleext, conf->pri.idleext, sizeof(pris[span].idleext));
07552                   ast_copy_string(pris[span].nocid, conf->pri.nocid, sizeof(pris[span].nocid));
07553                   ast_copy_string(pris[span].withheldcid, conf->pri.withheldcid, sizeof(pris[span].withheldcid));
07554                   ast_copy_string(pris[span].internationalprefix, conf->pri.internationalprefix, sizeof(pris[span].internationalprefix));
07555                   ast_copy_string(pris[span].nationalprefix, conf->pri.nationalprefix, sizeof(pris[span].nationalprefix));
07556                   ast_copy_string(pris[span].localprefix, conf->pri.localprefix, sizeof(pris[span].localprefix));
07557                   ast_copy_string(pris[span].privateprefix, conf->pri.privateprefix, sizeof(pris[span].privateprefix));
07558                   ast_copy_string(pris[span].unknownprefix, conf->pri.unknownprefix, sizeof(pris[span].unknownprefix));
07559                   pris[span].resetinterval = conf->pri.resetinterval;
07560                   
07561                   tmp->pri = &pris[span];
07562                   tmp->prioffset = offset;
07563                   tmp->call = NULL;
07564                } else {
07565                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07566                   destroy_zt_pvt(&tmp);
07567                   return NULL;
07568                }
07569             }
07570          } else {
07571             tmp->prioffset = 0;
07572          }
07573 #endif
07574 #ifdef HAVE_GSMAT
07575       if (conf->chan.sig == SIG_GSM) {
07576           struct zt_bufferinfo bi;
07577           ast_mutex_init(&tmp->gsm.lock);
07578           strncpy(tmp->gsm.pin, gsm_modem_pin, sizeof(tmp->gsm.pin) - 1);
07579           strncpy(tmp->gsm.exten, gsm_modem_exten, sizeof(tmp->gsm.exten) - 1);
07580           tmp->gsm.available = 0;
07581           snprintf(fn, sizeof(fn), "%d", channel + 1);
07582           /* Open non-blocking */
07583           tmp->gsm.fd = zt_open(fn);
07584           bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07585           bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07586           bi.numbufs = 16;
07587           bi.bufsize = 1024;
07588           if (ioctl(tmp->gsm.fd, ZT_SET_BUFINFO, &bi)) {
07589          ast_log(LOG_ERROR, "Unable to set buffer info on channel '%s': %s\n", fn, strerror(errno));
07590          return NULL;
07591           }
07592           tmp->gsm.pvt = tmp;
07593           tmp->gsm.span = tmp->span;
07594           tmp->gsm.modul = gsm_new(tmp->gsm.fd, 0, tmp->gsm.pin, tmp->span, tmp->channel);
07595           if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, tmp->channel)) {
07596          ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d: %s\n", tmp->channel, strerror(errno));
07597          destroy_zt_pvt(&tmp);
07598          return NULL;
07599           }
07600           if (ast_pthread_create(&tmp->gsm.master, NULL, gsm_dchannel, &tmp->gsm)) {
07601          zt_close(tmp->gsm.fd);
07602           }
07603       }
07604 #endif
07605       } else {
07606          chan_sig = tmp->sig;
07607          memset(&p, 0, sizeof(p));
07608          if (tmp->subs[SUB_REAL].zfd > -1)
07609             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07610       }
07611       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07612       switch (chan_sig) {
07613       case SIG_FXSKS:
07614       case SIG_FXSLS:
07615       case SIG_EM:
07616       case SIG_EM_E1:
07617       case SIG_EMWINK:
07618       case SIG_FEATD:
07619       case SIG_FEATDMF:
07620       case SIG_FEATDMF_TA:
07621       case SIG_FEATB:
07622       case SIG_E911:
07623       case SIG_SF:
07624       case SIG_SFWINK:
07625       case SIG_FGC_CAMA:
07626       case SIG_FGC_CAMAMF:
07627       case SIG_SF_FEATD:
07628       case SIG_SF_FEATDMF:
07629       case SIG_SF_FEATB:
07630          p.starttime = 250;
07631          break;
07632       }
07633 
07634       if (tmp->radio) {
07635          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07636          p.channo = channel;
07637          p.rxwinktime = 1;
07638          p.rxflashtime = 1;
07639          p.starttime = 1;
07640          p.debouncetime = 5;
07641       }
07642       if (!tmp->radio) {
07643          p.channo = channel;
07644          /* Override timing settings based on config file */
07645          if (conf->timing.prewinktime >= 0)
07646             p.prewinktime = conf->timing.prewinktime;
07647          if (conf->timing.preflashtime >= 0)
07648             p.preflashtime = conf->timing.preflashtime;
07649          if (conf->timing.winktime >= 0)
07650             p.winktime = conf->timing.winktime;
07651          if (conf->timing.flashtime >= 0)
07652             p.flashtime = conf->timing.flashtime;
07653          if (conf->timing.starttime >= 0)
07654             p.starttime = conf->timing.starttime;
07655          if (conf->timing.rxwinktime >= 0)
07656             p.rxwinktime = conf->timing.rxwinktime;
07657          if (conf->timing.rxflashtime >= 0)
07658             p.rxflashtime = conf->timing.rxflashtime;
07659          if (conf->timing.debouncetime >= 0)
07660             p.debouncetime = conf->timing.debouncetime;
07661       }
07662       
07663       /* dont set parms on a pseudo-channel (or CRV) */
07664       if (tmp->subs[SUB_REAL].zfd >= 0)
07665       {
07666          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07667          if (res < 0) {
07668             ast_log(LOG_ERROR, "Unable to set parameters\n");
07669             destroy_zt_pvt(&tmp);
07670             return NULL;
07671          }
07672       }
07673 #if 1
07674       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07675          memset(&bi, 0, sizeof(bi));
07676          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07677          if (!res) {
07678             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07679             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07680             bi.numbufs = numbufs;
07681             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07682             if (res < 0) {
07683                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07684             }
07685          } else
07686             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07687       }
07688 #endif
07689       tmp->immediate = conf->chan.immediate;
07690       tmp->transfertobusy = conf->chan.transfertobusy;
07691       tmp->sig = chan_sig;
07692       tmp->outsigmod = conf->chan.outsigmod;
07693       tmp->ringt_base = ringt_base;
07694       tmp->firstradio = 0;
07695       if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS))
07696          tmp->permcallwaiting = conf->chan.callwaiting;
07697       else
07698          tmp->permcallwaiting = 0;
07699       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07700       tmp->destroy = 0;
07701       tmp->drings = drings;
07702       tmp->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection;
07703       tmp->callwaitingcallerid = conf->chan.callwaitingcallerid;
07704       tmp->threewaycalling = conf->chan.threewaycalling;
07705       tmp->adsi = conf->chan.adsi;
07706       tmp->use_smdi = conf->chan.use_smdi;
07707       tmp->permhidecallerid = conf->chan.hidecallerid;
07708       tmp->callreturn = conf->chan.callreturn;
07709       tmp->echocancel = conf->chan.echocancel;
07710       tmp->echotraining = conf->chan.echotraining;
07711       tmp->pulse = conf->chan.pulse;
07712       if (tmp->echocancel)
07713          tmp->echocanbridged = conf->chan.echocanbridged;
07714       else {
07715          if (conf->chan.echocanbridged)
07716             ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
07717          tmp->echocanbridged = 0;
07718       }
07719       tmp->busydetect = conf->chan.busydetect;
07720       tmp->busycount = conf->chan.busycount;
07721       tmp->busy_tonelength = conf->chan.busy_tonelength;
07722       tmp->busy_quietlength = conf->chan.busy_quietlength;
07723       tmp->callprogress = conf->chan.callprogress;
07724       tmp->cancallforward = conf->chan.cancallforward;
07725       tmp->dtmfrelax = conf->chan.dtmfrelax;
07726       tmp->callwaiting = tmp->permcallwaiting;
07727       tmp->hidecallerid = tmp->permhidecallerid;
07728       tmp->channel = channel;
07729       tmp->stripmsd = conf->chan.stripmsd;
07730       tmp->use_callerid = conf->chan.use_callerid;
07731       tmp->cid_signalling = conf->chan.cid_signalling;
07732       tmp->cid_start = conf->chan.cid_start;
07733       tmp->zaptrcallerid = conf->chan.zaptrcallerid;
07734       tmp->restrictcid = conf->chan.restrictcid;
07735       tmp->use_callingpres = conf->chan.use_callingpres;
07736       tmp->priindication_oob = conf->chan.priindication_oob;
07737       tmp->pritransfer = conf->chan.pritransfer;
07738       tmp->priexclusive = conf->chan.priexclusive;
07739       if (tmp->usedistinctiveringdetection) {
07740          if (!tmp->use_callerid) {
07741             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07742             tmp->use_callerid = 1;
07743          }
07744       }
07745 
07746       if (tmp->cid_signalling == CID_SIG_SMDI) {
07747          if (!tmp->use_smdi) {
07748             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
07749             tmp->use_smdi = 1;
07750          }
07751       }
07752       if (tmp->use_smdi) {
07753          tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port);
07754          if (!(tmp->smdi_iface)) {
07755             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
07756             tmp->use_smdi = 0;
07757          }
07758       }
07759 
07760       ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode));
07761       tmp->amaflags = conf->chan.amaflags;
07762       if (!here) {
07763          tmp->confno = -1;
07764          tmp->propconfno = -1;
07765       }
07766       tmp->canpark = conf->chan.canpark;
07767       tmp->transfer = conf->chan.transfer;
07768       ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext));
07769       ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language));
07770       ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret));
07771       ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest));
07772       ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context));
07773       ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num));
07774       tmp->cid_ton = 0;
07775       ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name));
07776       ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox));
07777       tmp->msgstate = -1;
07778       tmp->group = conf->chan.group;
07779       tmp->callgroup = conf->chan.callgroup;
07780       tmp->pickupgroup= conf->chan.pickupgroup;
07781       tmp->rxgain = conf->chan.rxgain;
07782       tmp->txgain = conf->chan.txgain;
07783       tmp->tonezone = conf->chan.tonezone;
07784       tmp->onhooktime = time(NULL);
07785       if (tmp->subs[SUB_REAL].zfd > -1) {
07786          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07787          if (tmp->dsp)
07788             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07789          update_conf(tmp);
07790          if (!here) {
07791             if (chan_sig != SIG_PRI)
07792                /* Hang it up to be sure it's good */
07793                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07794          }
07795          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07796 #ifdef HAVE_PRI
07797          /* the dchannel is down so put the channel in alarm */
07798          if (tmp->pri && !pri_is_up(tmp->pri))
07799             tmp->inalarm = 1;
07800          else
07801             tmp->inalarm = 0;
07802 #endif            
07803          memset(&si, 0, sizeof(si));
07804          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07805             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07806             destroy_zt_pvt(&tmp);
07807             return NULL;
07808          }
07809          if (si.alarms) tmp->inalarm = 1;
07810       }
07811 
07812       tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
07813       tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
07814       tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
07815       tmp->sendcalleridafter = conf->chan.sendcalleridafter;
07816 
07817    }
07818    if (tmp && !here) {
07819       /* nothing on the iflist */
07820       if (!*wlist) {
07821          *wlist = tmp;
07822          tmp->prev = NULL;
07823          tmp->next = NULL;
07824          *wend = tmp;
07825       } else {
07826          /* at least one member on the iflist */
07827          struct zt_pvt *working = *wlist;
07828 
07829          /* check if we maybe have to put it on the begining */
07830          if (working->channel > tmp->channel) {
07831             tmp->next = *wlist;
07832             tmp->prev = NULL;
07833             (*wlist)->prev = tmp;
07834             *wlist = tmp;
07835          } else {
07836          /* go through all the members and put the member in the right place */
07837             while (working) {
07838                /* in the middle */
07839                if (working->next) {
07840                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07841                      tmp->next = working->next;
07842                      tmp->prev = working;
07843                      working->next->prev = tmp;
07844                      working->next = tmp;
07845                      break;
07846                   }
07847                } else {
07848                /* the last */
07849                   if (working->channel < tmp->channel) {
07850                      working->next = tmp;
07851                      tmp->next = NULL;
07852                      tmp->prev = working;
07853                      *wend = tmp;
07854                      break;
07855                   }
07856                }
07857                working = working->next;
07858             }
07859          }
07860       }
07861    }
07862    return tmp;
07863 }
07864 
07865 static inline int available(struct zt_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched)
07866 {
07867    int res;
07868    ZT_PARAMS par;
07869 
07870    /* First, check group matching */
07871    if (groupmatch) {
07872       if ((p->group & groupmatch) != groupmatch)
07873          return 0;
07874       *groupmatched = 1;
07875    }
07876    /* Check to see if we have a channel match */
07877    if (channelmatch != -1) {
07878       if (p->channel != channelmatch)
07879          return 0;
07880       *channelmatched = 1;
07881    }
07882    /* We're at least busy at this point */
07883    if (busy) {
07884       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07885          *busy = 1;
07886    }
07887    /* If do not disturb, definitely not */
07888    if (p->dnd)
07889       return 0;
07890    /* If guard time, definitely not */
07891    if (p->guardtime && (time(NULL) < p->guardtime)) 
07892       return 0;
07893       
07894    /* If no owner definitely available */
07895    if (!p->owner) {
07896 #ifdef HAVE_PRI
07897       /* Trust PRI */
07898       if (p->pri) {
07899          if (p->resetting || p->call)
07900             return 0;
07901          else
07902             return 1;
07903       }
07904 #endif
07905 #ifdef HAVE_GSMAT
07906       if (p->gsm.modul) {
07907           return gsm_available(p->gsm.modul);
07908       }
07909 
07910 #endif
07911       if (!(p->radio || (p->oprmode < 0)))
07912       {
07913          if (!p->sig || (p->sig == SIG_FXSLS))
07914             return 1;
07915          /* Check hook state */
07916          if (p->subs[SUB_REAL].zfd > -1)
07917             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07918          else {
07919             /* Assume not off hook on CVRS */
07920             res = 0;
07921             par.rxisoffhook = 0;
07922          }
07923          if (res) {
07924             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07925          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07926             /* When "onhook" that means no battery on the line, and thus
07927               it is out of service..., if it's on a TDM card... If it's a channel
07928               bank, there is no telling... */
07929             if (par.rxbits > -1)
07930                return 1;
07931             if (par.rxisoffhook)
07932                return 1;
07933             else
07934 #ifdef ZAP_CHECK_HOOKSTATE
07935                return 0;
07936 #else
07937                return 1;
07938 #endif
07939          } else if (par.rxisoffhook) {
07940             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07941             /* Not available when the other end is off hook */
07942             return 0;
07943          }
07944       }
07945       return 1;
07946    }
07947 
07948    /* If it's not an FXO, forget about call wait */
07949    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
07950       return 0;
07951 
07952    if (!p->callwaiting) {
07953       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
07954       return 0;
07955    }
07956 
07957    if (p->subs[SUB_CALLWAIT].zfd > -1) {
07958       /* If there is already a call waiting call, then we can't take a second one */
07959       return 0;
07960    }
07961    
07962    if ((p->owner->_state != AST_STATE_UP) &&
07963        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
07964       /* If the current call is not up, then don't allow the call */
07965       return 0;
07966    }
07967    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
07968       /* Can't take a call wait when the three way calling hasn't been merged yet. */
07969       return 0;
07970    }
07971    /* We're cool */
07972    return 1;
07973 }
07974 
07975 static struct zt_pvt *chandup(struct zt_pvt *src)
07976 {
07977    struct zt_pvt *p;
07978    ZT_BUFFERINFO bi;
07979    int res;
07980    
07981    if ((p = ast_malloc(sizeof(*p)))) {
07982       memcpy(p, src, sizeof(struct zt_pvt));
07983       ast_mutex_init(&p->lock);
07984       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07985       /* Allocate a zapata structure */
07986       if (p->subs[SUB_REAL].zfd < 0) {
07987          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07988          destroy_zt_pvt(&p);
07989          return NULL;
07990       }
07991       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07992       if (!res) {
07993          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07994          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07995          bi.numbufs = numbufs;
07996          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07997          if (res < 0) {
07998             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
07999          }
08000       } else
08001          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
08002    }
08003    p->destroy = 1;
08004    p->next = iflist;
08005    p->prev = NULL;
08006    iflist = p;
08007    if (iflist->next)
08008       iflist->next->prev = p;
08009    return p;
08010 }
08011    
08012 
08013 #ifdef HAVE_PRI
08014 static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
08015 {
08016    int x;
08017    if (backwards)
08018       x = pri->numchans;
08019    else
08020       x = 0;
08021    for (;;) {
08022       if (backwards && (x < 0))
08023          break;
08024       if (!backwards && (x >= pri->numchans))
08025          break;
08026       if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner && !pri->pvts[x]->call) {
08027          ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
08028             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
08029          return x;
08030       }
08031       if (backwards)
08032          x--;
08033       else
08034          x++;
08035    }
08036    return -1;
08037 }
08038 #endif
08039 
08040 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
08041 {
08042    ast_group_t groupmatch = 0;
08043    int channelmatch = -1;
08044    int roundrobin = 0;
08045    int callwait = 0;
08046    int busy = 0;
08047    struct zt_pvt *p;
08048    struct ast_channel *tmp = NULL;
08049    char *dest=NULL;
08050    int x;
08051    char *s;
08052    char opt=0;
08053    int res=0, y=0;
08054    int backwards = 0;
08055 #ifdef HAVE_PRI
08056    int crv;
08057    int bearer = -1;
08058    int trunkgroup;
08059    struct zt_pri *pri=NULL;
08060 #endif   
08061    struct zt_pvt *exit, *start, *end;
08062    ast_mutex_t *lock;
08063    int channelmatched = 0;
08064    int groupmatched = 0;
08065    
08066    /* Assume we're locking the iflock */
08067    lock = &iflock;
08068    start = iflist;
08069    end = ifend;
08070    if (data) {
08071       dest = ast_strdupa((char *)data);
08072    } else {
08073       ast_log(LOG_WARNING, "Channel requested with no data\n");
08074       return NULL;
08075    }
08076    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
08077       /* Retrieve the group number */
08078       char *stringp=NULL;
08079       stringp=dest + 1;
08080       s = strsep(&stringp, "/");
08081       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
08082          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
08083          return NULL;
08084       }
08085       groupmatch = ((ast_group_t) 1 << x);
08086       if (toupper(dest[0]) == 'G') {
08087          if (dest[0] == 'G') {
08088             backwards = 1;
08089             p = ifend;
08090          } else
08091             p = iflist;
08092       } else {
08093          if (dest[0] == 'R') {
08094             backwards = 1;
08095             p = round_robin[x]?round_robin[x]->prev:ifend;
08096             if (!p)
08097                p = ifend;
08098          } else {
08099             p = round_robin[x]?round_robin[x]->next:iflist;
08100             if (!p)
08101                p = iflist;
08102          }
08103          roundrobin = 1;
08104       }
08105    } else {
08106       char *stringp=NULL;
08107       stringp=dest;
08108       s = strsep(&stringp, "/");
08109       p = iflist;
08110       if (!strcasecmp(s, "pseudo")) {
08111          /* Special case for pseudo */
08112          x = CHAN_PSEUDO;
08113          channelmatch = x;
08114       } 
08115 #ifdef HAVE_PRI
08116       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
08117          if ((trunkgroup < 1) || (crv < 1)) {
08118             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
08119             return NULL;
08120          }
08121          res--;
08122          for (x = 0; x < NUM_SPANS; x++) {
08123             if (pris[x].trunkgroup == trunkgroup) {
08124                pri = pris + x;
08125                lock = &pri->lock;
08126                start = pri->crvs;
08127                end = pri->crvend;
08128                break;
08129             }
08130          }
08131          if (!pri) {
08132             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
08133             return NULL;
08134          }
08135          channelmatch = crv;
08136          p = pris[x].crvs;
08137       }
08138 #endif   
08139       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
08140          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
08141          return NULL;
08142       } else {
08143          channelmatch = x;
08144       }
08145    }
08146    /* Search for an unowned channel */
08147    ast_mutex_lock(lock);
08148    exit = p;
08149    while (p && !tmp) {
08150       if (roundrobin)
08151          round_robin[x] = p;
08152 #if 0
08153       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
08154 #endif
08155 
08156       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
08157          if (option_debug)
08158             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
08159             if (p->inalarm) 
08160                goto next;
08161 
08162          callwait = (p->owner != NULL);
08163 #ifdef HAVE_PRI
08164          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
08165             if (p->sig != SIG_FXSKS) {
08166                /* Gotta find an actual channel to use for this
08167                   CRV if this isn't a callwait */
08168                bearer = pri_find_empty_chan(pri, 0);
08169                if (bearer < 0) {
08170                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
08171                   p = NULL;
08172                   break;
08173                }
08174                pri_assign_bearer(p, pri, pri->pvts[bearer]);
08175             } else {
08176                if (alloc_sub(p, 0)) {
08177                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
08178                   p = NULL;
08179                   break;
08180                } else
08181                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
08182                p->pri = pri;
08183             }
08184          }
08185 #endif         
08186          if (p->channel == CHAN_PSEUDO) {
08187             p = chandup(p);
08188             if (!p) {
08189                break;
08190             }
08191          }
08192          if (p->owner) {
08193             if (alloc_sub(p, SUB_CALLWAIT)) {
08194                p = NULL;
08195                break;
08196             }
08197          }
08198          p->outgoing = 1;
08199          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
08200 #ifdef HAVE_PRI
08201          if (p->bearer) {
08202             /* Log owner to bearer channel, too */
08203             p->bearer->owner = tmp;
08204          }
08205 #endif         
08206          /* Make special notes */
08207          if (res > 1) {
08208             if (opt == 'c') {
08209                /* Confirm answer */
08210                p->confirmanswer = 1;
08211             } else if (opt == 'r') {
08212                /* Distinctive ring */
08213                if (res < 3)
08214                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
08215                else
08216                   p->distinctivering = y;
08217             } else if (opt == 'd') {
08218                /* If this is an ISDN call, make it digital */
08219                p->digital = 1;
08220                if (tmp)
08221                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
08222             } else if (opt == 'm') {
08223                /* If this is a modem/fax call, pretend to have the fax handled and dont do EC */
08224                p->faxhandled = 1;
08225                if (tmp)
08226                    tmp->transfercapability = AST_TRANS_CAP_3_1K_AUDIO;
08227             } else {
08228                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
08229             }
08230          }
08231          /* Note if the call is a call waiting call */
08232          if (tmp && callwait)
08233             tmp->cdrflags |= AST_CDR_CALLWAIT;
08234          break;
08235       }
08236 next:
08237       if (backwards) {
08238          p = p->prev;
08239          if (!p)
08240             p = end;
08241       } else {
08242          p = p->next;
08243          if (!p)
08244             p = start;
08245       }
08246       /* stop when you roll to the one that we started from */
08247       if (p == exit)
08248          break;
08249    }
08250    ast_mutex_unlock(lock);
08251    restart_monitor();
08252    if (callwait)
08253       *cause = AST_CAUSE_BUSY;
08254    else if (!tmp) {
08255       if (channelmatched) {
08256          if (busy)
08257             *cause = AST_CAUSE_BUSY;
08258       } else if (groupmatched) {
08259          *cause = AST_CAUSE_CONGESTION;
08260       } else {
08261          *cause = AST_CAUSE_CONGESTION;
08262       }
08263    }
08264       
08265    return tmp;
08266 }
08267 
08268 #ifdef HAVE_GSMAT
08269 static int zt_reset_span(int span, int sleep) {
08270    int ctl;
08271    int res;
08272 
08273    ctl = open("/dev/zap/ctl", O_RDWR);
08274    if (ctl < 0) {
08275       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
08276       return -1;
08277    }
08278    ast_verbose(VERBOSE_PREFIX_2 "Shutting down span %d. Please wait...\n", span);
08279    res = ioctl(ctl, ZT_SHUTDOWN, &span);
08280    if (res) {
08281       ast_log(LOG_WARNING, "error shutting down span %d\n", span);
08282       return -1;
08283    }
08284    usleep(sleep * 1000);
08285    ast_verbose(VERBOSE_PREFIX_2 "Starting up span %d. Please wait...\n", span);
08286    res = ioctl(ctl, ZT_STARTUP, &span);
08287    if (res) {
08288       ast_log(LOG_WARNING, "error starting up span %d\n", span);
08289       return -1;
08290    }
08291    ast_verbose(VERBOSE_PREFIX_2 "Reset of span %d completed.\n", span);
08292    return 0;
08293 }
08294 
08295 
08296 static void handle_gsm_event(struct zt_gsm *gsm, gsm_event *e)
08297 {
08298    struct ast_channel *c = NULL;
08299    int law = ZT_LAW_ALAW;
08300    int res = 0;
08301 
08302    switch(e->e) {
08303    case GSM_EVENT_DCHAN_UP:
08304       if (option_verbose > 2)
08305           ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d registered to network!\n", gsm->span);
08306       gsm->available = 1;
08307       break;
08308    case GSM_EVENT_DCHAN_DOWN:
08309       if (option_verbose > 2)
08310           ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d unregistered from network!\n", gsm->span);
08311       gsm->available = 0;
08312 /*    ast_mutex_lock(&gsm->pvt->lock);
08313       gsm->pvt->alreadyhungup = 1;
08314       if (gsm->pvt->owner) {
08315           gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08316       }
08317       ast_mutex_unlock(&gsm->pvt->lock); */
08318       break;
08319    case GSM_EVENT_RING:
08320       ast_mutex_lock(&gsm->pvt->lock);
08321       if (!ast_strlen_zero(e->ring.callingnum)) {
08322           strncpy(gsm->pvt->cid_num, e->ring.callingnum, sizeof(gsm->pvt->cid_num) - 1);
08323       } else {
08324           strncpy(gsm->pvt->cid_name, "CID withheld", sizeof(gsm->pvt->cid_name));
08325       }
08326       if (!ast_strlen_zero(gsm->exten)) {
08327           strncpy(gsm->pvt->exten, gsm->exten, sizeof(gsm->pvt->exten) - 1);
08328       } else {
08329           gsm->pvt->exten[0] = 's';
08330           gsm->pvt->exten[1] = '\0';
08331       }
08332       c = zt_new(gsm->pvt, AST_STATE_RING, 1, SUB_REAL, ZT_LAW_ALAW, AST_TRANS_CAP_SPEECH);
08333       if (c) {
08334           if (option_verbose > 2)
08335          ast_verbose(VERBOSE_PREFIX_3 "Ring on channel %d (from %s to %s)\n", e->ring.channel, e->ring.callingnum, gsm->exten);
08336           gsm->pvt->owner = c;
08337           if (ioctl(gsm->pvt->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
08338          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", gsm->pvt->channel, law);
08339           res = zt_setlaw(gsm->pvt->subs[SUB_REAL].zfd, law);
08340           res = set_actual_gain(gsm->pvt->subs[SUB_REAL].zfd, 0, gsm->pvt->rxgain, gsm->pvt->txgain, law);
08341           if (res < 0) {
08342               ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", gsm->pvt->channel);
08343 //        } else {
08344 //            ast_log(LOG_NOTICE, "tx gain %f rx gain %f law %d pvt->law %d\n", gsm->pvt->txgain, gsm->pvt->rxgain, law, gsm->pvt->law);
08345           }
08346       }
08347       ast_mutex_unlock(&gsm->pvt->lock);
08348       break;
08349    case GSM_EVENT_HANGUP:
08350       ast_verbose(VERBOSE_PREFIX_3 "Got hang up on channel %d\n", e->hangup.channel);
08351       ast_mutex_lock(&gsm->pvt->lock);
08352       gsm->pvt->alreadyhungup = 1;
08353       if (gsm->pvt->owner) {
08354           gsm->pvt->owner->hangupcause = e->hangup.cause;
08355           gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08356       }
08357       ast_mutex_unlock(&gsm->pvt->lock);
08358       break;
08359    case GSM_EVENT_ERROR:
08360       ast_log(LOG_WARNING, "Got error on channel\n");
08361       ast_mutex_lock(&gsm->pvt->lock);
08362       gsm->pvt->alreadyhungup = 1;
08363       if (gsm->pvt->owner) {
08364           gsm->pvt->owner->hangupcause = e->error.cause;
08365           gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08366       }
08367       ast_mutex_unlock(&gsm->pvt->lock);
08368       if (e->error.hard) {
08369 //        gsm_poweroff(gsm->modul);
08370           zt_reset_span(gsm->span, 8000);
08371 //        gsm_restart(gsm->modul, 10000);
08372       } else {
08373 //        gsm_poweroff(gsm->modul);
08374           zt_reset_span(gsm->span, 8000);
08375 //        gsm_restart(gsm->modul, 10000);
08376       }
08377       break;
08378    case GSM_EVENT_ALERTING:
08379       ast_mutex_lock(&gsm->pvt->lock);
08380       gsm->pvt->subs[SUB_REAL].needringing =1;
08381       ast_mutex_unlock(&gsm->pvt->lock);
08382       break;
08383    case GSM_EVENT_ANSWER:
08384       ast_mutex_lock(&gsm->pvt->lock);
08385       gsm->pvt->dialing = 0;
08386       gsm->pvt->subs[SUB_REAL].needanswer =1;
08387       gsm->pvt->ignoredtmf = 0;
08388       ast_mutex_unlock(&gsm->pvt->lock);
08389       break;
08390    case GSM_EVENT_PIN_REQUIRED:
08391       gsm_send_pin(gsm->modul, gsm->pin);
08392       break;
08393    case GSM_EVENT_SM_RECEIVED:
08394       ast_verbose(VERBOSE_PREFIX_3 "SMS from %s received on span %d. (Text: %s) (PDU: %s)\n", e->sm_received.sender, gsm->span, e->sm_received.text, e->sm_received.pdu);
08395       manager_event(EVENT_FLAG_CALL, "Message received",
08396          "Span: %d\r\n"
08397          "Sender: %s\r\n"
08398          "SMSC: %s\r\n"
08399                "Length: %d\r\n"
08400          "Text: %s\r\n"
08401          "PDU: %s\r\n",
08402          gsm->span,
08403          e->sm_received.sender,
08404          e->sm_received.smsc,
08405          e->sm_received.len,
08406          e->sm_received.text,
08407          e->sm_received.pdu);
08408       break;
08409    default:
08410       ast_log(LOG_WARNING,"!! Unknown GSM event %d !!\n", e->e);
08411    }
08412 }
08413 
08414 static void *gsm_dchannel(void *vgsm)
08415 {
08416    struct zt_gsm *gsm = vgsm;
08417    gsm_event *e;
08418    struct timeval tv = {0,0}, *next;
08419    fd_set rfds, efds;
08420    int res,x;
08421 
08422    if (!gsm) return NULL;
08423 
08424    if (!gsm->modul) {
08425       fprintf(stderr, "No gsm_mod\n");
08426       return NULL;
08427    }
08428    gsm_set_debug(gsm->modul, GSM_DEBUG_NONE);
08429    for (;;) {
08430 
08431       /* Run the D-Channel */
08432       FD_ZERO(&rfds);
08433       FD_ZERO(&efds);
08434       FD_SET(gsm->fd, &rfds);
08435       FD_SET(gsm->fd, &efds);
08436 
08437       if ((next = gsm_schedule_next(gsm->modul))) {
08438          gettimeofday(&tv, NULL);
08439          tv.tv_sec = next->tv_sec - tv.tv_sec;
08440          tv.tv_usec = next->tv_usec - tv.tv_usec;
08441          if (tv.tv_usec < 0) {
08442             tv.tv_usec += 1000000;
08443             tv.tv_sec -= 1;
08444          }
08445          if (tv.tv_sec < 0) {
08446             tv.tv_sec = 0;
08447             tv.tv_usec = 0;
08448          }
08449       }
08450       res = select(gsm->fd + 1, &rfds, NULL, &efds, next ? &tv : NULL);
08451       e = NULL;
08452 
08453       ast_mutex_lock(&gsm->lock);
08454       if (!res) {
08455          e = gsm_schedule_run(gsm->modul);
08456       } else if (res > 0) {
08457          e = gsm_check_event(gsm->modul, 1);
08458       } else if (errno == ELAST) {
08459          res = ioctl(gsm->fd, ZT_GETEVENT, &x);
08460          printf("Got Zaptel event: %d\n", x);
08461       } else if (errno != EINTR)
08462          fprintf(stderr, "Error (%d) on select: %s\n", ELAST, strerror(errno));
08463 
08464       if (!e) {
08465           e = gsm_check_event(gsm->modul, 0);
08466       }
08467 
08468       if (e) {
08469          handle_gsm_event(gsm, e);
08470       }
08471       ast_mutex_unlock(&gsm->lock);
08472 
08473       res = ioctl(gsm->fd, ZT_GETEVENT, &x);
08474 
08475       if (!res && x) {
08476          switch (x) {
08477              case ZT_EVENT_NOALARM:
08478             ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", gsm->span);
08479             usleep(1000);
08480             gsm_restart(gsm->modul, 10000);
08481              break;
08482              case ZT_EVENT_ALARM:
08483             ast_log(LOG_NOTICE, "Alarm detected on span %d\n", gsm->span);
08484              break;
08485              default:
08486             fprintf(stderr, "Got event on GSM interface: %d\n", x);
08487          }
08488       }
08489 
08490 
08491    }
08492    return NULL;
08493 }
08494 
08495 #endif
08496 
08497 #ifdef HAVE_PRI
08498 static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
08499 {
08500    struct zt_pvt *p;
08501    p = pri->crvs;
08502    while (p) {
08503       if (p->channel == crv)
08504          return p;
08505       p = p->next;
08506    }
08507    return NULL;
08508 }
08509 
08510 
08511 static int pri_find_principle(struct zt_pri *pri, int channel)
08512 {
08513    int x;
08514    int span = PRI_SPAN(channel);
08515    int spanfd;
08516    ZT_PARAMS param;
08517    int principle = -1;
08518    int explicit = PRI_EXPLICIT(channel);
08519    channel = PRI_CHANNEL(channel);
08520 
08521    if (!explicit) {
08522       spanfd = pri_active_dchan_fd(pri);
08523       if (ioctl(spanfd, ZT_GET_PARAMS, &param))
08524          return -1;
08525       span = pris[param.spanno - 1].prilogicalspan;
08526    }
08527 
08528    for (x = 0; x < pri->numchans; x++) {
08529       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
08530          principle = x;
08531          break;
08532       }
08533    }
08534    
08535    return principle;
08536 }
08537 
08538 static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
08539 {
08540    int x;
08541    int res = 0;
08542    struct zt_pvt *crv;
08543    if (!c) {
08544       if (principle < 0)
08545          return -1;
08546       return principle;
08547    }
08548    if ((principle > -1) && 
08549       (principle < pri->numchans) && 
08550       (pri->pvts[principle]) && 
08551       (pri->pvts[principle]->call == c))
08552       return principle;
08553    /* First, check for other bearers */
08554    for (x = 0; x < pri->numchans; x++) {
08555       if (!pri->pvts[x])
08556          continue;
08557       if (pri->pvts[x]->call == c) {
08558          /* Found our call */
08559          if (principle != x) {
08560             struct zt_pvt *new = pri->pvts[principle], *old = pri->pvts[x];
08561 
08562             if (option_verbose > 2)
08563                ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
08564                   old->channel, new->channel);
08565             if (new->owner) {
08566                ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
08567                   old->channel, new->channel, new->channel);
08568                return -1;
08569             }
08570             /* Fix it all up now */
08571             new->owner = old->owner;
08572             new->outgoing = old->outgoing;
08573             old->owner = NULL;
08574             if (new->owner) {
08575                ast_string_field_build(new->owner, name, 
08576                             "Zap/%d:%d-%d", pri->trunkgroup,
08577                             new->channel, 1);
08578                new->owner->tech_pvt = new;
08579                new->owner->fds[0] = new->subs[SUB_REAL].zfd;
08580                new->subs[SUB_REAL].owner = old->subs[SUB_REAL].owner;
08581                old->subs[SUB_REAL].owner = NULL;
08582             } else
08583                ast_log(LOG_WARNING, "Whoa, there's no  owner, and we're having to fix up channel %d to channel %d\n", old->channel, new->channel);
08584             new->call = old->call;
08585             old->call = NULL;
08586 
08587             /* Copy any DSP that may be present */
08588             new->dsp = old->dsp;
08589             new->dsp_features = old->dsp_features;
08590             old->dsp = NULL;
08591             old->dsp_features = 0;
08592 
08593             /* Copy faxhandled/digial, alreadyhungup */
08594             new->faxhandled = old->faxhandled;
08595             new->digital = old->digital;
08596             new->alreadyhungup = old->alreadyhungup;
08597 
08598             /* Copy law, gains, etc */
08599             new->law = old->law;
08600             if (ioctl(new->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &new->law) == -1)
08601                 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", new->channel, new->law);
08602             res = zt_setlaw(new->subs[SUB_REAL].zfd, new->law);
08603             if (res < 0)
08604                 ast_log(LOG_WARNING, "Unable to set law on channel %d\n", new->channel);
08605             if (!new->digital) {
08606                 res = set_actual_gain(new->subs[SUB_REAL].zfd, 0, new->rxgain, new->txgain, new->law);
08607             } else {
08608                 res = set_actual_gain(new->subs[SUB_REAL].zfd, 0, 0, 0, new->law);
08609             }
08610             if (res < 0)
08611                 ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", new->channel);
08612 
08613             /* Shutdown old channel */
08614             zt_confmute(old, 0);
08615             update_conf(old);
08616             reset_conf(old);
08617             restore_gains(old);
08618             zt_disable_ec(old);
08619             zt_setlinear(old->subs[SUB_REAL].zfd, 0);
08620          }
08621          return principle;
08622       }
08623    }
08624    /* Now check for a CRV with no bearer */
08625    crv = pri->crvs;
08626    while (crv) {
08627       if (crv->call == c) {
08628          /* This is our match...  Perform some basic checks */
08629          if (crv->bearer)
08630             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
08631          else if (pri->pvts[principle]->owner) 
08632             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
08633          else {
08634             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
08635                wakeup the potential sleeper */
08636             zt_close(crv->subs[SUB_REAL].zfd);
08637             pri->pvts[principle]->call = crv->call;
08638             pri_assign_bearer(crv, pri, pri->pvts[principle]);
08639             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
08640                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
08641                            pri->trunkgroup, crv->channel);
08642             wakeup_sub(crv, SUB_REAL, pri);
08643          }
08644          return principle;
08645       }
08646       crv = crv->next;
08647    }
08648    if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
08649        ast_log(LOG_WARNING, "Call specified, but not found?\n");
08650    }
08651    return -1;
08652 }
08653 
08654 static void *do_idle_thread(void *vchan)
08655 {
08656    struct ast_channel *chan = vchan;
08657    struct zt_pvt *pvt = chan->tech_pvt;
08658    struct ast_frame *f;
08659    char ex[80];
08660    /* Wait up to 30 seconds for an answer */
08661    int newms, ms = 30000;
08662    if (option_verbose > 2) 
08663       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
08664    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
08665    if (ast_call(chan, ex, 0)) {
08666       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
08667       ast_hangup(chan);
08668       return NULL;
08669    }
08670    while ((newms = ast_waitfor(chan, ms)) > 0) {
08671       f = ast_read(chan);
08672       if (!f) {
08673          /* Got hangup */
08674          break;
08675       }
08676       if (f->frametype == AST_FRAME_CONTROL) {
08677          switch (f->subclass) {
08678          case AST_CONTROL_ANSWER:
08679             /* Launch the PBX */
08680             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
08681             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
08682             chan->priority = 1;
08683             if (option_verbose > 3) 
08684                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
08685             ast_pbx_run(chan);
08686             /* It's already hungup, return immediately */
08687             return NULL;
08688          case AST_CONTROL_BUSY:
08689             if (option_verbose > 3) 
08690                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
08691             break;
08692          case AST_CONTROL_CONGESTION:
08693             if (option_verbose > 3) 
08694                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
08695             break;
08696          };
08697       }
08698       ast_frfree(f);
08699       ms = newms;
08700    }
08701    /* Hangup the channel since nothing happend */
08702    ast_hangup(chan);
08703    return NULL;
08704 }
08705 
08706 #ifndef PRI_RESTART
08707 #error "Upgrade your libpri"
08708 #endif
08709 static void zt_pri_message(char *s, int span)
08710 {
08711    ast_verbose("%d %s", span, s);
08712 }
08713 
08714 static void zt_pri_error(char *s, int span)
08715 {
08716    ast_log(LOG_WARNING, "%d %s", span, s);
08717 }
08718 
08719 #ifdef HAVE_GSMAT
08720 static void zt_gsm_message(char *s, int channel)
08721 {
08722    ast_verbose("GSM %d: %s", channel, s);
08723 }
08724 
08725 static void zt_gsm_error(char *s, int channel)
08726 {
08727    ast_log(LOG_WARNING, "GSM %d: %s", channel, s);
08728 }
08729 #endif
08730 
08731 static int pri_check_restart(struct zt_pri *pri)
08732 {
08733    if ((pri->nodetype != PRI_NETWORK) && (pri->nodetype != PRI_CPE)) {
08734        return 0;
08735    }
08736    do {
08737       pri->resetpos++;
08738    } while ((pri->resetpos < pri->numchans) &&
08739        (!pri->pvts[pri->resetpos] ||
08740         pri->pvts[pri->resetpos]->call ||
08741         pri->pvts[pri->resetpos]->resetting));
08742    if (pri->resetpos < pri->numchans) {
08743       /* Mark the channel as resetting and restart it */
08744       pri->pvts[pri->resetpos]->resetting = 1;
08745       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
08746    } else {
08747       pri->resetting = 0;
08748       time(&pri->lastreset);
08749    }
08750    return 0;
08751 }
08752 
08753 static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
08754 {
08755    int x;
08756    int redo;
08757    ast_mutex_unlock(&pri->lock);
08758    ast_mutex_lock(&p->lock);
08759    do {
08760       redo = 0;
08761       for (x = 0; x < 3; x++) {
08762          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
08763             redo++;
08764             DEADLOCK_AVOIDANCE(&p->lock);
08765          }
08766          if (p->subs[x].owner) {
08767             ast_queue_hangup(p->subs[x].owner);
08768             ast_mutex_unlock(&p->subs[x].owner->lock);
08769          }
08770       }
08771    } while (redo);
08772    ast_mutex_unlock(&p->lock);
08773    ast_mutex_lock(&pri->lock);
08774    return 0;
08775 }
08776 
08777 static char * redirectingreason2str(int redirectingreason)
08778 {
08779    switch (redirectingreason) {
08780    case 0:
08781       return "UNKNOWN";
08782    case 1:
08783       return "BUSY";
08784    case 2:
08785       return "NO_REPLY";
08786    case 0xF:
08787       return "UNCONDITIONAL";
08788    default:
08789       return "NOREDIRECT";
08790    }
08791 }
08792 
08793 static void apply_plan_to_number(char *buf, size_t size, const struct zt_pri *pri, const char *number, const int plan)
08794 {
08795    switch (plan) {
08796    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
08797       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
08798       break;
08799    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
08800       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
08801       break;
08802    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
08803       snprintf(buf, size, "%s%s", pri->localprefix, number);
08804       break;
08805    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
08806       snprintf(buf, size, "%s%s", pri->privateprefix, number);
08807       break;
08808    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
08809       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
08810       break;
08811    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
08812       snprintf(buf, size, "%s", number);
08813       break;
08814    }
08815 }
08816 
08817 static void pri_make_callerid(struct zt_pri *pri, char *callerid, int callerid_len, char *callingnum, int callingnum_len, int callingplan, int callingpres, int stripmsd) {
08818     if (callingnum && (callingnum_len > stripmsd)) {
08819    callingnum += stripmsd;
08820     }
08821     switch (callingplan) {
08822    case PRI_INTERNATIONAL_ISDN:
08823        snprintf(callerid, callerid_len, "%s%s", pri->internationalprefix, callingnum);
08824        break;
08825    case PRI_NATIONAL_ISDN:
08826        snprintf(callerid, callerid_len, "%s%s", pri->nationalprefix, callingnum);
08827        break;
08828    case PRI_LOCAL_ISDN:
08829        snprintf(callerid, callerid_len, "%s%s", pri->localprefix, callingnum);
08830        break;
08831    case PRI_PRIVATE:
08832        snprintf(callerid, callerid_len, "%s%s", pri->privateprefix, callingnum);
08833        break;
08834    case PRI_UNKNOWN:
08835        snprintf(callerid, callerid_len, "%s%s", pri->unknownprefix, callingnum);
08836        break;
08837    default:
08838        snprintf(callerid, callerid_len, "%s", callingnum);
08839        break;
08840     }
08841 }
08842 
08843 static void *pri_dchannel(void *vpri)
08844 {
08845    struct zt_pri *pri = vpri;
08846    pri_event *e;
08847    struct pollfd fds[NUM_DCHANS];
08848    int res;
08849    int chanpos = 0;
08850    int x;
08851    int haveidles;
08852    int activeidles;
08853    int nextidle = -1;
08854    struct ast_channel *c;
08855    struct timeval tv, lowest, *next;
08856    struct timeval lastidle = { 0, 0 };
08857    int doidling=0;
08858    char *cc;
08859    char idlen[80];
08860    struct ast_channel *idle;
08861    pthread_t p;
08862    time_t t;
08863    int i, which=-1;
08864    int numdchans;
08865    int cause=0;
08866    struct zt_pvt *crv;
08867    pthread_t threadid;
08868    pthread_attr_t attr;
08869    char ani2str[6];
08870    char plancallingnum[256];
08871    char plancallingani[256];
08872    char calledtonstr[10];
08873    
08874    gettimeofday(&lastidle, NULL);
08875    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
08876       /* Need to do idle dialing, check to be sure though */
08877       cc = strchr(pri->idleext, '@');
08878       if (cc) {
08879          *cc = '\0';
08880          cc++;
08881          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
08882 #if 0
08883          /* Extensions may not be loaded yet */
08884          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
08885             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
08886          else
08887 #endif
08888             doidling = 1;
08889       } else
08890          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
08891    }
08892    for (;;) {
08893       for (i = 0; i < NUM_DCHANS; i++) {
08894          if (!pri->dchannels[i])
08895             break;
08896          fds[i].fd = pri->fds[i];
08897          fds[i].events = POLLIN | POLLPRI;
08898          fds[i].revents = 0;
08899       }
08900       numdchans = i;
08901       time(&t);
08902       ast_mutex_lock(&pri->lock);
08903       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
08904          if (pri->resetting && pri_is_up(pri)) {
08905             if (pri->resetpos < 0)
08906                pri_check_restart(pri);
08907          } else {
08908             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
08909                pri->resetting = 1;
08910                pri->resetpos = -1;
08911             }
08912          }
08913       }
08914       /* Look for any idle channels if appropriate */
08915       if (doidling && pri_is_up(pri)) {
08916          nextidle = -1;
08917          haveidles = 0;
08918          activeidles = 0;
08919          for (x = pri->numchans; x >= 0; x--) {
08920             if (pri->pvts[x] && !pri->pvts[x]->owner && 
08921                 !pri->pvts[x]->call) {
08922                if (haveidles < pri->minunused) {
08923                   haveidles++;
08924                } else if (!pri->pvts[x]->resetting) {
08925                   nextidle = x;
08926                   break;
08927                }
08928             } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
08929                activeidles++;
08930          }
08931          if (nextidle > -1) {
08932             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
08933                /* Don't create a new idle call more than once per second */
08934                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
08935                idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
08936                if (idle) {
08937                   pri->pvts[nextidle]->isidlecall = 1;
08938                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
08939                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
08940                      zt_hangup(idle);
08941                   }
08942                } else
08943                   ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
08944                gettimeofday(&lastidle, NULL);
08945             }
08946          } else if ((haveidles < pri->minunused) &&
08947                (activeidles > pri->minidle)) {
08948             /* Mark something for hangup if there is something 
08949                that can be hungup */
08950             for (x = pri->numchans; x >= 0; x--) {
08951                /* find a candidate channel */
08952                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
08953                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08954                   haveidles++;
08955                   /* Stop if we have enough idle channels or
08956                     can't spare any more active idle ones */
08957                   if ((haveidles >= pri->minunused) ||
08958                       (activeidles <= pri->minidle))
08959                      break;
08960                } 
08961             }
08962          }
08963       }
08964       /* Start with reasonable max */
08965       lowest = ast_tv(60, 0);
08966       for (i = 0; i < NUM_DCHANS; i++) {
08967          /* Find lowest available d-channel */
08968          if (!pri->dchannels[i])
08969             break;
08970          if ((next = pri_schedule_next(pri->dchans[i]))) {
08971             /* We need relative time here */
08972             tv = ast_tvsub(*next, ast_tvnow());
08973             if (tv.tv_sec < 0) {
08974                tv = ast_tv(0,0);
08975             }
08976             if (doidling || pri->resetting) {
08977                if (tv.tv_sec > 1) {
08978                   tv = ast_tv(1, 0);
08979                }
08980             } else {
08981                if (tv.tv_sec > 60) {
08982                   tv = ast_tv(60, 0);
08983                }
08984             }
08985          } else if (doidling || pri->resetting) {
08986             /* Make sure we stop at least once per second if we're
08987                monitoring idle channels */
08988             tv = ast_tv(1,0);
08989          } else {
08990             /* Don't poll for more than 60 seconds */
08991             tv = ast_tv(60, 0);
08992          }
08993          if (!i || ast_tvcmp(tv, lowest) < 0) {
08994             lowest = tv;
08995          }
08996       }
08997       ast_mutex_unlock(&pri->lock);
08998 
08999       e = NULL;
09000       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
09001 
09002       ast_mutex_lock(&pri->lock);
09003       if (!res) {
09004          for (which = 0; which < NUM_DCHANS; which++) {
09005             if (!pri->dchans[which])
09006                break;
09007             /* Just a timeout, run the scheduler */
09008             e = pri_schedule_run(pri->dchans[which]);
09009             if (e)
09010                break;
09011          }
09012       } else if (res > -1) {
09013          for (which = 0; which < NUM_DCHANS; which++) {
09014             if (!pri->dchans[which])
09015                break;
09016             if (fds[which].revents & POLLPRI) {
09017                /* Check for an event */
09018                x = 0;
09019                res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
09020                if ((pri->nodetype != BRI_CPE) && (pri->nodetype != BRI_CPE_PTMP)) {
09021                    /* dont annoy BRI TE mode users with layer2layer alarms */
09022                    if (x)
09023                   ast_log(LOG_NOTICE, "PRI got event: %s (%d) on %s D-channel of span %d\n", event2str(x), x, pri_order(which), pri->span);
09024                }
09025                /* Keep track of alarm state */  
09026                if (x == ZT_EVENT_ALARM) {
09027                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
09028                   pri_find_dchan(pri);
09029                   if ((pri->nodetype == BRI_CPE) || (pri->nodetype == BRI_CPE_PTMP)) {
09030                       if (pri->pri) {
09031                      for (i=0; i<pri->numchans; i++) {
09032                          struct zt_pvt *p = pri->pvts[i];
09033                          if (p) {
09034                         if (p->call) {
09035                             if (p->pri && p->pri->pri) {
09036                               pri_destroycall(p->pri->pri, p->call);
09037                            p->call = NULL;
09038                            p->tei = -1;
09039                             } else
09040                            ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
09041                         }
09042                         if (p->owner)
09043                             p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09044                         p->inalarm = 1;
09045                          }
09046                      }
09047                      pri_shutdown(pri->pri);
09048                       }
09049                   }
09050                } else if (x == ZT_EVENT_NOALARM) {
09051                   if ((pri->nodetype == BRI_CPE) || (pri->nodetype == BRI_CPE_PTMP)) {
09052                       pri->dchanavail[which] |= DCHAN_NOTINALARM;
09053                   //    pri->dchanavail[which] |= DCHAN_UP;
09054                   } else {
09055                       pri->dchanavail[which] |= DCHAN_NOTINALARM;
09056                       pri_restart(pri->dchans[which]);
09057                   }
09058                }
09059             
09060                if (option_debug)
09061                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
09062             } else if (fds[which].revents & POLLIN) {
09063                e = pri_check_event(pri->dchans[which]);
09064             }
09065             if (e)
09066                break;
09067          }
09068       } else if (errno != EINTR)
09069          ast_log(LOG_WARNING, "pri_event returned error %d (%s) on span %d\n", errno, strerror(errno), pri->span);
09070       if (e) {
09071          if (pri->debug)
09072             pri_dump_event(pri->dchans[which], e);
09073 
09074          if (e->e != PRI_EVENT_DCHAN_DOWN) {
09075             if (!(pri->dchanavail[which] & DCHAN_UP)) {
09076                if (option_verbose > 1) 
09077                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
09078             }
09079             pri->dchanavail[which] |= DCHAN_UP;
09080          } else {
09081             if (pri->dchanavail[which] & DCHAN_UP) {
09082                if (option_verbose > 1) 
09083                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
09084             }
09085             pri->dchanavail[which] &= ~DCHAN_UP;
09086          }
09087 
09088          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
09089             /* Must be an NFAS group that has the secondary dchan active */
09090             pri->pri = pri->dchans[which];
09091 
09092          switch (e->e) {
09093          case PRI_EVENT_DCHAN_UP:
09094             if (pri->nodetype == BRI_NETWORK_PTMP) {
09095                 if (option_verbose > 3)
09096                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up for TEI %d\n", pri_order(which), pri->span, e->gen.tei);
09097             } else if (pri->nodetype == BRI_CPE_PTMP) {
09098                 if (option_verbose > 3)
09099                    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
09100             } else {
09101                 if (option_verbose > 1)
09102                    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
09103             }
09104 
09105             if (!pri->pri) pri_find_dchan(pri);
09106 
09107             /* Note presense of D-channel */
09108             time(&pri->lastreset);
09109 
09110             /* Restart in 5 seconds */
09111             if (pri->resetinterval > -1) {
09112                pri->lastreset -= pri->resetinterval;
09113                pri->lastreset += 5;
09114             }
09115             pri->resetting = 0;
09116             /* Take the channels from inalarm condition */
09117             for (i = 0; i < pri->numchans; i++)
09118                if (pri->pvts[i]) {
09119                   pri->pvts[i]->inalarm = 0;
09120                }
09121             break;
09122          case PRI_EVENT_DCHAN_DOWN:
09123             if (pri->nodetype == BRI_NETWORK_PTMP) {
09124                 if (option_verbose > 3)
09125                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down for TEI %d\n", pri_order(which), pri->span, e->gen.tei);
09126                 // PTMP BRIs have N dchans, handled by libpri
09127                 if (e->gen.tei == 0) break;
09128             }
09129             pri_find_dchan(pri);
09130             if (!pri_is_up(pri)) {
09131                pri->resetting = 0;
09132                /* Hangup active channels and put them in alarm mode */
09133                for (i = 0; i < pri->numchans; i++) {
09134                   struct zt_pvt *p = pri->pvts[i];
09135                   if (p) {
09136                       if ((p->tei == e->gen.tei) || (pri->nodetype != BRI_NETWORK_PTMP)) {
09137                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
09138                         /* T309 is not enabled : hangup calls when alarm occurs */
09139                         if (p->call) {
09140                            if (p->pri && p->pri->pri) {
09141                               pri_hangup(p->pri->pri, p->call, -1, -1);
09142                               pri_destroycall(p->pri->pri, p->call);
09143                               p->call = NULL;
09144                            } else
09145                               ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
09146                         }
09147                         p->tei = -1;
09148                         if (p->realcall) {
09149                            pri_hangup_all(p->realcall, pri);
09150                         } else if (p->owner)
09151                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09152                      }
09153                      p->inalarm = 1;
09154                   }
09155                }
09156                 }
09157             }
09158             break;
09159          case PRI_EVENT_RESTART:
09160             if (e->restart.channel > -1) {
09161                chanpos = pri_find_principle(pri, e->restart.channel);
09162                if (chanpos < 0)
09163                   ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 
09164                      PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
09165                else {
09166                   if (option_verbose > 2)
09167                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n", 
09168                         PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
09169                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09170                   if (pri->pvts[chanpos]->call) {
09171                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
09172                      pri->pvts[chanpos]->call = NULL;
09173                   }
09174                   /* Force soft hangup if appropriate */
09175                   if (pri->pvts[chanpos]->realcall) 
09176                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09177                   else if (pri->pvts[chanpos]->owner)
09178                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09179                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09180                }
09181             } else {
09182                if (option_verbose > 2)
09183                   ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
09184                for (x = 0; x < pri->numchans; x++)
09185                   if (pri->pvts[x]) {
09186                      ast_mutex_lock(&pri->pvts[x]->lock);
09187                      if (pri->pvts[x]->call) {
09188                         pri_destroycall(pri->pri, pri->pvts[x]->call);
09189                         pri->pvts[x]->call = NULL;
09190                      }
09191                      if (pri->pvts[x]->realcall)
09192                         pri_hangup_all(pri->pvts[x]->realcall, pri);
09193                      else if (pri->pvts[x]->owner)
09194                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09195                      ast_mutex_unlock(&pri->pvts[x]->lock);
09196                   }
09197             }
09198             break;
09199          case PRI_EVENT_KEYPAD_DIGIT:
09200             chanpos = pri_find_principle(pri, e->digit.channel);
09201             if (chanpos < 0) {
09202                ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 
09203                   PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
09204             } else {
09205                chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
09206                if (chanpos > -1) {
09207                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09208                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
09209                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
09210                      /* how to do that */
09211                      int digitlen = strlen(e->digit.digits);
09212                      char digit;
09213                      int i;               
09214                      for (i = 0; i < digitlen; i++) { 
09215                         digit = e->digit.digits[i];
09216                         {
09217                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
09218                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
09219                         }
09220                      }
09221                   }
09222                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09223                }
09224             }
09225             break;
09226          case PRI_EVENT_INFO_RECEIVED:
09227             chanpos = pri_find_principle(pri, e->ring.channel);
09228             if (chanpos < 0) {
09229                ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 
09230                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09231             } else {
09232                chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
09233                if (chanpos > -1) {
09234 //             ast_log(LOG_NOTICE, "INFO received on  channel %d/%d span %d\n",
09235 //                PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09236                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09237                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
09238                   if (pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
09239                      /* how to do that */
09240                      int digitlen = strlen(e->ring.callednum);
09241                      char digit;
09242                      int i;               
09243                      for (i = 0; i < digitlen; i++) { 
09244                         digit = e->ring.callednum[i];
09245                         {
09246                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
09247                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
09248                         }
09249                      }
09250                      if (!pri->overlapdial) {
09251                          strncat(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
09252                          if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten + 1)) {
09253                         tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1);
09254                          } else {
09255                         tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09256                          }
09257                      }
09258                   }
09259                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09260                }
09261             }
09262             break;
09263          case PRI_EVENT_RING:
09264             crv = NULL;
09265             if (e->ring.channel == -1) {
09266                /* if no channel specified find one empty */
09267                chanpos = pri_find_empty_chan(pri, 1);
09268             } else {
09269                chanpos = pri_find_principle(pri, e->ring.channel);
09270             }
09271             /* if no channel specified find one empty */
09272             if (chanpos < 0) {
09273                /* no channel specified and no free channel. this is a callwating SETUP */
09274                if (e->ring.channel <= 0) {
09275                    if (option_verbose > 2)
09276                   ast_verbose(VERBOSE_PREFIX_3 "Ignoring callwaiting SETUP on channel %d/%d span %d %d\n", PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span, e->ring.channel);
09277                    pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_USER_BUSY, -1);
09278                    break;
09279                }
09280             } else {
09281                /* ok, we got a b channel for this call, lock it */
09282                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09283                if (pri->pvts[chanpos]->owner) {
09284                    /* safety check, for messed up retransmissions? */
09285                    if (pri->pvts[chanpos]->call == e->ring.call) {
09286                   ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n",
09287                         PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09288                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09289                   chanpos = -1;
09290                   break;
09291                    } else {
09292                   ast_log(LOG_WARNING, "Ring requested on channel %d/%d already in use on span %d. Hanging up owner.\n",
09293                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09294                   if (pri->pvts[chanpos]->realcall) {
09295                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09296                   } else {
09297                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09298                      /* XXX destroy the call here, so we can accept the retransmission as a new call */
09299                      pri_destroycall(pri->pri, e->ring.call);
09300                   }
09301                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09302                   chanpos = -1;
09303                   break;
09304                    }
09305                }
09306                if (chanpos > -1) {
09307                   /* everything is ok with the b channel */
09308                    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09309                }
09310             }
09311             /* actually, we already got a valid channel by now */
09312             if (chanpos > -1) {
09313                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09314                /* dont detect dtmfs before the signalling is done */
09315                disable_dtmf_detect(pri->pvts[chanpos]);
09316                /* this channel is owned by this TEI */
09317                pri->pvts[chanpos]->tei = e->ring.tei;
09318                if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
09319                   /* Should be safe to lock CRV AFAIK while bearer is still locked */
09320                   crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
09321                   if (crv)
09322                      ast_mutex_lock(&crv->lock);
09323                   if (!crv || crv->owner) {
09324                      pri->pvts[chanpos]->call = NULL;
09325                      if (crv) {
09326                         if (crv->owner)
09327                            crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09328                         ast_log(LOG_WARNING, "Call received for busy CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
09329                      } else
09330                         ast_log(LOG_NOTICE, "Call received for unconfigured CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
09331                      pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE, -1);
09332                      if (crv)
09333                         ast_mutex_unlock(&crv->lock);
09334                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09335                      break;
09336                   }
09337                }
09338                /* assign call to b channel */
09339                pri->pvts[chanpos]->call = e->ring.call;
09340                apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
09341                if (pri->pvts[chanpos]->use_callerid) {
09342                   ast_shrink_phone_number(plancallingnum);
09343                   ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
09344 #ifdef PRI_ANI
09345                   if (!ast_strlen_zero(e->ring.callingani)) {
09346                      apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
09347                      ast_shrink_phone_number(plancallingani);
09348                      ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
09349                   } else {
09350                      pri->pvts[chanpos]->cid_ani[0] = '\0';
09351                   }
09352 #endif
09353                   ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
09354                   pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
09355                } else {
09356                   pri->pvts[chanpos]->cid_num[0] = '\0';
09357                   pri->pvts[chanpos]->cid_ani[0] = '\0';
09358                   pri->pvts[chanpos]->cid_name[0] = '\0';
09359                   pri->pvts[chanpos]->cid_ton = 0;
09360                }
09361                apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
09362                           e->ring.redirectingnum, e->ring.callingplanrdnis);
09363                /* get callingpres */
09364                pri->pvts[chanpos]->cid_pres = e->ring.callingpres;
09365                switch (e->ring.callingpres) {
09366                    case PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
09367                    case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
09368                    case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
09369                    case PRES_PROHIB_NETWORK_NUMBER:
09370                   ast_copy_string(pri->pvts[chanpos]->cid_name, pri->withheldcid, sizeof(pri->pvts[chanpos]->cid_name));
09371                   break;
09372                    case PRES_NUMBER_NOT_AVAILABLE:
09373                   ast_copy_string(pri->pvts[chanpos]->cid_name, pri->nocid, sizeof(pri->pvts[chanpos]->cid_name));
09374                   break;
09375                }
09376                /* If immediate=yes go to s|1 */
09377                if (pri->pvts[chanpos]->immediate) {
09378                   if (option_verbose > 2)
09379                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
09380                   pri->pvts[chanpos]->exten[0] = 's';
09381                   pri->pvts[chanpos]->exten[1] = '\0';
09382                } else if (ast_strlen_zero(e->ring.callednum)) {
09383                    /* called party number is empty */
09384                    if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
09385                   if (!pri->overlapdial) {
09386                       // be able to set digittimeout for BRI phones
09387                       pri->pvts[chanpos]->exten[0] = 's';
09388                       pri->pvts[chanpos]->exten[1] = '\0';
09389                       tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09390                   } else {
09391                       pri->pvts[chanpos]->exten[0] = '\0';
09392                   }
09393                    } else {
09394                   if (pri->nodetype == BRI_CPE) {
09395                       /* fix for .at p2p bri lines */
09396                       pri->pvts[chanpos]->exten[0] = 's';
09397                       pri->pvts[chanpos]->exten[1] = '\0';
09398                   } else if (pri->overlapdial) {
09399                       pri->pvts[chanpos]->exten[0] = '\0';
09400                   } else {
09401                       /* Some PRI circuits are set up to send _no_ digits.  Handle them as 's'. */
09402                       pri->pvts[chanpos]->exten[0] = 's';
09403                       pri->pvts[chanpos]->exten[1] = '\0';
09404                   }
09405                    }
09406                    /* No number yet, but received "sending complete"? */
09407                       if (e->ring.complete) {
09408                   if (option_verbose > 2)
09409                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
09410                   pri->pvts[chanpos]->exten[0] = 's';
09411                   pri->pvts[chanpos]->exten[1] = '\0';
09412                    }
09413                } else {
09414                   /* Get called number */
09415                   pri_make_callerid(pri, pri->pvts[chanpos]->dnid, sizeof(pri->pvts[chanpos]->dnid), e->ring.callednum, sizeof(e->ring.callednum),  e->ring.calledplan, 0, pri->pvts[chanpos]->stripmsd);
09416                   pri_make_callerid(pri, pri->pvts[chanpos]->exten, sizeof(pri->pvts[chanpos]->exten), e->ring.callednum, sizeof(e->ring.callednum), e->ring.calledplan, 0, pri->pvts[chanpos]->stripmsd);
09417                   if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
09418                       /* if we get the next digit we should stop the dialtone */
09419                       if (!pri->overlapdial) {
09420                      // with overlapdial=no the exten is always prefixed by "s"
09421                      if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten + 1)) {
09422                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1);
09423                      } else {
09424                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09425                      }
09426                       } else {
09427                      if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten)) {
09428                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1);
09429                      } else {
09430                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09431                      }
09432                       }
09433                   }
09434                }
09435                /* Part 3: create channel, setup audio... */
09436                /* Set DNID on all incoming calls -- even immediate */
09437                if (!ast_strlen_zero(e->ring.callednum))
09438                   strncpy(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid) - 1);
09439                /* Make sure extension exists (or in overlap dial mode, can exist) */
09440                if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
09441                   ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
09442                   /* Setup law */
09443                   int law;
09444                   if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
09445                      /* Set to audio mode at this point */
09446                      law = 1;
09447                      if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
09448                         ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law);
09449                   }
09450                   if (e->ring.layer1 == PRI_LAYER_1_ALAW)
09451                      law = ZT_LAW_ALAW;
09452                   else
09453                      law = ZT_LAW_MULAW;
09454                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
09455                   if (res < 0) 
09456                      ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
09457                   if (IS_DIGITAL(e->ring.ctype)) {
09458                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[chanpos]->law);
09459                   } else {
09460                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
09461                   }
09462                   if (res < 0)
09463                      ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
09464                   if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09465                       if (e->ring.complete || !pri->overlapdial) {
09466                      /* Just announce proceeding */
09467                      pri->pvts[chanpos]->proceeding = 1;
09468                      pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
09469                       } else {
09470                      if (pri->switchtype != PRI_SWITCH_GR303_TMC) 
09471                         pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09472                      else
09473                         pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09474                       }
09475                   } else {
09476                      /* BRI_NETWORK | BRI_NETWORK_PTMP */
09477                      if (pri->overlapdial || (!strcasecmp(pri->pvts[chanpos]->exten, "s"))) {
09478                          /* send a SETUP_ACKNOWLEDGE */
09479                          pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09480                      } else {
09481                          /* send an ALERTING ??? wtf */
09482                      //    pri_acknowledge(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09483                          pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
09484                      }
09485                   }
09486                   /* overlapdial = yes  and the extension can be valid */
09487                   /* Get the use_callingpres state */
09488                   pri->pvts[chanpos]->callingpres = e->ring.callingpres;
09489                
09490                   /* Start PBX */
09491                   if (!e->ring.complete && pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
09492                      /* Release the PRI lock while we create the channel */
09493                      ast_mutex_unlock(&pri->lock);
09494                      if (crv) {
09495                         /* Set bearer and such */
09496                         pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
09497                         c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
09498                         if (c && (e->ring.lowlayercompat[0] > 0)) {
09499                             memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat));
09500                         }
09501                         pri->pvts[chanpos]->owner = &inuse;
09502                         ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
09503                      } else {
09504                         c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
09505                         if (c && (e->ring.lowlayercompat[0] > 0)) {
09506                             memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat));
09507                         }
09508                         zt_enable_ec(pri->pvts[chanpos]);  /* XXX rethink */
09509                      }
09510 
09511                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09512 
09513                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
09514                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
09515                      }
09516                         if (!ast_strlen_zero(e->ring.callingnum)) {
09517                          char tmpstr[256];
09518                          pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingnum, sizeof(e->ring.callingnum), e->ring.callingplan, e->ring.callingpres, 0);
09519                          pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
09520                      }
09521                      if (!ast_strlen_zero(e->ring.callingani)) {
09522                          char tmpstr[256];
09523                          pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingani, sizeof(e->ring.callingani), e->ring.callingplanuser, e->ring.callingpresuser, 0);
09524                          pbx_builtin_setvar_helper(c, "PRI_USER_CID", tmpstr);
09525                      }
09526                      if (e->ring.ani2 >= 0) {
09527                         snprintf(ani2str, 5, "%.2d", e->ring.ani2);
09528                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
09529                      }
09530 
09531 #ifdef SUPPORT_USERUSER
09532                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
09533                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
09534                      }
09535 #endif
09536 
09537                      snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
09538                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
09539                      if (e->ring.redirectingreason >= 0)
09540                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
09541                   
09542                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09543                      ast_mutex_lock(&pri->lock);
09544 
09545                      pthread_attr_init(&attr);
09546                      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
09547                      if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
09548                         if (option_verbose > 2)
09549                            ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap %s call from '%s' to '%s' on channel %d/%d, span %d\n",
09550                               pri->pvts[chanpos]->digital ? "data" : "voice", plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
09551                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09552                      } else {
09553                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
09554                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09555                         if (c)
09556                            ast_hangup(c);
09557                         else {
09558                            pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1);
09559                            pri->pvts[chanpos]->call = NULL;
09560                         }
09561                      }
09562                      pthread_attr_destroy(&attr);
09563                   } else  {
09564                      /* overlapdial = no */
09565                      ast_mutex_unlock(&pri->lock);
09566                      /* Release PRI lock while we create the channel */
09567                      c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
09568                      if (c && (e->ring.lowlayercompat[0] > 0)) {
09569                          memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat));
09570                      }
09571                      if (c) {
09572                         char calledtonstr[10];
09573 
09574                         ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09575 
09576                         if (e->ring.ani2 >= 0) {
09577                            snprintf(ani2str, 5, "%d", e->ring.ani2);
09578                            pbx_builtin_setvar_helper(c, "ANI2", ani2str);
09579                         }
09580 
09581 #ifdef SUPPORT_USERUSER
09582                         if (!ast_strlen_zero(e->ring.useruserinfo)) {
09583                            pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
09584                         }
09585 #endif
09586 
09587                         if (e->ring.redirectingreason >= 0)
09588                            pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
09589                      
09590                         snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
09591                         pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
09592 
09593                         ast_mutex_lock(&pri->pvts[chanpos]->lock);
09594                         ast_mutex_lock(&pri->lock);
09595 
09596                         if (option_verbose > 2)
09597                            ast_verbose(VERBOSE_PREFIX_3 "Accepting %s call from '%s' to '%s' on channel %d/%d, span %d\n",
09598                               pri->pvts[chanpos]->digital ? "data" : "voice", e->ring.callingnum, pri->pvts[chanpos]->exten,
09599                                  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09600                         zt_enable_ec(pri->pvts[chanpos]);
09601                          if(!ast_strlen_zero(e->ring.callingsubaddr)) {
09602                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
09603                          }
09604                             if (!ast_strlen_zero(e->ring.callingnum)) {
09605                         char tmpstr[256];
09606                              pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingnum, sizeof(e->ring.callingnum), e->ring.callingplan, e->ring.callingpres, 0);
09607                              pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
09608                          }
09609                          if (!ast_strlen_zero(e->ring.callingani)) {
09610                         char tmpstr[256];
09611                              pri_make_callerid(pri, tmpstr,sizeof(tmpstr),  e->ring.callingani, sizeof(e->ring.callingani), e->ring.callingplanuser, e->ring.callingpresuser, 0);
09612                              pbx_builtin_setvar_helper(c, "PRI_USER_CID", e->ring.callednum);
09613                          }
09614                          if (!ast_strlen_zero(e->ring.useruserinfo)) {
09615                              pbx_builtin_setvar_helper(c, "UUI", e->ring.useruserinfo);
09616                          }
09617                      } else {
09618 
09619                         ast_mutex_lock(&pri->lock);
09620 
09621                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
09622                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09623                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1);
09624                         pri->pvts[chanpos]->call = NULL;
09625                      }
09626                   }
09627                } else {
09628                /* invalid extension */
09629                   if (option_verbose > 2)
09630                      ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist.  Rejecting call on channel %d/%d, span %d\n",
09631                         pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 
09632                            pri->pvts[chanpos]->prioffset, pri->span);
09633                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED, -1);
09634                   pri->pvts[chanpos]->call = NULL;
09635                   pri->pvts[chanpos]->exten[0] = '\0';
09636                }
09637                if (crv)
09638                   ast_mutex_unlock(&crv->lock);
09639                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09640             } else {
09641                if (e->ring.flexible)
09642                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION, -1);
09643                else
09644                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL, -1);
09645             }
09646             break;
09647          case PRI_EVENT_RINGING:
09648             chanpos = pri_find_principle(pri, e->ringing.channel);
09649             if (chanpos < 0) {
09650                ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 
09651                   PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
09652             } else {
09653                chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
09654                if (chanpos < 0) {
09655                   ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 
09656                      PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
09657                } else {
09658                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09659                   if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09660                   // XXX   zt_enable_ec(pri->pvts[chanpos]);
09661                      pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
09662                      pri->pvts[chanpos]->alerting = 1;
09663                   } else
09664                      ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
09665 #ifdef PRI_PROGRESS_MASK
09666                   if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09667 #else
09668                   if (e->ringing.progress == 8) {
09669 #endif
09670                      /* Now we can do call progress detection */
09671                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09672                         /* RINGING detection isn't required because we got ALERTING signal */
09673                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
09674                         pri->pvts[chanpos]->dsp_features = 0;
09675                      }
09676                   }
09677 
09678 #ifdef SUPPORT_USERUSER
09679                   if (!ast_strlen_zero(e->ringing.useruserinfo)) {
09680                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09681                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09682                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->ringing.useruserinfo);
09683                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09684                   }
09685 #endif
09686 
09687                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09688                }
09689             }
09690             break;
09691          case PRI_EVENT_PROGRESS:
09692             /* Get chan value if e->e is not PRI_EVENT_RINGING */
09693             chanpos = pri_find_principle(pri, e->proceeding.channel);
09694             if (chanpos > -1) {
09695                 if ((pri->pvts[chanpos]->priindication_oob == 2) && (e->proceeding.cause == PRI_CAUSE_USER_BUSY)) {
09696                /* received PROGRESS with cause BUSY, no inband callprogress wanted => hang up! */
09697                if (pri->pvts[chanpos]->owner) {
09698                    pri->pvts[chanpos]->owner->hangupcause = AST_CAUSE_USER_BUSY;
09699                    pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09700                }
09701                 } else {
09702 #ifdef PRI_PROGRESS_MASK
09703                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
09704 #else
09705                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progress == 8)) {
09706 #endif
09707                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
09708 
09709                   if (e->proceeding.cause > -1) {
09710                      if (option_verbose > 2)
09711                         ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
09712 
09713                      /* Work around broken, out of spec USER_BUSY cause in a progress message */
09714                      if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
09715                         if (pri->pvts[chanpos]->owner) {
09716                            if (option_verbose > 2)
09717                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
09718 
09719                            pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
09720                            f.subclass = AST_CONTROL_BUSY;
09721                         }
09722                      }
09723                   }
09724                   
09725                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09726                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
09727                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09728                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09729 #ifdef PRI_PROGRESS_MASK
09730                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09731 #else
09732                   if (e->proceeding.progress == 8) {
09733 #endif
09734                      /* Now we can do call progress detection */
09735                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09736                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09737                         pri->pvts[chanpos]->dsp_features = 0;
09738                      }
09739                   }
09740                   pri->pvts[chanpos]->progress = 1;
09741                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09742                }
09743                 }
09744             }
09745             break;
09746          case PRI_EVENT_PROCEEDING:
09747             chanpos = pri_find_principle(pri, e->proceeding.channel);
09748             if (chanpos > -1) {
09749                 chanpos = pri_fixup_principle(pri, chanpos, e->proceeding.call);
09750                 if (chanpos < 0) {
09751                ast_log(LOG_WARNING, "Received PROCEEDING on channel %d/%d not in use on span %d\n",
09752                   PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), pri->span);
09753                chanpos = -1;
09754                 } else {
09755                if (!pri->pvts[chanpos]->proceeding) {
09756                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
09757                   
09758                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09759                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
09760                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09761                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09762 #ifdef PRI_PROGRESS_MASK
09763                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09764 #else
09765                   if (e->proceeding.progress == 8) {
09766 #endif
09767                      /* Now we can do call progress detection */
09768                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09769                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09770                         pri->pvts[chanpos]->dsp_features = 0;
09771                      }
09772                      /* Bring voice path up */
09773                      f.subclass = AST_CONTROL_PROGRESS;
09774                      zap_queue_frame(pri->pvts[chanpos], &f, pri);
09775                   }
09776                   pri->pvts[chanpos]->proceeding = 1;
09777                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09778                }
09779                 }
09780             }
09781             break;
09782          case PRI_EVENT_FACNAME:
09783             chanpos = pri_find_principle(pri, e->facname.channel);
09784             if (chanpos < 0) {
09785                ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n", 
09786                   PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09787             } else {
09788                chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
09789                if (chanpos < 0) {
09790                   ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n", 
09791                      PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09792                } else {
09793                   /* Re-use *69 field for PRI */
09794                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09795                   ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
09796                   ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
09797                   pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
09798                   zt_enable_ec(pri->pvts[chanpos]);
09799                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09800                }
09801             }
09802             break;            
09803          case PRI_EVENT_SUSPEND_REQ:
09804             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09805                 pri_suspend_reject(pri->pri, e->suspend_req.call, "");
09806                 break;
09807             }
09808             chanpos = pri_find_principle(pri, e->suspend_req.channel);
09809             if (chanpos < 0)  {
09810                ast_log(LOG_WARNING, "Suspend requested on unconfigured channel %d span %d\n", chanpos, pri->span);
09811                chanpos = -1;
09812             }
09813 
09814             if (chanpos > -1) {
09815                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
09816                 if (pri->pvts[chanpos]->owner) {
09817                if (ast_bridged_channel(pri->pvts[chanpos]->owner)) {
09818                    struct zt_suspended_call *zpc;
09819                    char tmpstr[256];
09820                    zpc = malloc(sizeof(struct zt_suspended_call));
09821                    if (!zpc) {
09822                   ast_log(LOG_ERROR, "unable to malloc zt_suspended_call\n");
09823                   break;
09824                    }
09825                    strncpy(zpc->msn,  pri->pvts[chanpos]->cid_num, sizeof(zpc->msn));
09826                    strncpy(zpc->callid,  e->suspend_req.callid, sizeof(zpc->callid));
09827                    ast_masq_park_call(ast_bridged_channel(pri->pvts[chanpos]->owner), NULL, 0, &zpc->parked_at);
09828                    zpc->next = pri->suspended_calls;
09829                    pri->suspended_calls = zpc;
09830                    snprintf(tmpstr, sizeof(tmpstr), "Parked at %d", zpc->parked_at);
09831                    pri_suspend_acknowledge(pri->pri, e->suspend_req.call,tmpstr);
09832                    pri->pvts[chanpos]->call = NULL;
09833                    pri->pvts[chanpos]->tei = -1;
09834                    pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09835                } else {
09836                    pri_suspend_reject(pri->pri, e->suspend_req.call, "cant park a non-bridge");
09837                    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09838                    break;
09839                }
09840                 } else {
09841                pri_suspend_reject(pri->pri, e->suspend_req.call, "");
09842                 }
09843                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09844             }
09845             break;
09846          case PRI_EVENT_RESUME_REQ:
09847             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09848                 break;
09849             }
09850             chanpos = pri_find_empty_chan(pri, 1);
09851             if (chanpos < 0) {
09852                pri_resume_reject(pri->pri, e->resume_req.call,"All channels busy");
09853                ast_log(LOG_WARNING, "Resume requested on odd channel number %d span %d\n", chanpos, pri->span);
09854                chanpos = -1;
09855             } else if (!pri->pvts[chanpos]) {
09856                pri_resume_reject(pri->pri, e->resume_req.call,"General protection fault in module 0x0BRI");
09857                chanpos = -1;
09858             }
09859 
09860             if (chanpos > -1) {
09861                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
09862                 if (!pri->pvts[chanpos]->owner) {
09863                struct zt_suspended_call *zpc, *zpcl;
09864                int unparked=0;
09865                char extenstr[255], temp[255];
09866                zpc = NULL;
09867                zpcl = pri->suspended_calls;
09868                while (zpcl) {
09869                //    ast_log(LOG_NOTICE, "zpc->parked_at %d zpcl->callid %s\n",zpcl->parked_at, zpcl->callid);
09870                    if (((strlen(zpcl->callid) == 0) && (strlen(e->resume_req.callid)==0)) || (!strcmp(zpcl->callid,e->resume_req.callid))) {
09871                   int law;
09872                   // found a parked call
09873                   snprintf(extenstr, sizeof(extenstr), "%d", zpcl->parked_at);
09874                   strncpy(pri->pvts[chanpos]->exten, extenstr, sizeof(pri->pvts[chanpos]->exten));
09875                // strncpy(pri->pvts[chanpos]->context, ast_parking_con(), sizeof(pri->pvts[chanpos]->context));
09876                        pri->pvts[chanpos]->call = e->resume_req.call;
09877                        law = 1;
09878                        if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
09879                          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]), law);
09880                // uhh ohh...what shall we do without the bearer cap???
09881                   law = ZT_LAW_ALAW;
09882                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
09883                   if (res < 0)
09884                       ast_log(LOG_WARNING, "Unable to set law on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
09885                   if (!pri->pvts[chanpos]->digital) {
09886                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
09887                   } else {
09888                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[chanpos]->law);
09889                   }
09890                   if (res < 0)
09891                       ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
09892                   /* Start PBX */
09893                   c = zt_new(pri->pvts[chanpos], AST_STATE_UP, 1, SUB_REAL, law, PRI_TRANS_CAP_SPEECH);
09894                   if (c) {
09895                       pri->pvts[chanpos]->owner = c;
09896                       pri->pvts[chanpos]->call = e->resume_req.call;
09897                       zt_enable_ec(pri->pvts[chanpos]);
09898                       zt_train_ec(pri->pvts[chanpos]);
09899                   } else {
09900                       ast_log(LOG_ERROR, "unable to start pbx\n");
09901                   }
09902 
09903                   if (zpc) {
09904                       zpc->next = zpcl->next;
09905                       free(zpcl);
09906                       zpcl = zpc->next;
09907                   } else {
09908                       // remove head
09909                       pri->suspended_calls = zpcl->next;
09910                       free(zpcl);
09911                       zpcl = pri->suspended_calls;
09912                       zpc = NULL;
09913                   }
09914                   unparked = 1;
09915                   snprintf(temp, sizeof(temp), "Unparked %s", extenstr);
09916                   pri_resume_acknowledge(pri->pri, e->resume_req.call, chanpos + 1, temp);
09917                        break;
09918                    }
09919                    zpc = zpcl;
09920                    if (zpcl) zpcl = zpcl->next;
09921                }
09922                if (!unparked)
09923                    pri_resume_reject(pri->pri, e->resume_req.call,"No suspended call to unpark!");
09924                 } else {
09925                pri_resume_reject(pri->pri, e->resume_req.call,"No suspended call to unpark!");
09926                 }
09927                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09928             }
09929             break;
09930          case PRI_EVENT_HOLD_REQ:
09931             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09932                 pri_hold_reject(pri->pri, e->hold_req.call);
09933                 break;
09934             }
09935             /* holded calls are not implemented yet */
09936             pri_hold_reject(pri->pri, e->hold_req.call);
09937             break;
09938          case PRI_EVENT_RETRIEVE_REQ:
09939             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09940                 pri_retrieve_reject(pri->pri, e->retrieve_req.call);
09941                 break;
09942             }
09943             /* Holded calls are currently not supported */
09944             pri_retrieve_reject(pri->pri, e->retrieve_req.call);
09945             chanpos = -1;
09946             break;
09947          case PRI_EVENT_DISPLAY_RECEIVED:
09948             ast_log(LOG_NOTICE, "DISPLAY IE: [ %s ] received\n",e->display.text);
09949             chanpos = pri_find_principle(pri, e->display.channel);
09950             if (chanpos < 0) {
09951                 ast_log(LOG_WARNING, "odd channel number %d span %d\n", chanpos, pri->span);
09952                 chanpos = -1;
09953             }
09954             if (chanpos > -1) {
09955                 if (pri->pvts[chanpos]->owner) {
09956          //    ast_sendtext(pri->pvt[chanpos]->owner, e->display.text);
09957                 }
09958             }
09959             break;
09960          case PRI_EVENT_ANSWER:
09961             chanpos = pri_find_principle(pri, e->answer.channel);
09962             if (chanpos < 0) {
09963                ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 
09964                   PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09965             } else {
09966                chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
09967                if (chanpos < 0) {
09968                   ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 
09969                      PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09970                } else {
09971                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09972                   pri->pvts[chanpos]->tei = e->answer.tei;
09973                   /* Now we can do call progress detection */
09974 
09975                   /* We changed this so it turns on the DSP no matter what... progress or no progress.
09976                    * By this time, we need DTMF detection and other features that were previously disabled
09977                    * -- Matt F */
09978                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09979                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09980                      pri->pvts[chanpos]->dsp_features = 0;
09981                   }
09982                   if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
09983                      ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
09984                      x = ZT_START;
09985                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
09986                      if (res < 0) {
09987                         if (errno != EINPROGRESS) {
09988                            ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
09989                         }
09990                      }
09991                   } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09992                      pri->pvts[chanpos]->dialing = 1;
09993                      /* Send any "w" waited stuff */
09994                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
09995                      if (res < 0) {
09996                         ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
09997                         pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09998                      } else 
09999                         ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
10000                      pri->pvts[chanpos]->dop.dialstr[0] = '\0';
10001                   } else if (pri->pvts[chanpos]->confirmanswer) {
10002                      ast_log(LOG_DEBUG, "Waiting for answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
10003                      enable_dtmf_detect(pri->pvts[chanpos]);
10004                   } else {
10005                      pri->pvts[chanpos]->dialing = 0;
10006                      pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
10007                      /* Enable echo cancellation if it's not on already */
10008                      zt_enable_ec(pri->pvts[chanpos]);
10009                      zt_train_ec(pri->pvts[chanpos]);
10010                      /* stop ignoring inband dtmf */
10011                      enable_dtmf_detect(pri->pvts[chanpos]);
10012                   }
10013 
10014 #ifdef SUPPORT_USERUSER
10015                   if (!ast_strlen_zero(e->answer.useruserinfo)) {
10016                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10017                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10018                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo);
10019                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10020                   }
10021 #endif
10022 
10023                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10024                }
10025             }
10026             break;            
10027          case PRI_EVENT_HANGUP:
10028             chanpos = pri_find_principle(pri, e->hangup.channel);
10029             if (chanpos < 0) {
10030                ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 
10031                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10032             } else {
10033                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
10034                if (chanpos > -1) {
10035                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10036                   if (!pri->pvts[chanpos]->alreadyhungup) {
10037                      /* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
10038                      pri->pvts[chanpos]->alreadyhungup = 1;
10039                      if (pri->pvts[chanpos]->realcall) 
10040                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10041                      else if (pri->pvts[chanpos]->owner) {
10042                         /* Queue a BUSY instead of a hangup if our cause is appropriate */
10043                         pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
10044                         if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
10045                            pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10046                         else {
10047                            switch (e->hangup.cause) {
10048                               case PRI_CAUSE_USER_BUSY:
10049                                  pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
10050                                  break;
10051                               case PRI_CAUSE_CALL_REJECTED:
10052                               case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
10053                               case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
10054                               case PRI_CAUSE_SWITCH_CONGESTION:
10055                               case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
10056                               case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
10057                                  pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
10058                                  break;
10059                               default:
10060                                  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10061                            }
10062                         }
10063                      }
10064                      if (option_verbose > 2) 
10065                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", 
10066                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
10067                   } else {
10068                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
10069                      pri->pvts[chanpos]->call = NULL;
10070                      pri->pvts[chanpos]->tei = -1;
10071                   }
10072                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
10073                      if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) {
10074                          if (option_verbose > 2)
10075                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 
10076                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10077                          pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
10078                          pri->pvts[chanpos]->resetting = 1;
10079                      }
10080                   }
10081                   if (e->hangup.aoc_units > -1) {
10082                      if (pri->pvts[chanpos]->owner) {
10083                          char tmpstr[256];
10084                          snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units);
10085                          pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr);
10086                      }
10087                      if (option_verbose > 2)
10088                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10089                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10090                   }
10091 
10092 #ifdef SUPPORT_USERUSER
10093                   if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
10094                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10095                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10096                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
10097                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10098                   }
10099 #endif
10100 
10101                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10102                } else {
10103                   ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
10104                   ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n",
10105                         PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10106                }
10107             } 
10108             break;
10109 #ifndef PRI_EVENT_HANGUP_REQ
10110 #error please update libpri
10111 #endif
10112          case PRI_EVENT_HANGUP_REQ:
10113             chanpos = pri_find_principle(pri, e->hangup.channel);
10114             if (chanpos < 0) {
10115                if (pri->nodetype == BRI_NETWORK_PTMP) {
10116                    pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1);
10117                } else {
10118                    ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n",
10119                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10120                }
10121             } else if ((pri->pvts[chanpos]->priindication_oob != 2) || (!e->hangup.inband_progress) || (!pri->pvts[chanpos]->outgoing)) {
10122                             /* dont hang up if we want to hear inband call progress */
10123                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
10124                if (chanpos > -1) {
10125                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10126                   if (pri->pvts[chanpos]->realcall) 
10127                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10128                   else if (pri->pvts[chanpos]->owner) {
10129                      char tmpstr[256];
10130                      snprintf(tmpstr, sizeof(tmpstr), "%d", e->hangup.cause);
10131                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "PRI_CAUSE", tmpstr);
10132                      pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
10133                      if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
10134                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10135                      else {
10136                         switch (e->hangup.cause) {
10137                            case PRI_CAUSE_USER_BUSY:
10138                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
10139                               break;
10140                            case PRI_CAUSE_CALL_REJECTED:
10141                            case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
10142                            case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
10143                            case PRI_CAUSE_SWITCH_CONGESTION:
10144                            case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
10145                            case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
10146                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
10147                               break;
10148                            default:
10149                               pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10150                         }
10151                      }
10152                      if (option_verbose > 2) 
10153                         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);
10154                      if (e->hangup.aoc_units > -1)
10155                         if (option_verbose > 2)
10156                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10157                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10158                      if (e->hangup.aoc_units > -1) {
10159                          if (pri->pvts[chanpos]->owner) {
10160                         char tmpstr[256];
10161                         snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units);
10162                         pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr);
10163                          }
10164                          if (option_verbose > 2)
10165                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10166                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10167                      }
10168                      if (pri->nodetype == BRI_NETWORK_PTMP) {
10169                         pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
10170                         pri->pvts[chanpos]->call = NULL;
10171                         pri->pvts[chanpos]->tei = -1;
10172                      }
10173                   } else {
10174                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
10175                      pri->pvts[chanpos]->call = NULL;
10176                      pri->pvts[chanpos]->tei = -1;
10177                   }
10178                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
10179                      if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) {
10180                          if (option_verbose > 2)
10181                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", 
10182                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10183                          pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
10184                          pri->pvts[chanpos]->resetting = 1;
10185                      }
10186                   }
10187 
10188 #ifdef SUPPORT_USERUSER
10189                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
10190                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10191                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10192                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
10193                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10194                   }
10195 #endif
10196 
10197                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10198                } else {
10199                   if (pri->nodetype != BRI_NETWORK_PTMP) {
10200                       ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10201                   } else {
10202                      ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10203                   }
10204                }
10205             } 
10206             if ((chanpos > -1) && (pri->pvts[chanpos]->owner) && (pri->pvts[chanpos]->priindication_oob == 2) && (e->hangup.inband_progress) && (pri->pvts[chanpos]->outgoing)) {
10207                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
10208                if (e->hangup.aoc_units > -1) {
10209                    char tmpstr[256];
10210                    snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units);
10211                    pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr);
10212                    if (option_verbose > 2)
10213                   ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10214                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10215                }
10216                pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
10217                ast_channel_setwhentohangup(pri->pvts[chanpos]->owner, 5);
10218                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10219             }
10220             break;
10221          case PRI_EVENT_HANGUP_ACK:
10222             chanpos = pri_find_principle(pri, e->hangup.channel);
10223             if (chanpos < 0) {
10224                ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 
10225                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10226             } else {
10227                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
10228                if (chanpos > -1) {
10229                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10230                   pri->pvts[chanpos]->call = NULL;
10231                   pri->pvts[chanpos]->tei = -1;
10232                   pri->pvts[chanpos]->resetting = 0;
10233                   if (pri->pvts[chanpos]->owner) {
10234                      if (option_verbose > 2) 
10235                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10236                   }
10237 
10238 #ifdef SUPPORT_USERUSER
10239                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
10240                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10241                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10242                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
10243                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10244                   }
10245 #endif
10246 
10247                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10248                }
10249             }
10250             break;
10251          case PRI_EVENT_CONFIG_ERR:
10252             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
10253             break;
10254          case PRI_EVENT_RESTART_ACK:
10255             chanpos = pri_find_principle(pri, e->restartack.channel);
10256             if (chanpos < 0) {
10257                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
10258                   channel number, so we have to figure it out...  This must be why
10259                   everybody resets exactly a channel at a time. */
10260                for (x = 0; x < pri->numchans; x++) {
10261                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
10262                      chanpos = x;
10263                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10264                      ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
10265                            pri->pvts[chanpos]->prioffset, pri->span);
10266                      if (pri->pvts[chanpos]->realcall) 
10267                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10268                      else if (pri->pvts[chanpos]->owner) {
10269                         ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 
10270                            pri->pvts[chanpos]->prioffset, pri->span);
10271                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10272                      }
10273                      pri->pvts[chanpos]->resetting = 0;
10274                      if (option_verbose > 2)
10275                         ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
10276                            pri->pvts[chanpos]->prioffset, pri->span);
10277                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10278                      if (pri->resetting)
10279                         pri_check_restart(pri);
10280                      break;
10281                   }
10282                }
10283                if (chanpos < 0) {
10284                   ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 
10285                      PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
10286                }
10287             } else {
10288                if (pri->pvts[chanpos]) {
10289                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10290                   if (pri->pvts[chanpos]->realcall) 
10291                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10292                   else if (pri->pvts[chanpos]->owner) {
10293                      ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
10294                         PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
10295                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10296                   }
10297                   pri->pvts[chanpos]->resetting = 0;
10298                   if (option_verbose > 2)
10299                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
10300                            pri->pvts[chanpos]->prioffset, pri->span);
10301                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10302                   if (pri->resetting)
10303                      pri_check_restart(pri);
10304                }
10305             }
10306             break;
10307          case PRI_EVENT_SETUP_ACK:
10308             chanpos = pri_find_principle(pri, e->setup_ack.channel);
10309             if (chanpos < 0) {
10310                ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 
10311                   PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
10312             } else {
10313                chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
10314                if (chanpos > -1) {
10315                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10316                   pri->pvts[chanpos]->setup_ack = 1;
10317                   /* Send any queued digits */
10318                   for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
10319                      ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
10320                      pri_information(pri->pri, pri->pvts[chanpos]->call, 
10321                         pri->pvts[chanpos]->dialdest[x]);
10322                   }
10323                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10324                } else
10325                   ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
10326             }
10327             break;
10328          case PRI_EVENT_NOTIFY:
10329             chanpos = pri_find_principle(pri, e->notify.channel);
10330             if (chanpos < 0) {
10331                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
10332                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
10333             } else {
10334                struct ast_frame f = { AST_FRAME_CONTROL, };
10335                ast_mutex_lock(&pri->pvts[chanpos]->lock);
10336                switch (e->notify.info) {
10337                case PRI_NOTIFY_REMOTE_HOLD:
10338                   if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
10339                       ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on NETWORK channel. Starting MoH\n");
10340                       ast_moh_start(ast_bridged_channel(pri->pvts[chanpos]->owner), NULL, pri->pvts[chanpos]->mohinterpret);
10341                   } else {
10342                       ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on CPE channel. Not Starting MoH\n");
10343                   }
10344                   f.subclass = AST_CONTROL_HOLD;
10345                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
10346                   break;
10347                case PRI_NOTIFY_REMOTE_RETRIEVAL:
10348                   if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
10349                       ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on NETWORK channel. Stopping MoH\n");
10350                       ast_moh_stop(ast_bridged_channel(pri->pvts[chanpos]->owner));
10351                   } else {
10352                       ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on CPE channel.\n");
10353                   }
10354                   f.subclass = AST_CONTROL_UNHOLD;
10355                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
10356                   break;
10357                }
10358                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10359             }
10360             break;
10361          case PRI_EVENT_FACILITY:
10362                 if (e->facility.operation == 0x0D) {
10363                   struct ast_channel *owner = pri->pvts[chanpos]->owner;
10364 
10365                ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum);
10366                ast_mutex_lock(&pri->pvts[chanpos]->lock);
10367                    /* transfer */
10368                    if (owner) {
10369                   ast_string_field_build(owner, call_forward, 
10370                         "Local/%s@%s",  e->facility.forwardnum,
10371                         owner->context);
10372                    }
10373                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10374                 } else {
10375                ast_log(LOG_WARNING, "Unknown facility operation %#x requested.\n", e->facility.operation);
10376                 }
10377             break;
10378          default:
10379             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
10380          }
10381       }  
10382       ast_mutex_unlock(&pri->lock);
10383    }
10384    /* Never reached */
10385    return NULL;
10386 }
10387 
10388 static int start_pri(struct zt_pri *pri)
10389 {
10390    int res, x;
10391    ZT_PARAMS p;
10392    ZT_BUFFERINFO bi;
10393    struct zt_spaninfo si;
10394    int i;
10395    
10396    for (i = 0; i < NUM_DCHANS; i++) {
10397       if (!pri->dchannels[i])
10398          break;
10399       pri->fds[i] = open("/dev/zap/channel", O_RDWR, 0600);
10400       x = pri->dchannels[i];
10401       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],ZT_SPECIFY,&x) == -1)) {
10402          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
10403          return -1;
10404       }
10405       res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
10406       if (res) {
10407          zt_close(pri->fds[i]);
10408          pri->fds[i] = -1;
10409          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
10410          return -1;
10411       }
10412       if ((p.sigtype != ZT_SIG_HDLCFCS) && (p.sigtype != ZT_SIG_HARDHDLC)) {
10413          zt_close(pri->fds[i]);
10414          pri->fds[i] = -1;
10415          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/zaptel.conf\n", x);
10416          return -1;
10417       }
10418       memset(&si, 0, sizeof(si));
10419       res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
10420       if (res) {
10421          zt_close(pri->fds[i]);
10422          pri->fds[i] = -1;
10423          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
10424       }
10425       if (!si.alarms)
10426          pri->dchanavail[i] |= DCHAN_NOTINALARM;
10427       else
10428          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
10429       bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
10430       bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
10431       bi.numbufs = 32;
10432       bi.bufsize = 1024;
10433       if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
10434          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
10435          zt_close(pri->fds[i]);
10436          pri->fds[i] = -1;
10437          return -1;
10438       }
10439       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype, pri->span);
10440       /* Force overlap dial if we're doing GR-303! */
10441       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
10442          pri->overlapdial = 1;
10443       pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
10444       /* Enslave to master if appropriate */
10445       if (i)
10446          pri_enslave(pri->dchans[0], pri->dchans[i]);
10447       if (!pri->dchans[i]) {
10448          zt_close(pri->fds[i]);
10449          pri->fds[i] = -1;
10450          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
10451          return -1;
10452       }
10453       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
10454       pri_set_nsf(pri->dchans[i], pri->nsf);
10455 #ifdef PRI_GETSET_TIMERS
10456       for (x = 0; x < PRI_MAX_TIMERS; x++) {
10457          if (pritimers[x] != 0)
10458             pri_set_timer(pri->dchans[i], x, pritimers[x]);
10459       }
10460 #endif
10461    }
10462    /* Assume primary is the one we use */
10463    pri->pri = pri->dchans[0];
10464    pri->resetpos = -1;
10465    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
10466       for (i = 0; i < NUM_DCHANS; i++) {
10467          if (!pri->dchannels[i])
10468             break;
10469          zt_close(pri->fds[i]);
10470          pri->fds[i] = -1;
10471       }
10472       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
10473       return -1;
10474    }
10475    return 0;
10476 }
10477 
10478 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
10479 {
10480    int which, span;
10481    char *ret = NULL;
10482 
10483    if (pos != rpos)
10484       return ret;
10485 
10486    for (which = span = 0; span < NUM_SPANS; span++) {
10487       if (pris[span].pri && ++which > state) {
10488          asprintf(&ret, "%d", span + 1);  /* user indexes start from 1 */
10489          break;
10490       }
10491    }
10492    return ret;
10493 }
10494 
10495 static char *complete_span_4(const char *line, const char *word, int pos, int state)
10496 {
10497    return complete_span_helper(line,word,pos,state,3);
10498 }
10499 
10500 static char *complete_span_5(const char *line, const char *word, int pos, int state)
10501 {
10502    return complete_span_helper(line,word,pos,state,4);
10503 }
10504 
10505 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
10506 {
10507    int myfd, x, d;
10508    int span;
10509 
10510    if (argc < 6)
10511       return RESULT_SHOWUSAGE;
10512 
10513    if (!strncasecmp(argv[1], "set", 3)) {
10514       if (argc < 7)
10515          return RESULT_SHOWUSAGE;
10516 
10517       if (!argv[4] || ast_strlen_zero(argv[4]))
10518          return RESULT_SHOWUSAGE;
10519 
10520       if (!argv[5])
10521          return RESULT_SHOWUSAGE;
10522 
10523       if (!argv[6] || ast_strlen_zero(argv[6]))
10524          return RESULT_SHOWUSAGE;
10525 
10526       span = atoi(argv[6]);
10527       if ((span < 1) && (span > NUM_SPANS)) {
10528          return RESULT_SUCCESS;
10529       }
10530 
10531 
10532       myfd = open(argv[4], O_CREAT|O_WRONLY, 0600);
10533       if (myfd < 0) {
10534          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
10535          return RESULT_SUCCESS;
10536       }
10537       for (x=0; x < NUM_SPANS; x++) {
10538              ast_mutex_lock(&pris[x].lock);
10539 
10540           if (pris[x].span == span) {
10541          if (pris[x].debugfd >= 0)
10542              close(pris[x].debugfd);
10543          pris[x].debugfd = myfd;
10544          for (d=0; d < NUM_DCHANS; d++) {
10545              if (pris[x].dchans[d])
10546             pri_set_debug_fd(pris[x].dchans[d], myfd);
10547          }
10548           }
10549              ast_mutex_unlock(&pris[x].lock);
10550       }
10551 
10552       ast_cli(fd, "PRI debug output for span %d will be sent to '%s'\n", span, argv[4]);
10553    } else {
10554       if (!argv[5] || ast_strlen_zero(argv[5]))
10555          return RESULT_SHOWUSAGE;
10556       /* Assume it is unset */
10557       span = atoi(argv[5]);
10558       if ((span < 1) && (span > NUM_SPANS)) {
10559          return RESULT_SUCCESS;
10560       }
10561 
10562       for (x=0; x < NUM_SPANS; x++) {
10563              ast_mutex_lock(&pris[x].lock);
10564 
10565           if (pris[x].span == span) {
10566          if (pris[x].debugfd >= 0)
10567              close(pris[x].debugfd);
10568          pris[x].debugfd = -1;
10569          for (d=0; d < NUM_DCHANS; d++) {
10570              if (pris[x].dchans[d])
10571             pri_set_debug_fd(pris[x].dchans[d], -1);
10572          }
10573           }
10574              ast_mutex_unlock(&pris[x].lock);
10575       }
10576 
10577       ast_cli(fd, "PRI debug output to file for span %d disabled\n", span);
10578    }
10579 
10580    return RESULT_SUCCESS;
10581 }
10582 
10583 #ifdef HAVE_PRI_VERSION
10584 static int handle_pri_version(int fd, int agc, char *argv[]) {
10585    ast_cli(fd, "libpri version: %s\n", pri_get_version());
10586    return RESULT_SUCCESS;
10587 }
10588 #endif
10589 
10590 static int handle_pri_debug(int fd, int argc, char *argv[])
10591 {
10592    int span;
10593    int x;
10594    if (argc < 4) {
10595       return RESULT_SHOWUSAGE;
10596    }
10597    span = atoi(argv[3]);
10598    if ((span < 1) || (span > NUM_SPANS)) {
10599       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
10600       return RESULT_SUCCESS;
10601    }
10602    if (!pris[span-1].pri) {
10603       ast_cli(fd, "No PRI running on span %d\n", span);
10604       return RESULT_SUCCESS;
10605    }
10606    for (x = 0; x < NUM_DCHANS; x++) {
10607       if (pris[span-1].dchans[x])
10608          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
10609                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
10610                                                PRI_DEBUG_Q921_STATE);
10611    }
10612    ast_cli(fd, "Enabled debugging on span %d\n", span);
10613    return RESULT_SUCCESS;
10614 }
10615 
10616 
10617 
10618 
10619 static int handle_pri_no_debug(int fd, int argc, char *argv[])
10620 {
10621    int span;
10622    int x;
10623    if (argc < 5)
10624       return RESULT_SHOWUSAGE;
10625    span = atoi(argv[4]);
10626    if ((span < 1) || (span > NUM_SPANS)) {
10627       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
10628       return RESULT_SUCCESS;
10629    }
10630    if (!pris[span-1].pri) {
10631       ast_cli(fd, "No PRI running on span %d\n", span);
10632       return RESULT_SUCCESS;
10633    }
10634    for (x = 0; x < NUM_DCHANS; x++) {
10635       if (pris[span-1].dchans[x])
10636          pri_set_debug(pris[span-1].dchans[x], 0);
10637    }
10638    ast_cli(fd, "Disabled debugging on span %d\n", span);
10639    return RESULT_SUCCESS;
10640 }
10641 
10642 static int handle_pri_really_debug(int fd, int argc, char *argv[])
10643 {
10644    int span;
10645    int x;
10646    if (argc < 5)
10647       return RESULT_SHOWUSAGE;
10648    span = atoi(argv[4]);
10649    if ((span < 1) || (span > NUM_SPANS)) {
10650       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
10651       return RESULT_SUCCESS;
10652    }
10653    if (!pris[span-1].pri) {
10654       ast_cli(fd, "No PRI running on span %d\n", span);
10655       return RESULT_SUCCESS;
10656    }
10657    for (x = 0; x < NUM_DCHANS; x++) {
10658       if (pris[span-1].dchans[x])
10659          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
10660                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
10661                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
10662    }
10663    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
10664    return RESULT_SUCCESS;
10665 }
10666 
10667 static void build_status(char *s, size_t len, int status, int active)
10668 {
10669    if (!s || len < 1) {
10670       return;
10671    }
10672    s[0] = '\0';
10673    if (status & DCHAN_PROVISIONED)
10674       strncat(s, "Provisioned, ", len - strlen(s) - 1);
10675    if (!(status & DCHAN_NOTINALARM))
10676       strncat(s, "In Alarm, ", len - strlen(s) - 1);
10677    if (status & DCHAN_UP)
10678       strncat(s, "Up", len - strlen(s) - 1);
10679    else
10680       strncat(s, "Down", len - strlen(s) - 1);
10681    if (active)
10682       strncat(s, ", Active", len - strlen(s) - 1);
10683    else
10684       strncat(s, ", Standby", len - strlen(s) - 1);
10685    s[len - 1] = '\0';
10686 }
10687 
10688 static int handle_pri_show_spans(int fd, int argc, char *argv[])
10689 {
10690    int span;
10691    int x;
10692    char status[256];
10693    if (argc != 3)
10694       return RESULT_SHOWUSAGE;
10695 
10696    for (span = 0; span < NUM_SPANS; span++) {
10697       if (pris[span].pri) {
10698          for (x = 0; x < NUM_DCHANS; x++) {
10699             if (pris[span].dchannels[x]) {
10700                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
10701                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
10702             }
10703          }
10704       }
10705    }
10706    return RESULT_SUCCESS;
10707 }
10708 
10709 static int handle_pri_show_span(int fd, int argc, char *argv[])
10710 {
10711    int span;
10712    int x;
10713    char status[256];
10714    if (argc < 4)
10715       return RESULT_SHOWUSAGE;
10716    span = atoi(argv[3]);
10717    if ((span < 1) || (span > NUM_SPANS)) {
10718       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
10719       return RESULT_SUCCESS;
10720    }
10721    if (!pris[span-1].pri) {
10722       ast_cli(fd, "No PRI running on span %d\n", span);
10723       return RESULT_SUCCESS;
10724    }
10725    for (x = 0; x < NUM_DCHANS; x++) {
10726       if (pris[span-1].dchannels[x]) {
10727 #ifdef PRI_DUMP_INFO_STR
10728          char *info_str = NULL;
10729 #endif
10730          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
10731          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
10732          ast_cli(fd, "Status: %s\n", status);
10733 #ifdef PRI_DUMP_INFO_STR
10734          info_str = pri_dump_info_str(pris[span-1].pri);
10735          if (info_str) {
10736             ast_cli(fd, "%s", info_str);
10737             free(info_str);
10738          }
10739 #else
10740          pri_dump_info(pris[span-1].pri);
10741 #endif
10742          ast_cli(fd, "\n");
10743       }
10744    }
10745    return RESULT_SUCCESS;
10746 }
10747 
10748 static int handle_pri_show_debug(int fd, int argc, char *argv[])
10749 {
10750    int x;
10751    int span;
10752    int count=0;
10753    int debug=0;
10754 
10755    for (span = 0; span < NUM_SPANS; span++) {
10756            if (pris[span].pri) {
10757          for (x = 0; x < NUM_DCHANS; x++) {
10758             debug = 0;
10759                if (pris[span].dchans[x]) {
10760                   debug = pri_get_debug(pris[span].dchans[x]);
10761                ast_cli(fd, "Span %d: Debug: %s\tIntense: %s\n", span+1, (debug&PRI_DEBUG_Q931_STATE)? "Yes" : "No" ,(debug&PRI_DEBUG_Q921_RAW)? "Yes" : "No" );
10762                count++;
10763             }
10764          }
10765       }
10766 
10767    }
10768        
10769    if (!count) 
10770       ast_cli(fd, "No debug set or no PRI running\n");
10771    return RESULT_SUCCESS;
10772 }
10773 
10774 static const char pri_debug_help[] = 
10775    "Usage: pri debug span <span>\n"
10776    "       Enables debugging on a given PRI span\n";
10777    
10778 static const char pri_no_debug_help[] = 
10779    "Usage: pri no debug span <span>\n"
10780    "       Disables debugging on a given PRI span\n";
10781 
10782 static const char pri_really_debug_help[] = 
10783    "Usage: pri intensive debug span <span>\n"
10784    "       Enables debugging down to the Q.921 level\n";
10785 
10786 static const char pri_show_span_help[] = 
10787    "Usage: pri show span <span>\n"
10788    "       Displays PRI Information on a given PRI span\n";
10789 
10790 static const char pri_show_spans_help[] = 
10791    "Usage: pri show spans\n"
10792    "       Displays PRI Information\n";
10793 
10794 static char bri_debug_help[] =
10795    "Usage: bri debug span <span>\n"
10796    "       Enables debugging on a given BRI span\n";
10797 
10798 static char bri_no_debug_help[] =
10799    "Usage: bri no debug span <span>\n"
10800    "       Disables debugging on a given BRI span\n";
10801 
10802 static char bri_really_debug_help[] =
10803    "Usage: bri intensive debug span <span>\n"
10804    "       Enables debugging down to the Q.921 level\n";
10805 
10806 static struct ast_cli_entry zap_pri_cli[] = {
10807    { { "pri", "debug", "span", NULL },
10808    handle_pri_debug, "Enables PRI debugging on a span",
10809    pri_debug_help, complete_span_4 },
10810 
10811    { { "pri", "no", "debug", "span", NULL },
10812    handle_pri_no_debug, "Disables PRI debugging on a span",
10813    pri_no_debug_help, complete_span_5 },
10814 
10815    { { "pri", "intense", "debug", "span", NULL },
10816    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
10817    pri_really_debug_help, complete_span_5 },
10818 
10819    { { "pri", "show", "spans", NULL },
10820    handle_pri_show_spans, "Displays PRI Information",
10821    pri_show_spans_help },
10822 
10823    { { "pri", "show", "span", NULL },
10824    handle_pri_show_span, "Displays PRI Information",
10825    pri_show_span_help, complete_span_4 },
10826 
10827    { { "pri", "show", "debug", NULL },
10828    handle_pri_show_debug, "Displays current PRI debug settings" },
10829 
10830    { { "bri", "debug", "span", NULL }, handle_pri_debug,
10831      "Enables BRI debugging on a span", bri_debug_help, complete_span_4 },
10832 
10833    { { "bri", "no", "debug", "span", NULL }, handle_pri_no_debug,
10834      "Disables BRI debugging on a span", bri_no_debug_help, complete_span_5 },
10835 
10836    { { "bri", "intense", "debug", "span", NULL }, handle_pri_really_debug,
10837      "Enables REALLY INTENSE BRI debugging", bri_really_debug_help, complete_span_5 },
10838 
10839    { { "pri", "set", "debug", "file", NULL },
10840    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
10841 
10842    { { "pri", "unset", "debug", "file", NULL },
10843    handle_pri_set_debug_file, "Ends PRI debug output to file" },
10844 
10845 #ifdef HAVE_PRI_VERSION
10846    { { "pri", "show", "version", NULL },
10847    handle_pri_version, "Displays version of libpri" },
10848 #endif
10849 };
10850 
10851 static char *zapCD_tdesc = "Call Deflection";
10852 static char *zapCD_app = "zapCD";
10853 static char *zapCD_synopsis = "Call Deflection";
10854 
10855 static int app_zapCD(struct ast_channel *chan, void *data)
10856 {
10857  struct zt_pvt *p = chan->tech_pvt;
10858 
10859  if((!p->pri) || (!p->pri->pri)) {
10860    return -1;
10861  }
10862 
10863  if(!data) {
10864      ast_log(LOG_WARNING, "zapCD wants a number to deflect to\n");
10865    return -1;
10866  }
10867  return pri_deflect(p->pri->pri, p->call, data);
10868 }
10869 
10870 static char *zapInband_tdesc = "Inband Call Progress (pre-answer)";
10871 static char *zapInband_app = "zapInband";
10872 static char *zapInband_synopsis = "Inband Call Progress";
10873 
10874 static int app_zapInband(struct ast_channel *chan, void *data)
10875 {
10876  struct zt_pvt *p = chan->tech_pvt;
10877 
10878  return pri_acknowledge(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1);
10879 }
10880 
10881 #endif /* HAVE_PRI */
10882 
10883 #ifdef HAVE_GSMAT
10884 static int handle_zap_reset_span(int fd, int argc, char *argv[])
10885 {
10886    int span;
10887    int sleep = 5000;
10888    if (argc < 4)
10889       return RESULT_SHOWUSAGE;
10890    span = atoi(argv[3]);
10891    if ((span < 1) || (span > NUM_SPANS)) {
10892       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
10893       return RESULT_SUCCESS;
10894    }
10895    if (zt_reset_span(span, sleep)) {
10896        return RESULT_FAILURE;
10897    }
10898    return RESULT_SUCCESS;
10899 }
10900 
10901 static int handle_gsm_debug_helper(int fd, int channel, int debug)
10902 {
10903 /* gsm debug channel <channel> */
10904    struct zt_pvt *pvt = NULL;
10905    if (channel < 1) {
10906       ast_cli(fd, "Invalid channel %d.  Should be a number.\n", channel);
10907       return RESULT_SUCCESS;
10908    }
10909    pvt = iflist;
10910    while (pvt) {
10911        if (pvt->channel == channel) {
10912       ast_mutex_lock(&pvt->lock);
10913       gsm_set_debug(pvt->gsm.modul, debug);
10914       ast_mutex_unlock(&pvt->lock);
10915       ast_cli(fd, "%s debugging on channel %d\n", debug ? "Enabled":"Disabled", channel);
10916       return RESULT_SUCCESS;
10917        }
10918        pvt = pvt->next;
10919    }
10920 
10921    ast_cli(fd, "No GSM running on channel %d\n", channel);
10922    return RESULT_SUCCESS;
10923 }
10924 
10925 
10926 
10927 static int handle_gsm_debug(int fd, int argc, char *argv[])
10928 {
10929 /* gsm debug channel <channel> */
10930  int channel;
10931  if (argc < 4) {
10932    return RESULT_SHOWUSAGE;
10933  }
10934  channel = atoi(argv[3]);
10935  return handle_gsm_debug_helper(fd, channel, GSM_DEBUG_AT);
10936 }
10937 
10938 static int handle_gsm_no_debug(int fd, int argc, char *argv[])
10939 {
10940 /* gsm no debug channel <channel> */
10941  int channel;
10942  if (argc < 5) {
10943    return RESULT_SHOWUSAGE;
10944  }
10945  channel = atoi(argv[4]);
10946  return handle_gsm_debug_helper(fd, channel, GSM_DEBUG_NONE);
10947 }
10948 
10949 static char zap_reset_help[] =
10950    "Usage: zap reset span <span>\n"
10951    "       Reset/Restart a zaptel span\n";
10952 
10953 static char gsm_debug_help[] =
10954    "Usage: gsm debug channel <channel>\n"
10955    "       Enables debugging on a given GSM channel\n";
10956 
10957 static char gsm_no_debug_help[] =
10958    "Usage: gsm no debug channel <channel>\n"
10959    "       Disables debugging on a given GSM channel\n";
10960 
10961 static struct ast_cli_entry zap_gsm_cli[] = {
10962    { { "zap", "reset", "span", NULL }, handle_zap_reset_span,
10963      "Restart a zaptel span", zap_reset_help, complete_span_4 },
10964    { { "gsm", "debug", "channel", NULL }, handle_gsm_debug,
10965      "Enables GSM debugging on a channel", gsm_debug_help },
10966    { { "gsm", "no", "debug", "channel", NULL }, handle_gsm_no_debug,
10967      "Disables GSM debugging on a channel", gsm_no_debug_help},
10968 };
10969 
10970 
10971 
10972 static char gsm_send_pdu_help[] =
10973    "Usage: gsm send pdu <channel> <pdu>\n"
10974    "       Sends a PDU on a GSM channel\n";
10975 
10976 
10977 
10978 static int handle_gsm_send_pdu(int fd, int argc, char *argv[])
10979 {
10980 /* gsm send sms <channel> <destination> <message> */
10981    int channel;
10982    struct zt_pvt *pvt = NULL;
10983    if (argc < 5) {
10984       return RESULT_SHOWUSAGE;
10985    }
10986    channel = atoi(argv[3]);
10987    if (channel < 1) {
10988       ast_cli(fd, "Invalid channel %s.  Should be a number.\n", argv[3]);
10989       return RESULT_SUCCESS;
10990    }
10991    pvt = iflist;
10992    while (pvt) {
10993        if (pvt->channel == channel) {
10994       if (pvt->owner) {
10995           ast_cli(fd, "Channel in use.\n");
10996           return RESULT_FAILURE;
10997       } else {
10998           ast_mutex_lock(&pvt->lock);
10999           gsm_sms_send_pdu(pvt->gsm.modul, argv[4]);
11000           ast_mutex_unlock(&pvt->lock);
11001           return RESULT_SUCCESS;
11002       }
11003        }
11004        pvt = pvt->next;
11005    }
11006 
11007    return RESULT_SUCCESS;
11008 }
11009 
11010 static struct ast_cli_entry gsm_send_pdu = {
11011    { "gsm", "send", "pdu", NULL }, handle_gsm_send_pdu, "Sends a SM on a GSM channel", gsm_send_pdu_help, complete_span_4 };
11012 
11013 
11014 static char gsm_send_sms_help[] =
11015    "Usage: gsm send sms <channel> <destination> <message>\n"
11016    "       Sends a SM on a GSM channel\n";
11017 
11018 
11019 static int handle_gsm_send_sms(int fd, int argc, char *argv[])
11020 {
11021 /* gsm send sms <channel> <destination> <message> */
11022    int channel;
11023    struct zt_pvt *pvt = NULL;
11024    if (argc < 6) {
11025       return RESULT_SHOWUSAGE;
11026    }
11027    channel = atoi(argv[3]);
11028    if (channel < 1) {
11029       ast_cli(fd, "Invalid channel %s.  Should be a number.\n", argv[3]);
11030       return RESULT_SUCCESS;
11031    }
11032    pvt = iflist;
11033    while (pvt) {
11034        if (pvt->channel == channel) {
11035       if (pvt->owner) {
11036           ast_cli(fd, "Channel in use.\n");
11037           return RESULT_FAILURE;
11038       } else {
11039           ast_mutex_lock(&pvt->lock);
11040           gsm_sms_send_text(pvt->gsm.modul, argv[4], argv[5]);
11041           ast_mutex_unlock(&pvt->lock);
11042           return RESULT_SUCCESS;
11043       }
11044        }
11045        pvt = pvt->next;
11046    }
11047 
11048    return RESULT_SUCCESS;
11049 }
11050 
11051 static int zt_gsm_sendtext(struct ast_channel *chan, const char * dest, const char *text, int ispdu) {
11052      struct zt_pvt *pvt = NULL;
11053      char *c = NULL;
11054      pvt = chan->tech_pvt;
11055 
11056      if (!pvt) return -1;
11057 
11058      /* parse dialstring */
11059      c = strrchr(dest, '/');
11060      if (c)
11061    c++;
11062      else
11063    c = (char *)dest;
11064 
11065      ast_mutex_lock(&pvt->lock);
11066    if (ispdu) {
11067           gsm_sms_send_pdu(pvt->gsm.modul, (char *)text);
11068    } else {
11069           gsm_sms_send_text(pvt->gsm.modul, c, (char *)text);
11070    }
11071      ast_mutex_unlock(&pvt->lock);
11072      gsm_wait(pvt->gsm.modul);
11073      return 0;
11074 }
11075 
11076 static struct ast_cli_entry gsm_send_sms = {
11077    { "gsm", "send", "sms", NULL }, handle_gsm_send_sms, "Sends a SM on a GSM channel", gsm_send_sms_help, complete_span_4 };
11078 
11079 static char gsm_show_status_help[] =
11080    "Usage: gsm show status <channel>>\n"
11081    "       Displays status information about the GSM channel.\n";
11082 
11083 
11084 static int handle_gsm_show_status(int fd, int argc, char *argv[])
11085 {
11086    int channel;
11087    struct zt_pvt *pvt = NULL;
11088    if (argc < 4) {
11089       return RESULT_SHOWUSAGE;
11090    }
11091    channel = atoi(argv[3]);
11092    if (channel < 1) {
11093       ast_cli(fd, "Invalid channel %s.  Should be a number.\n", argv[3]);
11094       return RESULT_SUCCESS;
11095    }
11096    pvt = iflist;
11097    while (pvt) {
11098        if (pvt->channel == channel) {
11099       if (pvt->owner) {
11100           ast_cli(fd, "Channel in use.\n");
11101           return RESULT_FAILURE;
11102       } else {
11103           ast_mutex_lock(&pvt->lock);
11104           gsm_request_status(pvt->gsm.modul);
11105           ast_mutex_unlock(&pvt->lock);
11106           return RESULT_SUCCESS;
11107       }
11108        }
11109        pvt = pvt->next;
11110    }
11111 
11112    return RESULT_SUCCESS;
11113 }
11114 
11115 static struct ast_cli_entry gsm_show_status = {
11116    { "gsm", "show", "status", NULL }, handle_gsm_show_status, "Displays status information about the GSM channel.", gsm_show_status_help, complete_span_4 };
11117 
11118 #endif /* HAVE_GSMAT */
11119 
11120 static int app_zapEC(struct ast_channel *chan, void *data)
11121 {
11122  int res=-1;
11123  struct zt_pvt *p = NULL;
11124 
11125  if (!data) {
11126    ast_log(LOG_WARNING, "zapEC requires one argument (on | off)\n");
11127  }
11128  if (chan && !strcasecmp("ZAP",chan->tech->type)) {
11129    p = chan->tech_pvt;
11130    if (!p) return res;
11131    if (!strcasecmp("on",(char *)data)) {
11132        zt_enable_ec(p);
11133        res = 0;
11134        if (option_verbose > 3) {
11135       ast_verbose(VERBOSE_PREFIX_3 "Enabled echo cancelation on channel %s.\n", chan->name);
11136        }
11137    } else if (!strcasecmp("off",(char *)data)) {
11138        zt_disable_ec(p);
11139        res = 0;
11140        if (option_verbose > 3) {
11141       ast_verbose(VERBOSE_PREFIX_3 "Disabled echo cancelation on channel %s.\n", chan->name);
11142        }
11143    } else {
11144        ast_log(LOG_WARNING, "Unknown argument %s to zapEC\n", (char *)data);
11145    }
11146  } else {
11147   ast_log(LOG_WARNING, "zapNoEC only works on ZAP channels, check your extensions.conf!\n");
11148   res = 0;
11149  }
11150 
11151  return res;
11152 }
11153 
11154 static char *zapEC_tdesc = "Enable/disable Echo cancelation";
11155 static char *zapEC_app = "zapEC";
11156 static char *zapEC_synopsis = "Enable/Disable Echo Cancelation on a Zap channel";
11157 
11158 static int zap_destroy_channel(int fd, int argc, char **argv)
11159 {
11160    int channel;
11161    
11162    if (argc != 4)
11163       return RESULT_SHOWUSAGE;
11164    
11165    channel = atoi(argv[3]);
11166 
11167    return zap_destroy_channel_bynum(channel);
11168 }
11169 
11170 static int setup_zap(int reload);
11171 static int zap_restart(void)
11172 {
11173    if (option_verbose > 0)
11174       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
11175    while (iflist) {
11176       if (option_debug)
11177          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
11178       /* Also updates iflist: */
11179       destroy_channel(NULL, iflist, 1);
11180    }
11181    if (option_debug)
11182       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
11183    if (setup_zap(0) != 0) {
11184       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
11185       return 1;
11186    }
11187    return 0;
11188 }
11189 
11190 static int zap_restart_cmd(int fd, int argc, char **argv)
11191 {
11192    if (argc != 2) {
11193       return RESULT_SHOWUSAGE;
11194    }
11195 
11196    if (zap_restart() != 0)
11197       return RESULT_FAILURE;
11198    return RESULT_SUCCESS;
11199 }
11200 
11201 static int action_zaprestart(struct mansession *s, const struct message *m)
11202 {
11203    if (zap_restart() != 0) {
11204       astman_send_error(s, m, "Failed rereading zaptel configuration");
11205       return 1;
11206    }
11207    astman_send_ack(s, m, "ZapRestart: Success");
11208    return 0;
11209 }
11210 
11211 static int zap_show_channels(int fd, int argc, char **argv)
11212 {
11213 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
11214 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
11215    struct zt_pvt *tmp = NULL;
11216    char tmps[20] = "";
11217    ast_mutex_t *lock;
11218    struct zt_pvt *start;
11219 #ifdef HAVE_PRI
11220    int trunkgroup;
11221    struct zt_pri *pri = NULL;
11222    int x;
11223 #endif
11224 
11225    lock = &iflock;
11226    start = iflist;
11227 
11228 #ifdef HAVE_PRI
11229    if (argc == 4) {
11230       if ((trunkgroup = atoi(argv[3])) < 1)
11231          return RESULT_SHOWUSAGE;
11232       for (x = 0; x < NUM_SPANS; x++) {
11233          if (pris[x].trunkgroup == trunkgroup) {
11234             pri = pris + x;
11235             break;
11236          }
11237       }
11238       if (pri) {
11239          start = pri->crvs;
11240          lock = &pri->lock;
11241       } else {
11242          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
11243          return RESULT_FAILURE;
11244       }
11245    } else
11246 #endif
11247    if (argc != 3)
11248       return RESULT_SHOWUSAGE;
11249 
11250    ast_mutex_lock(lock);
11251 #ifdef HAVE_PRI
11252    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
11253 #else
11254    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
11255 #endif   
11256    
11257    tmp = start;
11258    while (tmp) {
11259       if (tmp->channel > 0) {
11260          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
11261       } else
11262          ast_copy_string(tmps, "pseudo", sizeof(tmps));
11263       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
11264       tmp = tmp->next;
11265    }
11266    ast_mutex_unlock(lock);
11267    return RESULT_SUCCESS;
11268 #undef FORMAT
11269 #undef FORMAT2
11270 }
11271 
11272 static int zap_show_channel(int fd, int argc, char **argv)
11273 {
11274    int channel;
11275    struct zt_pvt *tmp = NULL;
11276    ZT_CONFINFO ci;
11277    ZT_PARAMS ps;
11278    int x;
11279    ast_mutex_t *lock;
11280    struct zt_pvt *start;
11281 #ifdef HAVE_PRI
11282    char *c;
11283    int trunkgroup;
11284    struct zt_pri *pri=NULL;
11285 #endif
11286 
11287    lock = &iflock;
11288    start = iflist;
11289 
11290    if (argc != 4)
11291       return RESULT_SHOWUSAGE;
11292 #ifdef HAVE_PRI
11293    if ((c = strchr(argv[3], ':'))) {
11294       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
11295          return RESULT_SHOWUSAGE;
11296       if ((trunkgroup < 1) || (channel < 1))
11297          return RESULT_SHOWUSAGE;
11298       for (x = 0; x < NUM_SPANS; x++) {
11299          if (pris[x].trunkgroup == trunkgroup) {
11300             pri = pris + x;
11301             break;
11302          }
11303       }
11304       if (pri) {
11305          start = pri->crvs;
11306          lock = &pri->lock;
11307       } else {
11308          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
11309          return RESULT_FAILURE;
11310       }
11311    } else
11312 #endif
11313       channel = atoi(argv[3]);
11314 
11315    ast_mutex_lock(lock);
11316    tmp = start;
11317    while (tmp) {
11318       if (tmp->channel == channel) {
11319 #ifdef HAVE_PRI
11320          if (pri) 
11321             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
11322          else
11323 #endif         
11324          ast_cli(fd, "Channel: %d\n", tmp->channel);
11325          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
11326          ast_cli(fd, "Span: %d\n", tmp->span);
11327          ast_cli(fd, "Extension: %s\n", tmp->exten);
11328          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
11329          ast_cli(fd, "Context: %s\n", tmp->context);
11330          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
11331          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
11332          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
11333          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
11334          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
11335          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
11336          ast_cli(fd, "Radio: %d\n", tmp->radio);
11337          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
11338          ast_cli(fd, "Real: %s%s%s\n", tmp->subs[SUB_REAL].owner ? tmp->subs[SUB_REAL].owner->name : "<None>", tmp->subs[SUB_REAL].inthreeway ? " (Confed)" : "", tmp->subs[SUB_REAL].linear ? " (Linear)" : "");
11339          ast_cli(fd, "Callwait: %s%s%s\n", tmp->subs[SUB_CALLWAIT].owner ? tmp->subs[SUB_CALLWAIT].owner->name : "<None>", tmp->subs[SUB_CALLWAIT].inthreeway ? " (Confed)" : "", tmp->subs[SUB_CALLWAIT].linear ? " (Linear)" : "");
11340          ast_cli(fd, "Threeway: %s%s%s\n", tmp->subs[SUB_THREEWAY].owner ? tmp->subs[SUB_THREEWAY].owner->name : "<None>", tmp->subs[SUB_THREEWAY].inthreeway ? " (Confed)" : "", tmp->subs[SUB_THREEWAY].linear ? " (Linear)" : "");
11341          ast_cli(fd, "Confno: %d\n", tmp->confno);
11342          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
11343          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
11344          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
11345          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
11346          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
11347          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
11348          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
11349          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
11350          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
11351          if (tmp->master)
11352             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
11353          for (x = 0; x < MAX_SLAVES; x++) {
11354             if (tmp->slaves[x])
11355                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
11356          }
11357 #ifdef HAVE_PRI
11358          if (tmp->pri) {
11359             ast_cli(fd, "PRI Flags: ");
11360             if (tmp->resetting)
11361                ast_cli(fd, "Resetting ");
11362             if (tmp->call)
11363                ast_cli(fd, "Call ");
11364             if (tmp->bearer)
11365                ast_cli(fd, "Bearer ");
11366             ast_cli(fd, "\n");
11367             if (tmp->logicalspan) 
11368                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
11369             else
11370                ast_cli(fd, "PRI Logical Span: Implicit\n");
11371          }
11372             
11373 #endif
11374          memset(&ci, 0, sizeof(ci));
11375          ps.channo = tmp->channel;
11376          if (tmp->subs[SUB_REAL].zfd > -1) {
11377             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
11378                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
11379             }
11380 #ifdef ZT_GETCONFMUTE
11381             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
11382                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
11383             }
11384 #endif
11385             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
11386                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
11387             } else {
11388                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
11389             }
11390          }
11391          ast_mutex_unlock(lock);
11392          return RESULT_SUCCESS;
11393       }
11394       tmp = tmp->next;
11395    }
11396    
11397    ast_cli(fd, "Unable to find given channel %d\n", channel);
11398    ast_mutex_unlock(lock);
11399    return RESULT_FAILURE;
11400 }
11401 
11402 static char zap_show_cadences_help[] =
11403 "Usage: zap show cadences\n"
11404 "       Shows all cadences currently defined\n";
11405 
11406 static int handle_zap_show_cadences(int fd, int argc, char *argv[])
11407 {
11408    int i, j;
11409    for (i = 0; i < num_cadence; i++) {
11410       char output[1024];
11411       char tmp[16], tmp2[64];
11412       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
11413       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
11414 
11415       for (j = 0; j < 16; j++) {
11416          if (cadences[i].ringcadence[j] == 0)
11417             break;
11418          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
11419          if (cidrings[i] * 2 - 1 == j)
11420             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
11421          else
11422             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
11423          if (j != 0)
11424             strncat(output, ",", sizeof(output) - strlen(output) - 1);
11425          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
11426       }
11427       ast_cli(fd,"%s\n",output);
11428    }
11429    return 0;
11430 }
11431 
11432 /* Based on irqmiss.c */
11433 static int zap_show_status(int fd, int argc, char *argv[]) {
11434    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
11435    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
11436 
11437    int span;
11438    int res;
11439    char alarms[50];
11440 
11441    int ctl;
11442    ZT_SPANINFO s;
11443 
11444    ctl = open("/dev/zap/ctl", O_RDWR);
11445    if (ctl < 0) {
11446       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
11447       ast_cli(fd, "No Zaptel interface found.\n");
11448       return RESULT_FAILURE;
11449    }
11450    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
11451 
11452    for (span = 1; span < ZT_MAX_SPANS; ++span) {
11453       s.spanno = span;
11454       res = ioctl(ctl, ZT_SPANSTAT, &s);
11455       if (res) {
11456          continue;
11457       }
11458       alarms[0] = '\0';
11459       if (s.alarms > 0) {
11460          if (s.alarms & ZT_ALARM_BLUE)
11461             strcat(alarms, "BLU/");
11462          if (s.alarms & ZT_ALARM_YELLOW)
11463             strcat(alarms, "YEL/");
11464          if (s.alarms & ZT_ALARM_RED)
11465             strcat(alarms, "RED/");
11466          if (s.alarms & ZT_ALARM_LOOPBACK)
11467             strcat(alarms, "LB/");
11468          if (s.alarms & ZT_ALARM_RECOVER)
11469             strcat(alarms, "REC/");
11470          if (s.alarms & ZT_ALARM_NOTOPEN)
11471             strcat(alarms, "NOP/");
11472          if (!strlen(alarms))
11473             strcat(alarms, "UUU/");
11474          if (strlen(alarms)) {
11475             /* Strip trailing / */
11476             alarms[strlen(alarms) - 1] = '\0';
11477          }
11478       } else {
11479          if (s.numchans)
11480             strcpy(alarms, "OK");
11481          else
11482             strcpy(alarms, "UNCONFIGURED");
11483       }
11484 
11485       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
11486    }
11487    close(ctl);
11488 
11489    return RESULT_SUCCESS;
11490 #undef FORMAT
11491 #undef FORMAT2
11492 }
11493 
11494 static char show_channels_usage[] =
11495    "Usage: zap show channels\n"
11496    "  Shows a list of available channels\n";
11497 
11498 static char show_channel_usage[] =
11499    "Usage: zap show channel <chan num>\n"
11500    "  Detailed information about a given channel\n";
11501 
11502 static char zap_show_status_usage[] =
11503    "Usage: zap show status\n"
11504    "       Shows a list of Zaptel cards with status\n";
11505 
11506 static char destroy_channel_usage[] =
11507    "Usage: zap destroy channel <chan num>\n"
11508    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
11509 
11510 static char zap_restart_usage[] =
11511    "Usage: zap restart\n"
11512    "  Restarts the zaptel channels: destroys them all and then\n"
11513    "  re-reads them from zapata.conf.\n"
11514    "  Note that this will STOP any running CALL on zaptel channels.\n"
11515    "";
11516 
11517 static struct ast_cli_entry zap_cli[] = {
11518    { { "zap", "show", "cadences", NULL },
11519    handle_zap_show_cadences, "List cadences",
11520    zap_show_cadences_help },
11521 
11522    { { "zap", "show", "channels", NULL},
11523    zap_show_channels, "Show active zapata channels",
11524    show_channels_usage },
11525 
11526    { { "zap", "show", "channel", NULL},
11527    zap_show_channel, "Show information on a channel",
11528    show_channel_usage },
11529 
11530    { { "zap", "destroy", "channel", NULL},
11531    zap_destroy_channel, "Destroy a channel",
11532    destroy_channel_usage },
11533 
11534    { { "zap", "restart", NULL},
11535    zap_restart_cmd, "Fully restart zaptel channels",
11536    zap_restart_usage },
11537 
11538    { { "zap", "show", "status", NULL},
11539    zap_show_status, "Show all Zaptel cards status",
11540    zap_show_status_usage },
11541 };
11542 
11543 #define TRANSFER  0
11544 #define HANGUP    1
11545 
11546 static int zap_fake_event(struct zt_pvt *p, int mode)
11547 {
11548    if (p) {
11549       switch (mode) {
11550          case TRANSFER:
11551             p->fake_event = ZT_EVENT_WINKFLASH;
11552             break;
11553          case HANGUP:
11554             p->fake_event = ZT_EVENT_ONHOOK;
11555             break;
11556          default:
11557             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
11558       }
11559    }
11560    return 0;
11561 }
11562 static struct zt_pvt *find_channel(int channel)
11563 {
11564    struct zt_pvt *p = iflist;
11565    while (p) {
11566       if (p->channel == channel) {
11567          break;
11568       }
11569       p = p->next;
11570    }
11571    return p;
11572 }
11573 
11574 static int action_zapdndon(struct mansession *s, const struct message *m)
11575 {
11576    struct zt_pvt *p = NULL;
11577    const char *channel = astman_get_header(m, "ZapChannel");
11578 
11579    if (ast_strlen_zero(channel)) {
11580       astman_send_error(s, m, "No channel specified");
11581       return 0;
11582    }
11583    p = find_channel(atoi(channel));
11584    if (!p) {
11585       astman_send_error(s, m, "No such channel");
11586       return 0;
11587    }
11588    p->dnd = 1;
11589    astman_send_ack(s, m, "DND Enabled");
11590    return 0;
11591 }
11592 
11593 static int action_zapdndoff(struct mansession *s, const struct message *m)
11594 {
11595    struct zt_pvt *p = NULL;
11596    const char *channel = astman_get_header(m, "ZapChannel");
11597 
11598    if (ast_strlen_zero(channel)) {
11599       astman_send_error(s, m, "No channel specified");
11600       return 0;
11601    }
11602    p = find_channel(atoi(channel));
11603    if (!p) {
11604       astman_send_error(s, m, "No such channel");
11605       return 0;
11606    }
11607    p->dnd = 0;
11608    astman_send_ack(s, m, "DND Disabled");
11609    return 0;
11610 }
11611 
11612 static int action_transfer(struct mansession *s, const struct message *m)
11613 {
11614    struct zt_pvt *p = NULL;
11615    const char *channel = astman_get_header(m, "ZapChannel");
11616 
11617    if (ast_strlen_zero(channel)) {
11618       astman_send_error(s, m, "No channel specified");
11619       return 0;
11620    }
11621    p = find_channel(atoi(channel));
11622    if (!p) {
11623       astman_send_error(s, m, "No such channel");
11624       return 0;
11625    }
11626    zap_fake_event(p,TRANSFER);
11627    astman_send_ack(s, m, "ZapTransfer");
11628    return 0;
11629 }
11630 
11631 static int action_transferhangup(struct mansession *s, const struct message *m)
11632 {
11633    struct zt_pvt *p = NULL;
11634    const char *channel = astman_get_header(m, "ZapChannel");
11635 
11636    if (ast_strlen_zero(channel)) {
11637       astman_send_error(s, m, "No channel specified");
11638       return 0;
11639    }
11640    p = find_channel(atoi(channel));
11641    if (!p) {
11642       astman_send_error(s, m, "No such channel");
11643       return 0;
11644    }
11645    zap_fake_event(p,HANGUP);
11646    astman_send_ack(s, m, "ZapHangup");
11647    return 0;
11648 }
11649 
11650 static int action_zapdialoffhook(struct mansession *s, const struct message *m)
11651 {
11652    struct zt_pvt *p = NULL;
11653    const char *channel = astman_get_header(m, "ZapChannel");
11654    const char *number = astman_get_header(m, "Number");
11655    int i;
11656 
11657    if (ast_strlen_zero(channel)) {
11658       astman_send_error(s, m, "No channel specified");
11659       return 0;
11660    }
11661    if (ast_strlen_zero(number)) {
11662       astman_send_error(s, m, "No number specified");
11663       return 0;
11664    }
11665    p = find_channel(atoi(channel));
11666    if (!p) {
11667       astman_send_error(s, m, "No such channel");
11668       return 0;
11669    }
11670    if (!p->owner) {
11671       astman_send_error(s, m, "Channel does not have it's owner");
11672       return 0;
11673    }
11674    for (i = 0; i < strlen(number); i++) {
11675       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
11676       zap_queue_frame(p, &f, NULL); 
11677    }
11678    astman_send_ack(s, m, "ZapDialOffhook");
11679    return 0;
11680 }
11681 
11682 static int action_zapshowchannels(struct mansession *s, const struct message *m)
11683 {
11684    struct zt_pvt *tmp = NULL;
11685    const char *id = astman_get_header(m, "ActionID");
11686    char idText[256] = "";
11687 
11688    astman_send_ack(s, m, "Zapata channel status will follow");
11689    if (!ast_strlen_zero(id))
11690       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
11691 
11692    ast_mutex_lock(&iflock);
11693    
11694    tmp = iflist;
11695    while (tmp) {
11696       if (tmp->channel > 0) {
11697          int alarm = get_alarms(tmp);
11698          astman_append(s,
11699             "Event: ZapShowChannels\r\n"
11700             "Channel: %d\r\n"
11701             "Signalling: %s\r\n"
11702             "Context: %s\r\n"
11703             "DND: %s\r\n"
11704             "Alarm: %s\r\n"
11705             "%s"
11706             "\r\n",
11707             tmp->channel, sig2str(tmp->sig), tmp->context, 
11708             tmp->dnd ? "Enabled" : "Disabled",
11709             alarm2str(alarm), idText);
11710       } 
11711 
11712       tmp = tmp->next;
11713    }
11714 
11715    ast_mutex_unlock(&iflock);
11716    
11717    astman_append(s, 
11718       "Event: ZapShowChannelsComplete\r\n"
11719       "%s"
11720       "\r\n", 
11721       idText);
11722    return 0;
11723 }
11724 
11725 static int __unload_module(void)
11726 {
11727    int x;
11728    struct zt_pvt *p, *pl;
11729 
11730 #ifdef HAVE_PRI
11731    int i;
11732    for (i = 0; i < NUM_SPANS; i++) {
11733       if (pris[i].master != AST_PTHREADT_NULL) 
11734          pthread_cancel(pris[i].master);
11735    }
11736    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
11737    ast_unregister_application(zap_send_keypad_facility_app);
11738    ast_unregister_application(zapCD_app);
11739    ast_unregister_application(zapInband_app);
11740 #endif
11741 #ifdef HAVE_GSMAT
11742    ast_cli_unregister_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0]));
11743    ast_cli_unregister(&gsm_send_sms);
11744    ast_cli_unregister(&gsm_send_pdu);
11745    ast_cli_unregister(&gsm_show_status);
11746 #endif
11747    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
11748    ast_unregister_application(zapEC_app);
11749    ast_manager_unregister( "ZapDialOffhook" );
11750    ast_manager_unregister( "ZapHangup" );
11751    ast_manager_unregister( "ZapTransfer" );
11752    ast_manager_unregister( "ZapDNDoff" );
11753    ast_manager_unregister( "ZapDNDon" );
11754    ast_manager_unregister("ZapShowChannels");
11755    ast_manager_unregister("ZapRestart");
11756    ast_channel_unregister(&zap_tech);
11757    ast_mutex_lock(&iflock);
11758    /* Hangup all interfaces if they have an owner */
11759    p = iflist;
11760    while (p) {
11761       if (p->owner)
11762          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
11763       p = p->next;
11764    }
11765    ast_mutex_unlock(&iflock);
11766    ast_mutex_lock(&monlock);
11767    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
11768       pthread_cancel(monitor_thread);
11769       pthread_kill(monitor_thread, SIGURG);
11770       pthread_join(monitor_thread, NULL);
11771    }
11772    monitor_thread = AST_PTHREADT_STOP;
11773    ast_mutex_unlock(&monlock);
11774 
11775    ast_mutex_lock(&iflock);
11776    /* Destroy all the interfaces and free their memory */
11777    p = iflist;
11778    while (p) {
11779       /* Free any callerid */
11780       if (p->cidspill)
11781          free(p->cidspill);
11782       /* Close the zapata thingy */
11783       if (p->subs[SUB_REAL].zfd > -1)
11784          zt_close(p->subs[SUB_REAL].zfd);
11785       pl = p;
11786       p = p->next;
11787       x = pl->channel;
11788       /* Free associated memory */
11789       if (pl)
11790          destroy_zt_pvt(&pl);
11791       ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
11792    }
11793    iflist = NULL;
11794    ifcount = 0;
11795    ast_mutex_unlock(&iflock);
11796 #ifdef HAVE_PRI      
11797    for (i = 0; i < NUM_SPANS; i++) {
11798       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
11799          pthread_join(pris[i].master, NULL);
11800       zt_close(pris[i].fds[i]);
11801    }
11802 #endif
11803    return 0;
11804 }
11805 
11806 static int unload_module(void)
11807 {
11808 #ifdef HAVE_PRI      
11809    int y;
11810    for (y = 0; y < NUM_SPANS; y++)
11811       ast_mutex_destroy(&pris[y].lock);
11812 #endif
11813    return __unload_module();
11814 }
11815 
11816 static int build_channels(struct zt_chan_conf *conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
11817 {
11818    char *c, *chan;
11819    int x, start, finish;
11820    struct zt_pvt *tmp;
11821 #ifdef HAVE_PRI
11822    struct zt_pri *pri;
11823    int trunkgroup, y;
11824 #endif
11825    
11826    if ((reload == 0) && (conf->chan.sig < 0)) {
11827       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
11828       return -1;
11829    }
11830 
11831    c = ast_strdupa(value);
11832 
11833 #ifdef HAVE_PRI
11834    pri = NULL;
11835    if (iscrv) {
11836       if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
11837          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
11838          return -1;
11839       }
11840       if (trunkgroup < 1) {
11841          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
11842          return -1;
11843       }
11844       c += y;
11845       for (y = 0; y < NUM_SPANS; y++) {
11846          if (pris[y].trunkgroup == trunkgroup) {
11847             pri = pris + y;
11848             break;
11849          }
11850       }
11851       if (!pri) {
11852          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
11853          return -1;
11854       }
11855    }
11856 #endif         
11857 
11858    while ((chan = strsep(&c, ","))) {
11859       if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
11860          /* Range */
11861       } else if (sscanf(chan, "%d", &start)) {
11862          /* Just one */
11863          finish = start;
11864       } else if (!strcasecmp(chan, "pseudo")) {
11865          finish = start = CHAN_PSEUDO;
11866          if (found_pseudo)
11867             *found_pseudo = 1;
11868       } else {
11869          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
11870          return -1;
11871       }
11872       if (finish < start) {
11873          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
11874          x = finish;
11875          finish = start;
11876          start = x;
11877       }
11878 
11879       for (x = start; x <= finish; x++) {
11880 #ifdef HAVE_PRI
11881          tmp = mkintf(x, conf, pri, reload);
11882 #else       
11883          tmp = mkintf(x, conf, NULL, reload);
11884 #endif         
11885 
11886          if (tmp) {
11887             if (option_verbose > 2) {
11888 #ifdef HAVE_PRI
11889                if (pri)
11890                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
11891                else
11892 #endif
11893                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
11894             }
11895          } else {
11896             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
11897                (reload == 1) ? "reconfigure" : "register", value);
11898             return -1;
11899          }
11900       }
11901    }
11902 
11903    return 0;
11904 }
11905 
11906 /** The length of the parameters list of 'zapchan'. 
11907  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
11908 #define MAX_CHANLIST_LEN 80
11909 static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
11910 {
11911    struct zt_pvt *tmp;
11912    char *ringc; /* temporary string for parsing the dring number. */
11913    int y;
11914    int found_pseudo = 0;
11915         char zapchan[MAX_CHANLIST_LEN] = {};
11916 
11917    for (; v; v = v->next) {
11918       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
11919          continue;
11920 
11921       /* Create the interface list */
11922       if (!strcasecmp(v->name, "channel")
11923 #ifdef HAVE_PRI
11924           || !strcasecmp(v->name, "crv")
11925 #endif         
11926          ) {
11927          int iscrv;
11928          if (skipchannels)
11929             continue;
11930          iscrv = !strcasecmp(v->name, "crv");
11931          if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
11932                return -1;
11933       } else if (!strcasecmp(v->name, "zapchan")) {
11934          ast_copy_string(zapchan, v->value, sizeof(zapchan));
11935       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
11936          if (ast_true(v->value))
11937             confp->chan.usedistinctiveringdetection = 1;
11938       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
11939          if (ast_true(v->value))
11940             distinctiveringaftercid = 1;
11941       } else if (!strcasecmp(v->name, "dring1context")) {
11942          ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
11943       } else if (!strcasecmp(v->name, "dring2context")) {
11944          ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
11945       } else if (!strcasecmp(v->name, "dring3context")) {
11946          ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
11947       } else if (!strcasecmp(v->name, "dring1")) {
11948          ringc = v->value;
11949          sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
11950       } else if (!strcasecmp(v->name, "dring2")) {
11951          ringc = v->value;
11952          sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
11953       } else if (!strcasecmp(v->name, "dring3")) {
11954          ringc = v->value;
11955          sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
11956       } else if (!strcasecmp(v->name, "usecallerid")) {
11957          confp->chan.use_callerid = ast_true(v->value);
11958       } else if (!strcasecmp(v->name, "cidsignalling")) {
11959          if (!strcasecmp(v->value, "bell"))
11960             confp->chan.cid_signalling = CID_SIG_BELL;
11961          else if (!strcasecmp(v->value, "v23"))
11962             confp->chan.cid_signalling = CID_SIG_V23;
11963          else if (!strcasecmp(v->value, "dtmf"))
11964             confp->chan.cid_signalling = CID_SIG_DTMF;
11965          else if (!strcasecmp(v->value, "smdi"))
11966             confp->chan.cid_signalling = CID_SIG_SMDI;
11967          else if (!strcasecmp(v->value, "v23_jp"))
11968             confp->chan.cid_signalling = CID_SIG_V23_JP;
11969          else if (ast_true(v->value))
11970             confp->chan.cid_signalling = CID_SIG_BELL;
11971       } else if (!strcasecmp(v->name, "cidstart")) {
11972          if (!strcasecmp(v->value, "ring"))
11973             confp->chan.cid_start = CID_START_RING;
11974          else if (!strcasecmp(v->value, "polarity"))
11975             confp->chan.cid_start = CID_START_POLARITY;
11976          else if (ast_true(v->value))
11977             confp->chan.cid_start = CID_START_RING;
11978       } else if (!strcasecmp(v->name, "threewaycalling")) {
11979          confp->chan.threewaycalling = ast_true(v->value);
11980       } else if (!strcasecmp(v->name, "cancallforward")) {
11981          confp->chan.cancallforward = ast_true(v->value);
11982       } else if (!strcasecmp(v->name, "relaxdtmf")) {
11983          if (ast_true(v->value)) 
11984             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
11985          else
11986             confp->chan.dtmfrelax = 0;
11987       } else if (!strcasecmp(v->name, "mailbox")) {
11988          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
11989       } else if (!strcasecmp(v->name, "adsi")) {
11990          confp->chan.adsi = ast_true(v->value);
11991       } else if (!strcasecmp(v->name, "usesmdi")) {
11992          confp->chan.use_smdi = ast_true(v->value);
11993       } else if (!strcasecmp(v->name, "smdiport")) {
11994          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
11995       } else if (!strcasecmp(v->name, "transfer")) {
11996          confp->chan.transfer = ast_true(v->value);
11997       } else if (!strcasecmp(v->name, "canpark")) {
11998          confp->chan.canpark = ast_true(v->value);
11999       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
12000          confp->chan.echocanbridged = ast_true(v->value);
12001       } else if (!strcasecmp(v->name, "busydetect")) {
12002          confp->chan.busydetect = ast_true(v->value);
12003       } else if (!strcasecmp(v->name, "busycount")) {
12004          confp->chan.busycount = atoi(v->value);
12005       } else if (!strcasecmp(v->name, "busypattern")) {
12006          if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
12007             ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n");
12008          }
12009       } else if (!strcasecmp(v->name, "callprogress")) {
12010          if (ast_true(v->value))
12011             confp->chan.callprogress |= 1;
12012          else
12013             confp->chan.callprogress &= ~1;
12014       } else if (!strcasecmp(v->name, "faxdetect")) {
12015          if (!strcasecmp(v->value, "incoming")) {
12016             confp->chan.callprogress |= 4;
12017             confp->chan.callprogress &= ~2;
12018          } else if (!strcasecmp(v->value, "outgoing")) {
12019             confp->chan.callprogress &= ~4;
12020             confp->chan.callprogress |= 2;
12021          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
12022             confp->chan.callprogress |= 6;
12023          else
12024             confp->chan.callprogress &= ~6;
12025       } else if (!strcasecmp(v->name, "echocancel")) {
12026          if (!ast_strlen_zero(v->value)) {
12027             y = atoi(v->value);
12028          } else
12029             y = 0;
12030          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
12031             confp->chan.echocancel = y;
12032          else {
12033             confp->chan.echocancel = ast_true(v->value);
12034             if (confp->chan.echocancel)
12035                confp->chan.echocancel=128;
12036          }
12037       } else if (!strcasecmp(v->name, "echotraining")) {
12038          if (sscanf(v->value, "%d", &y) == 1) {
12039             if ((y < 10) || (y > 4000)) {
12040                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
12041             } else {
12042                confp->chan.echotraining = y;
12043             }
12044          } else if (ast_true(v->value)) {
12045             confp->chan.echotraining = 400;
12046          } else
12047             confp->chan.echotraining = 0;
12048       } else if (!strcasecmp(v->name, "hidecallerid")) {
12049          confp->chan.hidecallerid = ast_true(v->value);
12050       } else if (!strcasecmp(v->name, "hidecalleridname")) {
12051          confp->chan.hidecalleridname = ast_true(v->value);
12052       } else if (!strcasecmp(v->name, "pulsedial")) {
12053          confp->chan.pulse = ast_true(v->value);
12054       } else if (!strcasecmp(v->name, "callreturn")) {
12055          confp->chan.callreturn = ast_true(v->value);
12056       } else if (!strcasecmp(v->name, "callwaiting")) {
12057          confp->chan.callwaiting = ast_true(v->value);
12058       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
12059          confp->chan.callwaitingcallerid = ast_true(v->value);
12060       } else if (!strcasecmp(v->name, "context")) {
12061          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
12062       } else if (!strcasecmp(v->name, "language")) {
12063          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
12064       } else if (!strcasecmp(v->name, "progzone")) {
12065          ast_copy_string(progzone, v->value, sizeof(progzone));
12066       } else if (!strcasecmp(v->name, "mohinterpret") 
12067          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
12068          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
12069       } else if (!strcasecmp(v->name, "mohsuggest")) {
12070          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
12071       } else if (!strcasecmp(v->name, "stripmsd")) {
12072          confp->chan.stripmsd = atoi(v->value);
12073       } else if (!strcasecmp(v->name, "jitterbuffers")) {
12074          numbufs = atoi(v->value);
12075       } else if (!strcasecmp(v->name, "group")) {
12076          confp->chan.group = ast_get_group(v->value);
12077       } else if (!strcasecmp(v->name, "callgroup")) {
12078          confp->chan.callgroup = ast_get_group(v->value);
12079       } else if (!strcasecmp(v->name, "pickupgroup")) {
12080          confp->chan.pickupgroup = ast_get_group(v->value);
12081       } else if (!strcasecmp(v->name, "immediate")) {
12082          confp->chan.immediate = ast_true(v->value);
12083       } else if (!strcasecmp(v->name, "transfertobusy")) {
12084          confp->chan.transfertobusy = ast_true(v->value);
12085       } else if (!strcasecmp(v->name, "rxgain")) {
12086          if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
12087             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
12088          }
12089       } else if (!strcasecmp(v->name, "txgain")) {
12090          if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) {
12091             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
12092          }
12093       } else if (!strcasecmp(v->name, "tonezone")) {
12094          if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) {
12095             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
12096          }
12097       } else if (!strcasecmp(v->name, "callerid")) {
12098          if (!strcasecmp(v->value, "asreceived")) {
12099             confp->chan.cid_num[0] = '\0';
12100             confp->chan.cid_name[0] = '\0';
12101          } else {
12102             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
12103          } 
12104       } else if (!strcasecmp(v->name, "fullname")) {
12105          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
12106       } else if (!strcasecmp(v->name, "cid_number")) {
12107          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
12108       } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
12109          confp->chan.zaptrcallerid = ast_true(v->value);
12110       } else if (!strcasecmp(v->name, "restrictcid")) {
12111          confp->chan.restrictcid = ast_true(v->value);
12112       } else if (!strcasecmp(v->name, "usecallingpres")) {
12113          confp->chan.use_callingpres = ast_true(v->value);
12114       } else if (!strcasecmp(v->name, "accountcode")) {
12115          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
12116       } else if (!strcasecmp(v->name, "amaflags")) {
12117          y = ast_cdr_amaflags2int(v->value);
12118          if (y < 0) 
12119             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
12120          else
12121             confp->chan.amaflags = y;
12122       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
12123          confp->chan.polarityonanswerdelay = atoi(v->value);
12124       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
12125          confp->chan.answeronpolarityswitch = ast_true(v->value);
12126       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
12127          confp->chan.hanguponpolarityswitch = ast_true(v->value);
12128       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
12129          confp->chan.sendcalleridafter = atoi(v->value);
12130       } else if (!reload){ 
12131           if (!strcasecmp(v->name, "signalling")) {
12132             confp->chan.outsigmod = -1;
12133             if (!strcasecmp(v->value, "em")) {
12134                confp->chan.sig = SIG_EM;
12135             } else if (!strcasecmp(v->value, "em_e1")) {
12136                confp->chan.sig = SIG_EM_E1;
12137             } else if (!strcasecmp(v->value, "em_w")) {
12138                confp->chan.sig = SIG_EMWINK;
12139                confp->chan.radio = 0;
12140             } else if (!strcasecmp(v->value, "fxs_ls")) {
12141                confp->chan.sig = SIG_FXSLS;
12142                confp->chan.radio = 0;
12143             } else if (!strcasecmp(v->value, "fxs_gs")) {
12144                confp->chan.sig = SIG_FXSGS;
12145                confp->chan.radio = 0;
12146             } else if (!strcasecmp(v->value, "fxs_ks")) {
12147                confp->chan.sig = SIG_FXSKS;
12148                confp->chan.radio = 0;
12149             } else if (!strcasecmp(v->value, "fxo_ls")) {
12150                confp->chan.sig = SIG_FXOLS;
12151                confp->chan.radio = 0;
12152             } else if (!strcasecmp(v->value, "fxo_gs")) {
12153                confp->chan.sig = SIG_FXOGS;
12154                confp->chan.radio = 0;
12155             } else if (!strcasecmp(v->value, "fxo_ks")) {
12156                confp->chan.sig = SIG_FXOKS;
12157                confp->chan.radio = 0;
12158             } else if (!strcasecmp(v->value, "fxs_rx")) {
12159                confp->chan.sig = SIG_FXSKS;
12160                confp->chan.radio = 1;
12161             } else if (!strcasecmp(v->value, "fxo_rx")) {
12162                confp->chan.sig = SIG_FXOLS;
12163                confp->chan.radio = 1;
12164             } else if (!strcasecmp(v->value, "fxs_tx")) {
12165                confp->chan.sig = SIG_FXSLS;
12166                confp->chan.radio = 1;
12167             } else if (!strcasecmp(v->value, "fxo_tx")) {
12168                confp->chan.sig = SIG_FXOGS;
12169                confp->chan.radio = 1;
12170             } else if (!strcasecmp(v->value, "em_rx")) {
12171                confp->chan.sig = SIG_EM;
12172                confp->chan.radio = 1;
12173             } else if (!strcasecmp(v->value, "em_tx")) {
12174                confp->chan.sig = SIG_EM;
12175                confp->chan.radio = 1;
12176             } else if (!strcasecmp(v->value, "em_rxtx")) {
12177                confp->chan.sig = SIG_EM;
12178                confp->chan.radio = 2;
12179             } else if (!strcasecmp(v->value, "em_txrx")) {
12180                confp->chan.sig = SIG_EM;
12181                confp->chan.radio = 2;
12182             } else if (!strcasecmp(v->value, "sf")) {
12183                confp->chan.sig = SIG_SF;
12184                confp->chan.radio = 0;
12185             } else if (!strcasecmp(v->value, "sf_w")) {
12186                confp->chan.sig = SIG_SFWINK;
12187                confp->chan.radio = 0;
12188             } else if (!strcasecmp(v->value, "sf_featd")) {
12189                confp->chan.sig = SIG_FEATD;
12190                confp->chan.radio = 0;
12191             } else if (!strcasecmp(v->value, "sf_featdmf")) {
12192                confp->chan.sig = SIG_FEATDMF;
12193                confp->chan.radio = 0;
12194             } else if (!strcasecmp(v->value, "sf_featb")) {
12195                confp->chan.sig = SIG_SF_FEATB;
12196                confp->chan.radio = 0;
12197             } else if (!strcasecmp(v->value, "sf")) {
12198                confp->chan.sig = SIG_SF;
12199                confp->chan.radio = 0;
12200             } else if (!strcasecmp(v->value, "sf_rx")) {
12201                confp->chan.sig = SIG_SF;
12202                confp->chan.radio = 1;
12203             } else if (!strcasecmp(v->value, "sf_tx")) {
12204                confp->chan.sig = SIG_SF;
12205                confp->chan.radio = 1;
12206             } else if (!strcasecmp(v->value, "sf_rxtx")) {
12207                confp->chan.sig = SIG_SF;
12208                confp->chan.radio = 2;
12209             } else if (!strcasecmp(v->value, "sf_txrx")) {
12210                confp->chan.sig = SIG_SF;
12211                confp->chan.radio = 2;
12212             } else if (!strcasecmp(v->value, "featd")) {
12213                confp->chan.sig = SIG_FEATD;
12214                confp->chan.radio = 0;
12215             } else if (!strcasecmp(v->value, "featdmf")) {
12216                confp->chan.sig = SIG_FEATDMF;
12217                confp->chan.radio = 0;
12218             } else if (!strcasecmp(v->value, "featdmf_ta")) {
12219                confp->chan.sig = SIG_FEATDMF_TA;
12220                confp->chan.radio = 0;
12221             } else if (!strcasecmp(v->value, "e911")) {
12222                confp->chan.sig = SIG_E911;
12223                confp->chan.radio = 0;
12224             } else if (!strcasecmp(v->value, "fgccama")) {
12225                confp->chan.sig = SIG_FGC_CAMA;
12226                confp->chan.radio = 0;
12227             } else if (!strcasecmp(v->value, "fgccamamf")) {
12228                confp->chan.sig = SIG_FGC_CAMAMF;
12229                confp->chan.radio = 0;
12230             } else if (!strcasecmp(v->value, "featb")) {
12231                confp->chan.sig = SIG_FEATB;
12232                confp->chan.radio = 0;
12233 #ifdef HAVE_PRI
12234             } else if (!strcasecmp(v->value, "pri_net")) {
12235                confp->chan.radio = 0;
12236                confp->chan.sig = SIG_PRI;
12237                confp->pri.nodetype = PRI_NETWORK;
12238             } else if (!strcasecmp(v->value, "pri_cpe")) {
12239                confp->chan.sig = SIG_PRI;
12240                confp->chan.radio = 0;
12241                confp->pri.nodetype = PRI_CPE;
12242             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
12243                confp->chan.sig = SIG_GR303FXOKS;
12244                confp->chan.radio = 0;
12245                confp->pri.nodetype = PRI_NETWORK;
12246             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
12247                confp->chan.sig = SIG_GR303FXSKS;
12248                confp->chan.radio = 0;
12249                confp->pri.nodetype = PRI_CPE;
12250             } else if (!strcasecmp(v->value, "bri_net_ptmp")) {
12251                confp->chan.radio = 0;
12252                confp->chan.sig = SIG_PRI;
12253                confp->pri.nodetype = BRI_NETWORK_PTMP;
12254             } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) {
12255                confp->chan.sig = SIG_PRI;
12256                confp->chan.radio = 0;
12257                confp->pri.nodetype = BRI_CPE_PTMP;
12258             } else if (!strcasecmp(v->value, "bri_net")) {
12259                confp->chan.radio = 0;
12260                confp->chan.sig = SIG_PRI;
12261                confp->pri.nodetype = BRI_NETWORK;
12262             } else if (!strcasecmp(v->value, "bri_cpe")) {
12263                confp->chan.sig = SIG_PRI;
12264                confp->chan.radio = 0;
12265                confp->pri.nodetype = BRI_CPE;
12266 #endif
12267 #ifdef HAVE_GSMAT
12268             } else if (!strcasecmp(v->value, "gsm")) {
12269                confp->chan.sig = SIG_GSM;
12270                confp->chan.radio = 0;
12271 #endif
12272             } else {
12273                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
12274             }
12275           } else if (!strcasecmp(v->name, "outsignalling")) {
12276             if (!strcasecmp(v->value, "em")) {
12277                confp->chan.outsigmod = SIG_EM;
12278             } else if (!strcasecmp(v->value, "em_e1")) {
12279                confp->chan.outsigmod = SIG_EM_E1;
12280             } else if (!strcasecmp(v->value, "em_w")) {
12281                confp->chan.outsigmod = SIG_EMWINK;
12282             } else if (!strcasecmp(v->value, "sf")) {
12283                confp->chan.outsigmod = SIG_SF;
12284             } else if (!strcasecmp(v->value, "sf_w")) {
12285                confp->chan.outsigmod = SIG_SFWINK;
12286             } else if (!strcasecmp(v->value, "sf_featd")) {
12287                confp->chan.outsigmod = SIG_FEATD;
12288             } else if (!strcasecmp(v->value, "sf_featdmf")) {
12289                confp->chan.outsigmod = SIG_FEATDMF;
12290             } else if (!strcasecmp(v->value, "sf_featb")) {
12291                confp->chan.outsigmod = SIG_SF_FEATB;
12292             } else if (!strcasecmp(v->value, "sf")) {
12293                confp->chan.outsigmod = SIG_SF;
12294             } else if (!strcasecmp(v->value, "featd")) {
12295                confp->chan.outsigmod = SIG_FEATD;
12296             } else if (!strcasecmp(v->value, "featdmf")) {
12297                confp->chan.outsigmod = SIG_FEATDMF;
12298             } else if (!strcasecmp(v->value, "featdmf_ta")) {
12299                confp->chan.outsigmod = SIG_FEATDMF_TA;
12300             } else if (!strcasecmp(v->value, "e911")) {
12301                confp->chan.outsigmod = SIG_E911;
12302             } else if (!strcasecmp(v->value, "fgccama")) {
12303                confp->chan.outsigmod = SIG_FGC_CAMA;
12304             } else if (!strcasecmp(v->value, "fgccamamf")) {
12305                confp->chan.outsigmod = SIG_FGC_CAMAMF;
12306             } else if (!strcasecmp(v->value, "featb")) {
12307                confp->chan.outsigmod = SIG_FEATB;
12308             } else {
12309                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
12310             }
12311 #ifdef HAVE_PRI
12312          } else if (!strcasecmp(v->name, "pridialplan")) {
12313             if (!strcasecmp(v->value, "national")) {
12314                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
12315             } else if (!strcasecmp(v->value, "unknown")) {
12316                confp->pri.dialplan = PRI_UNKNOWN + 1;
12317             } else if (!strcasecmp(v->value, "private")) {
12318                confp->pri.dialplan = PRI_PRIVATE + 1;
12319             } else if (!strcasecmp(v->value, "international")) {
12320                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
12321             } else if (!strcasecmp(v->value, "local")) {
12322                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
12323             } else if (!strcasecmp(v->value, "dynamic")) {
12324                confp->pri.dialplan = -1;
12325             } else {
12326                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
12327             }
12328          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
12329             if (!strcasecmp(v->value, "national")) {
12330                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
12331             } else if (!strcasecmp(v->value, "unknown")) {
12332                confp->pri.localdialplan = PRI_UNKNOWN + 1;
12333             } else if (!strcasecmp(v->value, "private")) {
12334                confp->pri.localdialplan = PRI_PRIVATE + 1;
12335             } else if (!strcasecmp(v->value, "international")) {
12336                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
12337             } else if (!strcasecmp(v->value, "local")) {
12338                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
12339             } else if (!strcasecmp(v->value, "dynamic")) {
12340                confp->pri.localdialplan = -1;
12341             } else {
12342                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
12343             }
12344          } else if (!strcasecmp(v->name, "switchtype")) {
12345             if (!strcasecmp(v->value, "national")) 
12346                confp->pri.switchtype = PRI_SWITCH_NI2;
12347             else if (!strcasecmp(v->value, "ni1"))
12348                confp->pri.switchtype = PRI_SWITCH_NI1;
12349             else if (!strcasecmp(v->value, "dms100"))
12350                confp->pri.switchtype = PRI_SWITCH_DMS100;
12351             else if (!strcasecmp(v->value, "4ess"))
12352                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
12353             else if (!strcasecmp(v->value, "5ess"))
12354                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
12355             else if (!strcasecmp(v->value, "euroisdn"))
12356                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
12357             else if (!strcasecmp(v->value, "qsig"))
12358                confp->pri.switchtype = PRI_SWITCH_QSIG;
12359             else {
12360                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
12361                return -1;
12362             }
12363          } else if (!strcasecmp(v->name, "nsf")) {
12364             if (!strcasecmp(v->value, "sdn"))
12365                confp->pri.nsf = PRI_NSF_SDN;
12366             else if (!strcasecmp(v->value, "megacom"))
12367                confp->pri.nsf = PRI_NSF_MEGACOM;
12368             else if (!strcasecmp(v->value, "tollfreemegacom"))
12369                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
12370             else if (!strcasecmp(v->value, "accunet"))
12371                confp->pri.nsf = PRI_NSF_ACCUNET;
12372             else if (!strcasecmp(v->value, "none"))
12373                confp->pri.nsf = PRI_NSF_NONE;
12374             else {
12375                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
12376                confp->pri.nsf = PRI_NSF_NONE;
12377             }
12378          } else if (!strcasecmp(v->name, "priindication")) {
12379             if (!strcasecmp(v->value, "outofband"))
12380                confp->chan.priindication_oob = 1;
12381             else if (!strcasecmp(v->value, "inband"))
12382                confp->chan.priindication_oob = 0;
12383             else if (!strcasecmp(v->value, "passthrough"))
12384                confp->chan.priindication_oob = 2;
12385             else
12386                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband', 'outofband' or 'passthrough' at line %d\n",
12387                   v->value, v->lineno);
12388          } else if (!strcasecmp(v->name, "pritransfer")) {
12389             if (!strcasecmp(v->value, "no"))
12390                confp->chan.pritransfer = 0;
12391             else if (!strcasecmp(v->value, "ect"))
12392                confp->chan.pritransfer = 1;
12393             else if (!strcasecmp(v->value, "hangup"))
12394                confp->chan.pritransfer = 2;
12395             else
12396                ast_log(LOG_WARNING, "'%s' is not a valid pri transfer value, should be 'no' , 'ect' or 'hangup' at line %d\n",
12397                   v->value, v->lineno);
12398          } else if (!strcasecmp(v->name, "priexclusive")) {
12399             confp->chan.priexclusive = ast_true(v->value);
12400          } else if (!strcasecmp(v->name, "internationalprefix")) {
12401             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
12402          } else if (!strcasecmp(v->name, "nationalprefix")) {
12403             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
12404          } else if (!strcasecmp(v->name, "localprefix")) {
12405             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
12406          } else if (!strcasecmp(v->name, "privateprefix")) {
12407             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
12408          } else if (!strcasecmp(v->name, "unknownprefix")) {
12409             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
12410          } else if (!strcasecmp(v->name, "nocid")) {
12411             ast_copy_string(confp->pri.nocid, v->value, sizeof(confp->pri.nocid));
12412          } else if (!strcasecmp(v->name, "withheldcid")) {
12413             ast_copy_string(confp->pri.withheldcid, v->value, sizeof(confp->pri.withheldcid));
12414          } else if (!strcasecmp(v->name, "pin")) {
12415             ast_copy_string(gsm_modem_pin, v->value, sizeof(gsm_modem_pin) - 1);
12416          } else if (!strcasecmp(v->name, "exten")) {
12417             ast_copy_string(gsm_modem_exten, v->value, sizeof(gsm_modem_exten) - 1);
12418          } else if (!strcasecmp(v->name, "resetinterval")) {
12419             if (!strcasecmp(v->value, "never"))
12420                confp->pri.resetinterval = -1;
12421             else if (atoi(v->value) >= 60)
12422                confp->pri.resetinterval = atoi(v->value);
12423             else
12424                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
12425                   v->value, v->lineno);
12426          } else if (!strcasecmp(v->name, "minunused")) {
12427             confp->pri.minunused = atoi(v->value);
12428          } else if (!strcasecmp(v->name, "minidle")) {
12429             confp->pri.minidle = atoi(v->value); 
12430          } else if (!strcasecmp(v->name, "idleext")) {
12431             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
12432          } else if (!strcasecmp(v->name, "idledial")) {
12433             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
12434          } else if (!strcasecmp(v->name, "pritrustusercid")) {
12435             confp->pri.usercid = ast_true(v->value);
12436          } else if (!strcasecmp(v->name, "overlapdial")) {
12437             confp->pri.overlapdial = ast_true(v->value);
12438          } else if (!strcasecmp(v->name, "pritimer")) {
12439 #ifdef PRI_GETSET_TIMERS
12440             char *timerc, *c;
12441             int timer, timeridx;
12442             c = v->value;
12443             timerc = strsep(&c, ",");
12444             if (timerc) {
12445                timer = atoi(c);
12446                if (!timer)
12447                   ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
12448                else {
12449                   if ((timeridx = pri_timer2idx(timerc)) >= 0)
12450                      pritimers[timeridx] = timer;
12451                   else
12452                      ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
12453                }
12454             } else
12455                ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
12456 
12457          } else if (!strcasecmp(v->name, "facilityenable")) {
12458             confp->pri.facilityenable = ast_true(v->value);
12459 #endif /* PRI_GETSET_TIMERS */
12460 #endif /* HAVE_PRI */
12461          } else if (!strcasecmp(v->name, "cadence")) {
12462             /* setup to scan our argument */
12463             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
12464             int i;
12465             struct zt_ring_cadence new_cadence;
12466             int cid_location = -1;
12467             int firstcadencepos = 0;
12468             char original_args[80];
12469             int cadence_is_ok = 1;
12470 
12471             ast_copy_string(original_args, v->value, sizeof(original_args));
12472             /* 16 cadences allowed (8 pairs) */
12473             element_count = sscanf(v->value, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12], &c[13], &c[14], &c[15]);
12474    
12475             /* Cadence must be even (on/off) */
12476             if (element_count % 2 == 1) {
12477                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
12478                cadence_is_ok = 0;
12479             }
12480    
12481             /* Ring cadences cannot be negative */
12482             for (i = 0; i < element_count; i++) {
12483                if (c[i] == 0) {
12484                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
12485                   cadence_is_ok = 0;
12486                   break;
12487                } else if (c[i] < 0) {
12488                   if (i % 2 == 1) {
12489                      /* Silence duration, negative possibly okay */
12490                      if (cid_location == -1) {
12491                         cid_location = i;
12492                         c[i] *= -1;
12493                      } else {
12494                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
12495                         cadence_is_ok = 0;
12496                         break;
12497                      }
12498                   } else {
12499                      if (firstcadencepos == 0) {
12500                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
12501                                  /* duration will be passed negative to the zaptel driver */
12502                      } else {
12503                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
12504                         cadence_is_ok = 0;
12505                         break;
12506                      }
12507                   }
12508                }
12509             }
12510    
12511             /* Substitute our scanned cadence */
12512             for (i = 0; i < 16; i++) {
12513                new_cadence.ringcadence[i] = c[i];
12514             }
12515    
12516             if (cadence_is_ok) {
12517                /* ---we scanned it without getting annoyed; now some sanity checks--- */
12518                if (element_count < 2) {
12519                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
12520                } else {
12521                   if (cid_location == -1) {
12522                      /* user didn't say; default to first pause */
12523                      cid_location = 1;
12524                   } else {
12525                      /* convert element_index to cidrings value */
12526                      cid_location = (cid_location + 1) / 2;
12527                   }
12528                   /* ---we like their cadence; try to install it--- */
12529                   if (!user_has_defined_cadences++)
12530                      /* this is the first user-defined cadence; clear the default user cadences */
12531                      num_cadence = 0;
12532                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
12533                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
12534                   else {
12535                      cadences[num_cadence] = new_cadence;
12536                      cidrings[num_cadence++] = cid_location;
12537                      if (option_verbose > 2)
12538                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
12539                   }
12540                }
12541             }
12542          } else if (!strcasecmp(v->name, "ringtimeout")) {
12543             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
12544          } else if (!strcasecmp(v->name, "prewink")) {
12545             confp->timing.prewinktime = atoi(v->value);
12546          } else if (!strcasecmp(v->name, "preflash")) {
12547             confp->timing.preflashtime = atoi(v->value);
12548          } else if (!strcasecmp(v->name, "wink")) {
12549             confp->timing.winktime = atoi(v->value);
12550          } else if (!strcasecmp(v->name, "flash")) {
12551             confp->timing.flashtime = atoi(v->value);
12552          } else if (!strcasecmp(v->name, "start")) {
12553             confp->timing.starttime = atoi(v->value);
12554          } else if (!strcasecmp(v->name, "rxwink")) {
12555             confp->timing.rxwinktime = atoi(v->value);
12556          } else if (!strcasecmp(v->name, "rxflash")) {
12557             confp->timing.rxflashtime = atoi(v->value);
12558          } else if (!strcasecmp(v->name, "debounce")) {
12559             confp->timing.debouncetime = atoi(v->value);
12560          } else if (!strcasecmp(v->name, "toneduration")) {
12561             int toneduration;
12562             int ctlfd;
12563             int res;
12564             struct zt_dialparams dps;
12565 
12566             ctlfd = open("/dev/zap/ctl", O_RDWR);
12567             if (ctlfd == -1) {
12568                ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
12569                return -1;
12570             }
12571 
12572             toneduration = atoi(v->value);
12573             if (toneduration > -1) {
12574                memset(&dps, 0, sizeof(dps));
12575 
12576                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
12577                res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
12578                if (res < 0) {
12579                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
12580                   return -1;
12581                }
12582             }
12583             close(ctlfd);
12584          } else if (!strcasecmp(v->name, "defaultcic")) {
12585             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
12586          } else if (!strcasecmp(v->name, "defaultozz")) {
12587             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
12588          } 
12589       } else if (!skipchannels)
12590          ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12591    }
12592    if (zapchan[0]) { 
12593       /* The user has set 'zapchan' */
12594       /*< \todo pass proper line number instead of 0 */
12595       if (build_channels(confp, 0, zapchan, reload, 0, &found_pseudo)) {
12596          return -1;
12597       }
12598    }
12599    /*< \todo why check for the pseudo in the per-channel section.
12600     * Any actual use for manual setup of the pseudo channel? */
12601    if (!found_pseudo && reload == 0) {
12602       /* Make sure pseudo isn't a member of any groups if
12603          we're automatically making it. */   
12604       
12605       confp->chan.group = 0;
12606       confp->chan.callgroup = 0;
12607       confp->chan.pickupgroup = 0;
12608 
12609       tmp = mkintf(CHAN_PSEUDO, confp, NULL, reload);
12610 
12611       if (tmp) {
12612          if (option_verbose > 2)
12613             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
12614       } else {
12615          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
12616       }
12617    }
12618    return 0;
12619 }
12620       
12621 static int setup_zap(int reload)
12622 {
12623    struct ast_config *cfg;
12624    struct ast_variable *v;
12625    struct zt_chan_conf conf = zt_chan_conf_default();
12626    int res;
12627 
12628 #ifdef HAVE_PRI
12629    char *c;
12630    int spanno;
12631    int i, x;
12632    int logicalspan;
12633    int trunkgroup;
12634    int dchannels[NUM_DCHANS];
12635 #endif
12636 
12637    cfg = ast_config_load(config);
12638 
12639    /* Error if we have no config file */
12640    if (!cfg) {
12641       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
12642       return 0;
12643    }
12644 
12645    /* It's a little silly to lock it, but we mind as well just to be sure */
12646    ast_mutex_lock(&iflock);
12647 #ifdef HAVE_PRI
12648    if (!reload) {
12649       /* Process trunkgroups first */
12650       v = ast_variable_browse(cfg, "trunkgroups");
12651       while (v) {
12652          if (!strcasecmp(v->name, "trunkgroup")) {
12653             trunkgroup = atoi(v->value);
12654             if (trunkgroup > 0) {
12655                if ((c = strchr(v->value, ','))) {
12656                   i = 0;
12657                   memset(dchannels, 0, sizeof(dchannels));
12658                   while (c && (i < NUM_DCHANS)) {
12659                      dchannels[i] = atoi(c + 1);
12660                      if (dchannels[i] < 0) {
12661                         ast_log(LOG_WARNING, "D-channel for trunk group %d must be a postiive number at line %d of zapata.conf\n", trunkgroup, v->lineno);
12662                      } else
12663                         i++;
12664                      c = strchr(c + 1, ',');
12665                   }
12666                   if (i) {
12667                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
12668                         ast_log(LOG_WARNING, "Unable to create trunk group %d with Primary D-channel %d at line %d of zapata.conf\n", trunkgroup, dchannels[0], v->lineno);
12669                      } else if (option_verbose > 1)
12670                         ast_verbose(VERBOSE_PREFIX_2 "Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup, dchannels[0], i - 1, (i == 1) ? "" : "s");
12671                   } else
12672                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
12673                } else
12674                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
12675             } else
12676                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
12677          } else if (!strcasecmp(v->name, "spanmap")) {
12678             spanno = atoi(v->value);
12679             if (spanno > 0) {
12680                if ((c = strchr(v->value, ','))) {
12681                   trunkgroup = atoi(c + 1);
12682                   if (trunkgroup > 0) {
12683                      if ((c = strchr(c + 1, ','))) 
12684                         logicalspan = atoi(c + 1);
12685                      else
12686                         logicalspan = 0;
12687                      if (logicalspan >= 0) {
12688                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
12689                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
12690                         } else if (option_verbose > 1) 
12691                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
12692                      } else
12693                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
12694                   } else
12695                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
12696                } else
12697                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
12698             } else
12699                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
12700          } else {
12701             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
12702          }
12703          v = v->next;
12704       }
12705    }
12706 #endif
12707    
12708    /* Copy the default jb config over global_jbconf */
12709    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
12710 
12711    v = ast_variable_browse(cfg, "channels");
12712    res = process_zap(&conf, v, reload, 0);
12713    ast_mutex_unlock(&iflock);
12714    ast_config_destroy(cfg);
12715    if (res)
12716       return res;
12717    cfg = ast_config_load("users.conf");
12718    if (cfg) {
12719       char *cat;
12720       const char *chans;
12721       process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1);
12722       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
12723          if (!strcasecmp(cat, "general"))
12724             continue;
12725          chans = ast_variable_retrieve(cfg, cat, "zapchan");
12726          if (!ast_strlen_zero(chans)) {
12727             struct zt_chan_conf sect_conf;
12728             memcpy(&sect_conf, &conf, sizeof(sect_conf));
12729 
12730             process_zap(&sect_conf, ast_variable_browse(cfg, cat), reload, 0);
12731          }
12732       }
12733       ast_config_destroy(cfg);
12734    }
12735 #ifdef HAVE_PRI
12736    if (!reload) {
12737       for (x = 0; x < NUM_SPANS; x++) {
12738          pris[x].debugfd = -1;
12739          if (pris[x].pvts[0]) {
12740             if (start_pri(pris + x)) {
12741                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
12742                return -1;
12743             } else if (option_verbose > 1)
12744                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
12745          }
12746       }
12747    }
12748 #endif
12749    /* And start the monitor for the first time */
12750    restart_monitor();
12751    return 0;
12752 }
12753 
12754 static int load_module(void)
12755 {
12756    int res;
12757 
12758 #ifdef HAVE_PRI
12759    int y,i;
12760    memset(pris, 0, sizeof(pris));
12761    for (y = 0; y < NUM_SPANS; y++) {
12762       ast_mutex_init(&pris[y].lock);
12763       pris[y].offset = -1;
12764       pris[y].master = AST_PTHREADT_NULL;
12765       for (i = 0; i < NUM_DCHANS; i++)
12766          pris[y].fds[i] = -1;
12767    }
12768    pri_set_error(zt_pri_error);
12769    pri_set_message(zt_pri_message);
12770    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
12771          zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
12772 #endif
12773 #ifdef HAVE_GSMAT
12774    gsm_set_error(zt_gsm_error);
12775    gsm_set_message(zt_gsm_message);
12776 #endif
12777    res = setup_zap(0);
12778    /* Make sure we can register our Zap channel type */
12779    if (res)
12780       return AST_MODULE_LOAD_DECLINE;
12781    if (ast_channel_register(&zap_tech)) {
12782       ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
12783       __unload_module();
12784       return -1;
12785    }
12786 #ifdef HAVE_PRI
12787    ast_string_field_init(&inuse, 16);
12788    ast_string_field_set(&inuse, name, "GR-303InUse");
12789    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
12790    ast_register_application(zapCD_app, app_zapCD, zapCD_synopsis, zapCD_tdesc);
12791         ast_register_application(zapInband_app, app_zapInband, zapInband_synopsis, zapInband_tdesc);
12792 #endif   
12793    ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc);
12794    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
12795 #ifdef HAVE_GSMAT
12796    ast_cli_register(&gsm_send_sms);
12797    ast_cli_register(&gsm_send_pdu);
12798    ast_cli_register(&gsm_show_status);
12799    ast_cli_register_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0]));
12800 #endif
12801    
12802    memset(round_robin, 0, sizeof(round_robin));
12803    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
12804    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
12805    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
12806    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
12807    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
12808    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
12809    ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
12810 
12811    return res;
12812 }
12813 
12814 #ifdef HAVE_PRI
12815 static int zt_tdd_sendtext(struct ast_channel *c, const char *text);
12816 
12817 static int zt_pri_sendtext(struct ast_channel *c, const char *text) {
12818  struct zt_pvt *p = c->tech_pvt;
12819  if (!p) return -1;
12820  if (!p->pri) return -1;
12821        if (strlen(text)) {
12822       if (p->pri) {
12823           if (!pri_grab(p, p->pri)) {
12824       // ast_log(LOG_NOTICE, "Sending Display IE  '%s'\n", text);
12825          pri_information_display(p->pri->pri,p->call,(char *)text);
12826          pri_rel(p->pri);
12827              } else ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
12828       }
12829        }
12830  return 0;
12831 }
12832 #endif
12833 
12834 static int zt_sendtext(struct ast_channel *c, const char *text) {
12835  struct zt_pvt *p = c->tech_pvt;
12836  if (!p) return -1;
12837  if (p->sig == SIG_PRI) {
12838 #ifdef HAVE_PRI
12839    return zt_pri_sendtext(c, text);
12840 #endif
12841  } else if (p->sig == SIG_GSM) {
12842  } else {
12843    return zt_tdd_sendtext(c, text);
12844  }
12845  return -1;
12846 }
12847 
12848 static int zt_sendmessage(struct ast_channel *c, const char *dest, const char *text, int ispdu) {
12849 struct zt_pvt *p = c->tech_pvt;
12850  if (!p) return -1;
12851  if (p->sig == SIG_PRI) {
12852 #ifdef HAVE_PRI
12853    if (ispdu) {
12854        ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP ISDN channel\n");
12855        return -1;
12856    }
12857    return zt_pri_sendtext(c, text);
12858 #endif
12859  } else if (p->sig == SIG_GSM) {
12860 #ifdef HAVE_GSMAT
12861      return zt_gsm_sendtext(c, dest, text, ispdu);
12862 #endif
12863  } else {
12864    if (ispdu) {
12865        ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP channel\n");
12866        return -1;
12867    }
12868    return zt_tdd_sendtext(c, text);
12869  }
12870  return -1;
12871 }
12872 
12873 static int zt_tdd_sendtext(struct ast_channel *c, const char *text)
12874 {
12875 #define  END_SILENCE_LEN 400
12876 #define  HEADER_MS 50
12877 #define  TRAILER_MS 5
12878 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
12879 #define  ASCII_BYTES_PER_CHAR 80
12880 
12881    unsigned char *buf,*mybuf;
12882    struct zt_pvt *p = c->tech_pvt;
12883    struct pollfd fds[1];
12884    int size,res,fd,len,x;
12885    int bytes=0;
12886    /* Initial carrier (imaginary) */
12887    float cr = 1.0;
12888    float ci = 0.0;
12889    float scont = 0.0;
12890    int index;
12891 
12892 
12893    index = zt_get_index(c, p, 0);
12894    if (index < 0) {
12895       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
12896       return -1;
12897    }
12898    if (!text[0]) return(0); /* if nothing to send, dont */
12899    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
12900    if (p->mate) 
12901       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
12902    else
12903       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
12904    if (!buf)
12905       return -1;
12906    mybuf = buf;
12907    if (p->mate) {
12908       int codec = AST_LAW(p);
12909       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
12910          PUT_CLID_MARKMS;
12911       }
12912       /* Put actual message */
12913       for (x = 0; text[x]; x++) {
12914          PUT_CLID(text[x]);
12915       }
12916       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
12917          PUT_CLID_MARKMS;
12918       }
12919       len = bytes;
12920       buf = mybuf;
12921    } else {
12922       len = tdd_generate(p->tdd, buf, text);
12923       if (len < 1) {
12924          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
12925          free(mybuf);
12926          return -1;
12927       }
12928    }
12929    memset(buf + len, 0x7f, END_SILENCE_LEN);
12930    len += END_SILENCE_LEN;
12931    fd = p->subs[index].zfd;
12932    while (len) {
12933       if (ast_check_hangup(c)) {
12934          free(mybuf);
12935          return -1;
12936       }
12937       size = len;
12938       if (size > READ_SIZE)
12939          size = READ_SIZE;
12940       fds[0].fd = fd;
12941       fds[0].events = POLLOUT | POLLPRI;
12942       fds[0].revents = 0;
12943       res = poll(fds, 1, -1);
12944       if (!res) {
12945          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
12946          continue;
12947       }
12948         /* if got exception */
12949       if (fds[0].revents & POLLPRI) {
12950          ast_free(mybuf);
12951          return -1;
12952       }
12953       if (!(fds[0].revents & POLLOUT)) {
12954          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
12955          continue;
12956       }
12957       res = write(fd, buf, size);
12958       if (res != size) {
12959          if (res == -1) {
12960             free(mybuf);
12961             return -1;
12962          }
12963          if (option_debug)
12964             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
12965          break;
12966       }
12967       len -= size;
12968       buf += size;
12969    }
12970    free(mybuf);
12971    return(0);
12972 }
12973 
12974 
12975 static int reload(void)
12976 {
12977    int res = 0;
12978 
12979    res = setup_zap(1);
12980    if (res) {
12981       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
12982       return -1;
12983    }
12984    return 0;
12985 }
12986 
12987 /* This is a workaround so that menuselect displays a proper description
12988  * AST_MODULE_INFO(, , "Zapata Telephony"
12989  */
12990 
12991 #ifdef ZAPATA_PRI
12992 #define tdesc "Zapata Telephony w/PRI"
12993 #else
12994 #define tdesc "Zapata Telephony"
12995 #endif
12996 
12997 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
12998       .load = load_module,
12999       .unload = unload_module,
13000       .reload = reload,
13001           );
13002 
13003 

Generated on Thu Oct 8 21:56:00 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6